@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,157 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql';
|
|
2
|
+
import { type ChannelMemberEntityType } from '@endora-commerce/contracts';
|
|
3
|
+
import type { AuditPort } from '../ports/audit.js';
|
|
4
|
+
import type { EventBus } from '../../events/bus.js';
|
|
5
|
+
import { SalesChannel } from './sales-channel.entity.js';
|
|
6
|
+
import { type ChannelBridgeRegistry } from './channel-bridge-registry.js';
|
|
7
|
+
/**
|
|
8
|
+
* SalesChannelMembershipService — feature 005 / T016.
|
|
9
|
+
*
|
|
10
|
+
* Single mutator for every M:N bridge between Sales Channels and the
|
|
11
|
+
* channel-scoped entity types (FR-009). Going through this service is
|
|
12
|
+
* mandatory: `check:module-boundary`'s `sql` predicate resolves every
|
|
13
|
+
* `sales_channel_*` table to its owner out of the DDL, so an owning module
|
|
14
|
+
* reaching for a bridge table in raw SQL is a ledgered finding (D-87). Until
|
|
15
|
+
* then this clause was credited to `no-unscoped-channel-query`, an ESLint rule
|
|
16
|
+
* wired into no config that never looked at a bridge table.
|
|
17
|
+
*
|
|
18
|
+
* Responsibilities:
|
|
19
|
+
*
|
|
20
|
+
* - {@link addToChannel} / {@link removeFromChannel} — idempotent
|
|
21
|
+
* mutations against the right bridge table.
|
|
22
|
+
* - The "at-least-one-channel" invariant (FR-008) — `removeFromChannel`
|
|
23
|
+
* refuses when it would leave an entity with zero channels, unless
|
|
24
|
+
* the caller passes `fallbackToDefault: true`, in which case the
|
|
25
|
+
* entity is re-bound to the system-default channel inside the
|
|
26
|
+
* same transaction.
|
|
27
|
+
* - {@link bindToDefaultIfEmpty} — wired into every owning module's
|
|
28
|
+
* create-path so entities created without explicit channels land
|
|
29
|
+
* in Default automatically (FR-011).
|
|
30
|
+
* - {@link listChannelsForEntity} / {@link listEntityIdsForChannel}
|
|
31
|
+
* — symmetric reads from either side of the relationship.
|
|
32
|
+
*
|
|
33
|
+
* Bridges are resolved through {@link ChannelBridgeRegistry}, which the
|
|
34
|
+
* module owning each entity type contributes to at compose time (feature 120,
|
|
35
|
+
* FR-015). This service used to hold the map itself, **total** over
|
|
36
|
+
* `ChannelMemberEntityTypeSchema` — nine module-owned tables named from inside
|
|
37
|
+
* the platform, which is D-52/D-53's prohibition expressed in a contract
|
|
38
|
+
* instead of an import, and which meant a membership call for an entity type
|
|
39
|
+
* whose module an instance never installed ran SQL against a relation that is
|
|
40
|
+
* not there. A member nothing registered now refuses before the database is
|
|
41
|
+
* touched (FR-017). The service uses `em.getConnection().execute()` (which
|
|
42
|
+
* honours the EM's active transaction — knex's `getKnex()` would bypass it via
|
|
43
|
+
* its own connection pool, breaking transactional integration tests).
|
|
44
|
+
*
|
|
45
|
+
* Every successful add / remove writes one audit row through
|
|
46
|
+
* {@link AuditPort} and emits one EventBus event. Idempotent
|
|
47
|
+
* no-ops (adding an existing membership / removing a missing one) are
|
|
48
|
+
* NOT audited because they did not change state.
|
|
49
|
+
*/
|
|
50
|
+
export interface MembershipMutationOptions {
|
|
51
|
+
/** When true, falling to zero channels triggers automatic rebind to Default instead of refusal. */
|
|
52
|
+
fallbackToDefault?: boolean;
|
|
53
|
+
/** Optional admin actor for the audit row. */
|
|
54
|
+
actorAdminUserId?: string | null;
|
|
55
|
+
}
|
|
56
|
+
export interface MembershipMutationResult {
|
|
57
|
+
/** True if the mutation actually changed state (false for idempotent no-ops). */
|
|
58
|
+
changed: boolean;
|
|
59
|
+
/** Set when the FR-008 fallback was applied. */
|
|
60
|
+
fallbackAppliedToDefault?: boolean;
|
|
61
|
+
}
|
|
62
|
+
export declare class SalesChannelMembershipService {
|
|
63
|
+
private readonly emFactory;
|
|
64
|
+
private readonly eventBus;
|
|
65
|
+
private readonly auditLogService?;
|
|
66
|
+
private readonly bridges;
|
|
67
|
+
/**
|
|
68
|
+
* `bridges` defaults to the process-level registry the composition roots
|
|
69
|
+
* contribute into, so every existing construction site keeps working
|
|
70
|
+
* unchanged. Pass one explicitly to compose an isolated platform — or, in a
|
|
71
|
+
* test, to drive the FR-017 refusal without a database in reach.
|
|
72
|
+
*/
|
|
73
|
+
constructor(emFactory: () => EntityManager, eventBus: EventBus, auditLogService?: AuditPort | undefined, bridges?: ChannelBridgeRegistry);
|
|
74
|
+
/**
|
|
75
|
+
* Add `entityId` to `channelId`'s member set for `entityType`. Idempotent —
|
|
76
|
+
* adding an existing membership returns `{ changed: false }` without
|
|
77
|
+
* touching the database.
|
|
78
|
+
*/
|
|
79
|
+
addToChannel(channelId: string, entityType: ChannelMemberEntityType, entityId: string, options?: MembershipMutationOptions): Promise<MembershipMutationResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Remove `entityId` from `channelId`'s member set for `entityType`. If the
|
|
82
|
+
* removal would leave the entity with zero channel bindings:
|
|
83
|
+
* - when `fallbackToDefault = true`: re-bind to the system-default
|
|
84
|
+
* channel inside the same transaction; mark the result with
|
|
85
|
+
* `fallbackAppliedToDefault: true`.
|
|
86
|
+
* - otherwise: throw `ENTITY_WOULD_HAVE_ZERO_CHANNELS` (HTTP 422).
|
|
87
|
+
*
|
|
88
|
+
* Idempotent on the row itself: removing a missing membership returns
|
|
89
|
+
* `{ changed: false }`.
|
|
90
|
+
*/
|
|
91
|
+
removeFromChannel(channelId: string, entityType: ChannelMemberEntityType, entityId: string, options?: MembershipMutationOptions): Promise<MembershipMutationResult>;
|
|
92
|
+
/**
|
|
93
|
+
* If the entity has no memberships in any channel, bind it to the
|
|
94
|
+
* system-default channel. Wired into every owning module's create
|
|
95
|
+
* transaction (FR-011 / T027).
|
|
96
|
+
*/
|
|
97
|
+
bindToDefaultIfEmpty(entityType: ChannelMemberEntityType, entityId: string): Promise<MembershipMutationResult>;
|
|
98
|
+
/**
|
|
99
|
+
* Give `targetEntityId` every channel `sourceEntityId` belongs to (issue #185).
|
|
100
|
+
*
|
|
101
|
+
* `catalog` duplicates a product and copies the source's whole channel
|
|
102
|
+
* assortment. It did that with one `insert … select` against
|
|
103
|
+
* `sales_channel_products` — Principle XII's accessor clause and Principle
|
|
104
|
+
* XIII in a single statement, because the bridge was written directly and not
|
|
105
|
+
* one of the memberships it created was audited.
|
|
106
|
+
*
|
|
107
|
+
* Implemented over {@link addToChannel} rather than as a set-based insert on
|
|
108
|
+
* purpose: that is what makes each new membership carry its audit row and its
|
|
109
|
+
* `sales_channel_membership_changed` event, which is the entire reason the
|
|
110
|
+
* copy moved here. An assortment is tens of channels at the very most, so the
|
|
111
|
+
* per-row round trip costs nothing worth the divergence.
|
|
112
|
+
*
|
|
113
|
+
* Memberships the target already holds are skipped by `addToChannel`'s own
|
|
114
|
+
* idempotency and are not counted.
|
|
115
|
+
*/
|
|
116
|
+
copyMemberships(entityType: ChannelMemberEntityType, sourceEntityId: string, targetEntityId: string, options?: MembershipMutationOptions): Promise<{
|
|
117
|
+
copied: number;
|
|
118
|
+
}>;
|
|
119
|
+
/**
|
|
120
|
+
* Replace an entity's complete channel membership set atomically.
|
|
121
|
+
*
|
|
122
|
+
* Complete-record integrations use this instead of composing add/remove:
|
|
123
|
+
* product creation initially binds the system default, while the delivered
|
|
124
|
+
* record names the exact channel that must remain. A delete-then-add sequence
|
|
125
|
+
* through the public methods would either trip the zero-channel invariant or
|
|
126
|
+
* retain the unrelated default.
|
|
127
|
+
*/
|
|
128
|
+
replaceChannelsForEntity(entityType: ChannelMemberEntityType, entityId: string, channelIds: readonly [string, ...string[]], options?: MembershipMutationOptions): Promise<MembershipMutationResult>;
|
|
129
|
+
/**
|
|
130
|
+
* Narrow a **known** set of entity ids to those bound to `channelId`
|
|
131
|
+
* (issue #185).
|
|
132
|
+
*
|
|
133
|
+
* The read half of the same finding. Three `catalog` services asked
|
|
134
|
+
* `select <entity>_id from sales_channel_<type> where sales_channel_id = ?
|
|
135
|
+
* and <entity>_id in (…)` by hand, one per channel-scoped listing, and every
|
|
136
|
+
* one of them fails closed to the empty set — which is the right behaviour
|
|
137
|
+
* and the wrong place to spell it.
|
|
138
|
+
*
|
|
139
|
+
* Not {@link listEntityIdsForChannel}: that one enumerates a channel's whole
|
|
140
|
+
* membership a page at a time, and a caller holding a page of ids wants the
|
|
141
|
+
* intersection rather than the enumeration. Using it here would mean pulling
|
|
142
|
+
* every product in the channel to filter twenty.
|
|
143
|
+
*/
|
|
144
|
+
filterEntityIdsInChannel(channelId: string, entityType: ChannelMemberEntityType, entityIds: readonly string[]): Promise<string[]>;
|
|
145
|
+
/** Channels an entity currently belongs to. */
|
|
146
|
+
listChannelsForEntity(entityType: ChannelMemberEntityType, entityId: string): Promise<SalesChannel[]>;
|
|
147
|
+
/** Entity ids of `entityType` that currently belong to `channelId`. */
|
|
148
|
+
listEntityIdsForChannel(channelId: string, entityType: ChannelMemberEntityType, page?: number, pageSize?: number): Promise<{
|
|
149
|
+
entityIds: string[];
|
|
150
|
+
total: number;
|
|
151
|
+
}>;
|
|
152
|
+
private countMembershipsForEntity;
|
|
153
|
+
private requireSystemDefaultId;
|
|
154
|
+
private auditMembership;
|
|
155
|
+
private emitMembershipChanged;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=sales-channel-membership.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sales-channel-membership.service.d.ts","sourceRoot":"","sources":["../../../src/kernel/sales-channels/sales-channel-membership.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { ERROR_CODES, SALES_CHANNEL_AUDIT_ACTIONS, } from '@endora-commerce/contracts';
|
|
2
|
+
import { HttpError } from '../../http/error-envelope.js';
|
|
3
|
+
import { SalesChannel } from './sales-channel.entity.js';
|
|
4
|
+
import { channelBridges, } from './channel-bridge-registry.js';
|
|
5
|
+
export class SalesChannelMembershipService {
|
|
6
|
+
emFactory;
|
|
7
|
+
eventBus;
|
|
8
|
+
auditLogService;
|
|
9
|
+
bridges;
|
|
10
|
+
/**
|
|
11
|
+
* `bridges` defaults to the process-level registry the composition roots
|
|
12
|
+
* contribute into, so every existing construction site keeps working
|
|
13
|
+
* unchanged. Pass one explicitly to compose an isolated platform — or, in a
|
|
14
|
+
* test, to drive the FR-017 refusal without a database in reach.
|
|
15
|
+
*/
|
|
16
|
+
constructor(emFactory, eventBus, auditLogService, bridges = channelBridges) {
|
|
17
|
+
this.emFactory = emFactory;
|
|
18
|
+
this.eventBus = eventBus;
|
|
19
|
+
this.auditLogService = auditLogService;
|
|
20
|
+
this.bridges = bridges;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Add `entityId` to `channelId`'s member set for `entityType`. Idempotent —
|
|
24
|
+
* adding an existing membership returns `{ changed: false }` without
|
|
25
|
+
* touching the database.
|
|
26
|
+
*/
|
|
27
|
+
async addToChannel(channelId, entityType, entityId, options = {}) {
|
|
28
|
+
const bridge = this.bridges.require(entityType);
|
|
29
|
+
const em = this.emFactory();
|
|
30
|
+
const inserted = await em
|
|
31
|
+
.getConnection()
|
|
32
|
+
.execute(`insert into "${bridge.table}" ("sales_channel_id", "${bridge.entityIdColumn}") ` +
|
|
33
|
+
`values (?, ?) ` +
|
|
34
|
+
`on conflict ("sales_channel_id", "${bridge.entityIdColumn}") do nothing ` +
|
|
35
|
+
`returning "${bridge.entityIdColumn}"`, [channelId, entityId], 'all', em.getTransactionContext());
|
|
36
|
+
if (inserted.length === 0) {
|
|
37
|
+
return { changed: false };
|
|
38
|
+
}
|
|
39
|
+
await this.auditMembership(channelId, entityType, entityId, 'add', options);
|
|
40
|
+
this.emitMembershipChanged(channelId, entityType, entityId, 'add');
|
|
41
|
+
return { changed: true };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Remove `entityId` from `channelId`'s member set for `entityType`. If the
|
|
45
|
+
* removal would leave the entity with zero channel bindings:
|
|
46
|
+
* - when `fallbackToDefault = true`: re-bind to the system-default
|
|
47
|
+
* channel inside the same transaction; mark the result with
|
|
48
|
+
* `fallbackAppliedToDefault: true`.
|
|
49
|
+
* - otherwise: throw `ENTITY_WOULD_HAVE_ZERO_CHANNELS` (HTTP 422).
|
|
50
|
+
*
|
|
51
|
+
* Idempotent on the row itself: removing a missing membership returns
|
|
52
|
+
* `{ changed: false }`.
|
|
53
|
+
*/
|
|
54
|
+
async removeFromChannel(channelId, entityType, entityId, options = {}) {
|
|
55
|
+
const bridge = this.bridges.require(entityType);
|
|
56
|
+
const em = this.emFactory();
|
|
57
|
+
// Step 1: check existence so the no-op path is idempotent and so FR-008
|
|
58
|
+
// can be evaluated BEFORE we delete anything.
|
|
59
|
+
const existing = await em
|
|
60
|
+
.getConnection()
|
|
61
|
+
.execute(`select 1 as present from "${bridge.table}" ` +
|
|
62
|
+
`where "sales_channel_id" = ? and "${bridge.entityIdColumn}" = ? limit 1`, [channelId, entityId], 'all', em.getTransactionContext());
|
|
63
|
+
if (existing.length === 0) {
|
|
64
|
+
return { changed: false };
|
|
65
|
+
}
|
|
66
|
+
// Step 2: count total memberships for the entity. If this is the last
|
|
67
|
+
// one, FR-008 either refuses (default) or rebinds to Default (when the
|
|
68
|
+
// caller opted in).
|
|
69
|
+
const totalChannels = await this.countMembershipsForEntity(em, bridge, entityId);
|
|
70
|
+
const wouldOrphan = totalChannels === 1;
|
|
71
|
+
if (wouldOrphan && !options.fallbackToDefault) {
|
|
72
|
+
throw new HttpError(422, ERROR_CODES.ENTITY_WOULD_HAVE_ZERO_CHANNELS, `Removing this membership would leave the ${entityType} with zero sales channels. ` +
|
|
73
|
+
`Pass fallbackToDefault=true to rebind it to the system default instead.`, [{ path: 'entityId', issue: entityId }]);
|
|
74
|
+
}
|
|
75
|
+
// Step 3: when we get here either the entity has another channel left or
|
|
76
|
+
// the caller asked for the rebind. The actual DELETE is now safe.
|
|
77
|
+
await em
|
|
78
|
+
.getConnection()
|
|
79
|
+
.execute(`delete from "${bridge.table}" ` +
|
|
80
|
+
`where "sales_channel_id" = ? and "${bridge.entityIdColumn}" = ?`, [channelId, entityId], 'run', em.getTransactionContext());
|
|
81
|
+
if (!wouldOrphan) {
|
|
82
|
+
await this.auditMembership(channelId, entityType, entityId, 'remove', options);
|
|
83
|
+
this.emitMembershipChanged(channelId, entityType, entityId, 'remove');
|
|
84
|
+
return { changed: true };
|
|
85
|
+
}
|
|
86
|
+
// wouldOrphan && fallbackToDefault — rebind in the same transaction.
|
|
87
|
+
const defaultId = await this.requireSystemDefaultId(em);
|
|
88
|
+
await em
|
|
89
|
+
.getConnection()
|
|
90
|
+
.execute(`insert into "${bridge.table}" ("sales_channel_id", "${bridge.entityIdColumn}") ` +
|
|
91
|
+
`values (?, ?) ` +
|
|
92
|
+
`on conflict ("sales_channel_id", "${bridge.entityIdColumn}") do nothing`, [defaultId, entityId], 'run', em.getTransactionContext());
|
|
93
|
+
await this.auditMembership(channelId, entityType, entityId, 'remove', options, true);
|
|
94
|
+
this.emitMembershipChanged(channelId, entityType, entityId, 'remove');
|
|
95
|
+
return { changed: true, fallbackAppliedToDefault: true };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* If the entity has no memberships in any channel, bind it to the
|
|
99
|
+
* system-default channel. Wired into every owning module's create
|
|
100
|
+
* transaction (FR-011 / T027).
|
|
101
|
+
*/
|
|
102
|
+
async bindToDefaultIfEmpty(entityType, entityId) {
|
|
103
|
+
const bridge = this.bridges.require(entityType);
|
|
104
|
+
const em = this.emFactory();
|
|
105
|
+
const remaining = await this.countMembershipsForEntity(em, bridge, entityId);
|
|
106
|
+
if (remaining > 0)
|
|
107
|
+
return { changed: false };
|
|
108
|
+
const defaultId = await this.requireSystemDefaultId(em);
|
|
109
|
+
await em
|
|
110
|
+
.getConnection()
|
|
111
|
+
.execute(`insert into "${bridge.table}" ("sales_channel_id", "${bridge.entityIdColumn}") ` +
|
|
112
|
+
`values (?, ?) ` +
|
|
113
|
+
`on conflict ("sales_channel_id", "${bridge.entityIdColumn}") do nothing`, [defaultId, entityId], 'run', em.getTransactionContext());
|
|
114
|
+
await this.auditMembership(defaultId, entityType, entityId, 'add', {});
|
|
115
|
+
this.emitMembershipChanged(defaultId, entityType, entityId, 'add');
|
|
116
|
+
return { changed: true };
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Give `targetEntityId` every channel `sourceEntityId` belongs to (issue #185).
|
|
120
|
+
*
|
|
121
|
+
* `catalog` duplicates a product and copies the source's whole channel
|
|
122
|
+
* assortment. It did that with one `insert … select` against
|
|
123
|
+
* `sales_channel_products` — Principle XII's accessor clause and Principle
|
|
124
|
+
* XIII in a single statement, because the bridge was written directly and not
|
|
125
|
+
* one of the memberships it created was audited.
|
|
126
|
+
*
|
|
127
|
+
* Implemented over {@link addToChannel} rather than as a set-based insert on
|
|
128
|
+
* purpose: that is what makes each new membership carry its audit row and its
|
|
129
|
+
* `sales_channel_membership_changed` event, which is the entire reason the
|
|
130
|
+
* copy moved here. An assortment is tens of channels at the very most, so the
|
|
131
|
+
* per-row round trip costs nothing worth the divergence.
|
|
132
|
+
*
|
|
133
|
+
* Memberships the target already holds are skipped by `addToChannel`'s own
|
|
134
|
+
* idempotency and are not counted.
|
|
135
|
+
*/
|
|
136
|
+
async copyMemberships(entityType, sourceEntityId, targetEntityId, options = {}) {
|
|
137
|
+
const bridge = this.bridges.require(entityType);
|
|
138
|
+
const em = this.emFactory();
|
|
139
|
+
const rows = await em
|
|
140
|
+
.getConnection()
|
|
141
|
+
.execute(`select "sales_channel_id" from "${bridge.table}" where "${bridge.entityIdColumn}" = ?`, [sourceEntityId], 'all', em.getTransactionContext());
|
|
142
|
+
let copied = 0;
|
|
143
|
+
for (const row of rows) {
|
|
144
|
+
const result = await this.addToChannel(row.sales_channel_id, entityType, targetEntityId, options);
|
|
145
|
+
if (result.changed)
|
|
146
|
+
copied += 1;
|
|
147
|
+
}
|
|
148
|
+
return { copied };
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Replace an entity's complete channel membership set atomically.
|
|
152
|
+
*
|
|
153
|
+
* Complete-record integrations use this instead of composing add/remove:
|
|
154
|
+
* product creation initially binds the system default, while the delivered
|
|
155
|
+
* record names the exact channel that must remain. A delete-then-add sequence
|
|
156
|
+
* through the public methods would either trip the zero-channel invariant or
|
|
157
|
+
* retain the unrelated default.
|
|
158
|
+
*/
|
|
159
|
+
async replaceChannelsForEntity(entityType, entityId, channelIds, options = {}) {
|
|
160
|
+
const bridge = this.bridges.require(entityType);
|
|
161
|
+
const desiredIds = [...new Set(channelIds)];
|
|
162
|
+
const em = this.emFactory();
|
|
163
|
+
const existingRows = await em
|
|
164
|
+
.getConnection()
|
|
165
|
+
.execute(`select "sales_channel_id" from "${bridge.table}" ` +
|
|
166
|
+
`where "${bridge.entityIdColumn}" = ? order by "sales_channel_id" asc`, [entityId], 'all', em.getTransactionContext());
|
|
167
|
+
const existingIds = existingRows.map((row) => row.sales_channel_id);
|
|
168
|
+
const desiredSorted = [...desiredIds].sort();
|
|
169
|
+
if (existingIds.length === desiredSorted.length &&
|
|
170
|
+
existingIds.every((id, index) => id === desiredSorted[index])) {
|
|
171
|
+
return { changed: false };
|
|
172
|
+
}
|
|
173
|
+
await em.transactional(async (tx) => {
|
|
174
|
+
await tx
|
|
175
|
+
.getConnection()
|
|
176
|
+
.execute(`delete from "${bridge.table}" where "${bridge.entityIdColumn}" = ?`, [entityId], 'run', tx.getTransactionContext());
|
|
177
|
+
for (const channelId of desiredIds) {
|
|
178
|
+
await tx
|
|
179
|
+
.getConnection()
|
|
180
|
+
.execute(`insert into "${bridge.table}" ("sales_channel_id", "${bridge.entityIdColumn}") ` +
|
|
181
|
+
`values (?, ?)`, [channelId, entityId], 'run', tx.getTransactionContext());
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
const desiredSet = new Set(desiredIds);
|
|
185
|
+
const existingSet = new Set(existingIds);
|
|
186
|
+
for (const channelId of existingIds) {
|
|
187
|
+
if (desiredSet.has(channelId))
|
|
188
|
+
continue;
|
|
189
|
+
await this.auditMembership(channelId, entityType, entityId, 'remove', options);
|
|
190
|
+
this.emitMembershipChanged(channelId, entityType, entityId, 'remove');
|
|
191
|
+
}
|
|
192
|
+
for (const channelId of desiredIds) {
|
|
193
|
+
if (existingSet.has(channelId))
|
|
194
|
+
continue;
|
|
195
|
+
await this.auditMembership(channelId, entityType, entityId, 'add', options);
|
|
196
|
+
this.emitMembershipChanged(channelId, entityType, entityId, 'add');
|
|
197
|
+
}
|
|
198
|
+
return { changed: true };
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Narrow a **known** set of entity ids to those bound to `channelId`
|
|
202
|
+
* (issue #185).
|
|
203
|
+
*
|
|
204
|
+
* The read half of the same finding. Three `catalog` services asked
|
|
205
|
+
* `select <entity>_id from sales_channel_<type> where sales_channel_id = ?
|
|
206
|
+
* and <entity>_id in (…)` by hand, one per channel-scoped listing, and every
|
|
207
|
+
* one of them fails closed to the empty set — which is the right behaviour
|
|
208
|
+
* and the wrong place to spell it.
|
|
209
|
+
*
|
|
210
|
+
* Not {@link listEntityIdsForChannel}: that one enumerates a channel's whole
|
|
211
|
+
* membership a page at a time, and a caller holding a page of ids wants the
|
|
212
|
+
* intersection rather than the enumeration. Using it here would mean pulling
|
|
213
|
+
* every product in the channel to filter twenty.
|
|
214
|
+
*/
|
|
215
|
+
async filterEntityIdsInChannel(channelId, entityType, entityIds) {
|
|
216
|
+
if (entityIds.length === 0)
|
|
217
|
+
return [];
|
|
218
|
+
const bridge = this.bridges.require(entityType);
|
|
219
|
+
const em = this.emFactory();
|
|
220
|
+
const placeholders = entityIds.map(() => '?').join(',');
|
|
221
|
+
const rows = await em
|
|
222
|
+
.getConnection()
|
|
223
|
+
.execute(`select "${bridge.entityIdColumn}" from "${bridge.table}" ` +
|
|
224
|
+
`where "sales_channel_id" = ? and "${bridge.entityIdColumn}" in (${placeholders})`, [channelId, ...entityIds], 'all', em.getTransactionContext());
|
|
225
|
+
return rows.map((row) => row[bridge.entityIdColumn]);
|
|
226
|
+
}
|
|
227
|
+
/** Channels an entity currently belongs to. */
|
|
228
|
+
async listChannelsForEntity(entityType, entityId) {
|
|
229
|
+
const bridge = this.bridges.require(entityType);
|
|
230
|
+
const em = this.emFactory();
|
|
231
|
+
const rows = await em
|
|
232
|
+
.getConnection()
|
|
233
|
+
.execute(`select "sales_channel_id" from "${bridge.table}" where "${bridge.entityIdColumn}" = ?`, [entityId], 'all', em.getTransactionContext());
|
|
234
|
+
const ids = rows.map((r) => r.sales_channel_id);
|
|
235
|
+
if (ids.length === 0)
|
|
236
|
+
return [];
|
|
237
|
+
return em.find(SalesChannel, { id: { $in: ids } });
|
|
238
|
+
}
|
|
239
|
+
/** Entity ids of `entityType` that currently belong to `channelId`. */
|
|
240
|
+
async listEntityIdsForChannel(channelId, entityType, page = 0, pageSize = 100) {
|
|
241
|
+
const bridge = this.bridges.require(entityType);
|
|
242
|
+
const em = this.emFactory();
|
|
243
|
+
const totalRows = await em
|
|
244
|
+
.getConnection()
|
|
245
|
+
.execute(`select count(*)::text as count from "${bridge.table}" where "sales_channel_id" = ?`, [channelId], 'all', em.getTransactionContext());
|
|
246
|
+
const total = Number(totalRows[0]?.count ?? '0');
|
|
247
|
+
const rows = await em
|
|
248
|
+
.getConnection()
|
|
249
|
+
.execute(`select "${bridge.entityIdColumn}" from "${bridge.table}" ` +
|
|
250
|
+
`where "sales_channel_id" = ? order by "${bridge.entityIdColumn}" asc ` +
|
|
251
|
+
`offset ? limit ?`, [channelId, page * pageSize, pageSize], 'all', em.getTransactionContext());
|
|
252
|
+
const entityIds = rows.map((r) => r[bridge.entityIdColumn]);
|
|
253
|
+
return { entityIds, total };
|
|
254
|
+
}
|
|
255
|
+
// -------------------------------------------------------------------------
|
|
256
|
+
// Internals
|
|
257
|
+
// -------------------------------------------------------------------------
|
|
258
|
+
async countMembershipsForEntity(em, bridge, entityId) {
|
|
259
|
+
const rows = await em
|
|
260
|
+
.getConnection()
|
|
261
|
+
.execute(`select count(*)::text as count from "${bridge.table}" where "${bridge.entityIdColumn}" = ?`, [entityId], 'all', em.getTransactionContext());
|
|
262
|
+
return Number(rows[0]?.count ?? '0');
|
|
263
|
+
}
|
|
264
|
+
async requireSystemDefaultId(em) {
|
|
265
|
+
const rows = await em
|
|
266
|
+
.getConnection()
|
|
267
|
+
.execute(`select "id" from "sales_channels" where "system_default" = true limit 1`, [], 'all', em.getTransactionContext());
|
|
268
|
+
const id = rows[0]?.id;
|
|
269
|
+
if (!id) {
|
|
270
|
+
throw new HttpError(500, ERROR_CODES.INTERNAL, 'No system-default sales channel found; cannot apply fallback.');
|
|
271
|
+
}
|
|
272
|
+
return id;
|
|
273
|
+
}
|
|
274
|
+
async auditMembership(channelId, entityType, entityId, op, options, fallbackAppliedToDefault) {
|
|
275
|
+
if (!this.auditLogService)
|
|
276
|
+
return;
|
|
277
|
+
await this.auditLogService.record({
|
|
278
|
+
actorAdminUserId: options.actorAdminUserId ?? null,
|
|
279
|
+
action: SALES_CHANNEL_AUDIT_ACTIONS.MEMBERSHIP_CHANGED,
|
|
280
|
+
objectType: 'sales_channel_membership',
|
|
281
|
+
objectId: `${channelId}:${entityType}:${entityId}`,
|
|
282
|
+
stateAfter: {
|
|
283
|
+
channelId,
|
|
284
|
+
entityType,
|
|
285
|
+
entityId,
|
|
286
|
+
op,
|
|
287
|
+
...(fallbackAppliedToDefault ? { fallbackAppliedToDefault: true } : {}),
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
emitMembershipChanged(channelId, entityType, entityId, op) {
|
|
292
|
+
this.eventBus.emit('sales_channels.membership_changed', {
|
|
293
|
+
eventId: `sales_channels.membership_changed:${channelId}:${entityType}:${entityId}:${op}:${Date.now()}`,
|
|
294
|
+
occurredAt: new Date().toISOString(),
|
|
295
|
+
channelId,
|
|
296
|
+
entityType,
|
|
297
|
+
entityId,
|
|
298
|
+
op,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=sales-channel-membership.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sales-channel-membership.service.js","sourceRoot":"","sources":["../../../src/kernel/sales-channels/sales-channel-membership.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { FastifyInstance, FastifyRequest } from 'fastify';
|
|
2
|
+
import type { CachedChannel } from './sales-channels-cache.js';
|
|
3
|
+
import type { SalesChannelResolverService } from './sales-channel-resolver.service.js';
|
|
4
|
+
import type { AuditPort } from '../ports/audit.js';
|
|
5
|
+
/**
|
|
6
|
+
* Sales-channel resolver middleware — feature 005 / T015.
|
|
7
|
+
*
|
|
8
|
+
* Runs as a Fastify `onRequest` hook on every `/api/v1/*` request and fills the
|
|
9
|
+
* request scope's channel slot with the resolved channel (research R-5;
|
|
10
|
+
* feature 072 T028 moved it off the `request.salesChannel` property, so a
|
|
11
|
+
* consumer no longer has to be handed the request to know its channel).
|
|
12
|
+
*
|
|
13
|
+
* Resolution order:
|
|
14
|
+
*
|
|
15
|
+
* 0. Bound api-key actor (feature 062) — the channel derives from the
|
|
16
|
+
* key's binding. An explicit header/query signal naming a DIFFERENT
|
|
17
|
+
* channel refuses with 403 `API_KEY_CHANNEL_MISMATCH` (audited); an
|
|
18
|
+
* unknown/inactive bound channel refuses with the standard
|
|
19
|
+
* `UNKNOWN_/INACTIVE_SALES_CHANNEL` — never a fallback.
|
|
20
|
+
* 1. `X-Sales-Channel: <code>` header
|
|
21
|
+
* 2. `?salesChannel=<code>` query parameter — IGNORED on
|
|
22
|
+
* `/api/v1/admin/*` paths to prevent cross-channel admin bleed.
|
|
23
|
+
* 3. Host-based mapping (env-configured `SALES_CHANNEL_HOST_MAP`).
|
|
24
|
+
* 4. System-default fallback — ONLY on storefront / integration
|
|
25
|
+
* paths. Admin paths refuse with `MISSING_SALES_CHANNEL_CONTEXT`.
|
|
26
|
+
*
|
|
27
|
+
* If a step matches a code that does not exist or is inactive, the
|
|
28
|
+
* middleware refuses with `UNKNOWN_SALES_CHANNEL` /
|
|
29
|
+
* `INACTIVE_SALES_CHANNEL`. The fallback NEVER applies in those cases
|
|
30
|
+
* (FR-014).
|
|
31
|
+
*
|
|
32
|
+
* Every response carries `X-Sales-Channel: <resolvedCode>` so HTTP
|
|
33
|
+
* caches and dev tools can see the effective channel.
|
|
34
|
+
*
|
|
35
|
+
* Paths that should bypass resolution entirely (e.g. health checks)
|
|
36
|
+
* are excluded by the {@link SHOULD_RESOLVE} predicate so liveness
|
|
37
|
+
* probes do not depend on the channel registry being available.
|
|
38
|
+
*/
|
|
39
|
+
export interface SalesChannelResolverPluginOptions {
|
|
40
|
+
resolver: SalesChannelResolverService;
|
|
41
|
+
/**
|
|
42
|
+
* When true, admin paths refuse with `MISSING_SALES_CHANNEL_CONTEXT`
|
|
43
|
+
* if no signal resolves to a channel (FR-014 spirit). When false
|
|
44
|
+
* (default), admin paths fall back to the system default just like
|
|
45
|
+
* storefront paths so the existing admin UI keeps working until it
|
|
46
|
+
* is updated to send `X-Sales-Channel` (T034+). The US3 resolver
|
|
47
|
+
* contract tests (T046) construct a server with `strictAdmin: true`
|
|
48
|
+
* to exercise the production behaviour.
|
|
49
|
+
*/
|
|
50
|
+
strictAdmin?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Feature 062 — sink for the `api_key.channel_mismatch` refusal audit
|
|
53
|
+
* (bound key named a channel other than its bound one). Optional so
|
|
54
|
+
* minimal test composition roots keep working.
|
|
55
|
+
*/
|
|
56
|
+
auditLogService?: AuditPort;
|
|
57
|
+
}
|
|
58
|
+
export declare function registerSalesChannelResolverMiddleware(app: FastifyInstance, options: SalesChannelResolverPluginOptions): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* The resolved channel for the current execution, or `null` when the resolver
|
|
61
|
+
* did not run on this path (`/api/v1/_health`, non-API routes) or there is no
|
|
62
|
+
* request scope at all.
|
|
63
|
+
*
|
|
64
|
+
* Takes no argument on purpose: the channel lives on the scope now, so a caller
|
|
65
|
+
* deep in a service no longer has to be threaded a `FastifyRequest` to read it.
|
|
66
|
+
*/
|
|
67
|
+
export declare function currentSalesChannel(): CachedChannel | null;
|
|
68
|
+
/**
|
|
69
|
+
* Helper used by route handlers downstream. Throws if not resolved.
|
|
70
|
+
*
|
|
71
|
+
* The `request` parameter is retained so the 49 existing call sites keep
|
|
72
|
+
* compiling unchanged; it is no longer read. New code calls
|
|
73
|
+
* `getResolvedChannel()` or `currentSalesChannel()`.
|
|
74
|
+
*/
|
|
75
|
+
export declare function getResolvedChannel(_request?: FastifyRequest): CachedChannel;
|
|
76
|
+
//# sourceMappingURL=sales-channel-resolver.middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sales-channel-resolver.middleware.d.ts","sourceRoot":"","sources":["../../../src/kernel/sales-channels/sales-channel-resolver.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgB,cAAc,EAAE,MAAM,SAAS,CAAC;AAI7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,WAAW,iCAAiC;IAChD,QAAQ,EAAE,2BAA2B,CAAC;IACtC;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;CAC7B;AAsCD,wBAAsB,sCAAsC,CAC1D,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,iCAAiC,GACzC,OAAO,CAAC,IAAI,CAAC,CA4Gf;AAgDD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,GAAG,IAAI,CAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,CAU3E"}
|