@flowscripter/dynamic-cli-framework
    Preparing search index...

    Class KeyValueServiceProvider

    Provides a generic, per-scope key-value store for commands and services (KeyValueService).

    The underlying data is read from/written to the same configuration file managed by ConfigurationServiceProvider - see ConfigurationServiceProvider.getKeyValueData and ConfigurationServiceProvider.flushIfDirty, reached via a direct constructor reference wired up by BaseCLI (never via Context, since that would expose config-file read/write access more broadly than intended).

    Its serviceId is KEY_VALUE_SERVICE_ID and its ServiceInfo.service is a placeholder (UnreachableKeyValueService) - real access always goes through a per-consumer decorated Context from getContextForScope, applied by runner.ts.

    Any node within a value passed to KeyValueService.set can be wrapped in Secret - at any depth - to have that node, and only that node, stored as an OS-native secret. When a node is wrapped in Secret, its value (of any shape) is JSON-serialized and stored as a single OS-native secret via Bun.secrets, with a sentinel value of the format __SECRET__:<bun_secret_name> substituted in its place in the structure that gets stored in the config file. Everything else in the value is stored as plain (unencrypted) config data. The sentinel prefix __SECRET__: is reserved and must not be used for regular key-value data.

    Independently of how a value was written, KeyValueService.get recursively resolves any string leaf - at any depth within the retrieved value - which starts with the sentinel prefix, via the OS secret store. This means a secret reference may also be hand-embedded (nested arbitrarily deep) directly within a plain, non-secret value in the config file.

    Secret support requires secretServiceEnabled=true in the constructor (which also requires keyValueServiceEnabled=true on the ConfigurationServiceProvider to have config enabled).

    As an example of the underlying config file structure:

    {
    "defaults": {
    ...
    },
    "key-values": {
    "commands": {
    "command1": {
    "foo1": "bar1",
    "foo2": "__SECRET__:command_command1_foo2",
    "foo3": {
    "nested": ["a", "__SECRET__:command_command1_foo3_nested"]
    }
    },
    "command2": {
    "foo1": "bar3"
    }
    },
    "services": {
    "service-id-1": {
    "foo1": "bar"
    }
    }
    }
    }

    Implements

    Index
    keyValueServiceEnabled: boolean
    secretServiceEnabled: boolean
    serviceId: string = KEY_VALUE_SERVICE_ID

    The ID which identifies the service provided.

    servicePriority: number

    Used to determine the order in which multiple service instances will be initialised. Higher values will be initialised before lower values.

    • Return a Context which delegates every lookup to context unchanged, except getServiceById(KEY_VALUE_SERVICE_ID), which resolves to the scope-bound instance from getScopedKeyValueService for the given scope. Used by runner.ts to give each command/service/task a KeyValueService isolated to its own scope, invisibly at the call site.

      Returns context itself, unchanged, if neither keyValueServiceEnabled nor secretServiceEnabled is set.

      Also forwards addServiceInstance, even though it is not part of the Context interface: runner.ts applies this same scoping to every ServiceProvider's initService() call (scope "service"), and PluginServiceProvider.initService() relies on casting its received context to DefaultContext to register services discovered from plugins at runtime - a capability every ServiceProvider already had before this scoping was introduced, since initService() always received the real DefaultContext directly.

      Parameters

      Returns Context

    • Return the KeyValueService bound to the given scope, creating (and caching) it on first request. The returned instance is permanently bound to that scope's data and secret prefix - it is never re-pointed, so it may be held and used for as long as its owning command/service/task is alive without racing any other scope's window.

      Parameters

      • scopeType: KeyValueServiceScopeType

        whether scopeKey is a command name or a service/task ID.

      • scopeKey: string

        the command name or service/task ID to scope the key-value data to.

      Returns KeyValueService

      if neither keyValueServiceEnabled nor secretServiceEnabled is set.