@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,127 @@
|
|
|
1
|
+
import type { FastifyInstance, FastifyRequest } from 'fastify';
|
|
2
|
+
import { type ErrorCode, type ModuleErrorCode, type SupportedLanguage } from '@endora-commerce/contracts';
|
|
3
|
+
/**
|
|
4
|
+
* Fastify plugin that converts every error — Zod validation failures, MikroORM unique-constraint
|
|
5
|
+
* violations, HttpError throws, or unexpected exceptions — into the project-wide error envelope
|
|
6
|
+
* documented in specs/001-b2b-platform-foundation/contracts/README.md.
|
|
7
|
+
*/
|
|
8
|
+
export declare class HttpError extends Error {
|
|
9
|
+
readonly statusCode: number;
|
|
10
|
+
/**
|
|
11
|
+
* The platform's own enumeration, or a code a module declared (feature 090,
|
|
12
|
+
* D-182). `ModuleErrorCode` is branded and is produced only by
|
|
13
|
+
* `defineModuleErrorCodes`, so a bare `'ACME_TYPO'` here is a compile error
|
|
14
|
+
* rather than a code that travels the whole path and renders raw to an
|
|
15
|
+
* operator with nothing reporting it.
|
|
16
|
+
*/
|
|
17
|
+
readonly code: ErrorCode | ModuleErrorCode;
|
|
18
|
+
readonly details?: Array<{
|
|
19
|
+
path: string;
|
|
20
|
+
issue: string;
|
|
21
|
+
}> | Record<string, unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Response headers this error implies, applied by the error handler below.
|
|
24
|
+
*
|
|
25
|
+
* A status code is sometimes only half the answer: `503 MODULE_DISABLED` is
|
|
26
|
+
* `Retry-After` or it is an outage, and which one the client believes decides
|
|
27
|
+
* whether it backs off or gives up. Before this, the header was set by the
|
|
28
|
+
* one hook that knew it — `defineModuleRoutes` — so the identical error
|
|
29
|
+
* thrown from a service call (`requireModuleEnabled`) or from a port
|
|
30
|
+
* resolution reached the client without it. Carrying it on the error keeps
|
|
31
|
+
* the answer the same wherever the throw happens.
|
|
32
|
+
*/
|
|
33
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
34
|
+
constructor(statusCode: number, code: ErrorCode | ModuleErrorCode, message: string, details?: Array<{
|
|
35
|
+
path: string;
|
|
36
|
+
issue: string;
|
|
37
|
+
}> | Record<string, unknown>, headers?: Readonly<Record<string, string>>);
|
|
38
|
+
}
|
|
39
|
+
/** Which translation bundle owns an error code's message. Injected — see below. */
|
|
40
|
+
export interface ErrorTranslationTargets {
|
|
41
|
+
readonly [code: string]: {
|
|
42
|
+
readonly moduleId: string;
|
|
43
|
+
readonly key: string;
|
|
44
|
+
} | undefined;
|
|
45
|
+
}
|
|
46
|
+
export interface ErrorEnvelopeOptions {
|
|
47
|
+
/**
|
|
48
|
+
* `ErrorCode → {moduleId, key}`, injected by the composition root (D-54).
|
|
49
|
+
*
|
|
50
|
+
* The map lives in `_i18n` and used to be imported here directly — the one
|
|
51
|
+
* thing in this plugin that was not injected, while the two functions below
|
|
52
|
+
* already were. `src/http` is a kernel-obeying platform peer (D-52): the
|
|
53
|
+
* kernel cannot compile without it, so a peer permitted to import a module is
|
|
54
|
+
* a kernel importing modules with one extra hop, and in package terms it is
|
|
55
|
+
* the cycle `kernel → http → mod-i18n → kernel`. Nothing was broken at
|
|
56
|
+
* runtime — `_i18n` is `nonDeactivatable` and the map was then a static table
|
|
57
|
+
* — but F4's precondition is that packages are not cyclic.
|
|
58
|
+
*
|
|
59
|
+
* **It stays injected rather than moving into `@endora-commerce/contracts`**, for symmetry
|
|
60
|
+
* with the two functions below and because a routing table frozen into a
|
|
61
|
+
* contracts release is a routing table a module cannot re-point when it takes
|
|
62
|
+
* ownership of a code family.
|
|
63
|
+
*
|
|
64
|
+
* It is *not*, however, a per-deployment override, and this comment used to
|
|
65
|
+
* say it was (issue #106). Translation values are shipped as module JSON,
|
|
66
|
+
* reconciled into `translation_bundles` at boot and re-read on reload, and no
|
|
67
|
+
* admin route edits one — so a deployment genuinely cannot change a sentence
|
|
68
|
+
* by configuration. But re-routing a family through this map does not help:
|
|
69
|
+
* both composition roots pass the same derivation, and a deployment cannot
|
|
70
|
+
* substitute it without editing a core file, which is the thing the overlay
|
|
71
|
+
* pattern exists to avoid. **A deployment's own overlay module can now change
|
|
72
|
+
* the answer honestly** (feature 090): the map is
|
|
73
|
+
* `buildErrorTranslationTargets` over the resolved manifest set, so an overlay
|
|
74
|
+
* module that declares a code owns it — and one that declares a code a core
|
|
75
|
+
* module already declares collides with it, and the code routes to neither.
|
|
76
|
+
* What a deployment *can* already
|
|
77
|
+
* do, with no new machinery, is decorate the `adminI18nService` registration
|
|
78
|
+
* from its own overlay module (`ctx.di.decorate`, D-103) and answer
|
|
79
|
+
* differently for the keys it cares about — a lever that reaches every string
|
|
80
|
+
* rather than only an error family. Whether that is the answer #106 wants is a product
|
|
81
|
+
* question, not a technical one, and nothing here assumes an answer: this hook
|
|
82
|
+
* chooses the **key** and the **params**, never the value, so a value-level
|
|
83
|
+
* override built later slots underneath both it and issue #65's token rule
|
|
84
|
+
* without touching either.
|
|
85
|
+
*
|
|
86
|
+
* Absent, no message is translated; the envelope keeps the original text.
|
|
87
|
+
*/
|
|
88
|
+
errorTranslationTargets?: ErrorTranslationTargets;
|
|
89
|
+
translateErrorMessage?: (args: {
|
|
90
|
+
moduleId: string;
|
|
91
|
+
key: string;
|
|
92
|
+
language: SupportedLanguage;
|
|
93
|
+
originalMessage: string;
|
|
94
|
+
/**
|
|
95
|
+
* Values for the `{placeholder}`s in the sentence, read off the error's
|
|
96
|
+
* `details` (issue #161).
|
|
97
|
+
*
|
|
98
|
+
* Substitution stays in `_i18n` — it already interpolates `{name}` for
|
|
99
|
+
* every other backend-side lookup, and two implementations of one template
|
|
100
|
+
* syntax is one too many. What this plugin decides is *which* values, and
|
|
101
|
+
* the answer is the error's own structured metadata: `details` is already
|
|
102
|
+
* on the wire, already survives the message replacement, and is already
|
|
103
|
+
* where issue #65 put the discriminator this hook reads.
|
|
104
|
+
*/
|
|
105
|
+
params?: Record<string, string | number>;
|
|
106
|
+
request: FastifyRequest;
|
|
107
|
+
}) => Promise<string>;
|
|
108
|
+
/**
|
|
109
|
+
* Which language this response is written in, decided per audience.
|
|
110
|
+
*
|
|
111
|
+
* Injected for the same reason the two functions above are: the *policy* —
|
|
112
|
+
* the buyer's q-weighted header, the channel backstop, the admin's stored
|
|
113
|
+
* preference — lives in `src/kernel/i18n/request-language.ts`, and
|
|
114
|
+
* `src/http` may not import `src/kernel` (the kernel already imports
|
|
115
|
+
* `HttpError` from here, so an edge back is the package cycle D-52 refuses).
|
|
116
|
+
* Both composition roots may import both, and that is what joins them
|
|
117
|
+
* (feature 083, D-137).
|
|
118
|
+
*
|
|
119
|
+
* Absent, or answering nothing, the envelope falls back to
|
|
120
|
+
* `LANGUAGE_FALLBACK`. That fallback used to be reached by **every** buyer,
|
|
121
|
+
* because both roots' closures returned `null` for a non-admin actor — issue
|
|
122
|
+
* #234, and the reason the constant is no longer called "admin".
|
|
123
|
+
*/
|
|
124
|
+
resolvePreferredLanguage?: (request: FastifyRequest) => Promise<SupportedLanguage | null | undefined>;
|
|
125
|
+
}
|
|
126
|
+
export declare function registerErrorEnvelope(app: FastifyInstance, options?: ErrorEnvelopeOptions): void;
|
|
127
|
+
//# sourceMappingURL=error-envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-envelope.d.ts","sourceRoot":"","sources":["../../src/http/error-envelope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgB,cAAc,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAkC,KAAK,SAAS,EAAsB,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAK9J;;;;GAIG;AAEH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,eAAe,CAAC;IAK3C,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpF;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;gBAGlD,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,GAAG,eAAe,EACjC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAa7C;AAED,mFAAmF;AACnF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC1F;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAClD,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC7B,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,iBAAiB,CAAC;QAC5B,eAAe,EAAE,MAAM,CAAC;QACxB;;;;;;;;;;WAUG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;QACzC,OAAO,EAAE,cAAc,CAAC;KACzB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB;;;;;;;;;;;;;;;OAeG;IACH,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CACvG;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,GAAE,oBAAyB,GAAG,IAAI,CAkMpG"}
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { LANGUAGE_FALLBACK, ERROR_CODES } from '@endora-commerce/contracts';
|
|
2
|
+
import { ZodError } from 'zod';
|
|
3
|
+
import { hasZodFastifySchemaValidationErrors } from '@fastify/type-provider-zod';
|
|
4
|
+
import { OrgWriteOutOfScopeError } from '../tenancy/tenant-context.js';
|
|
5
|
+
/**
|
|
6
|
+
* Fastify plugin that converts every error — Zod validation failures, MikroORM unique-constraint
|
|
7
|
+
* violations, HttpError throws, or unexpected exceptions — into the project-wide error envelope
|
|
8
|
+
* documented in specs/001-b2b-platform-foundation/contracts/README.md.
|
|
9
|
+
*/
|
|
10
|
+
export class HttpError extends Error {
|
|
11
|
+
statusCode;
|
|
12
|
+
/**
|
|
13
|
+
* The platform's own enumeration, or a code a module declared (feature 090,
|
|
14
|
+
* D-182). `ModuleErrorCode` is branded and is produced only by
|
|
15
|
+
* `defineModuleErrorCodes`, so a bare `'ACME_TYPO'` here is a compile error
|
|
16
|
+
* rather than a code that travels the whole path and renders raw to an
|
|
17
|
+
* operator with nothing reporting it.
|
|
18
|
+
*/
|
|
19
|
+
code;
|
|
20
|
+
// The legacy shape (an array of {path, issue}) is preserved for Zod-style
|
|
21
|
+
// validation failures. Feature 022 introduced bulk-operation errors that
|
|
22
|
+
// need a free-form object (e.g. `{ maxBatchSize: 200, attribute: "brand" }`).
|
|
23
|
+
// Both shapes are propagated verbatim into the response envelope.
|
|
24
|
+
details;
|
|
25
|
+
/**
|
|
26
|
+
* Response headers this error implies, applied by the error handler below.
|
|
27
|
+
*
|
|
28
|
+
* A status code is sometimes only half the answer: `503 MODULE_DISABLED` is
|
|
29
|
+
* `Retry-After` or it is an outage, and which one the client believes decides
|
|
30
|
+
* whether it backs off or gives up. Before this, the header was set by the
|
|
31
|
+
* one hook that knew it — `defineModuleRoutes` — so the identical error
|
|
32
|
+
* thrown from a service call (`requireModuleEnabled`) or from a port
|
|
33
|
+
* resolution reached the client without it. Carrying it on the error keeps
|
|
34
|
+
* the answer the same wherever the throw happens.
|
|
35
|
+
*/
|
|
36
|
+
headers;
|
|
37
|
+
constructor(statusCode, code, message, details, headers) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.statusCode = statusCode;
|
|
40
|
+
this.code = code;
|
|
41
|
+
if (details !== undefined) {
|
|
42
|
+
this.details = details;
|
|
43
|
+
}
|
|
44
|
+
if (headers !== undefined) {
|
|
45
|
+
this.headers = headers;
|
|
46
|
+
}
|
|
47
|
+
this.name = 'HttpError';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function registerErrorEnvelope(app, options = {}) {
|
|
51
|
+
app.addHook('preSerialization', async (request, reply, payload) => {
|
|
52
|
+
if (!options.translateErrorMessage || !isErrorEnvelope(payload))
|
|
53
|
+
return payload;
|
|
54
|
+
const target = options.errorTranslationTargets?.[payload.error.code];
|
|
55
|
+
if (!target)
|
|
56
|
+
return payload;
|
|
57
|
+
try {
|
|
58
|
+
return await localizeErrorEnvelope(options, target, payload, request, reply);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// **Localising an error may never replace the error.**
|
|
62
|
+
//
|
|
63
|
+
// Every other way out of the decoration below already returns `payload`
|
|
64
|
+
// unchanged — no target, a `VALIDATION_FAILED` carrying a machine token,
|
|
65
|
+
// a sentence with a placeholder nothing filled — on the ruling that
|
|
66
|
+
// untranslated prose which is true beats a rendered sentence that is
|
|
67
|
+
// not. A throw was the one path that did neither, and it is the worst of
|
|
68
|
+
// them: this hook runs during the serialisation of a reply Fastify is
|
|
69
|
+
// already treating as an error, so Fastify cannot route the throw back
|
|
70
|
+
// through `setErrorHandler`. It falls back to its own serialiser, and
|
|
71
|
+
// the response stops being an `ErrorEnvelope` at all —
|
|
72
|
+
// `{ statusCode, code, error, message }`, where `error` is the status
|
|
73
|
+
// phrase and `error.code` is `undefined`.
|
|
74
|
+
// The admin's API client (`@endora-commerce/admin-kit/lib`) sees
|
|
75
|
+
// `'error' in body`, builds an `ApiError` out of it and reports
|
|
76
|
+
// `undefined: undefined`.
|
|
77
|
+
//
|
|
78
|
+
// Both injected callbacks can throw and one of them measurably did:
|
|
79
|
+
// feature 080's T052 turned the root's `adminPreferredLanguage` closure
|
|
80
|
+
// into a read of the gated `adminUserReadPort`, so while `admin_users`
|
|
81
|
+
// was platform-absent every error answered to a signed-in admin lost its
|
|
82
|
+
// envelope — the `MODULE_DISABLED` refusal included, which is the one
|
|
83
|
+
// whose job is to name the module an operator has to restore (issue
|
|
84
|
+
// #161). `RequestLanguageDeps.adminPreferredLanguage` had said in
|
|
85
|
+
// writing that a gated port here would do exactly that.
|
|
86
|
+
//
|
|
87
|
+
// So the guarantee is stated once, at the renderer, rather than at each
|
|
88
|
+
// callback a root injects: an absent owner, a bundle store that cannot be
|
|
89
|
+
// reached, and whatever the next callback turns out to be all degrade to
|
|
90
|
+
// the untranslated envelope. This is deliberately **not** a
|
|
91
|
+
// `catch` that hides a capability's absence from a caller — the caller
|
|
92
|
+
// still gets the refusal, in full, in `LANGUAGE_FALLBACK`.
|
|
93
|
+
request.log.warn({ err: error, code: payload.error.code, moduleId: target.moduleId }, 'error-envelope localisation failed; answering with the untranslated envelope');
|
|
94
|
+
return payload;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
app.setErrorHandler((error, request, reply) => {
|
|
98
|
+
const requestId = request.id;
|
|
99
|
+
// Fastify wraps Zod validation errors from the Zod type provider — detect them via
|
|
100
|
+
// the helper exposed by @fastify/type-provider-zod, then fall back to a plain ZodError.
|
|
101
|
+
if (hasZodFastifySchemaValidationErrors(error)) {
|
|
102
|
+
const envelope = {
|
|
103
|
+
error: {
|
|
104
|
+
code: ERROR_CODES.VALIDATION_FAILED,
|
|
105
|
+
message: 'Request failed validation.',
|
|
106
|
+
details: error.validation.map((issue) => ({
|
|
107
|
+
path: issue.instancePath.replace(/^\//, '').replace(/\//g, '.'),
|
|
108
|
+
issue: issue.message ?? 'invalid',
|
|
109
|
+
})),
|
|
110
|
+
requestId,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
reply.status(400).send(envelope);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (error instanceof ZodError) {
|
|
117
|
+
const envelope = {
|
|
118
|
+
error: {
|
|
119
|
+
code: ERROR_CODES.VALIDATION_FAILED,
|
|
120
|
+
message: 'Request failed validation.',
|
|
121
|
+
details: error.issues.map((issue) => ({
|
|
122
|
+
path: issue.path.map(String).join('.'),
|
|
123
|
+
issue: issue.message,
|
|
124
|
+
})),
|
|
125
|
+
requestId,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
reply.status(400).send(envelope);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (error instanceof HttpError) {
|
|
132
|
+
// A **server fault** is logged whether or not somebody wrapped it, and the
|
|
133
|
+
// status code is what decides — not the class, and not the code.
|
|
134
|
+
//
|
|
135
|
+
// The 5xx branch used to return in silence, and that silence is what let
|
|
136
|
+
// an instance answer `500 INTERNAL` to every request for months with
|
|
137
|
+
// nothing to read: `NoSystemDefaultChannel` is an `HttpError`, so it never
|
|
138
|
+
// reached the `request.log.error` at the bottom of this handler, and the
|
|
139
|
+
// envelope's `requestId` was the entire trace. Diagnosing it needed a
|
|
140
|
+
// `console.error` patched into an installed package.
|
|
141
|
+
//
|
|
142
|
+
// A 4xx stays silent, deliberately: it is the client saying something
|
|
143
|
+
// wrong, its own envelope already says what, and logging it turns a
|
|
144
|
+
// mistyped URL into log volume.
|
|
145
|
+
if (error.statusCode >= 500) {
|
|
146
|
+
request.log.error({ err: error, statusCode: error.statusCode, code: error.code }, 'server fault');
|
|
147
|
+
}
|
|
148
|
+
const envelope = {
|
|
149
|
+
error: {
|
|
150
|
+
code: error.code,
|
|
151
|
+
message: error.message,
|
|
152
|
+
...(error.details ? { details: error.details } : {}),
|
|
153
|
+
requestId,
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
for (const [name, value] of Object.entries(error.headers ?? {})) {
|
|
157
|
+
reply.header(name, value);
|
|
158
|
+
}
|
|
159
|
+
reply.status(error.statusCode).send(envelope);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// The tenant write guard's refusal (D-260/A). Raised by
|
|
163
|
+
// `tenancy/org-write-guard.ts` from inside `em.flush()`, so it arrives here
|
|
164
|
+
// having rolled the whole transaction back — including the audit row.
|
|
165
|
+
//
|
|
166
|
+
// **403 and not 404, and this is deliberate** — a future reader will
|
|
167
|
+
// otherwise "fix" it to a 404 by citing FR-008. FR-008 is about not
|
|
168
|
+
// disclosing whether a *record* exists, and this is not that answer: it is a
|
|
169
|
+
// **backstop** behind the surface's own gate (D-260/B), reached only when a
|
|
170
|
+
// route accepted an organization id it never authorised. The caller supplied
|
|
171
|
+
// the id, so "outside your scope" tells it nothing it did not already know,
|
|
172
|
+
// and the error carries no organization and no set — see
|
|
173
|
+
// `OrgWriteOutOfScopeError`. A 404 here would also be a lie about the one
|
|
174
|
+
// thing the operator needs: that the request was refused rather than lost.
|
|
175
|
+
// The indistinguishable-from-not-found answer is the *surface's* to give,
|
|
176
|
+
// upstream, before the command runs.
|
|
177
|
+
if (error instanceof OrgWriteOutOfScopeError) {
|
|
178
|
+
const envelope = {
|
|
179
|
+
error: {
|
|
180
|
+
code: ERROR_CODES.FORBIDDEN,
|
|
181
|
+
message: 'This write is outside your organization scope.',
|
|
182
|
+
requestId,
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
reply.status(403).send(envelope);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// MikroORM unique-constraint violation: `UniqueConstraintViolationException` has a
|
|
189
|
+
// stable class name we can test without importing the full ORM type.
|
|
190
|
+
//
|
|
191
|
+
// **A 409 arriving from a tenant-keyed unique constraint is a missing scope
|
|
192
|
+
// gate upstream, not a lost race** (D-260, corollary 1). The mapping is
|
|
193
|
+
// right and stays: for a genuine duplicate, 409 and *"the resource was
|
|
194
|
+
// changed by another process"* are the correct answer. What used to arrive
|
|
195
|
+
// through it was a *refusal* — a scoped actor inserting a row for an
|
|
196
|
+
// organization whose existing row its own narrowed read could not see, so
|
|
197
|
+
// the composite primary key collided. Measured twice on the same shape, in
|
|
198
|
+
// `quick_order` (087 §2.2) and in the five payment gateways. Both authors
|
|
199
|
+
// delete it at its cause — the branch above refuses before the insert, and
|
|
200
|
+
// the surface's own gate answers before the command runs — so a 409 on such
|
|
201
|
+
// a path today means one of those two is missing, and the repair is
|
|
202
|
+
// upstream rather than here.
|
|
203
|
+
if (error.constructor?.name === 'UniqueConstraintViolationException') {
|
|
204
|
+
const envelope = {
|
|
205
|
+
error: {
|
|
206
|
+
code: ERROR_CODES.VERSION_CONFLICT,
|
|
207
|
+
message: 'Unique constraint violated.',
|
|
208
|
+
requestId,
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
reply.status(409).send(envelope);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
// Fallback — 500. Log the full error; do not leak details to the client.
|
|
215
|
+
request.log.error({ err: error }, 'unhandled error');
|
|
216
|
+
const envelope = {
|
|
217
|
+
error: {
|
|
218
|
+
code: ERROR_CODES.INTERNAL,
|
|
219
|
+
message: 'Internal server error.',
|
|
220
|
+
requestId,
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
reply.status(500).send(envelope);
|
|
224
|
+
});
|
|
225
|
+
// 404 fallback (Fastify's default is a plain text; we want the envelope).
|
|
226
|
+
app.setNotFoundHandler((request, reply) => {
|
|
227
|
+
const envelope = {
|
|
228
|
+
error: {
|
|
229
|
+
code: ERROR_CODES.NOT_FOUND,
|
|
230
|
+
message: `Route ${request.method} ${request.url} not found.`,
|
|
231
|
+
requestId: request.id,
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
reply.status(404).send(envelope);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* The decoration itself: the written message replaced by the registered
|
|
239
|
+
* sentence for its code, in the language this response is being answered in.
|
|
240
|
+
*
|
|
241
|
+
* Split out of the hook so the guard above wraps the whole of it and nothing
|
|
242
|
+
* else — a `try` opened around the early returns too would be a blanket catch
|
|
243
|
+
* over a payload that never entered the decoration.
|
|
244
|
+
*/
|
|
245
|
+
async function localizeErrorEnvelope(options, target, payload, request, reply) {
|
|
246
|
+
// Narrowing only: the hook already refused a composition that injects no
|
|
247
|
+
// translator, and this is the same `options` object.
|
|
248
|
+
if (!options.translateErrorMessage)
|
|
249
|
+
return payload;
|
|
250
|
+
// VALIDATION_FAILED is overloaded: besides generic Zod failures it is the
|
|
251
|
+
// code several services reuse while putting a specific, machine-readable
|
|
252
|
+
// token in the message (e.g. `sku_in_use`, `attribute_not_found`,
|
|
253
|
+
// `language_not_in_channel`). Unlike other registered codes — whose
|
|
254
|
+
// message is human prose safe to localize wholesale — replacing this one
|
|
255
|
+
// with the generic localized string would destroy the token that API
|
|
256
|
+
// consumers (and contract tests) depend on. Leave its message verbatim.
|
|
257
|
+
if (payload.error.code === ERROR_CODES.VALIDATION_FAILED)
|
|
258
|
+
return payload;
|
|
259
|
+
// The same phenomenon one code lower, written down somewhere else (issue
|
|
260
|
+
// #65). A code such as `FORBIDDEN` is shared by every permission failure in
|
|
261
|
+
// the tree, so its sentence has to be generic — "You do not have permission
|
|
262
|
+
// to perform this action." A refusal that is *not* about permission carries
|
|
263
|
+
// a machine-readable token in `details.code` to say so, and the four
|
|
264
|
+
// transact gates (`orders`, its external intake, `carts`, `quote_requests`)
|
|
265
|
+
// all publish `organization_cannot_transact` there. Replacing their written
|
|
266
|
+
// message with the family sentence told a buyer whose Organization was
|
|
267
|
+
// blocked for a business reason that they lack permission: wrong, and
|
|
268
|
+
// unactionable — they contact support about access rather than about the
|
|
269
|
+
// block.
|
|
270
|
+
//
|
|
271
|
+
// So the token keys the sentence: `errors.<CODE>.<token>` when the bundle
|
|
272
|
+
// has one, `errors.<CODE>` when the error carries no token. A token with no
|
|
273
|
+
// sentence yet resolves to nothing, and both roots' translators answer a
|
|
274
|
+
// missing key with the original message — which is the right fallback here,
|
|
275
|
+
// because untranslated prose that is true beats a translated sentence that
|
|
276
|
+
// is false. Re-routing the family to another module's bundle keeps working:
|
|
277
|
+
// the module is still chosen by the injected map, and only the key inside it
|
|
278
|
+
// changes. (That routing is not the per-deployment override this comment
|
|
279
|
+
// once called it — see `errorTranslationTargets` above, issue #106.)
|
|
280
|
+
//
|
|
281
|
+
// The same reasoning one step further along (issue #161). `MODULE_DISABLED`
|
|
282
|
+
// is one code for every gated port in the platform, so its sentence is
|
|
283
|
+
// generic for the same reason `FORBIDDEN`'s is — but the specific part is
|
|
284
|
+
// not a token choosing a different sentence, it is a *value* the one
|
|
285
|
+
// sentence is missing. An operator refused a refund because a payment
|
|
286
|
+
// gateway is switched off read "Module Disabled." and was not told which
|
|
287
|
+
// module to switch back on, while `ModuleDisabledError` had carried the id
|
|
288
|
+
// on the error object all along.
|
|
289
|
+
//
|
|
290
|
+
// So the error's structured metadata fills the sentence: `details`' scalar
|
|
291
|
+
// members become the interpolation parameters. It is the same `details` the
|
|
292
|
+
// token above is read from — already on the wire, already surviving this
|
|
293
|
+
// replacement — so a thrower that wants its refusal named says so once, in
|
|
294
|
+
// the place a client can branch on too.
|
|
295
|
+
const params = messageParams(payload.error.details);
|
|
296
|
+
const token = refusalToken(payload.error.details);
|
|
297
|
+
const language = (await options.resolvePreferredLanguage?.(request)) ?? LANGUAGE_FALLBACK;
|
|
298
|
+
const translated = await options.translateErrorMessage({
|
|
299
|
+
moduleId: target.moduleId,
|
|
300
|
+
key: token === null ? target.key : `${target.key}.${token}`,
|
|
301
|
+
language,
|
|
302
|
+
originalMessage: payload.error.message,
|
|
303
|
+
...(params ? { params } : {}),
|
|
304
|
+
request,
|
|
305
|
+
});
|
|
306
|
+
// A sentence with a placeholder nothing filled is worse than the prose the
|
|
307
|
+
// thrower wrote: `The "{module}" module is off` tells the operator less than
|
|
308
|
+
// the original message and looks broken doing it. Same ruling as the missing
|
|
309
|
+
// token key above — untranslated prose that is true beats a rendered
|
|
310
|
+
// sentence that is not.
|
|
311
|
+
if (hasUnfilledPlaceholder(translated))
|
|
312
|
+
return payload;
|
|
313
|
+
// Say which language was chosen, and that the body varies with the header
|
|
314
|
+
// that chose it (D-139 § 8.2). The sales-channel resolver already echoes
|
|
315
|
+
// `X-Sales-Channel` on every response for exactly this reason, and the
|
|
316
|
+
// precedent is the right one: a resolution nobody can see is a resolution
|
|
317
|
+
// nobody audits. Had this header existed, issue #234 — every buyer
|
|
318
|
+
// answered in English — would have been visible in a browser's network tab
|
|
319
|
+
// from the first day.
|
|
320
|
+
//
|
|
321
|
+
// `Vary` is set only here, on a response whose body genuinely varies:
|
|
322
|
+
// `catalog`, `search` and `cms` vary content on the same header and carry
|
|
323
|
+
// no `Vary` either, which is a pre-existing cache-key gap this feature does
|
|
324
|
+
// not widen and does not fix (T024).
|
|
325
|
+
reply.header('Content-Language', language);
|
|
326
|
+
varyBy(reply, 'Accept-Language');
|
|
327
|
+
return {
|
|
328
|
+
...payload,
|
|
329
|
+
error: {
|
|
330
|
+
...payload.error,
|
|
331
|
+
message: translated,
|
|
332
|
+
},
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* The refusal token an error carries, or `null`.
|
|
337
|
+
*
|
|
338
|
+
* `details` has two shapes (see `errorEnvelopeSchema`): the Zod-style array of
|
|
339
|
+
* `{path, issue}` pairs, which carries no token, and the free-form object a
|
|
340
|
+
* domain error uses for structured metadata. Only the second can name one, and
|
|
341
|
+
* only a non-empty string counts.
|
|
342
|
+
*/
|
|
343
|
+
function refusalToken(details) {
|
|
344
|
+
if (!details || Array.isArray(details))
|
|
345
|
+
return null;
|
|
346
|
+
const code = details['code'];
|
|
347
|
+
return typeof code === 'string' && code.length > 0 ? code : null;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* The values a sentence's `{placeholder}`s may be filled from, or `undefined`.
|
|
351
|
+
*
|
|
352
|
+
* Same two shapes as {@link refusalToken}: the Zod-style array carries
|
|
353
|
+
* `{path, issue}` pairs and nothing a sentence names, so it contributes
|
|
354
|
+
* nothing. From the free-form object only **scalars** are taken — an array or a
|
|
355
|
+
* nested object has no defensible rendering inside prose, and one that
|
|
356
|
+
* stringified to `[object Object]` in front of an operator would be a worse
|
|
357
|
+
* message than the one it replaced.
|
|
358
|
+
*/
|
|
359
|
+
function messageParams(details) {
|
|
360
|
+
if (!details || Array.isArray(details))
|
|
361
|
+
return undefined;
|
|
362
|
+
const params = {};
|
|
363
|
+
for (const [name, value] of Object.entries(details)) {
|
|
364
|
+
if (typeof value === 'string' || typeof value === 'number')
|
|
365
|
+
params[name] = value;
|
|
366
|
+
}
|
|
367
|
+
return Object.keys(params).length > 0 ? params : undefined;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Add one field name to the response's `Vary`, keeping whatever is already
|
|
371
|
+
* there.
|
|
372
|
+
*
|
|
373
|
+
* `reply.header('Vary', …)` replaces, and `@fastify/cors` writes `Vary: Origin`
|
|
374
|
+
* on a cross-origin response — so a plain set would trade one cache-key defect
|
|
375
|
+
* for another: every buyer's language, or every allowed origin, collapsing onto
|
|
376
|
+
* one cached entry.
|
|
377
|
+
*/
|
|
378
|
+
function varyBy(reply, field) {
|
|
379
|
+
const existing = reply.getHeader('Vary');
|
|
380
|
+
const current = Array.isArray(existing) ? existing.join(', ') : (existing ?? '');
|
|
381
|
+
const fields = String(current)
|
|
382
|
+
.split(',')
|
|
383
|
+
.map((part) => part.trim())
|
|
384
|
+
.filter((part) => part.length > 0);
|
|
385
|
+
if (fields.some((part) => part.toLowerCase() === field.toLowerCase()))
|
|
386
|
+
return;
|
|
387
|
+
reply.header('Vary', [...fields, field].join(', '));
|
|
388
|
+
}
|
|
389
|
+
/** `{name}` left standing after interpolation — see the call site. */
|
|
390
|
+
function hasUnfilledPlaceholder(message) {
|
|
391
|
+
return /\{\w+\}/.test(message);
|
|
392
|
+
}
|
|
393
|
+
function isErrorEnvelope(payload) {
|
|
394
|
+
if (!payload || typeof payload !== 'object')
|
|
395
|
+
return false;
|
|
396
|
+
const error = payload.error;
|
|
397
|
+
if (!error || typeof error !== 'object')
|
|
398
|
+
return false;
|
|
399
|
+
const candidate = error;
|
|
400
|
+
return typeof candidate.code === 'string' && typeof candidate.message === 'string';
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=error-envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-envelope.js","sourceRoot":"","sources":["../../src/http/error-envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import type { MikroORM } from '@mikro-orm/postgresql';
|
|
3
|
+
import type { Redis } from 'ioredis';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
/**
|
|
6
|
+
* The liveness and readiness probe — **the platform's, not a module's**
|
|
7
|
+
* (D-229).
|
|
8
|
+
*
|
|
9
|
+
* It moved here from `health_checks`, which was then dissolved. The module owned
|
|
10
|
+
* nothing a module owns: no entity, no migration, no permission, no i18n
|
|
11
|
+
* bundle, no palette action, no Setting. What it had was this route and three
|
|
12
|
+
* closures over host values, and everything those closures reach — `orm`,
|
|
13
|
+
* `redis`, an address — is already platform- or kernel-owned.
|
|
14
|
+
*
|
|
15
|
+
* **Why the move rather than a default-set entry.** `endora new instance`
|
|
16
|
+
* writes the closure over the modules declaring `activation.nonDeactivatable`;
|
|
17
|
+
* `health_checks` declared no `activation` block at all, so no scaffolded
|
|
18
|
+
* instance installed it, and `deploy/compose.prod.yml` healthchecks this exact
|
|
19
|
+
* path on the `backend` service with the storefront waiting on
|
|
20
|
+
* `service_healthy`. An instance's API container therefore never became
|
|
21
|
+
* healthy and its storefront never started. Naming the module in the
|
|
22
|
+
* scaffolder's set would have replaced a derivation with a derivation plus one
|
|
23
|
+
* hand-written exception (D-100), and left the withdrawal open besides:
|
|
24
|
+
* `assertDeactivatable` returns early for a module carrying no activation
|
|
25
|
+
* block, so `module:uninstall health_checks` was accepted and an operator could
|
|
26
|
+
* take the liveness route off a running instance with one command.
|
|
27
|
+
*
|
|
28
|
+
* **And the exemption it used to need is now structural.** The module's own
|
|
29
|
+
* comment argued the probes must never be gated: *a liveness probe that answers
|
|
30
|
+
* 503 because its module is absent makes the orchestrator kill the container,
|
|
31
|
+
* restart it, get 503 again, and repeat — and nothing stays up long enough to
|
|
32
|
+
* serve the surface that would switch the module back on.* That reasoning was
|
|
33
|
+
* correct and stopped one case short of the never-installed one, where the 503
|
|
34
|
+
* is a 404 and there is no route to exempt. A route the platform registers has
|
|
35
|
+
* no presence axis to be gated on, which is what `ctx.ungatedRoutes`' reason
|
|
36
|
+
* paragraph had been asking for.
|
|
37
|
+
*
|
|
38
|
+
* An instance serves `/api/v1/_health` because it is an Endora instance.
|
|
39
|
+
*
|
|
40
|
+
* Not exported from `http/index.ts` on purpose (T1-B): the platform's own app
|
|
41
|
+
* composition is the only caller, no consumer names it, and publishing a
|
|
42
|
+
* subpath for a route nobody imports would widen the host surface for nothing.
|
|
43
|
+
*/
|
|
44
|
+
export interface HealthDeps {
|
|
45
|
+
pingDatabase: () => Promise<boolean>;
|
|
46
|
+
pingRedis: () => Promise<boolean>;
|
|
47
|
+
pingMeilisearch: () => Promise<boolean>;
|
|
48
|
+
}
|
|
49
|
+
export declare const healthResponseSchema: z.ZodObject<{
|
|
50
|
+
status: z.ZodEnum<{
|
|
51
|
+
ok: "ok";
|
|
52
|
+
degraded: "degraded";
|
|
53
|
+
}>;
|
|
54
|
+
checks: z.ZodObject<{
|
|
55
|
+
database: z.ZodBoolean;
|
|
56
|
+
redis: z.ZodBoolean;
|
|
57
|
+
meilisearch: z.ZodBoolean;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
version: z.ZodString;
|
|
60
|
+
uptimeSeconds: z.ZodNumber;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export type HealthResponse = z.infer<typeof healthResponseSchema>;
|
|
63
|
+
/** What the probes read from a composed application. */
|
|
64
|
+
export interface HealthProbeSources {
|
|
65
|
+
/** Kernel-owned. The probe pings on the shared EM. */
|
|
66
|
+
readonly orm: MikroORM;
|
|
67
|
+
/** Platform-owned. Absent in a deployment that runs without Redis. */
|
|
68
|
+
readonly redis: Redis | undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The three probes, over the values a composition already holds. Carried across
|
|
72
|
+
* from the dissolved module's `registerModule` unchanged.
|
|
73
|
+
*/
|
|
74
|
+
export declare function platformHealthProbes(sources: HealthProbeSources): HealthDeps;
|
|
75
|
+
/**
|
|
76
|
+
* The probe as a plugin, ready to go into a composition's `modules` array.
|
|
77
|
+
*
|
|
78
|
+
* There are two composition roots — `composeApp` and the test kit's
|
|
79
|
+
* `composeTestServer` — and each assembles that array itself. They both call
|
|
80
|
+
* this, for the reason the test kit already gives about
|
|
81
|
+
* `registerRequestScopeHook`: one factory with two call sites is a shared
|
|
82
|
+
* seam, two hand-written registrations are a drift waiting to happen. The
|
|
83
|
+
* module this replaced existed in production and nowhere else for exactly that
|
|
84
|
+
* reason, its route having been wired by an inline plugin in one root only.
|
|
85
|
+
*/
|
|
86
|
+
export declare function healthRoutePlugin(sources: HealthProbeSources): (app: FastifyInstance) => Promise<void>;
|
|
87
|
+
export declare function registerHealthRoutes(app: FastifyInstance, deps: HealthDeps): Promise<void>;
|
|
88
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/http/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACzC;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;iBAS/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,wDAAwD;AACxD,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;IACvB,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,UAAU,CAgB5E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAKzC;AAED,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhG"}
|