@endora-commerce/platform 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +58 -0
- package/dist/cli/dispatch.d.ts +146 -0
- package/dist/cli/dispatch.d.ts.map +1 -0
- package/dist/cli/dispatch.js +259 -0
- package/dist/cli/dispatch.js.map +1 -0
- package/dist/cli/index.d.ts +58 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +58 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/module-commands.d.ts +118 -0
- package/dist/cli/module-commands.d.ts.map +1 -0
- package/dist/cli/module-commands.js +120 -0
- package/dist/cli/module-commands.js.map +1 -0
- package/dist/commands/actor.d.ts +19 -0
- package/dist/commands/actor.d.ts.map +1 -0
- package/dist/commands/actor.js +45 -0
- package/dist/commands/actor.js.map +1 -0
- package/dist/commands/audit-from-context.d.ts +24 -0
- package/dist/commands/audit-from-context.d.ts.map +1 -0
- package/dist/commands/audit-from-context.js +28 -0
- package/dist/commands/audit-from-context.js.map +1 -0
- package/dist/commands/command-bus.d.ts +40 -0
- package/dist/commands/command-bus.d.ts.map +1 -0
- package/dist/commands/command-bus.js +46 -0
- package/dist/commands/command-bus.js.map +1 -0
- package/dist/commands/command.d.ts +76 -0
- package/dist/commands/command.d.ts.map +1 -0
- package/dist/commands/command.js +2 -0
- package/dist/commands/command.js.map +1 -0
- package/dist/commands/index.d.ts +65 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +57 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/reversible.d.ts +66 -0
- package/dist/commands/reversible.d.ts.map +1 -0
- package/dist/commands/reversible.js +41 -0
- package/dist/commands/reversible.js.map +1 -0
- package/dist/composition/compose-app.d.ts +305 -0
- package/dist/composition/compose-app.d.ts.map +1 -0
- package/dist/composition/compose-app.js +939 -0
- package/dist/composition/compose-app.js.map +1 -0
- package/dist/composition/index.d.ts +92 -0
- package/dist/composition/index.d.ts.map +1 -0
- package/dist/composition/index.js +175 -0
- package/dist/composition/index.js.map +1 -0
- package/dist/composition/newsletter-token-secret.d.ts +19 -0
- package/dist/composition/newsletter-token-secret.d.ts.map +1 -0
- package/dist/composition/newsletter-token-secret.js +24 -0
- package/dist/composition/newsletter-token-secret.js.map +1 -0
- package/dist/composition/process-runs-workers.d.ts +17 -0
- package/dist/composition/process-runs-workers.d.ts.map +1 -0
- package/dist/composition/process-runs-workers.js +19 -0
- package/dist/composition/process-runs-workers.js.map +1 -0
- package/dist/db/baseline-migration-inventory.d.ts +15 -0
- package/dist/db/baseline-migration-inventory.d.ts.map +1 -0
- package/dist/db/baseline-migration-inventory.js +115 -0
- package/dist/db/baseline-migration-inventory.js.map +1 -0
- package/dist/db/configured-entities.d.ts +74 -0
- package/dist/db/configured-entities.d.ts.map +1 -0
- package/dist/db/configured-entities.js +20 -0
- package/dist/db/configured-entities.js.map +1 -0
- package/dist/db/configured-migrations.d.ts +199 -0
- package/dist/db/configured-migrations.d.ts.map +1 -0
- package/dist/db/configured-migrations.js +181 -0
- package/dist/db/configured-migrations.js.map +1 -0
- package/dist/db/index.d.ts +54 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +54 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrate.d.ts +21 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +48 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/migration-order.d.ts +159 -0
- package/dist/db/migration-order.d.ts.map +1 -0
- package/dist/db/migration-order.js +273 -0
- package/dist/db/migration-order.js.map +1 -0
- package/dist/db/mikro-orm.config.d.ts +51 -0
- package/dist/db/mikro-orm.config.d.ts.map +1 -0
- package/dist/db/mikro-orm.config.js +64 -0
- package/dist/db/mikro-orm.config.js.map +1 -0
- package/dist/db/orm.d.ts +40 -0
- package/dist/db/orm.d.ts.map +1 -0
- package/dist/db/orm.js +25 -0
- package/dist/db/orm.js.map +1 -0
- package/dist/db/platform-schema.d.ts +102 -0
- package/dist/db/platform-schema.d.ts.map +1 -0
- package/dist/db/platform-schema.js +79 -0
- package/dist/db/platform-schema.js.map +1 -0
- package/dist/db/pluralizing-naming-strategy.d.ts +16 -0
- package/dist/db/pluralizing-naming-strategy.d.ts.map +1 -0
- package/dist/db/pluralizing-naming-strategy.js +66 -0
- package/dist/db/pluralizing-naming-strategy.js.map +1 -0
- package/dist/demo/guard.d.ts +101 -0
- package/dist/demo/guard.d.ts.map +1 -0
- package/dist/demo/guard.js +168 -0
- package/dist/demo/guard.js.map +1 -0
- package/dist/demo/host-command.d.ts +133 -0
- package/dist/demo/host-command.d.ts.map +1 -0
- package/dist/demo/host-command.js +113 -0
- package/dist/demo/host-command.js.map +1 -0
- package/dist/demo/index.d.ts +82 -0
- package/dist/demo/index.d.ts.map +1 -0
- package/dist/demo/index.js +82 -0
- package/dist/demo/index.js.map +1 -0
- package/dist/demo/packages.d.ts +67 -0
- package/dist/demo/packages.d.ts.map +1 -0
- package/dist/demo/packages.js +132 -0
- package/dist/demo/packages.js.map +1 -0
- package/dist/demo/plan.d.ts +111 -0
- package/dist/demo/plan.d.ts.map +1 -0
- package/dist/demo/plan.js +74 -0
- package/dist/demo/plan.js.map +1 -0
- package/dist/demo/report.d.ts +17 -0
- package/dist/demo/report.d.ts.map +1 -0
- package/dist/demo/report.js +85 -0
- package/dist/demo/report.js.map +1 -0
- package/dist/demo/runner.d.ts +207 -0
- package/dist/demo/runner.d.ts.map +1 -0
- package/dist/demo/runner.js +169 -0
- package/dist/demo/runner.js.map +1 -0
- package/dist/demo/scope.d.ts +44 -0
- package/dist/demo/scope.d.ts.map +1 -0
- package/dist/demo/scope.js +44 -0
- package/dist/demo/scope.js.map +1 -0
- package/dist/env/index.d.ts +68 -0
- package/dist/env/index.d.ts.map +1 -0
- package/dist/env/index.js +427 -0
- package/dist/env/index.js.map +1 -0
- package/dist/events/bus.d.ts +29 -0
- package/dist/events/bus.d.ts.map +1 -0
- package/dist/events/bus.js +67 -0
- package/dist/events/bus.js.map +1 -0
- package/dist/events/index.d.ts +19 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +19 -0
- package/dist/events/index.js.map +1 -0
- package/dist/http/cursor.d.ts +10 -0
- package/dist/http/cursor.d.ts.map +1 -0
- package/dist/http/cursor.js +20 -0
- package/dist/http/cursor.js.map +1 -0
- package/dist/http/error-envelope.d.ts +127 -0
- package/dist/http/error-envelope.d.ts.map +1 -0
- package/dist/http/error-envelope.js +402 -0
- package/dist/http/error-envelope.js.map +1 -0
- package/dist/http/health.d.ts +88 -0
- package/dist/http/health.d.ts.map +1 -0
- package/dist/http/health.js +77 -0
- package/dist/http/health.js.map +1 -0
- package/dist/http/index.d.ts +50 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +50 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/interceptors/dispatch.d.ts +14 -0
- package/dist/http/interceptors/dispatch.d.ts.map +1 -0
- package/dist/http/interceptors/dispatch.js +113 -0
- package/dist/http/interceptors/dispatch.js.map +1 -0
- package/dist/http/interceptors/index.d.ts +6 -0
- package/dist/http/interceptors/index.d.ts.map +1 -0
- package/dist/http/interceptors/index.js +5 -0
- package/dist/http/interceptors/index.js.map +1 -0
- package/dist/http/interceptors/registry.d.ts +44 -0
- package/dist/http/interceptors/registry.d.ts.map +1 -0
- package/dist/http/interceptors/registry.js +123 -0
- package/dist/http/interceptors/registry.js.map +1 -0
- package/dist/http/interceptors/route-table.d.ts +33 -0
- package/dist/http/interceptors/route-table.d.ts.map +1 -0
- package/dist/http/interceptors/route-table.js +39 -0
- package/dist/http/interceptors/route-table.js.map +1 -0
- package/dist/http/interceptors/types.d.ts +101 -0
- package/dist/http/interceptors/types.d.ts.map +1 -0
- package/dist/http/interceptors/types.js +2 -0
- package/dist/http/interceptors/types.js.map +1 -0
- package/dist/http/interceptors/validation.d.ts +22 -0
- package/dist/http/interceptors/validation.d.ts.map +1 -0
- package/dist/http/interceptors/validation.js +39 -0
- package/dist/http/interceptors/validation.js.map +1 -0
- package/dist/http/logger.d.ts +9 -0
- package/dist/http/logger.d.ts.map +1 -0
- package/dist/http/logger.js +25 -0
- package/dist/http/logger.js.map +1 -0
- package/dist/http/openapi.d.ts +21 -0
- package/dist/http/openapi.d.ts.map +1 -0
- package/dist/http/openapi.js +114 -0
- package/dist/http/openapi.js.map +1 -0
- package/dist/http/product-audience.d.ts +78 -0
- package/dist/http/product-audience.d.ts.map +1 -0
- package/dist/http/product-audience.js +92 -0
- package/dist/http/product-audience.js.map +1 -0
- package/dist/http/request-actor.d.ts +82 -0
- package/dist/http/request-actor.d.ts.map +1 -0
- package/dist/http/request-actor.js +2 -0
- package/dist/http/request-actor.js.map +1 -0
- package/dist/http/server.d.ts +60 -0
- package/dist/http/server.d.ts.map +1 -0
- package/dist/http/server.js +117 -0
- package/dist/http/server.js.map +1 -0
- package/dist/http/storefront-revalidator.d.ts +29 -0
- package/dist/http/storefront-revalidator.d.ts.map +1 -0
- package/dist/http/storefront-revalidator.js +34 -0
- package/dist/http/storefront-revalidator.js.map +1 -0
- package/dist/http/test-actor-carrier.d.ts +28 -0
- package/dist/http/test-actor-carrier.d.ts.map +1 -0
- package/dist/http/test-actor-carrier.js +10 -0
- package/dist/http/test-actor-carrier.js.map +1 -0
- package/dist/http/trusted-proxy.d.ts +48 -0
- package/dist/http/trusted-proxy.d.ts.map +1 -0
- package/dist/http/trusted-proxy.js +136 -0
- package/dist/http/trusted-proxy.js.map +1 -0
- package/dist/kernel/audit/audit-log-entry.entity.d.ts +33 -0
- package/dist/kernel/audit/audit-log-entry.entity.d.ts.map +1 -0
- package/dist/kernel/audit/audit-log-entry.entity.js +102 -0
- package/dist/kernel/audit/audit-log-entry.entity.js.map +1 -0
- package/dist/kernel/audit/audit-log-service.d.ts +63 -0
- package/dist/kernel/audit/audit-log-service.d.ts.map +1 -0
- package/dist/kernel/audit/audit-log-service.js +107 -0
- package/dist/kernel/audit/audit-log-service.js.map +1 -0
- package/dist/kernel/cache/in-process-cache-registry.d.ts +93 -0
- package/dist/kernel/cache/in-process-cache-registry.d.ts.map +1 -0
- package/dist/kernel/cache/in-process-cache-registry.js +78 -0
- package/dist/kernel/cache/in-process-cache-registry.js.map +1 -0
- package/dist/kernel/cache/shared-drop-marks.d.ts +39 -0
- package/dist/kernel/cache/shared-drop-marks.d.ts.map +1 -0
- package/dist/kernel/cache/shared-drop-marks.js +68 -0
- package/dist/kernel/cache/shared-drop-marks.js.map +1 -0
- package/dist/kernel/compose.d.ts +234 -0
- package/dist/kernel/compose.d.ts.map +1 -0
- package/dist/kernel/compose.js +279 -0
- package/dist/kernel/compose.js.map +1 -0
- package/dist/kernel/container.d.ts +95 -0
- package/dist/kernel/container.d.ts.map +1 -0
- package/dist/kernel/container.js +90 -0
- package/dist/kernel/container.js.map +1 -0
- package/dist/kernel/contribution-sinks.d.ts +106 -0
- package/dist/kernel/contribution-sinks.d.ts.map +1 -0
- package/dist/kernel/contribution-sinks.js +153 -0
- package/dist/kernel/contribution-sinks.js.map +1 -0
- package/dist/kernel/crypto/password-hasher.d.ts +3 -0
- package/dist/kernel/crypto/password-hasher.d.ts.map +1 -0
- package/dist/kernel/crypto/password-hasher.js +44 -0
- package/dist/kernel/crypto/password-hasher.js.map +1 -0
- package/dist/kernel/i18n/error-envelope-options.d.ts +56 -0
- package/dist/kernel/i18n/error-envelope-options.d.ts.map +1 -0
- package/dist/kernel/i18n/error-envelope-options.js +46 -0
- package/dist/kernel/i18n/error-envelope-options.js.map +1 -0
- package/dist/kernel/i18n/error-translation.d.ts +144 -0
- package/dist/kernel/i18n/error-translation.d.ts.map +1 -0
- package/dist/kernel/i18n/error-translation.js +84 -0
- package/dist/kernel/i18n/error-translation.js.map +1 -0
- package/dist/kernel/i18n/request-language.d.ts +80 -0
- package/dist/kernel/i18n/request-language.d.ts.map +1 -0
- package/dist/kernel/i18n/request-language.js +168 -0
- package/dist/kernel/i18n/request-language.js.map +1 -0
- package/dist/kernel/index.d.ts +142 -0
- package/dist/kernel/index.d.ts.map +1 -0
- package/dist/kernel/index.js +160 -0
- package/dist/kernel/index.js.map +1 -0
- package/dist/kernel/lazy-port.d.ts +59 -0
- package/dist/kernel/lazy-port.d.ts.map +1 -0
- package/dist/kernel/lazy-port.js +78 -0
- package/dist/kernel/lazy-port.js.map +1 -0
- package/dist/kernel/lifecycle/activation-resolver.d.ts +63 -0
- package/dist/kernel/lifecycle/activation-resolver.d.ts.map +1 -0
- package/dist/kernel/lifecycle/activation-resolver.js +70 -0
- package/dist/kernel/lifecycle/activation-resolver.js.map +1 -0
- package/dist/kernel/lifecycle/capability-registry.d.ts +145 -0
- package/dist/kernel/lifecycle/capability-registry.d.ts.map +1 -0
- package/dist/kernel/lifecycle/capability-registry.js +170 -0
- package/dist/kernel/lifecycle/capability-registry.js.map +1 -0
- package/dist/kernel/lifecycle/effective-state.d.ts +126 -0
- package/dist/kernel/lifecycle/effective-state.d.ts.map +1 -0
- package/dist/kernel/lifecycle/effective-state.js +111 -0
- package/dist/kernel/lifecycle/effective-state.js.map +1 -0
- package/dist/kernel/lifecycle/module-registration.entity.d.ts +57 -0
- package/dist/kernel/lifecycle/module-registration.entity.d.ts.map +1 -0
- package/dist/kernel/lifecycle/module-registration.entity.js +111 -0
- package/dist/kernel/lifecycle/module-registration.entity.js.map +1 -0
- package/dist/kernel/lifecycle/plugin-helpers.d.ts +165 -0
- package/dist/kernel/lifecycle/plugin-helpers.d.ts.map +1 -0
- package/dist/kernel/lifecycle/plugin-helpers.js +395 -0
- package/dist/kernel/lifecycle/plugin-helpers.js.map +1 -0
- package/dist/kernel/lifecycle/registry-cache.d.ts +318 -0
- package/dist/kernel/lifecycle/registry-cache.d.ts.map +1 -0
- package/dist/kernel/lifecycle/registry-cache.js +509 -0
- package/dist/kernel/lifecycle/registry-cache.js.map +1 -0
- package/dist/kernel/lifecycle/required-modules.d.ts +137 -0
- package/dist/kernel/lifecycle/required-modules.d.ts.map +1 -0
- package/dist/kernel/lifecycle/required-modules.js +80 -0
- package/dist/kernel/lifecycle/required-modules.js.map +1 -0
- package/dist/kernel/lifecycle/unique-module-ids.d.ts +58 -0
- package/dist/kernel/lifecycle/unique-module-ids.d.ts.map +1 -0
- package/dist/kernel/lifecycle/unique-module-ids.js +82 -0
- package/dist/kernel/lifecycle/unique-module-ids.js.map +1 -0
- package/dist/kernel/logging.d.ts +116 -0
- package/dist/kernel/logging.d.ts.map +1 -0
- package/dist/kernel/logging.js +71 -0
- package/dist/kernel/logging.js.map +1 -0
- package/dist/kernel/module-context.d.ts +563 -0
- package/dist/kernel/module-context.d.ts.map +1 -0
- package/dist/kernel/module-context.js +670 -0
- package/dist/kernel/module-context.js.map +1 -0
- package/dist/kernel/ports/audit.d.ts +115 -0
- package/dist/kernel/ports/audit.d.ts.map +1 -0
- package/dist/kernel/ports/audit.js +2 -0
- package/dist/kernel/ports/audit.js.map +1 -0
- package/dist/kernel/ports/organizations.d.ts +56 -0
- package/dist/kernel/ports/organizations.d.ts.map +1 -0
- package/dist/kernel/ports/organizations.js +2 -0
- package/dist/kernel/ports/organizations.js.map +1 -0
- package/dist/kernel/ports/provide.d.ts +14 -0
- package/dist/kernel/ports/provide.d.ts.map +1 -0
- package/dist/kernel/ports/provide.js +50 -0
- package/dist/kernel/ports/provide.js.map +1 -0
- package/dist/kernel/ports/require-admin.d.ts +61 -0
- package/dist/kernel/ports/require-admin.d.ts.map +1 -0
- package/dist/kernel/ports/require-admin.js +2 -0
- package/dist/kernel/ports/require-admin.js.map +1 -0
- package/dist/kernel/ports/require-customer.d.ts +17 -0
- package/dist/kernel/ports/require-customer.d.ts.map +1 -0
- package/dist/kernel/ports/require-customer.js +2 -0
- package/dist/kernel/ports/require-customer.js.map +1 -0
- package/dist/kernel/ports/sales-channel.d.ts +84 -0
- package/dist/kernel/ports/sales-channel.d.ts.map +1 -0
- package/dist/kernel/ports/sales-channel.js +2 -0
- package/dist/kernel/ports/sales-channel.js.map +1 -0
- package/dist/kernel/ports/settings.d.ts +59 -0
- package/dist/kernel/ports/settings.d.ts.map +1 -0
- package/dist/kernel/ports/settings.js +2 -0
- package/dist/kernel/ports/settings.js.map +1 -0
- package/dist/kernel/public-api-base-url.d.ts +98 -0
- package/dist/kernel/public-api-base-url.d.ts.map +1 -0
- package/dist/kernel/public-api-base-url.js +144 -0
- package/dist/kernel/public-api-base-url.js.map +1 -0
- package/dist/kernel/request-scope-hook.d.ts +63 -0
- package/dist/kernel/request-scope-hook.d.ts.map +1 -0
- package/dist/kernel/request-scope-hook.js +67 -0
- package/dist/kernel/request-scope-hook.js.map +1 -0
- package/dist/kernel/sales-channels/channel-bridge-registry.d.ts +109 -0
- package/dist/kernel/sales-channels/channel-bridge-registry.d.ts.map +1 -0
- package/dist/kernel/sales-channels/channel-bridge-registry.js +75 -0
- package/dist/kernel/sales-channels/channel-bridge-registry.js.map +1 -0
- package/dist/kernel/sales-channels/compose.d.ts +69 -0
- package/dist/kernel/sales-channels/compose.d.ts.map +1 -0
- package/dist/kernel/sales-channels/compose.js +43 -0
- package/dist/kernel/sales-channels/compose.js.map +1 -0
- package/dist/kernel/sales-channels/default-channel-reconciler.d.ts +66 -0
- package/dist/kernel/sales-channels/default-channel-reconciler.d.ts.map +1 -0
- package/dist/kernel/sales-channels/default-channel-reconciler.js +91 -0
- package/dist/kernel/sales-channels/default-channel-reconciler.js.map +1 -0
- package/dist/kernel/sales-channels/no-system-default-channel.error.d.ts +28 -0
- package/dist/kernel/sales-channels/no-system-default-channel.error.d.ts.map +1 -0
- package/dist/kernel/sales-channels/no-system-default-channel.error.js +33 -0
- package/dist/kernel/sales-channels/no-system-default-channel.error.js.map +1 -0
- package/dist/kernel/sales-channels/request-channel-assortment.d.ts +72 -0
- package/dist/kernel/sales-channels/request-channel-assortment.d.ts.map +1 -0
- package/dist/kernel/sales-channels/request-channel-assortment.js +83 -0
- package/dist/kernel/sales-channels/request-channel-assortment.js.map +1 -0
- package/dist/kernel/sales-channels/sales-channel-membership.service.d.ts +157 -0
- package/dist/kernel/sales-channels/sales-channel-membership.service.d.ts.map +1 -0
- package/dist/kernel/sales-channels/sales-channel-membership.service.js +302 -0
- package/dist/kernel/sales-channels/sales-channel-membership.service.js.map +1 -0
- package/dist/kernel/sales-channels/sales-channel-resolver.middleware.d.ts +76 -0
- package/dist/kernel/sales-channels/sales-channel-resolver.middleware.d.ts.map +1 -0
- package/dist/kernel/sales-channels/sales-channel-resolver.middleware.js +184 -0
- package/dist/kernel/sales-channels/sales-channel-resolver.middleware.js.map +1 -0
- package/dist/kernel/sales-channels/sales-channel-resolver.service.d.ts +82 -0
- package/dist/kernel/sales-channels/sales-channel-resolver.service.d.ts.map +1 -0
- package/dist/kernel/sales-channels/sales-channel-resolver.service.js +126 -0
- package/dist/kernel/sales-channels/sales-channel-resolver.service.js.map +1 -0
- package/dist/kernel/sales-channels/sales-channel.entity.d.ts +50 -0
- package/dist/kernel/sales-channels/sales-channel.entity.d.ts.map +1 -0
- package/dist/kernel/sales-channels/sales-channel.entity.js +132 -0
- package/dist/kernel/sales-channels/sales-channel.entity.js.map +1 -0
- package/dist/kernel/sales-channels/sales-channels-cache.d.ts +170 -0
- package/dist/kernel/sales-channels/sales-channels-cache.d.ts.map +1 -0
- package/dist/kernel/sales-channels/sales-channels-cache.js +243 -0
- package/dist/kernel/sales-channels/sales-channels-cache.js.map +1 -0
- package/dist/kernel/scope.d.ts +153 -0
- package/dist/kernel/scope.d.ts.map +1 -0
- package/dist/kernel/scope.js +172 -0
- package/dist/kernel/scope.js.map +1 -0
- package/dist/kernel/settings/compose.d.ts +49 -0
- package/dist/kernel/settings/compose.d.ts.map +1 -0
- package/dist/kernel/settings/compose.js +21 -0
- package/dist/kernel/settings/compose.js.map +1 -0
- package/dist/kernel/settings/manifest-reconciler.d.ts +78 -0
- package/dist/kernel/settings/manifest-reconciler.d.ts.map +1 -0
- package/dist/kernel/settings/manifest-reconciler.js +343 -0
- package/dist/kernel/settings/manifest-reconciler.js.map +1 -0
- package/dist/kernel/settings/secret-value-codec.d.ts +52 -0
- package/dist/kernel/settings/secret-value-codec.d.ts.map +1 -0
- package/dist/kernel/settings/secret-value-codec.js +102 -0
- package/dist/kernel/settings/secret-value-codec.js.map +1 -0
- package/dist/kernel/settings/setting-group.entity.d.ts +25 -0
- package/dist/kernel/settings/setting-group.entity.d.ts.map +1 -0
- package/dist/kernel/settings/setting-group.entity.js +79 -0
- package/dist/kernel/settings/setting-group.entity.js.map +1 -0
- package/dist/kernel/settings/setting-value.entity.d.ts +23 -0
- package/dist/kernel/settings/setting-value.entity.d.ts.map +1 -0
- package/dist/kernel/settings/setting-value.entity.js +66 -0
- package/dist/kernel/settings/setting-value.entity.js.map +1 -0
- package/dist/kernel/settings/setting.entity.d.ts +56 -0
- package/dist/kernel/settings/setting.entity.d.ts.map +1 -0
- package/dist/kernel/settings/setting.entity.js +147 -0
- package/dist/kernel/settings/setting.entity.js.map +1 -0
- package/dist/kernel/settings/settings-cache.d.ts +158 -0
- package/dist/kernel/settings/settings-cache.d.ts.map +1 -0
- package/dist/kernel/settings/settings-cache.js +253 -0
- package/dist/kernel/settings/settings-cache.js.map +1 -0
- package/dist/kernel/settings/settings.service.d.ts +142 -0
- package/dist/kernel/settings/settings.service.d.ts.map +1 -0
- package/dist/kernel/settings/settings.service.js +294 -0
- package/dist/kernel/settings/settings.service.js.map +1 -0
- package/dist/lifecycle/backend.d.ts +51 -0
- package/dist/lifecycle/backend.d.ts.map +1 -0
- package/dist/lifecycle/backend.js +40 -0
- package/dist/lifecycle/backend.js.map +1 -0
- package/dist/lifecycle/commands/activation.commands.d.ts +97 -0
- package/dist/lifecycle/commands/activation.commands.d.ts.map +1 -0
- package/dist/lifecycle/commands/activation.commands.js +142 -0
- package/dist/lifecycle/commands/activation.commands.js.map +1 -0
- package/dist/lifecycle/commands/disable.d.ts +3 -0
- package/dist/lifecycle/commands/disable.d.ts.map +1 -0
- package/dist/lifecycle/commands/disable.js +126 -0
- package/dist/lifecycle/commands/disable.js.map +1 -0
- package/dist/lifecycle/commands/enable.d.ts +3 -0
- package/dist/lifecycle/commands/enable.d.ts.map +1 -0
- package/dist/lifecycle/commands/enable.js +102 -0
- package/dist/lifecycle/commands/enable.js.map +1 -0
- package/dist/lifecycle/commands/install.d.ts +3 -0
- package/dist/lifecycle/commands/install.d.ts.map +1 -0
- package/dist/lifecycle/commands/install.js +263 -0
- package/dist/lifecycle/commands/install.js.map +1 -0
- package/dist/lifecycle/commands/operator-entry.d.ts +104 -0
- package/dist/lifecycle/commands/operator-entry.d.ts.map +1 -0
- package/dist/lifecycle/commands/operator-entry.js +127 -0
- package/dist/lifecycle/commands/operator-entry.js.map +1 -0
- package/dist/lifecycle/commands/operator-runtime.d.ts +147 -0
- package/dist/lifecycle/commands/operator-runtime.d.ts.map +1 -0
- package/dist/lifecycle/commands/operator-runtime.js +40 -0
- package/dist/lifecycle/commands/operator-runtime.js.map +1 -0
- package/dist/lifecycle/commands/status.d.ts +3 -0
- package/dist/lifecycle/commands/status.d.ts.map +1 -0
- package/dist/lifecycle/commands/status.js +108 -0
- package/dist/lifecycle/commands/status.js.map +1 -0
- package/dist/lifecycle/commands/uninstall.d.ts +3 -0
- package/dist/lifecycle/commands/uninstall.d.ts.map +1 -0
- package/dist/lifecycle/commands/uninstall.js +223 -0
- package/dist/lifecycle/commands/uninstall.js.map +1 -0
- package/dist/lifecycle/divergence-declaration.d.ts +74 -0
- package/dist/lifecycle/divergence-declaration.d.ts.map +1 -0
- package/dist/lifecycle/divergence-declaration.js +92 -0
- package/dist/lifecycle/divergence-declaration.js.map +1 -0
- package/dist/lifecycle/i18n/en.json +4 -0
- package/dist/lifecycle/i18n/pl.json +4 -0
- package/dist/lifecycle/index.d.ts +110 -0
- package/dist/lifecycle/index.d.ts.map +1 -0
- package/dist/lifecycle/index.js +189 -0
- package/dist/lifecycle/index.js.map +1 -0
- package/dist/lifecycle/manifest-registry.d.ts +244 -0
- package/dist/lifecycle/manifest-registry.d.ts.map +1 -0
- package/dist/lifecycle/manifest-registry.js +223 -0
- package/dist/lifecycle/manifest-registry.js.map +1 -0
- package/dist/lifecycle/manifest.d.ts +166 -0
- package/dist/lifecycle/manifest.d.ts.map +1 -0
- package/dist/lifecycle/manifest.js +121 -0
- package/dist/lifecycle/manifest.js.map +1 -0
- package/dist/lifecycle/plugin.d.ts +56 -0
- package/dist/lifecycle/plugin.d.ts.map +1 -0
- package/dist/lifecycle/plugin.js +59 -0
- package/dist/lifecycle/plugin.js.map +1 -0
- package/dist/lifecycle/resident.d.ts +16 -0
- package/dist/lifecycle/resident.d.ts.map +1 -0
- package/dist/lifecycle/resident.js +59 -0
- package/dist/lifecycle/resident.js.map +1 -0
- package/dist/lifecycle/routes.admin.d.ts +57 -0
- package/dist/lifecycle/routes.admin.d.ts.map +1 -0
- package/dist/lifecycle/routes.admin.js +162 -0
- package/dist/lifecycle/routes.admin.js.map +1 -0
- package/dist/lifecycle/routes.storefront.d.ts +26 -0
- package/dist/lifecycle/routes.storefront.d.ts.map +1 -0
- package/dist/lifecycle/routes.storefront.js +36 -0
- package/dist/lifecycle/routes.storefront.js.map +1 -0
- package/dist/lifecycle/services/deactivation-ledger.d.ts +216 -0
- package/dist/lifecycle/services/deactivation-ledger.d.ts.map +1 -0
- package/dist/lifecycle/services/deactivation-ledger.js +171 -0
- package/dist/lifecycle/services/deactivation-ledger.js.map +1 -0
- package/dist/lifecycle/services/dep-graph.d.ts +119 -0
- package/dist/lifecycle/services/dep-graph.d.ts.map +1 -0
- package/dist/lifecycle/services/dep-graph.js +334 -0
- package/dist/lifecycle/services/dep-graph.js.map +1 -0
- package/dist/lifecycle/services/gating-graph.d.ts +164 -0
- package/dist/lifecycle/services/gating-graph.d.ts.map +1 -0
- package/dist/lifecycle/services/gating-graph.js +203 -0
- package/dist/lifecycle/services/gating-graph.js.map +1 -0
- package/dist/lifecycle/services/lock.d.ts +27 -0
- package/dist/lifecycle/services/lock.d.ts.map +1 -0
- package/dist/lifecycle/services/lock.js +82 -0
- package/dist/lifecycle/services/lock.js.map +1 -0
- package/dist/lifecycle/services/manifest-loader.d.ts +125 -0
- package/dist/lifecycle/services/manifest-loader.d.ts.map +1 -0
- package/dist/lifecycle/services/manifest-loader.js +210 -0
- package/dist/lifecycle/services/manifest-loader.js.map +1 -0
- package/dist/lifecycle/services/migration-ownership.d.ts +36 -0
- package/dist/lifecycle/services/migration-ownership.d.ts.map +1 -0
- package/dist/lifecycle/services/migration-ownership.js +15 -0
- package/dist/lifecycle/services/migration-ownership.js.map +1 -0
- package/dist/lifecycle/services/module-id-claims.d.ts +38 -0
- package/dist/lifecycle/services/module-id-claims.d.ts.map +1 -0
- package/dist/lifecycle/services/module-id-claims.js +123 -0
- package/dist/lifecycle/services/module-id-claims.js.map +1 -0
- package/dist/lifecycle/services/module-origin.d.ts +55 -0
- package/dist/lifecycle/services/module-origin.d.ts.map +1 -0
- package/dist/lifecycle/services/module-origin.js +47 -0
- package/dist/lifecycle/services/module-origin.js.map +1 -0
- package/dist/lifecycle/services/orchestrator.d.ts +235 -0
- package/dist/lifecycle/services/orchestrator.d.ts.map +1 -0
- package/dist/lifecycle/services/orchestrator.js +954 -0
- package/dist/lifecycle/services/orchestrator.js.map +1 -0
- package/dist/lifecycle/services/presence-load.d.ts +281 -0
- package/dist/lifecycle/services/presence-load.d.ts.map +1 -0
- package/dist/lifecycle/services/presence-load.js +437 -0
- package/dist/lifecycle/services/presence-load.js.map +1 -0
- package/dist/lifecycle/services/static-registry.d.ts +47 -0
- package/dist/lifecycle/services/static-registry.d.ts.map +1 -0
- package/dist/lifecycle/services/static-registry.js +41 -0
- package/dist/lifecycle/services/static-registry.js.map +1 -0
- package/dist/migrations/20260424T165847_core_foundation_init.d.ts +25 -0
- package/dist/migrations/20260424T165847_core_foundation_init.d.ts.map +1 -0
- package/dist/migrations/20260424T165847_core_foundation_init.js +238 -0
- package/dist/migrations/20260424T165847_core_foundation_init.js.map +1 -0
- package/dist/migrations/20260425T050720_core_commerce_init.d.ts +19 -0
- package/dist/migrations/20260425T050720_core_commerce_init.d.ts.map +1 -0
- package/dist/migrations/20260425T050720_core_commerce_init.js +200 -0
- package/dist/migrations/20260425T050720_core_commerce_init.js.map +1 -0
- package/dist/migrations/20260430T101450_core_settings_init.d.ts +25 -0
- package/dist/migrations/20260430T101450_core_settings_init.d.ts.map +1 -0
- package/dist/migrations/20260430T101450_core_settings_init.js +113 -0
- package/dist/migrations/20260430T101450_core_settings_init.js.map +1 -0
- package/dist/migrations/20260430T170044_core_sales_channels_promote.d.ts +67 -0
- package/dist/migrations/20260430T170044_core_sales_channels_promote.d.ts.map +1 -0
- package/dist/migrations/20260430T170044_core_sales_channels_promote.js +101 -0
- package/dist/migrations/20260430T170044_core_sales_channels_promote.js.map +1 -0
- package/dist/migrations/20260506T200657_core_module_lifecycle_init.d.ts +21 -0
- package/dist/migrations/20260506T200657_core_module_lifecycle_init.d.ts.map +1 -0
- package/dist/migrations/20260506T200657_core_module_lifecycle_init.js +41 -0
- package/dist/migrations/20260506T200657_core_module_lifecycle_init.js.map +1 -0
- package/dist/migrations/20260514T111329_core_settings_global_value.d.ts +30 -0
- package/dist/migrations/20260514T111329_core_settings_global_value.d.ts.map +1 -0
- package/dist/migrations/20260514T111329_core_settings_global_value.js +34 -0
- package/dist/migrations/20260514T111329_core_settings_global_value.js.map +1 -0
- package/dist/migrations/20260611T140411_core_settings_secret_value_type.d.ts +26 -0
- package/dist/migrations/20260611T140411_core_settings_secret_value_type.d.ts.map +1 -0
- package/dist/migrations/20260611T140411_core_settings_secret_value_type.js +63 -0
- package/dist/migrations/20260611T140411_core_settings_secret_value_type.js.map +1 -0
- package/dist/migrations/20260611T140419_core_settings_enum_options.d.ts +19 -0
- package/dist/migrations/20260611T140419_core_settings_enum_options.d.ts.map +1 -0
- package/dist/migrations/20260611T140419_core_settings_enum_options.js +23 -0
- package/dist/migrations/20260611T140419_core_settings_enum_options.js.map +1 -0
- package/dist/migrations/20260629T090100_core_settings_hidden_flag.d.ts +20 -0
- package/dist/migrations/20260629T090100_core_settings_hidden_flag.d.ts.map +1 -0
- package/dist/migrations/20260629T090100_core_settings_hidden_flag.js +24 -0
- package/dist/migrations/20260629T090100_core_settings_hidden_flag.js.map +1 -0
- package/dist/migrations/20260717T134752_core_tenant_scope_indexes.d.ts +27 -0
- package/dist/migrations/20260717T134752_core_tenant_scope_indexes.d.ts.map +1 -0
- package/dist/migrations/20260717T134752_core_tenant_scope_indexes.js +32 -0
- package/dist/migrations/20260717T134752_core_tenant_scope_indexes.js.map +1 -0
- package/dist/migrations/20260721T011510_core_settings_credential_ref_value_type.d.ts +24 -0
- package/dist/migrations/20260721T011510_core_settings_credential_ref_value_type.d.ts.map +1 -0
- package/dist/migrations/20260721T011510_core_settings_credential_ref_value_type.js +57 -0
- package/dist/migrations/20260721T011510_core_settings_credential_ref_value_type.js.map +1 -0
- package/dist/migrations/20260816T203339_core_retire_core_activation_settings.d.ts +39 -0
- package/dist/migrations/20260816T203339_core_retire_core_activation_settings.d.ts.map +1 -0
- package/dist/migrations/20260816T203339_core_retire_core_activation_settings.js +59 -0
- package/dist/migrations/20260816T203339_core_retire_core_activation_settings.js.map +1 -0
- package/dist/migrations/20260919T101500_core_module_registrations_boot_converged.d.ts +34 -0
- package/dist/migrations/20260919T101500_core_module_registrations_boot_converged.d.ts.map +1 -0
- package/dist/migrations/20260919T101500_core_module_registrations_boot_converged.js +38 -0
- package/dist/migrations/20260919T101500_core_module_registrations_boot_converged.js.map +1 -0
- package/dist/migrations/baseline-migrations.generated.d.ts +2 -0
- package/dist/migrations/baseline-migrations.generated.d.ts.map +1 -0
- package/dist/migrations/baseline-migrations.generated.js +136 -0
- package/dist/migrations/baseline-migrations.generated.js.map +1 -0
- package/dist/migrations/index.d.ts +62 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +75 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/overlay/deployment-roots.d.ts +37 -0
- package/dist/overlay/deployment-roots.d.ts.map +1 -0
- package/dist/overlay/deployment-roots.js +90 -0
- package/dist/overlay/deployment-roots.js.map +1 -0
- package/dist/overlay/index.d.ts +62 -0
- package/dist/overlay/index.d.ts.map +1 -0
- package/dist/overlay/index.js +62 -0
- package/dist/overlay/index.js.map +1 -0
- package/dist/overlay/overlay-runtime.d.ts +173 -0
- package/dist/overlay/overlay-runtime.d.ts.map +1 -0
- package/dist/overlay/overlay-runtime.js +281 -0
- package/dist/overlay/overlay-runtime.js.map +1 -0
- package/dist/overlay/resolve-overlay.d.ts +41 -0
- package/dist/overlay/resolve-overlay.d.ts.map +1 -0
- package/dist/overlay/resolve-overlay.js +72 -0
- package/dist/overlay/resolve-overlay.js.map +1 -0
- package/dist/packages/index.d.ts +57 -0
- package/dist/packages/index.d.ts.map +1 -0
- package/dist/packages/index.js +57 -0
- package/dist/packages/index.js.map +1 -0
- package/dist/packages/installed-packages.d.ts +79 -0
- package/dist/packages/installed-packages.d.ts.map +1 -0
- package/dist/packages/installed-packages.js +312 -0
- package/dist/packages/installed-packages.js.map +1 -0
- package/dist/packages/package-entity-lookup.d.ts +120 -0
- package/dist/packages/package-entity-lookup.d.ts.map +1 -0
- package/dist/packages/package-entity-lookup.js +17 -0
- package/dist/packages/package-entity-lookup.js.map +1 -0
- package/dist/packages/package-runtime.d.ts +177 -0
- package/dist/packages/package-runtime.d.ts.map +1 -0
- package/dist/packages/package-runtime.js +386 -0
- package/dist/packages/package-runtime.js.map +1 -0
- package/dist/tenancy/derived-scope.d.ts +43 -0
- package/dist/tenancy/derived-scope.d.ts.map +1 -0
- package/dist/tenancy/derived-scope.js +76 -0
- package/dist/tenancy/derived-scope.js.map +1 -0
- package/dist/tenancy/escape-hatch.d.ts +30 -0
- package/dist/tenancy/escape-hatch.d.ts.map +1 -0
- package/dist/tenancy/escape-hatch.js +50 -0
- package/dist/tenancy/escape-hatch.js.map +1 -0
- package/dist/tenancy/filters.d.ts +87 -0
- package/dist/tenancy/filters.d.ts.map +1 -0
- package/dist/tenancy/filters.js +126 -0
- package/dist/tenancy/filters.js.map +1 -0
- package/dist/tenancy/index.d.ts +63 -0
- package/dist/tenancy/index.d.ts.map +1 -0
- package/dist/tenancy/index.js +61 -0
- package/dist/tenancy/index.js.map +1 -0
- package/dist/tenancy/org-scoped.decorator.d.ts +150 -0
- package/dist/tenancy/org-scoped.decorator.d.ts.map +1 -0
- package/dist/tenancy/org-scoped.decorator.js +339 -0
- package/dist/tenancy/org-scoped.decorator.js.map +1 -0
- package/dist/tenancy/org-write-guard.d.ts +106 -0
- package/dist/tenancy/org-write-guard.d.ts.map +1 -0
- package/dist/tenancy/org-write-guard.js +141 -0
- package/dist/tenancy/org-write-guard.js.map +1 -0
- package/dist/tenancy/resolve-tenant-context.d.ts +91 -0
- package/dist/tenancy/resolve-tenant-context.d.ts.map +1 -0
- package/dist/tenancy/resolve-tenant-context.js +85 -0
- package/dist/tenancy/resolve-tenant-context.js.map +1 -0
- package/dist/tenancy/scoped-em.d.ts +10 -0
- package/dist/tenancy/scoped-em.d.ts.map +1 -0
- package/dist/tenancy/scoped-em.js +11 -0
- package/dist/tenancy/scoped-em.js.map +1 -0
- package/dist/tenancy/tenant-context.d.ts +154 -0
- package/dist/tenancy/tenant-context.d.ts.map +1 -0
- package/dist/tenancy/tenant-context.js +109 -0
- package/dist/tenancy/tenant-context.js.map +1 -0
- package/package.json +123 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { Setting } from './setting.entity.js';
|
|
2
|
+
import { SettingValue } from './setting-value.entity.js';
|
|
3
|
+
import { decryptSecretValue, isSecretEnvelope } from './secret-value-codec.js';
|
|
4
|
+
/**
|
|
5
|
+
* SettingsService — the universal getter (US3 / T049).
|
|
6
|
+
*
|
|
7
|
+
* The single read mechanism every other module uses to retrieve a setting's
|
|
8
|
+
* value. A read either **names a real sales channel** or says it has **none**;
|
|
9
|
+
* nothing in between is spellable (feature 072, D-41).
|
|
10
|
+
*
|
|
11
|
+
* Resolution order for a channel-scoped read (`salesChannelId` is a uuid):
|
|
12
|
+
*
|
|
13
|
+
* 0. Channel-id shape check; a non-uuid → throw {@link SettingsChannelIdInvalid}.
|
|
14
|
+
* 1. Cache hit (read-through Redis + per-process LRU).
|
|
15
|
+
* 2. Setting lookup by code; absent → throw {@link SettingNotRegistered}.
|
|
16
|
+
* 3. Scope check; the channel must be in the setting's `salesChannels`
|
|
17
|
+
* collection (or the collection must be empty = "all channels").
|
|
18
|
+
* Otherwise → throw {@link SettingOutOfScopeForChannel}.
|
|
19
|
+
* 4. Per-channel `setting_values` row → return its `value`.
|
|
20
|
+
* 5. Else → `setting.globalValue`, else `setting.defaultValue`.
|
|
21
|
+
*
|
|
22
|
+
* For a **platform-wide** read (`salesChannelId === null`) step 4 is skipped:
|
|
23
|
+
* the answer is `globalValue ?? defaultValue`, the tier the admin service has
|
|
24
|
+
* always written ("Platform-wide global override") and `resolveEffectiveValue`
|
|
25
|
+
* has always resolved, but which had no read API. Three modules independently
|
|
26
|
+
* invented the nil UUID as its spelling and a fourth inlined it — it worked by
|
|
27
|
+
* accident, being well-formed enough for Postgres and matching no row. A
|
|
28
|
+
* setting scoped to a *subset* of channels has no platform-wide answer, so it
|
|
29
|
+
* throws {@link SettingOutOfScopeForChannel} with a `null` channel.
|
|
30
|
+
*
|
|
31
|
+
* No schema change: `setting_values.sales_channel_id` stays `uuid NOT NULL`.
|
|
32
|
+
* The null lives in the read signature, not in a column.
|
|
33
|
+
*
|
|
34
|
+
* The optional caller-supplied schema is validated AFTER the resolved value
|
|
35
|
+
* is materialised; mismatches surface as {@link SettingValueShapeMismatch}.
|
|
36
|
+
*/
|
|
37
|
+
export class SettingNotRegistered extends Error {
|
|
38
|
+
settingCode;
|
|
39
|
+
name = 'SettingNotRegistered';
|
|
40
|
+
code = 'SETTING_NOT_REGISTERED';
|
|
41
|
+
constructor(settingCode) {
|
|
42
|
+
super(`Setting "${settingCode}" is not registered.`);
|
|
43
|
+
this.settingCode = settingCode;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export class SettingOutOfScopeForChannel extends Error {
|
|
47
|
+
settingCode;
|
|
48
|
+
salesChannelId;
|
|
49
|
+
name = 'SettingOutOfScopeForChannel';
|
|
50
|
+
code = 'SETTING_OUT_OF_SCOPE_FOR_CHANNEL';
|
|
51
|
+
constructor(settingCode,
|
|
52
|
+
/** `null` = the read was platform-wide, and this setting is not. */
|
|
53
|
+
salesChannelId) {
|
|
54
|
+
super(salesChannelId === null
|
|
55
|
+
? `Setting "${settingCode}" is scoped to specific sales channels, so it has no platform-wide value.`
|
|
56
|
+
: `Setting "${settingCode}" is not in scope for sales channel "${salesChannelId}".`);
|
|
57
|
+
this.settingCode = settingCode;
|
|
58
|
+
this.salesChannelId = salesChannelId;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The caller passed something that is not a sales-channel id (feature 072,
|
|
63
|
+
* D-42 layer 3).
|
|
64
|
+
*
|
|
65
|
+
* `setting_values.sales_channel_id` is `uuid`, so a channel **code**, an empty
|
|
66
|
+
* string or any other id-shaped string cannot address a row: PostgreSQL rejects
|
|
67
|
+
* the comparison outright. Before this guard the failure surfaced as a driver
|
|
68
|
+
* error naming a column, which every caller's `catch` read as "not configured
|
|
69
|
+
* yet" — that is the whole of the defect family this error exists to end.
|
|
70
|
+
*
|
|
71
|
+
* Thrown **before** the `EntityManager` is touched, and deliberately outside
|
|
72
|
+
* the set of errors a settings read may absorb (D-43): a malformed channel id
|
|
73
|
+
* is a code defect, not a missing value. "No channel" is spelled `null`.
|
|
74
|
+
*/
|
|
75
|
+
export class SettingsChannelIdInvalid extends Error {
|
|
76
|
+
settingCode;
|
|
77
|
+
salesChannelId;
|
|
78
|
+
name = 'SettingsChannelIdInvalid';
|
|
79
|
+
code = 'SETTINGS_CHANNEL_ID_INVALID';
|
|
80
|
+
constructor(settingCode, salesChannelId) {
|
|
81
|
+
super(`"${salesChannelId}" is not a sales-channel id (reading setting "${settingCode}"). ` +
|
|
82
|
+
`Pass a channel uuid, or null for a platform-wide read.`);
|
|
83
|
+
this.settingCode = settingCode;
|
|
84
|
+
this.salesChannelId = salesChannelId;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The shape `sales_channels.id` and `setting_values.sales_channel_id` share.
|
|
89
|
+
* Deliberately not a version-specific UUID pattern: the nil UUID must be
|
|
90
|
+
* rejected as a *spelling of platform-wide*, not as a malformed id, and it is
|
|
91
|
+
* `check-channel-resolution.ts` — which can see the literal — that says so.
|
|
92
|
+
*/
|
|
93
|
+
const CHANNEL_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
94
|
+
export class SettingValueShapeMismatch extends Error {
|
|
95
|
+
settingCode;
|
|
96
|
+
issues;
|
|
97
|
+
name = 'SettingValueShapeMismatch';
|
|
98
|
+
code = 'SETTING_VALUE_SHAPE_MISMATCH';
|
|
99
|
+
constructor(settingCode, issues) {
|
|
100
|
+
super(`Stored value for setting "${settingCode}" does not match the caller's schema.`);
|
|
101
|
+
this.settingCode = settingCode;
|
|
102
|
+
this.issues = issues;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export class SettingsService {
|
|
106
|
+
emFactory;
|
|
107
|
+
cache;
|
|
108
|
+
secretEncryptionKey;
|
|
109
|
+
constructor(emFactory, cache,
|
|
110
|
+
/**
|
|
111
|
+
* Base64 32-byte key for the `secret` value type (feature 043). The
|
|
112
|
+
* cache stores ciphertext envelopes; decryption happens per read in this
|
|
113
|
+
* process so plaintext never sits in Redis.
|
|
114
|
+
*/
|
|
115
|
+
secretEncryptionKey) {
|
|
116
|
+
this.emFactory = emFactory;
|
|
117
|
+
this.cache = cache;
|
|
118
|
+
this.secretEncryptionKey = secretEncryptionKey;
|
|
119
|
+
}
|
|
120
|
+
async get(code, salesChannelId, schema) {
|
|
121
|
+
this.assertChannelId(code, salesChannelId);
|
|
122
|
+
// Cache lookup (covers both real values and "not registered" sentinel).
|
|
123
|
+
if (this.cache) {
|
|
124
|
+
const cached = await this.cache.get(code, salesChannelId);
|
|
125
|
+
if (cached.hit) {
|
|
126
|
+
if (cached.notRegistered)
|
|
127
|
+
throw new SettingNotRegistered(code);
|
|
128
|
+
return this.validate(code, this.maybeDecrypt(cached.value), schema);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const em = this.emFactory();
|
|
132
|
+
const setting = await em.findOne(Setting, { code }, { populate: ['salesChannels'] });
|
|
133
|
+
if (!setting) {
|
|
134
|
+
if (this.cache)
|
|
135
|
+
await this.cache.setNotRegistered(code, salesChannelId);
|
|
136
|
+
throw new SettingNotRegistered(code);
|
|
137
|
+
}
|
|
138
|
+
// Scope check: empty collection ⇒ all channels in scope. A platform-wide
|
|
139
|
+
// read of a channel-subset setting has no answer at all.
|
|
140
|
+
const scope = setting.salesChannels.getItems();
|
|
141
|
+
if (scope.length > 0 && !scope.some((c) => c.id === salesChannelId)) {
|
|
142
|
+
throw new SettingOutOfScopeForChannel(code, salesChannelId);
|
|
143
|
+
}
|
|
144
|
+
const value = salesChannelId === null
|
|
145
|
+
? null
|
|
146
|
+
: await em.findOne(SettingValue, {
|
|
147
|
+
setting,
|
|
148
|
+
salesChannel: { id: salesChannelId },
|
|
149
|
+
});
|
|
150
|
+
const resolved = resolveEffectiveValue(setting, value);
|
|
151
|
+
if (this.cache)
|
|
152
|
+
await this.cache.set(code, salesChannelId, resolved);
|
|
153
|
+
return this.validate(code, this.maybeDecrypt(resolved), schema);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Batch read. Every code is resolved independently; per-code errors are
|
|
157
|
+
* returned as `{ ok: false, error: ... }` instead of throwing, so a single
|
|
158
|
+
* missing code does not poison the whole batch.
|
|
159
|
+
*/
|
|
160
|
+
async getMany(codes, salesChannelId) {
|
|
161
|
+
const out = new Map();
|
|
162
|
+
for (const code of codes) {
|
|
163
|
+
try {
|
|
164
|
+
const value = await this.getRaw(code, salesChannelId);
|
|
165
|
+
out.set(code, { ok: true, value });
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
const name = err.name ?? 'Error';
|
|
169
|
+
if (name === 'SettingNotRegistered') {
|
|
170
|
+
out.set(code, { ok: false, error: 'not_registered' });
|
|
171
|
+
}
|
|
172
|
+
else if (name === 'SettingOutOfScopeForChannel') {
|
|
173
|
+
out.set(code, { ok: false, error: 'out_of_scope' });
|
|
174
|
+
}
|
|
175
|
+
else if (name === 'SettingValueShapeMismatch') {
|
|
176
|
+
out.set(code, {
|
|
177
|
+
ok: false,
|
|
178
|
+
error: 'shape_mismatch',
|
|
179
|
+
details: err.issues,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
// Includes SettingsChannelIdInvalid: a malformed channel is wrong for
|
|
184
|
+
// the whole batch, not a per-code outcome.
|
|
185
|
+
throw err;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
191
|
+
/** Raw-read variant used by `getMany` — no caller schema, returns `unknown`. */
|
|
192
|
+
async getRaw(code, salesChannelId) {
|
|
193
|
+
this.assertChannelId(code, salesChannelId);
|
|
194
|
+
if (this.cache) {
|
|
195
|
+
const cached = await this.cache.get(code, salesChannelId);
|
|
196
|
+
if (cached.hit) {
|
|
197
|
+
if (cached.notRegistered)
|
|
198
|
+
throw new SettingNotRegistered(code);
|
|
199
|
+
return this.maybeDecrypt(cached.value);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const em = this.emFactory();
|
|
203
|
+
const setting = await em.findOne(Setting, { code }, { populate: ['salesChannels'] });
|
|
204
|
+
if (!setting) {
|
|
205
|
+
if (this.cache)
|
|
206
|
+
await this.cache.setNotRegistered(code, salesChannelId);
|
|
207
|
+
throw new SettingNotRegistered(code);
|
|
208
|
+
}
|
|
209
|
+
const scope = setting.salesChannels.getItems();
|
|
210
|
+
if (scope.length > 0 && !scope.some((c) => c.id === salesChannelId)) {
|
|
211
|
+
throw new SettingOutOfScopeForChannel(code, salesChannelId);
|
|
212
|
+
}
|
|
213
|
+
const value = salesChannelId === null
|
|
214
|
+
? null
|
|
215
|
+
: await em.findOne(SettingValue, {
|
|
216
|
+
setting,
|
|
217
|
+
salesChannel: { id: salesChannelId },
|
|
218
|
+
});
|
|
219
|
+
const resolved = resolveEffectiveValue(setting, value);
|
|
220
|
+
if (this.cache)
|
|
221
|
+
await this.cache.set(code, salesChannelId, resolved);
|
|
222
|
+
return this.maybeDecrypt(resolved);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* The seam guard (D-42 layer 3). Runs before the cache and before the
|
|
226
|
+
* `EntityManager`, so a caller learns it passed a non-id rather than the
|
|
227
|
+
* driver reporting a column it has never heard of.
|
|
228
|
+
*/
|
|
229
|
+
assertChannelId(code, salesChannelId) {
|
|
230
|
+
if (salesChannelId === null)
|
|
231
|
+
return;
|
|
232
|
+
if (!CHANNEL_ID_PATTERN.test(salesChannelId)) {
|
|
233
|
+
throw new SettingsChannelIdInvalid(code, salesChannelId);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
validate(code, value, schema) {
|
|
237
|
+
const r = schema.safeParse(value);
|
|
238
|
+
if (!r.success)
|
|
239
|
+
throw new SettingValueShapeMismatch(code, r.error.issues);
|
|
240
|
+
return r.data;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Secret settings (feature 043) resolve to a ciphertext envelope; backend
|
|
244
|
+
* consumers receive the plaintext. Non-envelope values (every other value
|
|
245
|
+
* type, plus legacy plaintext secrets) pass through untouched.
|
|
246
|
+
*/
|
|
247
|
+
maybeDecrypt(value) {
|
|
248
|
+
if (!isSecretEnvelope(value))
|
|
249
|
+
return value;
|
|
250
|
+
return decryptSecretValue(value, this.secretEncryptionKey);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Feature 058 (US2) — delete-integrity lookup for the credentials module.
|
|
254
|
+
*
|
|
255
|
+
* Returns every `credential_ref` setting whose resolved value (global
|
|
256
|
+
* override OR a per-channel `SettingValue`) equals `configurationCode`. The
|
|
257
|
+
* credentials module calls this through its port interface (Principle I)
|
|
258
|
+
* before deleting a configuration; a non-empty result blocks the delete
|
|
259
|
+
* (`CREDENTIAL_IN_USE`, FR-012). The manifest `defaultValue` is intentionally
|
|
260
|
+
* ignored — a manifest never ships a real configuration code.
|
|
261
|
+
*/
|
|
262
|
+
async listReferencesToConfiguration(configurationCode) {
|
|
263
|
+
const em = this.emFactory();
|
|
264
|
+
const settings = await em.find(Setting, { valueType: 'credential_ref' });
|
|
265
|
+
const refs = [];
|
|
266
|
+
for (const setting of settings) {
|
|
267
|
+
if (setting.globalValue === configurationCode) {
|
|
268
|
+
refs.push({ settingCode: setting.code });
|
|
269
|
+
}
|
|
270
|
+
const values = await em.find(SettingValue, { setting }, { populate: ['salesChannel'] });
|
|
271
|
+
for (const v of values) {
|
|
272
|
+
if (v.value === configurationCode) {
|
|
273
|
+
refs.push({ settingCode: setting.code, salesChannelCode: v.salesChannel.code });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return refs;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Three-tier resolution: per-channel SettingValue row → setting.globalValue
|
|
282
|
+
* (when non-null) → manifest defaultValue. A NULL `globalValue` means the
|
|
283
|
+
* admin has not set a platform-wide override; the manifest default applies.
|
|
284
|
+
* Per-channel rows always win over `globalValue`.
|
|
285
|
+
*/
|
|
286
|
+
function resolveEffectiveValue(setting, perChannel) {
|
|
287
|
+
if (perChannel)
|
|
288
|
+
return perChannel.value;
|
|
289
|
+
if (setting.globalValue !== null && setting.globalValue !== undefined) {
|
|
290
|
+
return setting.globalValue;
|
|
291
|
+
}
|
|
292
|
+
return setting.defaultValue;
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=settings.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.service.js","sourceRoot":"","sources":["../../../src/kernel/settings/settings.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ModuleContext } from '../kernel/index.js';
|
|
2
|
+
import type { ApiInterceptorRegistry } from '../http/interceptors/index.js';
|
|
3
|
+
import type { RequireAdminFactory } from '../kernel/ports/require-admin.js';
|
|
4
|
+
import { type LifecycleAdminDeps, type ModulePresenceAdminDeps } from './routes.admin.js';
|
|
5
|
+
/**
|
|
6
|
+
* `_lifecycle` — the module remainder, after the wrappers and the registry
|
|
7
|
+
* became kernel-owned (feature 072, wave 2, T125).
|
|
8
|
+
*
|
|
9
|
+
* What converts is the **route half**: the presence projections, the activation
|
|
10
|
+
* write, the interceptor admin screen and the module list. The orchestrator does
|
|
11
|
+
* not, and the reason is not squeamishness — it is the one collaborator whose
|
|
12
|
+
* absence is a real composition, not a degraded one. The test harness runs no
|
|
13
|
+
* orchestrator on purpose: it never populates `module_registrations`, and a
|
|
14
|
+
* refresh from the database would blank the seeded enabled-set and take every
|
|
15
|
+
* gated route down mid-run. So the orchestrator is a contribution a root makes,
|
|
16
|
+
* and the module list mounts only where one exists.
|
|
17
|
+
*
|
|
18
|
+
* **Every route here is ungated, and that is the point of the module.** Gating
|
|
19
|
+
* the presence projection on `_lifecycle`'s own presence is the circle D-36 was
|
|
20
|
+
* decided to break: an operator who has switched something off reaches
|
|
21
|
+
* `/platform/modules` to switch it back on, and that screen must answer when
|
|
22
|
+
* the rest of the platform does not. `routes.admin.ts` already said as much in
|
|
23
|
+
* a comment ("registered outside `defineModuleRoutes`"); `ctx.ungatedRoutes`
|
|
24
|
+
* makes it a declaration with a reason attached rather than an omission.
|
|
25
|
+
*
|
|
26
|
+
* Both roots mounted these by hand — production through
|
|
27
|
+
* `lifecycleModuleFromStaticEntries`, the harness through three direct calls
|
|
28
|
+
* with its own propagation shape. That divergence is what this file removes:
|
|
29
|
+
* the routes are registered once, and what differs between compositions is
|
|
30
|
+
* named (`lifecycleActivationPropagation`, `lifecycleOrchestrator`).
|
|
31
|
+
*/
|
|
32
|
+
/** What `_lifecycle` resolves from the container, and the names it owns. */
|
|
33
|
+
export interface LifecycleCradle {
|
|
34
|
+
readonly requireAdmin: RequireAdminFactory;
|
|
35
|
+
readonly apiInterceptors: ApiInterceptorRegistry;
|
|
36
|
+
/**
|
|
37
|
+
* How a committed activation flip reaches the rest of the deployment:
|
|
38
|
+
* refreshing local state, publishing to other processes, dropping the
|
|
39
|
+
* storefront's cache. Root-shaped because the harness refreshes through the
|
|
40
|
+
* cache seam rather than the database — see the note above.
|
|
41
|
+
*/
|
|
42
|
+
readonly lifecycleActivationPropagation: NonNullable<ModulePresenceAdminDeps['activation']>;
|
|
43
|
+
/**
|
|
44
|
+
* Contribution point: absent in a composition that boots no orchestrator, and
|
|
45
|
+
* the module list is then not served. The projections still are — rendering a
|
|
46
|
+
* correct navigation must not depend on being able to install anything.
|
|
47
|
+
*/
|
|
48
|
+
readonly lifecycleOrchestrator: LifecycleAdminDeps['orchestrator'] | undefined;
|
|
49
|
+
}
|
|
50
|
+
export declare function registerModule(ctx: ModuleContext): void;
|
|
51
|
+
//# sourceMappingURL=backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/lifecycle/backend.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;AAG3B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,QAAQ,CAAC,eAAe,EAAE,sBAAsB,CAAC;IACjD;;;;;OAKG;IACH,QAAQ,CAAC,8BAA8B,EAAE,WAAW,CAClD,uBAAuB,CAAC,YAAY,CAAC,CACtC,CAAC;IACF;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,EAAE,kBAAkB,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;CAChF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA2CvD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { lazyPort } from '../kernel/index.js';
|
|
2
|
+
import { registerApiInterceptorAdminRoutes, registerLifecycleAdminRoutes, registerModulePresenceRoutes, } from './routes.admin.js';
|
|
3
|
+
import { registerModulePresenceStorefrontRoutes } from './routes.storefront.js';
|
|
4
|
+
export function registerModule(ctx) {
|
|
5
|
+
ctx.di.register({
|
|
6
|
+
// Contribution point, absent by default: no orchestrator, no module list.
|
|
7
|
+
lifecycleOrchestrator: ctx
|
|
8
|
+
.asFunction(() => undefined)
|
|
9
|
+
.singleton(),
|
|
10
|
+
});
|
|
11
|
+
ctx.ungatedRoutes('The module presence projection and the activation write: an operator reaches ' +
|
|
12
|
+
'/platform/modules precisely when something is switched off, so gating this surface on ' +
|
|
13
|
+
"this module's own presence is the circle D-36 exists to break — including the case " +
|
|
14
|
+
'where the module that is off is this one.', async (app) => {
|
|
15
|
+
const cradle = ctx.cradle();
|
|
16
|
+
registerApiInterceptorAdminRoutes(app, {
|
|
17
|
+
registry: cradle.apiInterceptors,
|
|
18
|
+
requireAdmin: cradle.requireAdmin,
|
|
19
|
+
});
|
|
20
|
+
registerModulePresenceRoutes(app, {
|
|
21
|
+
requireAdmin: cradle.requireAdmin,
|
|
22
|
+
activation: cradle.lifecycleActivationPropagation,
|
|
23
|
+
// The one live datum on the deactivation-confirmation screen: how many
|
|
24
|
+
// people hold a second factor. `mfa` owns `mfa_enrolments`, so it
|
|
25
|
+
// answers the question rather than this surface querying its table.
|
|
26
|
+
// The route probes `mfa`'s presence before it calls — the count is read
|
|
27
|
+
// while the module is still on, which is what the dialog is for.
|
|
28
|
+
mfaEnrolmentCount: lazyPort(ctx, 'mfaEnrolmentCountPort'),
|
|
29
|
+
});
|
|
30
|
+
registerModulePresenceStorefrontRoutes(app);
|
|
31
|
+
const orchestrator = ctx.cradle().lifecycleOrchestrator;
|
|
32
|
+
if (orchestrator !== undefined) {
|
|
33
|
+
await registerLifecycleAdminRoutes(app, {
|
|
34
|
+
orchestrator,
|
|
35
|
+
requireAdmin: cradle.requireAdmin,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/lifecycle/backend.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,OAAO,EACL,iCAAiC,EACjC,4BAA4B,EAC5B,4BAA4B,GAG7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sCAAsC,EAAE,MAAM,wBAAwB,CAAC;AAmDhF,MAAM,UAAU,cAAc,CAAC,GAAkB;IAC/C,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC;QACd,0EAA0E;QAC1E,qBAAqB,EAAE,GAAG;aACvB,UAAU,CAAC,GAA6C,EAAE,CAAC,SAAS,CAAC;aACrE,SAAS,EAAE;KACf,CAAC,CAAC;IAEH,GAAG,CAAC,aAAa,CACf,+EAA+E;QAC7E,wFAAwF;QACxF,qFAAqF;QACrF,2CAA2C,EAC7C,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAmB,CAAC;QAE7C,iCAAiC,CAAC,GAAG,EAAE;YACrC,QAAQ,EAAE,MAAM,CAAC,eAAe;YAChC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC,CAAC;QAEH,4BAA4B,CAAC,GAAG,EAAE;YAChC,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,UAAU,EAAE,MAAM,CAAC,8BAA8B;YACjD,uEAAuE;YACvE,kEAAkE;YAClE,oEAAoE;YACpE,wEAAwE;YACxE,iEAAiE;YACjE,iBAAiB,EAAE,QAAQ,CAAwB,GAAG,EAAE,uBAAuB,CAAC;SACjF,CAAC,CAAC;QAEH,sCAAsC,CAAC,GAAG,CAAC,CAAC;QAE5C,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAmB,CAAC,qBAAqB,CAAC;QACzE,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,4BAA4B,CAAC,GAAG,EAAE;gBACtC,YAAY;gBACZ,YAAY,EAAE,MAAM,CAAC,YAAY;aAClC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { Command } from '../../commands/command.js';
|
|
2
|
+
/**
|
|
3
|
+
* The operator-activation flip — feature 073 / US1, FR-007, Principle XIII.
|
|
4
|
+
*
|
|
5
|
+
* Hosted by `_lifecycle` rather than `settings`, for three reasons that are
|
|
6
|
+
* easy to lose:
|
|
7
|
+
*
|
|
8
|
+
* - `_lifecycle` already imports the `Setting` entity (the orchestrator
|
|
9
|
+
* reconciles rows on install) and already receives `auditLog`, so this adds
|
|
10
|
+
* no dependency edge in either direction;
|
|
11
|
+
* - there is **no existing settings-write Command to copy**. No `setting.*`
|
|
12
|
+
* Command exists and the settings module never receives a `commandBus`:
|
|
13
|
+
* `SettingsAdminService.setValue` audits by hand *after* `em.flush()` and
|
|
14
|
+
* outside any transaction, which is exactly the torn-write window the
|
|
15
|
+
* Command Bus exists to close;
|
|
16
|
+
* - "activation is not an ordinary setting write" stays visible in the code
|
|
17
|
+
* rather than being implied by a guard somewhere else.
|
|
18
|
+
*
|
|
19
|
+
* The control still *renders* in the Settings surface, as Constitution XVII
|
|
20
|
+
* requires. Only the write path is dedicated.
|
|
21
|
+
*
|
|
22
|
+
* What this command deliberately does **not** touch is `module_registrations`.
|
|
23
|
+
* The two axes never overwrite each other (FR-003), and that is enforced by
|
|
24
|
+
* this asymmetry rather than by a runtime check: the CLI path writes the
|
|
25
|
+
* registry and never the Setting, this path writes the Setting and never the
|
|
26
|
+
* registry.
|
|
27
|
+
*/
|
|
28
|
+
export interface SetModuleActivationInput {
|
|
29
|
+
moduleId: string;
|
|
30
|
+
active: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Refuse before the Command opens a transaction.
|
|
34
|
+
*
|
|
35
|
+
* A refusal rather than a no-op: a control that silently does nothing is worse
|
|
36
|
+
* than an absent one, because the operator believes they switched something.
|
|
37
|
+
*
|
|
38
|
+
* Four refusals, in the order an operator meets them: an unknown id, a module
|
|
39
|
+
* with no control, a deactivation something present still needs, and an
|
|
40
|
+
* activation into a deployment that cannot serve it. The last two are FR-008
|
|
41
|
+
* (T045/T046) and they are what makes this door agree with the CLI's — until
|
|
42
|
+
* they existed, `orchestrator.disable` refused `settings` because
|
|
43
|
+
* `organizations` depends on it while this function let the identical flip
|
|
44
|
+
* through in silence, taking the tenancy root down with it.
|
|
45
|
+
*
|
|
46
|
+
* **They read `gatingGraph()`, not `ModuleDepGraph`.** The manifest graph is a
|
|
47
|
+
* DAG on purpose and a handful of real edges are withheld from it so it can
|
|
48
|
+
* stay one; the refusal graph adds them back from
|
|
49
|
+
* `manifest.acknowledgedDependencies`. See `services/gating-graph.ts` for why
|
|
50
|
+
* the two directions read different edge sets.
|
|
51
|
+
*
|
|
52
|
+
* The direction is evaluated as asked, not as a delta against the stored value.
|
|
53
|
+
* A redundant write is an odd thing to refuse, but the alternative is a write
|
|
54
|
+
* path that skips its own invariant whenever the state is already wrong — which
|
|
55
|
+
* is precisely the state in which the check matters.
|
|
56
|
+
*/
|
|
57
|
+
export declare function assertActivationWritable(moduleId: string, active: boolean): string;
|
|
58
|
+
/**
|
|
59
|
+
* Flip one module's operator activation.
|
|
60
|
+
*
|
|
61
|
+
* The audit snapshot is the resolved activation on either side rather than the
|
|
62
|
+
* raw jsonb: `global_value` is `null` both for "the operator never chose" and
|
|
63
|
+
* for a literal JSON null, so recording it would leave two consecutive audit
|
|
64
|
+
* rows unable to say what the module's activation actually was at either moment.
|
|
65
|
+
*/
|
|
66
|
+
export declare function makeSetActivationCommand(input: SetModuleActivationInput): Command<{
|
|
67
|
+
moduleId: string;
|
|
68
|
+
active: boolean;
|
|
69
|
+
}>;
|
|
70
|
+
/** The two side effects that make a flip visible outside the writing process. */
|
|
71
|
+
export interface ActivationPropagation {
|
|
72
|
+
/** Re-reads both axes locally, so the next request in *this* process is correct. */
|
|
73
|
+
refreshLocalState: () => Promise<void>;
|
|
74
|
+
/** Notifies every other API and worker process over `b2b:module:state-changed`. */
|
|
75
|
+
publishStateChanged: (payload: {
|
|
76
|
+
moduleId: string;
|
|
77
|
+
newState: string;
|
|
78
|
+
}) => Promise<void>;
|
|
79
|
+
/** Drops the storefront's `modules:presence` cache entry. */
|
|
80
|
+
revalidateStorefront: (tags: string[]) => Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Propagate a committed flip. Called **after** the Command's transaction, never
|
|
84
|
+
* inside it: a Redis hiccup must not roll back a change the operator was told
|
|
85
|
+
* had been saved, and a subscriber that acted on a notification for a
|
|
86
|
+
* transaction that then aborted would be acting on a state that never existed.
|
|
87
|
+
*
|
|
88
|
+
* Each step is best-effort and independent. The local refresh is what makes the
|
|
89
|
+
* flip take effect without a redeploy in the writing process; the publish does
|
|
90
|
+
* the same everywhere else; the revalidation does it for the storefront. A
|
|
91
|
+
* process that misses the notification recovers through the degraded-mode timer.
|
|
92
|
+
*/
|
|
93
|
+
export declare function propagateActivationChange(propagation: ActivationPropagation, input: {
|
|
94
|
+
moduleId: string;
|
|
95
|
+
active: boolean;
|
|
96
|
+
}): Promise<void>;
|
|
97
|
+
//# sourceMappingURL=activation.commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activation.commands.d.ts","sourceRoot":"","sources":["../../../src/lifecycle/commands/activation.commands.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAOzD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CA8DlF;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC,CA8ChD;AAED,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC,oFAAoF;IACpF,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mFAAmF;IACnF,mBAAmB,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,6DAA6D;IAC7D,oBAAoB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,qBAAqB,EAClC,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC3C,OAAO,CAAC,IAAI,CAAC,CASf"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { ERROR_CODES } from '@endora-commerce/contracts';
|
|
3
|
+
import { HttpError } from '../../http/error-envelope.js';
|
|
4
|
+
import { Setting } from '../../kernel/settings/setting.entity.js';
|
|
5
|
+
import { effectiveState } from '../../kernel/lifecycle/effective-state.js';
|
|
6
|
+
import { gatingGraph } from '../services/gating-graph.js';
|
|
7
|
+
import { registryCache } from '../../kernel/lifecycle/registry-cache.js';
|
|
8
|
+
/**
|
|
9
|
+
* Refuse before the Command opens a transaction.
|
|
10
|
+
*
|
|
11
|
+
* A refusal rather than a no-op: a control that silently does nothing is worse
|
|
12
|
+
* than an absent one, because the operator believes they switched something.
|
|
13
|
+
*
|
|
14
|
+
* Four refusals, in the order an operator meets them: an unknown id, a module
|
|
15
|
+
* with no control, a deactivation something present still needs, and an
|
|
16
|
+
* activation into a deployment that cannot serve it. The last two are FR-008
|
|
17
|
+
* (T045/T046) and they are what makes this door agree with the CLI's — until
|
|
18
|
+
* they existed, `orchestrator.disable` refused `settings` because
|
|
19
|
+
* `organizations` depends on it while this function let the identical flip
|
|
20
|
+
* through in silence, taking the tenancy root down with it.
|
|
21
|
+
*
|
|
22
|
+
* **They read `gatingGraph()`, not `ModuleDepGraph`.** The manifest graph is a
|
|
23
|
+
* DAG on purpose and a handful of real edges are withheld from it so it can
|
|
24
|
+
* stay one; the refusal graph adds them back from
|
|
25
|
+
* `manifest.acknowledgedDependencies`. See `services/gating-graph.ts` for why
|
|
26
|
+
* the two directions read different edge sets.
|
|
27
|
+
*
|
|
28
|
+
* The direction is evaluated as asked, not as a delta against the stored value.
|
|
29
|
+
* A redundant write is an odd thing to refuse, but the alternative is a write
|
|
30
|
+
* path that skips its own invariant whenever the state is already wrong — which
|
|
31
|
+
* is precisely the state in which the check matters.
|
|
32
|
+
*/
|
|
33
|
+
export function assertActivationWritable(moduleId, active) {
|
|
34
|
+
const declaration = registryCache.activationDeclaration(moduleId);
|
|
35
|
+
if (!declaration) {
|
|
36
|
+
// Either the id is unknown, or the module has not declared a control yet
|
|
37
|
+
// (the conversion sweep is per batch). Both are "there is nothing here to
|
|
38
|
+
// switch", but they read differently to an operator.
|
|
39
|
+
const known = registryCache.platformStateOf(moduleId) !== 'not-installed';
|
|
40
|
+
if (!known) {
|
|
41
|
+
throw new HttpError(404, ERROR_CODES.MODULE_NOT_FOUND, `No module "${moduleId}" is registered on this deployment.`);
|
|
42
|
+
}
|
|
43
|
+
throw new HttpError(409, ERROR_CODES.MODULE_NOT_DEACTIVATABLE, `Module "${moduleId}" declares no activation control, so it cannot be switched on or off.`);
|
|
44
|
+
}
|
|
45
|
+
if (declaration.settingCode === null) {
|
|
46
|
+
throw new HttpError(409, ERROR_CODES.MODULE_NOT_DEACTIVATABLE, declaration.nonDeactivatableReason ??
|
|
47
|
+
`Module "${moduleId}" cannot be switched off.`);
|
|
48
|
+
}
|
|
49
|
+
const graph = gatingGraph();
|
|
50
|
+
const isPresent = (id) => effectiveState.isPresent(id);
|
|
51
|
+
if (!active) {
|
|
52
|
+
const blockedBy = graph.presentDependentsOf(moduleId, isPresent);
|
|
53
|
+
if (blockedBy.length > 0) {
|
|
54
|
+
// A distinct code from MODULE_NOT_DEACTIVATABLE, which says "there is
|
|
55
|
+
// nothing here to switch, ever". This one is "not in this order", and the
|
|
56
|
+
// remedy is in `details.blockedBy` — the admin renders the two
|
|
57
|
+
// differently, and so does the CLI (`non-deactivatable` vs
|
|
58
|
+
// `dependents-block`).
|
|
59
|
+
throw new HttpError(409, ERROR_CODES.MODULE_DEPENDENTS_PRESENT, `Module "${moduleId}" cannot be switched off while these modules need it: ` +
|
|
60
|
+
`${blockedBy.join(', ')}. Switch them off first.`, { moduleId, blockedBy });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const missing = graph.absentDependenciesOf(moduleId, isPresent);
|
|
65
|
+
if (missing.length > 0) {
|
|
66
|
+
throw new HttpError(409, ERROR_CODES.MODULE_DEPENDENCIES_ABSENT, `Module "${moduleId}" cannot be switched on while these modules it needs ` +
|
|
67
|
+
`are absent: ${missing.join(', ')}.`, { moduleId, missing });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return declaration.settingCode;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Flip one module's operator activation.
|
|
74
|
+
*
|
|
75
|
+
* The audit snapshot is the resolved activation on either side rather than the
|
|
76
|
+
* raw jsonb: `global_value` is `null` both for "the operator never chose" and
|
|
77
|
+
* for a literal JSON null, so recording it would leave two consecutive audit
|
|
78
|
+
* rows unable to say what the module's activation actually was at either moment.
|
|
79
|
+
*/
|
|
80
|
+
export function makeSetActivationCommand(input) {
|
|
81
|
+
const settingCode = assertActivationWritable(input.moduleId, input.active);
|
|
82
|
+
return {
|
|
83
|
+
action: 'module.activation.set',
|
|
84
|
+
objectType: 'module',
|
|
85
|
+
objectId: input.moduleId,
|
|
86
|
+
capture: async () => ({
|
|
87
|
+
moduleId: input.moduleId,
|
|
88
|
+
settingCode,
|
|
89
|
+
activated: effectiveState.presence(input.moduleId)?.operatorActivated ?? true,
|
|
90
|
+
}),
|
|
91
|
+
run: async ({ em }) => {
|
|
92
|
+
const setting = await em.findOne(Setting, { code: settingCode });
|
|
93
|
+
if (!setting) {
|
|
94
|
+
// The reconciler creates the row from the module's settings manifest at
|
|
95
|
+
// boot. Its absence means the module declared an activation code it
|
|
96
|
+
// does not own — a manifest error, not an operator one.
|
|
97
|
+
throw new HttpError(500, ERROR_CODES.SETTING_NOT_REGISTERED, `Module "${input.moduleId}" declares activation setting "${settingCode}", which is not registered.`);
|
|
98
|
+
}
|
|
99
|
+
setting.globalValue = input.active;
|
|
100
|
+
await em.flush();
|
|
101
|
+
return {
|
|
102
|
+
result: { moduleId: input.moduleId, active: input.active },
|
|
103
|
+
after: {
|
|
104
|
+
moduleId: input.moduleId,
|
|
105
|
+
settingCode,
|
|
106
|
+
activated: input.active,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
event: (result) => ({
|
|
111
|
+
eventName: 'module.activation.changed',
|
|
112
|
+
payload: {
|
|
113
|
+
eventId: randomUUID(),
|
|
114
|
+
occurredAt: new Date().toISOString(),
|
|
115
|
+
moduleId: result.moduleId,
|
|
116
|
+
active: result.active,
|
|
117
|
+
},
|
|
118
|
+
}),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Propagate a committed flip. Called **after** the Command's transaction, never
|
|
123
|
+
* inside it: a Redis hiccup must not roll back a change the operator was told
|
|
124
|
+
* had been saved, and a subscriber that acted on a notification for a
|
|
125
|
+
* transaction that then aborted would be acting on a state that never existed.
|
|
126
|
+
*
|
|
127
|
+
* Each step is best-effort and independent. The local refresh is what makes the
|
|
128
|
+
* flip take effect without a redeploy in the writing process; the publish does
|
|
129
|
+
* the same everywhere else; the revalidation does it for the storefront. A
|
|
130
|
+
* process that misses the notification recovers through the degraded-mode timer.
|
|
131
|
+
*/
|
|
132
|
+
export async function propagateActivationChange(propagation, input) {
|
|
133
|
+
await propagation.refreshLocalState().catch(() => undefined);
|
|
134
|
+
await propagation
|
|
135
|
+
.publishStateChanged({
|
|
136
|
+
moduleId: input.moduleId,
|
|
137
|
+
newState: input.active ? 'activated' : 'deactivated',
|
|
138
|
+
})
|
|
139
|
+
.catch(() => undefined);
|
|
140
|
+
await propagation.revalidateStorefront(['modules:presence']).catch(() => undefined);
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=activation.commands.js.map
|