@wildo-ai/saas-backend-lib 1.1.3 → 1.1.4
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/dist/esm/__tests__/fixture-deep-partial.d.ts.map +1 -1
- package/dist/esm/__tests__/integration/redis-integration-gate.d.ts.map +1 -1
- package/dist/esm/__tests__/setup.d.ts.map +1 -1
- package/dist/esm/__tests__/test-container.d.ts.map +1 -1
- package/dist/esm/applications/models/applications.backend.schemas.d.ts.map +1 -1
- package/dist/esm/applications/seeds/application-metadata-defaults.seeds.d.ts.map +1 -1
- package/dist/esm/applications/services/worker-remote-client-factory.backend.service.d.ts.map +1 -1
- package/dist/esm/applications/services/worker-remote-client-factory.backend.service.js.map +1 -1
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.d.ts.map +1 -1
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.js.map +1 -1
- package/dist/esm/base-classes/models/repositories.backend.schemas.d.ts.map +1 -1
- package/dist/esm/base-classes/services/__tests__/mock-resource-operation-helper.service.d.ts +1 -1
- package/dist/esm/base-classes/services/__tests__/mock-resource-operation-helper.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/batches/batches-cronjobs-custom-execution.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/batches/batches-cronjobs-executor.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/batches/batches-cronjobs-resource-execution.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.js +12 -1
- package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.d.ts.map +1 -1
- package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.js.map +1 -1
- package/dist/esm/base-classes/services/batches/resource-retention-sweep.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/batches/suspension-reactivation-sweep.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/abstract-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/controllers/utils/audit-access-fields.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/utils/operation-response-serializer.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/validate-field-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/__tests__/method-span-scan.guard-helpers.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/__tests__/mock-repositories-registry-handler.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-filter-translation.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.js +13 -4
- package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-query.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.js +17 -0
- package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-row-projection.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-subject-erasure-effect.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/odoo-jsonrpc-compiler.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/rest-json-query-compiler.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +57 -0
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +95 -2
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/repository-guarded-mutation.backend.types.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts +5 -2
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +14 -3
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/repository-version-metadata.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/resource-write-integrity.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/seed-row-default-materialization.backend.d.ts +72 -0
- package/dist/esm/base-classes/services/repositories/seed-row-default-materialization.backend.d.ts.map +1 -0
- package/dist/esm/base-classes/services/repositories/seed-row-default-materialization.backend.js +88 -0
- package/dist/esm/base-classes/services/repositories/seed-row-default-materialization.backend.js.map +1 -0
- package/dist/esm/base-classes/services/repositories/unique-constraint-conflict-reference.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/resource-operations-helper.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/__tests__/mock-services-registry-handler.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/__tests__/mock-system-access.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/read-only-field-change.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-audit-emission.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-server-injected-fields.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.js.map +1 -1
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +44 -6
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/system-access.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/system-access.backend.service.js.map +1 -1
- package/dist/esm/base-classes/utils/backend-type-utils.d.ts.map +1 -1
- package/dist/esm/base-classes/utils/single-subject-addressing.backend.utils.d.ts.map +1 -1
- package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.js.map +1 -1
- package/dist/esm/billing/batches/usage-flush.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/batches/usage-flush.batch.backend.service.js.map +1 -1
- package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.d.ts.map +1 -1
- package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.js.map +1 -1
- package/dist/esm/billing/services/back-office/abstract-billing.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/back-office/billing-feature-sync.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.d.ts +1 -1
- package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.js +5 -4
- package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.js.map +1 -1
- package/dist/esm/billing/services/back-office/billing-state.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/back-office/billing-state.backend.service.js +11 -1
- package/dist/esm/billing/services/back-office/billing-state.backend.service.js.map +1 -1
- package/dist/esm/billing/services/back-office/billing-subject-erasure-effect.backend.d.ts.map +1 -1
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.js.map +1 -1
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.js.map +1 -1
- package/dist/esm/billing/services/billing-adapter-registry.backend.d.ts.map +1 -1
- package/dist/esm/billing/services/billing-adapter-registry.backend.js.map +1 -1
- package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.d.ts.map +1 -1
- package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.js.map +1 -1
- package/dist/esm/billing/services/billing.utils.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts +32 -0
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js +32 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/credit-pool.custom-ops.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.d.ts +9 -6
- package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.js +9 -6
- package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.js.map +1 -1
- package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.d.ts.map +1 -1
- package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.js.map +1 -1
- package/dist/esm/billing/services/webhooks/billing-webhook-adapter.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/webhooks/billing-webhook-capability-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js +50 -3
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js.map +1 -1
- package/dist/esm/billing/testing/billing-test-fixtures.d.ts.map +1 -1
- package/dist/esm/billing/testing/mock-billing-provider.d.ts.map +1 -1
- package/dist/esm/billing/testing/mock-billing-provider.js.map +1 -1
- package/dist/esm/charts/controllers/chart.backend.controller.d.ts.map +1 -1
- package/dist/esm/charts/services/chart-registry.backend.service.d.ts +80 -7
- package/dist/esm/charts/services/chart-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/charts/services/chart-registry.backend.service.js +115 -8
- package/dist/esm/charts/services/chart-registry.backend.service.js.map +1 -1
- package/dist/esm/companion-exports.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-logs.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/batches/audit-logs-archive.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/batches/audit-logs-archive.batch.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/batches/immudb-audit-reconcile.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/batches/siem-webhook-delivery.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/__tests__/mock-audit-logs.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +107 -4
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +176 -5
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js +21 -0
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-class-mapping.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/siem-dictionary.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/siem-ocsf-projection.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/siem-projection-contract.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/utils/audit-actor.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/utils/layer2-audit-provider-boot-diagnostic.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/index.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-hide-predicate.backend.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/services/subject-erasure-external-effects.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/services/subject-session-revocation.backend.service.d.ts.map +1 -1
- package/dist/esm/config/bootstrap/application-runtime-profile.backend.d.ts.map +1 -1
- package/dist/esm/config/bootstrap/application-runtime-profile.backend.js.map +1 -1
- package/dist/esm/config/bootstrap/minion-initialization-projection.backend.d.ts.map +1 -1
- package/dist/esm/config/bootstrap/runtime-principal-attestation.backend.service.d.ts.map +1 -1
- package/dist/esm/config/bootstrap/runtime-principal-attestation.backend.service.js +3 -0
- package/dist/esm/config/bootstrap/runtime-principal-attestation.backend.service.js.map +1 -1
- package/dist/esm/config/bootstrap/runtime-principal.backend.service.d.ts.map +1 -1
- package/dist/esm/config/custom/application-config-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/config/models/app-config-secrets.backend.schemas.d.ts.map +1 -1
- package/dist/esm/config/models/app-config.backend-authored.definitions.d.ts.map +1 -1
- package/dist/esm/config/models/app-config.backend.schemas.d.ts +4 -4
- package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -1
- package/dist/esm/config/models/app-config.backend.schemas.js.map +1 -1
- package/dist/esm/config/models/app-env-config.backend.schemas.d.ts.map +1 -1
- package/dist/esm/config/models/apps-manager-transport.backend.definitions.d.ts +36 -0
- package/dist/esm/config/models/apps-manager-transport.backend.definitions.d.ts.map +1 -0
- package/dist/esm/config/models/apps-manager-transport.backend.definitions.js +36 -0
- package/dist/esm/config/models/apps-manager-transport.backend.definitions.js.map +1 -0
- package/dist/esm/config/models/config-mutation-boundary.utils.d.ts.map +1 -1
- package/dist/esm/config/models/postgresql-env-config.backend.schemas.d.ts.map +1 -1
- package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.d.ts.map +1 -1
- package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.js.map +1 -1
- package/dist/esm/config/models/runtime-topology.backend.contracts.d.ts.map +1 -1
- package/dist/esm/config/services/__tests__/mock-app-configuration.service.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration-loader.backend.service.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration-loader.backend.service.js +3 -0
- package/dist/esm/config/services/app-configuration-loader.backend.service.js.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.service.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.service.js.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -1
- package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts +12 -0
- package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts.map +1 -1
- package/dist/esm/config/services/application-startup-config-validator.backend.service.js +28 -0
- package/dist/esm/config/services/application-startup-config-validator.backend.service.js.map +1 -1
- package/dist/esm/data-seeding/batches/data-seeding-run-cleanup.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/batches/data-seeding-scheduled-rerun.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/controllers/data-seeding-admin.backend.contracts.d.ts.map +1 -1
- package/dist/esm/data-seeding/controllers/data-seeding-admin.backend.controller.d.ts.map +1 -1
- package/dist/esm/data-seeding/data-seeding-models.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/business-key-resolver.shared.utils.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/data-seed-execution-context.shared.types.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/data-seed-migrator-runner.shared.utils.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/data-seed-reconciler.shared.utils.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/data-seed-row-metadata.shared.schemas.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/data-seed-row-metadata.shared.utils.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/data-seed-run.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/data-seed-run.shared.schemas.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/data-seed-trigger-mode-matrix.shared.utils.d.ts.map +1 -1
- package/dist/esm/data-seeding/models/data-seed.shared.schemas.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/data-seed-application-bootstrap.backend.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/data-seed-dispatcher.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/data-seed-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/data-seed-scope-resolver-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/engines/additive-seed-engine.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/engines/lazy-seed-engine.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/engines/manual-seed-engine.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/engines/sync-seed-engine.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/engines/upgrade-seed-engine.backend.service.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/shared/data-seed-business-key.shared.utils.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/shared/data-seed-error.shared.utils.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/shared/data-seed-run-counters.shared.types.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/shared/data-seed-run-ledger.backend.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/shared/data-seed-scope-anchor.shared.types.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.d.ts.map +1 -1
- package/dist/esm/data-seeding/services/shared/data-seed-scope-resolution.backend.d.ts.map +1 -1
- package/dist/esm/databases/models/aggregation.backend.schemas.d.ts.map +1 -1
- package/dist/esm/databases/models/databases.backend.schemas.d.ts.map +1 -1
- package/dist/esm/databases/models/filter.backend.schemas.d.ts.map +1 -1
- package/dist/esm/databases/models/resolve-persistence-adapter.backend.utils.d.ts.map +1 -1
- package/dist/esm/databases/models/sql.backend.schemas.d.ts.map +1 -1
- package/dist/esm/databases/models/transaction.shared.schemas.d.ts.map +1 -1
- package/dist/esm/databases/services/__tests__/mock-mongo-transaction-registry.service.d.ts.map +1 -1
- package/dist/esm/databases/services/__tests__/mock-mongodb.service.d.ts.map +1 -1
- package/dist/esm/databases/services/__tests__/mock-mongoose-model.service.d.ts.map +1 -1
- package/dist/esm/databases/services/__tests__/mock-redis.service.d.ts.map +1 -1
- package/dist/esm/databases/services/__tests__/mock-zod-mongoose-schema-convertor.service.d.ts.map +1 -1
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/aggregation/aggregation-query.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/aggregation/computed-measure-evaluator.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/aggregation/field-access-validator.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/aggregation/time-series-densifier.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/aggregation/topn-processor.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/aggregation/window-function-processor.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/db-utils.d.ts.map +1 -1
- package/dist/esm/databases/services/mongo-aggregation.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/mongodb.service.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-aggregation.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-database.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-development-provisioning.backend.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-filter.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-migration-runner.backend.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-schema-ddl.backend.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-schema-migration-sql.backend.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.js.map +1 -1
- package/dist/esm/databases/services/postgresql-schema-plan-lockfile.backend.d.ts.map +1 -1
- package/dist/esm/databases/services/redis.service.d.ts.map +1 -1
- package/dist/esm/databases/services/resource-persistence-unit-of-work.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/schema-planning-standalone.backend.d.ts.map +1 -1
- package/dist/esm/databases/services/zod-to-mongoose-schema-convertor.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/zod-to-sql-hybrid-schema.planner.d.ts.map +1 -1
- package/dist/esm/databases/utils/postgresql-identifier.backend.utils.d.ts.map +1 -1
- package/dist/esm/errors/services/__tests__/mock-error-builder.service.d.ts.map +1 -1
- package/dist/esm/errors/services/error-builder.backend.service.d.ts.map +1 -1
- package/dist/esm/errors/services/error-builder.backend.service.js.map +1 -1
- package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -1
- package/dist/esm/errors/services/rate-limit.backend.service.d.ts.map +1 -1
- package/dist/esm/errors/services/rate-limit.backend.service.js.map +1 -1
- package/dist/esm/errors/utils/error-log-level-classification.backend.utils.d.ts.map +1 -1
- package/dist/esm/errors/utils/error-log-level-classification.backend.utils.js.map +1 -1
- package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.d.ts.map +1 -1
- package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.js.map +1 -1
- package/dist/esm/external-data/batches/external-data-pipeline-scheduled-run.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts.map +1 -1
- package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-extraction-source.backend.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-models.exports.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.js.map +1 -1
- package/dist/esm/external-data/external-data-transform.backend.d.ts.map +1 -1
- package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/models/external-providers.backend.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.d.ts.map +1 -1
- package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.js.map +1 -1
- package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.d.ts +102 -52
- package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.js +117 -71
- package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.js.map +1 -1
- package/dist/esm/external-providers/operations/provider-operation-request.backend.d.ts.map +1 -1
- package/dist/esm/external-providers/operations/provider-operation-request.backend.js.map +1 -1
- package/dist/esm/external-providers/operations/provider-request-signing.backend.d.ts.map +1 -1
- package/dist/esm/external-providers/operations/provider-request-signing.backend.js +26 -7
- package/dist/esm/external-providers/operations/provider-request-signing.backend.js.map +1 -1
- package/dist/esm/external-providers/operations/provider-rest-call-client.backend.d.ts.map +1 -1
- package/dist/esm/external-providers/operations/provider-rest-call-client.backend.js.map +1 -1
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.js.map +1 -1
- package/dist/esm/external-providers/services/backend-provider-loader.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/backend-provider-loader.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/backend-provider-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/backend-provider-registry.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/document-extraction.backend.service.d.ts +81 -34
- package/dist/esm/external-providers/services/document-extraction.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/document-extraction.backend.service.js +179 -98
- package/dist/esm/external-providers/services/document-extraction.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/embeddings.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/embeddings.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/external-api-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +121 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +151 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.d.ts +15 -1
- package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.js +60 -4
- package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.js.map +1 -1
- package/dist/esm/features/controllers/features.backend.controller.d.ts.map +1 -1
- package/dist/esm/features/services/__tests__/mock-feature-definition-registry.service.d.ts.map +1 -1
- package/dist/esm/features/services/__tests__/mock-feature-resolution.service.d.ts.map +1 -1
- package/dist/esm/features/services/application-features-admin-write-path.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/features/services/feature-definition-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/features/services/feature-gate.backend.service.d.ts.map +1 -1
- package/dist/esm/features/services/feature-resolution.backend.service.d.ts.map +1 -1
- package/dist/esm/features/services/organization-features-admin-write-path.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/features/services/scope-feature-ledger-relationship.backend.utils.d.ts.map +1 -1
- package/dist/esm/features/services/scope-features-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/features/testing/feature-test-utils.d.ts.map +1 -1
- package/dist/esm/files/batches/files-cleanup.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/files/constraints/file-analyzers.types.d.ts.map +1 -1
- package/dist/esm/files/constraints/file-constraint-resolver-chain.backend.service.d.ts.map +1 -1
- package/dist/esm/files/constraints/file-constraint.types.d.ts.map +1 -1
- package/dist/esm/files/constraints/file-validation.backend.service.d.ts.map +1 -1
- package/dist/esm/files/constraints/resource-field-constraint-resolver.backend.service.d.ts.map +1 -1
- package/dist/esm/files/controllers/file.controller.d.ts.map +1 -1
- package/dist/esm/files/controllers/file.controller.js.map +1 -1
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts.map +1 -1
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js.map +1 -1
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts +37 -0
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +221 -21
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -1
- package/dist/esm/files/scanning/clamav-scanner.backend.service.d.ts.map +1 -1
- package/dist/esm/files/scanning/file-scan.types.d.ts.map +1 -1
- package/dist/esm/files/scanning/yara-scanner.backend.service.d.ts.map +1 -1
- package/dist/esm/files/scanning/yara-scanner.backend.service.js +20 -2
- package/dist/esm/files/scanning/yara-scanner.backend.service.js.map +1 -1
- package/dist/esm/files/services/__tests__/mock-file-field-detection.service.d.ts.map +1 -1
- package/dist/esm/files/services/__tests__/mock-file-operation-handler.service.d.ts.map +1 -1
- package/dist/esm/files/services/__tests__/mock-file-repository.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-field-detection.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-operation-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-operation-handler.backend.service.js.map +1 -1
- package/dist/esm/files/services/file-population.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-scanning.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-scanning.backend.service.js +5 -0
- package/dist/esm/files/services/file-scanning.backend.service.js.map +1 -1
- package/dist/esm/files/services/file-text-extraction.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-text-extraction.backend.service.js +8 -5
- package/dist/esm/files/services/file-text-extraction.backend.service.js.map +1 -1
- package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -1
- package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/files.backend.service.js +3 -1
- package/dist/esm/files/services/files.backend.service.js.map +1 -1
- package/dist/esm/files/services/rag-source-field-detection.backend.service.d.ts.map +1 -1
- package/dist/esm/files/storage/application-storage-key.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/storage/application-storage-key.backend.utils.js.map +1 -1
- package/dist/esm/files/storage/file-storage-path-resolver.backend.service.d.ts.map +1 -1
- package/dist/esm/files/storage/file-storage-provider.types.d.ts +36 -1
- package/dist/esm/files/storage/file-storage-provider.types.d.ts.map +1 -1
- package/dist/esm/files/storage/file-storage-provider.types.js.map +1 -1
- package/dist/esm/files/storage/file-storage-router.backend.service.d.ts +21 -3
- package/dist/esm/files/storage/file-storage-router.backend.service.d.ts.map +1 -1
- package/dist/esm/files/storage/file-storage-router.backend.service.js +38 -5
- package/dist/esm/files/storage/file-storage-router.backend.service.js.map +1 -1
- package/dist/esm/files/storage/google-drive-storage-provider.backend.service.d.ts +87 -0
- package/dist/esm/files/storage/google-drive-storage-provider.backend.service.d.ts.map +1 -0
- package/dist/esm/files/storage/google-drive-storage-provider.backend.service.js +340 -0
- package/dist/esm/files/storage/google-drive-storage-provider.backend.service.js.map +1 -0
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.d.ts.map +1 -1
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.js.map +1 -1
- package/dist/esm/files/storage/storage-credential-provider.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/storage/storage-platform-sts-credential-resolver.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/storage/storage-sts-credential-resolver.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/storage/storage-sts-credential-resolver.backend.utils.js +10 -3
- package/dist/esm/files/storage/storage-sts-credential-resolver.backend.utils.js.map +1 -1
- package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.d.ts.map +1 -1
- package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.js.map +1 -1
- package/dist/esm/files/utils/file-field-schema-path.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/file-field-schema-path.backend.utils.js.map +1 -1
- package/dist/esm/files/utils/file-upload.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/file-uploader.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/file-uploader.utils.js.map +1 -1
- package/dist/esm/files/utils/file-validation.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/image-derivation.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/image-thumbnail.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/office-document-text-extraction.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/office-document-text-extraction.backend.utils.js.map +1 -1
- package/dist/esm/files/utils/rag-source-field-schema-path.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/storage-application-identity.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/a2a/batches/a2a-push-delivery.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/controllers/a2a.controller.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/controllers/a2a.controller.js.map +1 -1
- package/dist/esm/flows-actors/a2a/models/a2a-dialect.backend.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/models/a2a-push-notification-delivery.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/models/a2a-push-notification.backend.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-push-delivery-log.repository.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-push-dispatcher.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/controllers/flows-actors.controller.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/models/agent-facets.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/agents.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/models/flows-actors.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/flows-actors.backend.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/flows-actors.backend.schemas.js.map +1 -1
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts +107 -16
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.js +118 -18
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/models/mcp-client.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/mcp-client.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/services/__tests__/fixtures/meta-workflow-evaluation-treatment.test-fixture.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/actors-system.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/actors-system.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/agent-call-trace-sink.backend.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/agent-facets.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts +104 -5
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.js +263 -31
- package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/context-curation.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts +46 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.js +193 -6
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/flows-actors-registry.service.js.map +1 -1
- package/dist/esm/flows-actors/services/flows.backend.services.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/flows.backend.services.js.map +1 -1
- package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.js.map +1 -1
- package/dist/esm/flows-actors/services/mcp-client.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/mcp-client.backend.service.js +3 -0
- package/dist/esm/flows-actors/services/mcp-client.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/mcp-credential-resolver.backend.service.d.ts +99 -0
- package/dist/esm/flows-actors/services/mcp-credential-resolver.backend.service.d.ts.map +1 -0
- package/dist/esm/flows-actors/services/mcp-credential-resolver.backend.service.js +155 -0
- package/dist/esm/flows-actors/services/mcp-credential-resolver.backend.service.js.map +1 -0
- package/dist/esm/flows-actors/services/meta-workflow-evaluation-treatment-compiler.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/meta-workflow-standard-action-contracts.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/meta-workflow-standard-evaluation-contracts.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/meta-workflow-structured-artifact-action-compiler.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +9 -0
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
- package/dist/esm/flows-actors/utils/bounded-subprocess.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/flows-actors-frontend-extractor.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.js.map +1 -1
- package/dist/esm/flows-actors/utils/meta-workflow-structured-generation-plan.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/meta-workflow-structured-generation-plan.backend.utils.js.map +1 -1
- package/dist/esm/flows-actors/utils/prompt-ir-adapters.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/tool-approval-modification.backend.utils.d.ts +77 -0
- package/dist/esm/flows-actors/utils/tool-approval-modification.backend.utils.d.ts.map +1 -0
- package/dist/esm/flows-actors/utils/tool-approval-modification.backend.utils.js +164 -0
- package/dist/esm/flows-actors/utils/tool-approval-modification.backend.utils.js.map +1 -0
- package/dist/esm/flows-actors/utils/tool-approval-signing.backend.utils.d.ts +48 -0
- package/dist/esm/flows-actors/utils/tool-approval-signing.backend.utils.d.ts.map +1 -0
- package/dist/esm/flows-actors/utils/tool-approval-signing.backend.utils.js +101 -0
- package/dist/esm/flows-actors/utils/tool-approval-signing.backend.utils.js.map +1 -0
- package/dist/esm/guidance/batches/dormancy-detection.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/guidance/services/guidance-trigger-evaluator.backend.service.d.ts.map +1 -1
- package/dist/esm/guidance/services/lifecycle-custom-implementations.backend.d.ts.map +1 -1
- package/dist/esm/guidance/services/lifecycle-evaluator.backend.service.d.ts.map +1 -1
- package/dist/esm/guidance/services/lifecycle-scope-id.backend.utils.d.ts.map +1 -1
- package/dist/esm/guidance/services/milestone-condition-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/guidance/services/milestone-definition-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.d.ts.map +1 -1
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.js.map +1 -1
- package/dist/esm/guidance/services/progression-state-store.backend.service.d.ts.map +1 -1
- package/dist/esm/guidance/services/progression-state-store.backend.service.js.map +1 -1
- package/dist/esm/guidance/services/scoped-state-read-custom-implementations.backend.d.ts.map +1 -1
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.js.map +1 -1
- package/dist/esm/i18n/services/i18n.backend.service.d.ts.map +1 -1
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/inject/models/container.d.ts +10 -0
- package/dist/esm/inject/models/container.d.ts.map +1 -1
- package/dist/esm/inject/models/container.js +49 -1
- package/dist/esm/inject/models/container.js.map +1 -1
- package/dist/esm/inject/models/service-types.d.ts +3 -0
- package/dist/esm/inject/models/service-types.d.ts.map +1 -1
- package/dist/esm/inject/models/service-types.js +3 -0
- package/dist/esm/inject/models/service-types.js.map +1 -1
- package/dist/esm/mcp/controllers/mcp.controller.d.ts.map +1 -1
- package/dist/esm/mcp/controllers/mcp.controller.js +50 -3
- package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
- package/dist/esm/mcp/models/mcp-protocol.backend.schemas.d.ts.map +1 -1
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts.map +1 -1
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.js.map +1 -1
- package/dist/esm/mcp/services/mcp-server.backend.service.d.ts.map +1 -1
- package/dist/esm/mcp/services/mcp-server.backend.service.js.map +1 -1
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts.map +1 -1
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js.map +1 -1
- package/dist/esm/mcp/services/resource-server-instances-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/mcp/utils/zod-to-mcp-json-schema.backend.utils.d.ts.map +1 -1
- package/dist/esm/meta-workflow-runtime.exports.d.ts.map +1 -1
- package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.d.ts.map +1 -1
- package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.js.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.js.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.d.ts.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.js.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.js.map +1 -1
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.d.ts.map +1 -1
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.js.map +1 -1
- package/dist/esm/monitoring/logger/services/__tests__/mock-logger.service.d.ts.map +1 -1
- package/dist/esm/monitoring/logger/services/logger.service.d.ts +12 -0
- package/dist/esm/monitoring/logger/services/logger.service.d.ts.map +1 -1
- package/dist/esm/monitoring/logger/services/logger.service.js +3 -3
- package/dist/esm/monitoring/logger/services/logger.service.js.map +1 -1
- package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.d.ts.map +1 -1
- package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.js.map +1 -1
- package/dist/esm/monitoring/logger/utils/log-value-normalization.backend.utils.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/audit-observation-emission.backend.d.ts +10 -6
- package/dist/esm/monitoring/observability/audit-observation-emission.backend.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/audit-observation-emission.backend.js +10 -6
- package/dist/esm/monitoring/observability/audit-observation-emission.backend.js.map +1 -1
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.js.map +1 -1
- package/dist/esm/monitoring/observability/otel-preload.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/otel-sdk-global-handle.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/services/__tests__/mock-metrics.service.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/services/metrics.service.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/services/metrics.service.js.map +1 -1
- package/dist/esm/monitoring/observability/services/observability.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/email/components/email-components.d.ts.map +1 -1
- package/dist/esm/notifications/email/models/email-template-definition.d.ts.map +1 -1
- package/dist/esm/notifications/email/models/email-transport.backend.definitions.d.ts.map +1 -1
- package/dist/esm/notifications/email/services/email-batch-send.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.js.map +1 -1
- package/dist/esm/notifications/email/services/email-template-validator.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/email/services/email-template-validator.backend.service.js.map +1 -1
- package/dist/esm/notifications/email/services/email.backend.service.d.ts +47 -6
- package/dist/esm/notifications/email/services/email.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/email/services/email.backend.service.js +86 -36
- package/dist/esm/notifications/email/services/email.backend.service.js.map +1 -1
- package/dist/esm/notifications/email/utils/color-conversion.utils.d.ts.map +1 -1
- package/dist/esm/notifications/email/utils/color-conversion.utils.js.map +1 -1
- package/dist/esm/notifications/email/utils/interpolate-email-label.utils.d.ts.map +1 -1
- package/dist/esm/notifications/email/utils/zod-to-typescript.utils.d.ts.map +1 -1
- package/dist/esm/notifications/services/notification-badge.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/services/notification-badge.backend.service.js.map +1 -1
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -1
- package/dist/esm/notifications/sms/models/sms-transport.backend.definitions.d.ts +32 -0
- package/dist/esm/notifications/sms/models/sms-transport.backend.definitions.d.ts.map +1 -0
- package/dist/esm/notifications/sms/models/sms-transport.backend.definitions.js +32 -0
- package/dist/esm/notifications/sms/models/sms-transport.backend.definitions.js.map +1 -0
- package/dist/esm/notifications/sms/services/sms.backend.service.d.ts +64 -10
- package/dist/esm/notifications/sms/services/sms.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/sms/services/sms.backend.service.js +277 -82
- package/dist/esm/notifications/sms/services/sms.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.repository.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-dispatcher.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config-public-key.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/services/polymorphic-lookup.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.js.map +1 -1
- package/dist/esm/organizations/batches/organization-member-invitation-sweep.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/batches/organization-purge.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/batches/organization-purge.batch.backend.service.js.map +1 -1
- package/dist/esm/organizations/services/authority-change-audit.backend.utils.d.ts.map +1 -1
- package/dist/esm/organizations/services/invitation-acceptance.backend.utils.d.ts.map +1 -1
- package/dist/esm/organizations/services/org-creation-on-registration.backend.utils.d.ts.map +1 -1
- package/dist/esm/organizations/services/org-member-roles-validation.backend.utils.d.ts.map +1 -1
- package/dist/esm/organizations/services/organization-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/services/organization-custom-implementation.backend.service.js.map +1 -1
- package/dist/esm/organizations/services/organization-deletion-audit.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/services/organization-member-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/services/organization-onboarding-operation.backend.utils.d.ts.map +1 -1
- package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/services/organization-unit-member-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/services/scim-provisioning-gate.backend.utils.d.ts.map +1 -1
- package/dist/esm/organizations/services/user-org-type-grant.backend.utils.d.ts.map +1 -1
- package/dist/esm/organizations/services/user-type-revocation-on-org-leave.backend.utils.d.ts.map +1 -1
- package/dist/esm/pdf-templates/__tests__/fixtures/tiny-pdf-template.fixture.d.ts.map +1 -1
- package/dist/esm/pdf-templates/models/pdf-template-binding.d.ts.map +1 -1
- package/dist/esm/pdf-templates/models/pdf-template-definition.d.ts.map +1 -1
- package/dist/esm/pdf-templates/services/pdf-generated-file-writer.backend.service.d.ts.map +1 -1
- package/dist/esm/pdf-templates/services/pdf-generation-orchestrator.backend.service.d.ts.map +1 -1
- package/dist/esm/pdf-templates/services/pdf-renderer.backend.service.d.ts.map +1 -1
- package/dist/esm/pdf-templates/services/pdf-template-binding.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.js.map +1 -1
- package/dist/esm/queue/adapters/queue-adapter.backend.binding.d.ts.map +1 -1
- package/dist/esm/queue/adapters/queue-adapter.backend.binding.js.map +1 -1
- package/dist/esm/queue/adapters/queue-adapter.backend.interface.d.ts.map +1 -1
- package/dist/esm/queue/adapters/queue-adapter.backend.interface.js.map +1 -1
- package/dist/esm/queue/adapters/queue-adapter.backend.options.d.ts.map +1 -1
- package/dist/esm/queue/adapters/queue-adapter.backend.options.js.map +1 -1
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.js.map +1 -1
- package/dist/esm/queue/apps-crontabs-manager.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/cron-job-sync.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/domain-queue-consumer.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/domain-queue-consumer.backend.service.js.map +1 -1
- package/dist/esm/queue/job-completion-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/job-consumer.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/job-consumer.backend.service.js.map +1 -1
- package/dist/esm/queue/job-executor.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/job-executor.backend.service.js.map +1 -1
- package/dist/esm/queue/job-payload-storage.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/job-status-tracking.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/queue-monitoring.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/queue-monitoring.backend.service.js.map +1 -1
- package/dist/esm/queue/queue-worker-initializer.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/queue-worker-initializer.backend.service.js.map +1 -1
- package/dist/esm/queue/queue.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/queue.backend.service.js.map +1 -1
- package/dist/esm/queue/scheduled-message-verifier.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/worker-shutdown-manager.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/worker-shutdown-manager.backend.service.js.map +1 -1
- package/dist/esm/rag/batches/rag-embedding-drain.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/rag/batches/rag-reconciliation-sweep.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/rag/models/rag-chunk-store.backend.types.d.ts.map +1 -1
- package/dist/esm/rag/models/rag-retrieval.backend.types.d.ts.map +1 -1
- package/dist/esm/rag/services/mongodb-rag-chunk-store.backend.service.d.ts.map +1 -1
- package/dist/esm/rag/services/postgresql-rag-chunk-store.backend.service.d.ts.map +1 -1
- package/dist/esm/rag/services/rag-chunk-collection.mongodb-ddl.backend.d.ts.map +1 -1
- package/dist/esm/rag/services/rag-chunk-retrieval.mongodb-query.backend.d.ts.map +1 -1
- package/dist/esm/rag/services/rag-chunk-retrieval.postgresql-query.backend.d.ts.map +1 -1
- package/dist/esm/rag/services/rag-chunk-store.backend.service.d.ts.map +1 -1
- package/dist/esm/rag/services/rag-chunk-table.postgresql-ddl.backend.d.ts.map +1 -1
- package/dist/esm/rag/services/rag-ingestion.backend.service.d.ts.map +1 -1
- package/dist/esm/rag/services/rag-retrieval.backend.service.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-chunk-fusion.backend.utils.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-chunk-removal.backend.utils.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-chunk-row-shaping.backend.utils.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-chunking.backend.utils.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-chunking.backend.utils.js.map +1 -1
- package/dist/esm/rag/utils/rag-context-assembly.backend.utils.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-context-assembly.backend.utils.js.map +1 -1
- package/dist/esm/rag/utils/rag-ingestion-trigger.backend.utils.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-retrieval-scope.backend.utils.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-source-field-value.backend.utils.d.ts.map +1 -1
- package/dist/esm/requests/models/api-routes.backend.defintions.d.ts.map +1 -1
- package/dist/esm/requests/models/requests.backend.schemas.d.ts.map +1 -1
- package/dist/esm/requests/service/platform-mutualized-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/requests/service/platform-requests.backend.utils.d.ts.map +1 -1
- package/dist/esm/requests/service/remote-client-base.backend.service.d.ts.map +1 -1
- package/dist/esm/requests/service/serverless-services-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/requests/service/websocket.service.d.ts.map +1 -1
- package/dist/esm/requests/service/websocket.service.js +49 -1
- package/dist/esm/requests/service/websocket.service.js.map +1 -1
- package/dist/esm/resources/backend-resource-registry.exports.d.ts.map +1 -1
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -1
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +2 -0
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -1
- package/dist/esm/resources/models/index.d.ts.map +1 -1
- package/dist/esm/resources/models/resources-operations.backend.definitions.d.ts.map +1 -1
- package/dist/esm/resources/models/resources-operations.backend.definitions.js.map +1 -1
- package/dist/esm/resources/models/resources-relationships.backend.definitions.d.ts.map +1 -1
- package/dist/esm/resources/models/resources-relationships.backend.definitions.js.map +1 -1
- package/dist/esm/resources/models/resources-types.backend.schemas.d.ts.map +1 -1
- package/dist/esm/resources/models/resources-types.backend.schemas.js.map +1 -1
- package/dist/esm/resources/models/resources.backend.schemas.d.ts.map +1 -1
- package/dist/esm/resources/models/virtual-fields.backend.types.d.ts.map +1 -1
- package/dist/esm/resources/services/__tests__/mock-resources-registry.service.d.ts.map +1 -1
- package/dist/esm/resources/services/resource-context.backend.service.d.ts.map +1 -1
- package/dist/esm/resources/services/resource-id.backend.service.d.ts.map +1 -1
- package/dist/esm/resources/services/resource-population.backend.service.d.ts +17 -2
- package/dist/esm/resources/services/resource-population.backend.service.d.ts.map +1 -1
- package/dist/esm/resources/services/resource-population.backend.service.js +74 -18
- package/dist/esm/resources/services/resource-population.backend.service.js.map +1 -1
- package/dist/esm/resources/services/resources-registry.backend.service.d.ts +23 -0
- package/dist/esm/resources/services/resources-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/resources/services/resources-registry.backend.service.js +31 -0
- package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -1
- package/dist/esm/resources/services/virtual-fields.backend.service.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-retention.backend.utils.d.ts.map +1 -1
- package/dist/esm/runtime/controllers/health-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/controllers/health-controller.backend.service.js.map +1 -1
- package/dist/esm/runtime/domain-module.backend.definitions.d.ts.map +1 -1
- package/dist/esm/runtime/domain-module.backend.definitions.js.map +1 -1
- package/dist/esm/runtime/models/execution-context.backend.schemas.d.ts.map +1 -1
- package/dist/esm/runtime/models/request-context.als.backend.d.ts.map +1 -1
- package/dist/esm/runtime/models/runtime.backend.schemas.d.ts.map +1 -1
- package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/execution-context-creator.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/execution-context-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.d.ts.map +1 -1
- package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.js.map +1 -1
- package/dist/esm/runtime/services/http-server.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/http-server.backend.service.js +10 -0
- package/dist/esm/runtime/services/http-server.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/start-application.backend.service.js +26 -12
- package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/utils/oauth-body-cap.backend.utils.d.ts.map +1 -1
- package/dist/esm/runtime/testing/execution-context-test-fixtures.d.ts.map +1 -1
- package/dist/esm/runtime/testing/mock-execution-context-creator.service.d.ts.map +1 -1
- package/dist/esm/runtime/utils/application-startup-config-access.backend.utils.d.ts.map +1 -1
- package/dist/esm/runtime/utils/feature-gated-core-resource-exclusions.backend.utils.d.ts.map +1 -1
- package/dist/esm/runtime/utils/request-client-ip.utils.d.ts.map +1 -1
- package/dist/esm/runtime/utils/scan-default-exports.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-key-generation.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/controllers/auth-method-management-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.d.ts +22 -0
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js +84 -0
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/models/auth-constants.backend.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/authentications.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/authorization-client.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/cimd.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/cimd.backend.schemas.js.map +1 -1
- package/dist/esm/security/authentications/models/federated-auth-transport.backend.definitions.d.ts +37 -0
- package/dist/esm/security/authentications/models/federated-auth-transport.backend.definitions.d.ts.map +1 -0
- package/dist/esm/security/authentications/models/federated-auth-transport.backend.definitions.js +37 -0
- package/dist/esm/security/authentications/models/federated-auth-transport.backend.definitions.js.map +1 -0
- package/dist/esm/security/authentications/models/identity-persistence-boundaries.backend.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts +15 -0
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.js.map +1 -1
- package/dist/esm/security/authentications/models/saml-authentication.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/sso-connection.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/user-authorization-version.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/seeds/enterprise-config-defaults.seeds.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/__tests__/mock-auth-execution-context-factory.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/__tests__/mock-auth-token-issuer.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/__tests__/oauth-provider-audit-spies.mock.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-domain-to-org-lookup.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-enterprise-user-provisioning.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.js.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.js +2 -1
- package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts +9 -2
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.js +9 -2
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-credential-verifier.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-execution-context-factory.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-phone-verification.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.d.ts +97 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js +218 -26
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.d.ts +14 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js +36 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/saml-assertion-validator.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/saml-authentication.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/saml-metadata.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/saml-replay-guard.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-session-store.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/scim-tokens.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js +57 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.js +11 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/email-verification-initiator.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/machine-token-issuer.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/oidc-user-claims.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/resolve-active-member-orgs.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/__tests__/mock-auth-user-lookup.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-controller.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-credential-ops.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.js.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-response-helper.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/utils/concurrent-session-eviction.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/ensure-user-profile.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.js.map +1 -1
- package/dist/esm/security/authentications/services/utils/machine-auth-rate-limit.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/pkce.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/saml-java-availability.d.ts.map +1 -1
- package/dist/esm/security/authentications/utils/application-auth-policy-audit.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.js.map +1 -1
- package/dist/esm/security/authentications/utils/one-off-session-lifetime.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/utils/social-oauth2-purpose.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/access-grant-decision.factory.backend.d.ts +59 -0
- package/dist/esm/security/authorizations/access-grant-decision.factory.backend.d.ts.map +1 -0
- package/dist/esm/security/authorizations/access-grant-decision.factory.backend.js +111 -0
- package/dist/esm/security/authorizations/access-grant-decision.factory.backend.js.map +1 -0
- package/dist/esm/security/authorizations/access-grant-lifecycle-audit.backend.d.ts +57 -0
- package/dist/esm/security/authorizations/access-grant-lifecycle-audit.backend.d.ts.map +1 -0
- package/dist/esm/security/authorizations/access-grant-lifecycle-audit.backend.js +133 -0
- package/dist/esm/security/authorizations/access-grant-lifecycle-audit.backend.js.map +1 -0
- package/dist/esm/security/authorizations/application-access-grant-custom-implementation.backend.service.d.ts +41 -0
- package/dist/esm/security/authorizations/application-access-grant-custom-implementation.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authorizations/application-access-grant-custom-implementation.backend.service.js +157 -0
- package/dist/esm/security/authorizations/application-access-grant-custom-implementation.backend.service.js.map +1 -0
- package/dist/esm/security/authorizations/application-wide-read-admission.backend.d.ts +84 -0
- package/dist/esm/security/authorizations/application-wide-read-admission.backend.d.ts.map +1 -0
- package/dist/esm/security/authorizations/application-wide-read-admission.backend.js +99 -0
- package/dist/esm/security/authorizations/application-wide-read-admission.backend.js.map +1 -0
- package/dist/esm/security/authorizations/authorization-denial-audit.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.d.ts.map +1 -1
- package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.js.map +1 -1
- package/dist/esm/security/authorizations/initiator-organization-confinement.backend.d.ts.map +1 -1
- package/dist/esm/security/authorizations/junction-scope-resolution.backend.d.ts.map +1 -1
- package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.js.map +1 -1
- package/dist/esm/security/authorizations/organization-unit-narrowing-enforcement.backend.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.js +20 -181
- package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.js.map +1 -1
- package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/relationship-foreign-key-filter.backend.d.ts.map +1 -1
- package/dist/esm/security/authorizations/role-ceiling.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/role-ceiling.backend.utils.js.map +1 -1
- package/dist/esm/security/authorizations/role-conferral.backend.utils.d.ts +40 -0
- package/dist/esm/security/authorizations/role-conferral.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/role-conferral.backend.utils.js +43 -1
- package/dist/esm/security/authorizations/role-conferral.backend.utils.js.map +1 -1
- package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.d.ts +27 -17
- package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.d.ts.map +1 -1
- package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.js +27 -17
- package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.js.map +1 -1
- package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +72 -0
- package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authorizations/services/authorizations.backend.service.js +153 -10
- package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js.map +1 -1
- package/dist/esm/security/connected-accounts/connection-target-authorization.backend.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/connection-target-authorization.backend.js.map +1 -1
- package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.d.ts +139 -1
- package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.js +474 -33
- package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.js.map +1 -1
- package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.d.ts +40 -0
- package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.js.map +1 -1
- package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.d.ts +19 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.js +38 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.js.map +1 -1
- package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.js +17 -1
- package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.js.map +1 -1
- package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.d.ts +14 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.js +16 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.js.map +1 -1
- package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.js +1 -1
- package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.js.map +1 -1
- package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.d.ts +19 -0
- package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.js +45 -2
- package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.js.map +1 -1
- package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.d.ts +37 -1
- package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.js.map +1 -1
- package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.js.map +1 -1
- package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.js.map +1 -1
- package/dist/esm/security/connected-accounts/utils/user-delegated-access-token-slot.backend.utils.d.ts +34 -0
- package/dist/esm/security/connected-accounts/utils/user-delegated-access-token-slot.backend.utils.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/utils/user-delegated-access-token-slot.backend.utils.js +39 -0
- package/dist/esm/security/connected-accounts/utils/user-delegated-access-token-slot.backend.utils.js.map +1 -0
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/models/index.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/services/__tests__/mock-consumable-token.service.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -1
- package/dist/esm/security/credential-rotation-grace.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/credential-rotation-grace.backend.utils.js.map +1 -1
- package/dist/esm/security/jwt/services/auth-jwt-guard.backend.service.d.ts.map +1 -1
- package/dist/esm/security/jwt/services/jwt.backend.service.d.ts.map +1 -1
- package/dist/esm/security/jwt/services/wildo-worker-bootstrap-client.backend.service.d.ts +13 -0
- package/dist/esm/security/jwt/services/wildo-worker-bootstrap-client.backend.service.d.ts.map +1 -1
- package/dist/esm/security/jwt/services/wildo-worker-bootstrap-client.backend.service.js +14 -0
- package/dist/esm/security/jwt/services/wildo-worker-bootstrap-client.backend.service.js.map +1 -1
- package/dist/esm/security/jwt/utils/jwt-verification-error-classification.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/outbound/outbound-request-deadline.backend.utils.d.ts +39 -0
- package/dist/esm/security/outbound/outbound-request-deadline.backend.utils.d.ts.map +1 -0
- package/dist/esm/security/outbound/outbound-request-deadline.backend.utils.js +60 -0
- package/dist/esm/security/outbound/outbound-request-deadline.backend.utils.js.map +1 -0
- package/dist/esm/security/outbound/outbound-request-headers.backend.utils.d.ts +66 -0
- package/dist/esm/security/outbound/outbound-request-headers.backend.utils.d.ts.map +1 -0
- package/dist/esm/security/outbound/outbound-request-headers.backend.utils.js +75 -0
- package/dist/esm/security/outbound/outbound-request-headers.backend.utils.js.map +1 -0
- package/dist/esm/security/scim/controllers/scim.backend.controller.d.ts.map +1 -1
- package/dist/esm/security/scim/controllers/scim.backend.controller.js.map +1 -1
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.js.map +1 -1
- package/dist/esm/security/scim/utils/scim-attribute-path-resolver.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/scim/utils/scim-filter-parser.d.ts.map +1 -1
- package/dist/esm/security/scim/utils/scim-response-formatter.d.ts.map +1 -1
- package/dist/esm/security/session-invalidation-fence.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.js.map +1 -1
- package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.js.map +1 -1
- package/dist/esm/security/token-invalidation-fence.backend.utils.d.ts.map +1 -1
- package/dist/esm/testing.d.ts.map +1 -1
- package/dist/esm/users/services/inbound-contact-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-deletion-audit.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-self-custom-implementations.backend.d.ts.map +1 -1
- package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/dist/esm/external-providers/services/flow-actor-design.backend.service.d.ts +0 -45
- package/dist/esm/external-providers/services/flow-actor-design.backend.service.d.ts.map +0 -1
- package/dist/esm/external-providers/services/flow-actor-design.backend.service.js +0 -22
- package/dist/esm/external-providers/services/flow-actor-design.backend.service.js.map +0 -1
- package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts +0 -0
- package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts.map +0 -0
- package/dist/esm/notifications/email/models/email-context-provider.interface.js +0 -0
- package/dist/esm/notifications/email/models/email-context-provider.interface.js.map +0 -0
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts +0 -0
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts.map +0 -0
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js +0 -0
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js.map +0 -0
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts +0 -0
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts.map +0 -0
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js +0 -0
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js.map +0 -0
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts +0 -0
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts.map +0 -0
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js +0 -0
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js.map +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-builder.backend.service.js","sourceRoot":"","sources":["../../../../../src/errors/services/error-builder.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { injectable, inject } from 'inversify';\nimport {\n ErrorType,\n ErrorActionBackend,\n WildoError_Backend_Definition,\n WildoError_Backend,\n ErrorCustomMessageReference,\n ERROR_DEFINITIONS,\n ResourcesConfig_OperationPathUtils,\n ResourceConfiguration_Operation,\n ErrorHandling_Strategy,\n RetryPolicy_BackoffType,\n ErrorUserGuidance,\n isWildoBackendError,\n} from '@wildo-ai/saas-models';\nimport { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport { getCurrentCorrelationId } from '~wildo-backend-lib/runtime/models/request-context.als.backend';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\n\n\n/**\n * Backend Error Builder Service\n * Creates unified WildoError_Backend instances with ExecutionContext integration\n */\n@injectable()\nexport class ErrorBuilderBackendService {\n protected logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n constructor(\n\n @inject(SAAS_SERVICE_TYPES.Logger) private logger: LoggerService\n ) {\n this.logDebug = this.logger.debugByType('ErrorBuilderBackendService');\n this.logger.setDebugTypeLogging('ErrorBuilderBackendService', false);\n }\n\n /**\n * Build a WildoError_Backend with ExecutionContext integration\n */\n public buildError(\n errorType: ErrorType,\n executionContext?: ExecutionContext<any>,\n options: {\n customMessageReference?: ErrorCustomMessageReference,\n context?: Record<string, any>\n stack?: string;\n skipBackendActions?: boolean;\n skipBackendActionTypes?: readonly ErrorActionBackend[];\n } = {}\n ): WildoError_Backend {\n const errorDefinition = ERROR_DEFINITIONS[errorType];\n const statusCode = errorDefinition.statusCode;\n const effectiveBackendActions = options.skipBackendActions\n ? []\n : errorDefinition.backendActions.filter(\n action => !options.skipBackendActionTypes?.includes(action)\n );\n\n // Extract operation path from execution context\n const operationPathKey = (executionContext)\n ? ResourcesConfig_OperationPathUtils.buildOperationPathKeyFromOperation(executionContext.operation as ResourceConfiguration_Operation<any, any, any>)\n : undefined;\n\n\n // Build the WildoError_Backend (context preserved for backend logging;\n // sanitization happens at the HTTP serialization boundary in ErrorHandlerService)\n const wildoError: WildoError_Backend = {\n type: errorType,\n severity: errorDefinition.severity,\n operationPathKey,\n timestamp: new Date(),\n backendActions: effectiveBackendActions,\n customMessageReference: options.customMessageReference ?? errorDefinition.defaultCustomMessageReference,\n statusCode,\n errorHandlingStrategy: errorDefinition.errorHandlingStrategy ?? ErrorHandling_Strategy.STOP,\n retryPolicy: errorDefinition.retryPolicy ?? RetryPolicy_BackoffType.EXPONENTIAL,\n maxRetries: errorDefinition.maxRetries ?? 3,\n initialDelay: errorDefinition.initialDelay ?? 1000,\n baseDelay: errorDefinition.baseDelay ?? 1000,\n initiatorIds: executionContext?.initiatorIds ?? undefined,\n executionType: executionContext?.executionType ?? undefined,\n // Phase 3 — closes gap 3: prefer the threaded EC's id, but fall back to the ambient request-context\n // ALS frame when no EC was passed (the ~67% of buildError calls that pass `undefined`). This is what\n // makes an error built deep in a service — with no EC in hand — still attributable to its request.\n correlationId: executionContext?.correlationId ?? getCurrentCorrelationId(),\n stack: options.stack ?? undefined,\n context: options.context ?? undefined,\n };\n\n // Some callers (for example websocket handshake auth) need to reclassify an\n // expected failure locally instead of emitting the default backend warning.\n if (effectiveBackendActions.length > 0) {\n // Execute backend actions. do not await\n this.executeBackendActions(wildoError);\n }\n\n return wildoError;\n }\n\n public buildFromStandardError(error: unknown, executionContext?: ExecutionContext<any>, options: {\n customMessageReference?: ErrorCustomMessageReference,\n context?: Record<string, any>\n skipBackendActions?: boolean;\n skipBackendActionTypes?: readonly ErrorActionBackend[];\n } = {}): WildoError_Backend {\n // An ALREADY-CLASSIFIED backend error must never be re-derived from scratch here.\n //\n // `WildoError_Backend` is a Zod-INFERRED PLAIN OBJECT, not an `Error` subclass, so a\n // re-wrap fell into the `new Error('Unknown error')` branch below: the caught error's\n // `type`, its `context` (which is where every builder puts the real explanation — the\n // enumerated validation failures, the adapter name, the failing boundary) and its stack\n // were all discarded, and the wrapper was re-classified INTERNAL from a synthetic Error\n // whose only message was the literal string `Unknown error`.\n //\n // That is not a cosmetic loss. It is exactly how a boot failure reaches the log as\n // `{\"errorType\":\"INTERNAL\",\"msg\":\"Application initialization failed\"}` with a stack whose\n // top frame is this method — naming the wrapper and nothing about the cause. Measured\n // 2026-08-14 on `platform-apps-manager`, where a post-registry configuration validation\n // threw with its failing contracts enumerated in `context.message` and the operator saw\n // none of them.\n //\n // The caught error's classification wins: it was chosen deliberately by whoever built it,\n // and this seam's callers pass attribution (`service`, `operation`), not a reclassification.\n // Caller context still wins on key collision, matching the merge below.\n if (isWildoBackendError(error)) {\n return this.buildError(error.type, executionContext, {\n ...options,\n customMessageReference: options.customMessageReference ?? error.customMessageReference,\n context: { ...error.context, ...options.context },\n stack: error.stack,\n });\n }\n\n const err = error instanceof Error\n ? error\n : new Error(typeof error === 'string' ? error : 'Unknown error');\n\n const errorType = this.determineErrorType(err);\n\n // A RAW ZodError / Mongoose ValidationError can reach this global seam\n // (e.g. an express error boundary) WITHOUT having gone through the explicit\n // controller/service validation path, which is the only place that attaches\n // `context.zodIssues` itself. Such an error is still classified VALIDATION\n // by `determineErrorType` (via the name/message heuristics), but it arrives\n // here with no field-level detail — so the client would otherwise receive an\n // opaque `{ type: VALIDATION }` with the real message living only in the\n // (often inaccessible) backend log. Project the error's per-field issues into\n // the same `zodIssues` shape that `sendErrorResponse` surfaces as\n // `validationErrors`, so raw validation failures are debuggable from the API\n // response like the explicit-path ones are.\n //\n // Scoped strictly to VALIDATION-classified errors: no field detail is ever\n // attached to AUTHZ/INTERNAL/DATABASE/etc. errors, preserving the\n // `sanitizeErrorForClient` boundary that strips their context. Only the field\n // path + per-field message are lifted — both already client-safe (they ride\n // the `zodIssues` allowlist, and VALIDATION is a \"safe\" type). The internal\n // `err.message` / stack are deliberately NOT surfaced here.\n const fieldLevelDetail = errorType === ErrorType.VALIDATION\n ? this.extractFieldLevelValidationDetail(err)\n : undefined;\n\n // Caller-supplied context wins on key collision (an explicit path that set\n // `zodIssues` should not be overwritten by the duck-typed extraction).\n const mergedContext = fieldLevelDetail\n ? { ...fieldLevelDetail, ...options.context }\n : options.context;\n\n return this.buildError(errorType, executionContext, {\n ...options,\n context: mergedContext,\n stack: err.stack\n });\n }\n\n /**\n * Extract client-safe field-level detail from a RAW validation error — a plain\n * `ZodError` or a Mongoose `ValidationError` — that reached the global error\n * boundary without going through the explicit controller/service validation\n * path (which attaches `context.zodIssues` itself).\n *\n * Returns the detail in the `{ zodIssues }` shape that\n * `ErrorHandlerService.sendErrorResponse` reduces into the response\n * `validationErrors` map (`{ [fieldPath]: message }`). Only the field `path`\n * and per-field `message` are extracted — both already deemed client-safe (they\n * ride the `zodIssues` allowlist in `sanitizeErrorForClient`, and VALIDATION is\n * a \"safe\" error type). The error's own `message` / stack are NOT included, so\n * internal implementation detail never leaks to the client.\n *\n * Returns `undefined` when the error is not a recognisable field-level\n * validation error (e.g. a generic `Error` whose message merely contains the\n * substring \"invalid\", which `determineErrorType` still classifies VALIDATION)\n * — in that case no `zodIssues` are attached.\n */\n private extractFieldLevelValidationDetail(\n error: Error,\n ): { zodIssues: Array<{ path: (string | number)[]; message: string }> } | undefined {\n // Zod (any instance): duck-type on the `issues` array rather than\n // `instanceof z.ZodError`. Multiple Zod module instances can coexist in the\n // dependency graph, so a nominal `instanceof` check is unreliable at this\n // shared boundary — the shape check is the robust classifier.\n const zodIssues = (error as { issues?: unknown }).issues;\n if (error.name === 'ZodError' && Array.isArray(zodIssues)) {\n const mapped = zodIssues\n .filter(\n (issue): issue is { path: (string | number)[]; message: string } =>\n !!issue\n && typeof issue === 'object'\n && Array.isArray((issue as { path?: unknown }).path)\n && typeof (issue as { message?: unknown }).message === 'string',\n )\n .map(issue => ({ path: issue.path, message: issue.message }));\n return mapped.length > 0 ? { zodIssues: mapped } : undefined;\n }\n\n // Mongoose ValidationError: `errors` is a record keyed by field path, each\n // value a per-path sub-error carrying its own `message`.\n const mongooseErrors = (error as { errors?: unknown }).errors;\n if (\n error.name === 'ValidationError'\n && mongooseErrors\n && typeof mongooseErrors === 'object'\n && !Array.isArray(mongooseErrors)\n ) {\n const mapped = Object.entries(mongooseErrors as Record<string, unknown>).map(\n ([field, subError]) => {\n const message = (subError as { message?: unknown } | null)?.message;\n return {\n path: [field] as (string | number)[],\n message: typeof message === 'string' ? message : 'Invalid value',\n };\n },\n );\n return mapped.length > 0 ? { zodIssues: mapped } : undefined;\n }\n\n return undefined;\n }\n\n /**\n * @wildo_source:part:start saas.backend.error-builder.user-guidance facet:layer:backend facet:audience:app-developer\n *\n * Build an error with contextual user guidance.\n *\n * Reach for this instead of a bare `buildError` whenever the person who hits the failure could DO\n * something about it. A typed error tells a caller what went wrong; guidance tells a human what to\n * do next, and the frontend renders it from `ErrorResponse.error.userGuidance`.\n *\n * ⚠️ **Prefer `buildErrorWithGuidanceKey`.** The strings you pass here are rendered verbatim, so a\n * guidance written this way is English forever — the key variant resolves labels under\n * `errors_guidance.{guidanceKey}.{field}` and is translated like every other user-facing string.\n * Use the raw form only for a failure no user will read, or as the fallback beneath a key.\n *\n * The guidance is attached to the error and will be included in the\n * `ErrorResponse.error.userGuidance` field for the frontend to render.\n *\n * @example\n * ```\n * throw this.errorBuilder.buildErrorWithGuidance(\n * ErrorType.CONFIGURATION,\n * executionContext,\n * {\n * explanation: 'SMTP is not configured for this organization.',\n * resolution: 'Go to Settings → Email and configure your SMTP provider.',\n * nextAction: { label: 'Go to Settings', ref: '/settings/email', type: 'url' },\n * missingConfiguration: ['smtp_host', 'smtp_port'],\n * },\n * { customMessageReference: ErrorCustomMessageReference.GENERIC_DETAIL }\n * );\n * ```\n */\n public buildErrorWithGuidance(\n errorType: ErrorType,\n executionContext: ExecutionContext<any> | undefined,\n guidance: ErrorUserGuidance,\n options: {\n customMessageReference?: ErrorCustomMessageReference;\n context?: Record<string, any>;\n stack?: string;\n } = {}\n ): WildoError_Backend {\n const error = this.buildError(errorType, executionContext, options);\n error.userGuidance = guidance;\n return error;\n }\n\n /**\n * Build an error with a guidance key (i18n reference).\n *\n * Shorthand for `buildErrorWithGuidance` that sets the `guidanceKey` on the guidance object,\n * enabling i18n label resolution under `errors_guidance.{guidanceKey}.{field}`.\n *\n * @param errorType - The error type\n * @param executionContext - Current execution context\n * @param guidanceKey - i18n lookup key (resolves labels under `errors_guidance.{guidanceKey}.*`)\n * @param guidance - Guidance fields (explanation, resolution, etc.) — used as raw fallbacks\n * @param options - Additional error options\n */\n public buildErrorWithGuidanceKey(\n errorType: ErrorType,\n executionContext: ExecutionContext<any> | undefined,\n guidanceKey: string,\n guidance: Omit<ErrorUserGuidance, 'guidanceKey'> = {},\n options: {\n customMessageReference?: ErrorCustomMessageReference;\n context?: Record<string, any>;\n stack?: string;\n } = {}\n ): WildoError_Backend {\n return this.buildErrorWithGuidance(errorType, executionContext, { ...guidance, guidanceKey }, options);\n }\n /** @wildo_source:part:end saas.backend.error-builder.user-guidance */\n\n public wildoErrorToSimpleString(wildoError: any): string {\n\n const isWildoError = wildoError && typeof wildoError === 'object' && 'statusCode' in wildoError && 'backendActions' in wildoError;\n if(!isWildoError) {\n return wildoError instanceof Error ? wildoError.message : \"Unknown error\";\n }\n\n let errorMessage = `${wildoError.customMessageReference as string} - ${wildoError.type} - ${wildoError.severity}`;\n if(wildoError.context) {\n errorMessage += `: ${JSON.stringify(wildoError.context)}`;\n }\n return errorMessage;\n }\n\n /**\n * Sanitize an error for client-facing HTTP responses.\n * Called at the serialization boundary (ErrorHandlerService), NOT at build time,\n * so backend logging retains full context for diagnostics.\n *\n * - VALIDATION, CONFLICT, RATE_LIMIT: allowlist of frontend-useful context keys\n * - AUTHENTICATION: allows `authResponse` through (retry/lockout UI data)\n * - Everything else (AUTHZ, INTERNAL, DATABASE, etc.): strips context entirely\n */\n public sanitizeErrorForClient(wildoError: WildoError_Backend): WildoError_Backend {\n // Error types whose context is safe to expose to clients (field-level info needed by frontend)\n const safeTypes = new Set<ErrorType>([ErrorType.VALIDATION, ErrorType.CONFLICT, ErrorType.RATE_LIMIT]);\n\n if (safeTypes.has(wildoError.type)) {\n // For safe types: keep only frontend-relevant keys from context\n if (wildoError.context) {\n const allowedKeys = new Set([\n 'fieldName', 'duplicateValue', 'zodIssues', 'customErrorMessage',\n 'retryAfterSeconds', 'message', 'violations',\n 'versionConflict',\n // Stable, client-branchable error codes (e.g. CrossFrontendHandoffErrorCode).\n // These are non-PII enum values defined in shared schemas (`saas-models`)\n // and consumed by both first-party clients (saas-frontend-lib) and\n // out-of-tree clients (saas-technical-doc/docsAuthClient.ts) for switch-on-code\n // branching. Stripping them at the wire would force callers to regex-parse\n // the human-readable `message`, defeating the purpose of having a stable code\n // enum. See cross-app-jwt-propagation.md C-4 for the contract decision that\n // motivated promoting these keys (the docs-chat client must `import {\n // CrossFrontendHandoffErrorCode } from '@wildo-ai/saas-models'` and branch on\n // `error.details.code === CrossFrontendHandoffErrorCode.UNKNOWN_TARGET_FRONTEND`).\n 'code',\n // Identity selectors that scope a code to a specific resource/service. Already\n // present in the request the client made (so disclosure is a no-op), but echoing\n // them back lets the client emit useful diagnostics (\"target frontend `docs` is\n // not configured…\") without re-parsing its own request body. PII-safe by\n // construction: these are SaaS-config service keys, never user data.\n 'targetServiceKey',\n // ─────────────────────────────────────────────────────────────────────────\n // GENERAL RULE for future endpoints emitting stable client-branchable codes:\n // 1. Define the enum in `@wildo-ai/saas-models` (so frontend + backend share\n // the same source of truth) and reuse the `code` key above to carry it.\n // Do NOT invent a new \"errorKind\" / \"reason\" / \"type\" field — the docs-chat\n // and saas-frontend clients all switch on `error.details.code`.\n // 2. New per-endpoint identity selectors (analogous to `targetServiceKey`)\n // MAY be added to this allowlist when they are PII-safe enum values OR\n // direct echoes of caller-supplied input (i.e. zero net disclosure).\n // 3. NEVER add user-typed strings (emails, names, free-text) to this allowlist\n // — they belong in `customErrorMessage` / `message` and are already covered.\n // 4. NEVER promote an internal cause (`stackTrace`, `dbErrorCode`, `mongoMessage`)\n // — those go through the AUTHZ/INTERNAL/DATABASE branches below which strip\n // context entirely. Surface a stable Wildo enum from the issuing service if\n // the caller needs to branch.\n // ─────────────────────────────────────────────────────────────────────────\n ]);\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(wildoError.context)) {\n if (allowedKeys.has(key)) {\n sanitized[key] = value;\n }\n }\n return {\n ...wildoError,\n context: Object.keys(sanitized).length > 0 ? sanitized : undefined,\n };\n }\n return wildoError;\n }\n\n // AUTHENTICATION errors: allow the minimum safe retry/lockout UI\n // payload through. `authResponse` is the common case; for the\n // specific `AUTHENTICATION_ACCOUNT_LOCKED` envelope, the global\n // lockout bridge also needs `lockoutDurationMinutes`,\n // `retryAfterSeconds`, and its lockout-specific `message`.\n if (wildoError.type === ErrorType.AUTHENTICATION && wildoError.context) {\n const authAllowedKeys = new Set(['authResponse']);\n if (wildoError.customMessageReference === ErrorCustomMessageReference.AUTHENTICATION_ACCOUNT_LOCKED) {\n authAllowedKeys.add('lockoutDurationMinutes');\n authAllowedKeys.add('retryAfterSeconds');\n authAllowedKeys.add('message');\n }\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(wildoError.context)) {\n if (authAllowedKeys.has(key)) {\n sanitized[key] = value;\n }\n }\n return {\n ...wildoError,\n context: Object.keys(sanitized).length > 0 ? sanitized : undefined,\n };\n }\n\n // All other types (AUTHZ, INTERNAL, DATABASE, etc.): strip context entirely\n const { context, ...rest } = wildoError;\n return rest as WildoError_Backend;\n }\n\n\n\n\n private async executeBackendActions(wildoError: WildoError_Backend): Promise<void> {\n wildoError.backendActions.forEach(action => {\n try {\n switch (action) {\n case ErrorActionBackend.LOG:\n // Intentionally NOT logged at construction. Error logging is a\n // *handling-boundary* concern, not a *construction* concern: the\n // boundary (HTTP `expressErrorHandler`, batch/cron, websocket auth,\n // queue job-failure, response-DTO direct-send) is the only place\n // where the operational severity can be classified, the request\n // context (method/path/socketId/jobId) is available, and exactly\n // one line per error is guaranteed. Logging here as well produced a\n // double-log (and, historically, an unstructured multi-line blob).\n // Boundaries emit the line via\n // `logWildoBackendErrorAtClassifiedSeverity` /\n // `projectWildoBackendErrorLogFields`.\n break;\n case ErrorActionBackend.RECORD_METRICS:\n // Metrics recording would be handled by telemetry middleware\n break;\n case ErrorActionBackend.TRACE:\n // Tracing would be handled by telemetry middleware\n break;\n case ErrorActionBackend.ALERT:\n this.sendAlert(wildoError);\n break;\n case ErrorActionBackend.CIRCUIT_BREAK:\n // Circuit breaker logic would be implemented in specific services\n break;\n case ErrorActionBackend.GRACEFUL_DEGRADATION:\n // Graceful degradation would be handled by specific services\n break;\n }\n } catch (actionError) {\n // Don't let action execution errors break the main error flow\n this.logger.warn('Failed to execute error action', {\n action,\n originalError: wildoError,\n actionError: describeCaughtError(actionError)\n });\n }\n });\n }\n\n /**\n * Send alert for critical errors\n */\n private sendAlert(wildoError: WildoError_Backend): void {\n // todo implement it;\n }\n\n /**\n * Centralized error type determination based on error characteristics\n * This method provides consistent error type classification across all services\n */\n public determineErrorType(error: Error): ErrorType {\n const message = (error && typeof error.message === 'string') ? error.message.toLowerCase() : '';\n const errorName = (error && typeof error.name === 'string') ? error.name : '';\n\n // Check error name first for more specific classification\n if (errorName === 'ValidationError' || errorName === 'ZodError') {\n return ErrorType.VALIDATION;\n }\n\n if (errorName === 'MulterError') {\n return ErrorType.VALIDATION;\n }\n\n // Body-parser (express.json / urlencoded / raw-body) rejections — an oversized or malformed request\n // body — are CLIENT input problems, exactly like the MulterError case above (both are request-body\n // libraries). They surface as `http-errors` carrying a string `type` (`entity.too.large`,\n // `entity.parse.failed`, `charset.unsupported`, …) plus a well-known 4xx `status`/`statusCode`. Classify\n // VALIDATION so a benign bad body returns a clean 4xx instead of masquerading as an INTERNAL 500 — which\n // additionally mis-fires `severity:critical` alerting/SIEM on an ordinary bad request. Keyed on the\n // body-parser `type`+4xx-`status` signature (NOT a bare `SyntaxError`/`Error` name), so a generic\n // application error is never swept in, and the 5xx body-parser faults (`stream.not.readable`, …)\n // correctly fall through to INTERNAL. (The `/oauth` mount additionally has a dedicated translator that\n // preserves the exact status — see `applyOAuthBodyCap`. Framework-wide, an oversized body (413) classifies\n // as PAYLOAD_TOO_LARGE so EVERY route returns the precise 413; the other body-parser client errors\n // (malformed 400, unsupported-charset/encoding 415) fold into VALIDATION's 400 bucket.)\n const bodyParserType = (error as { type?: unknown }).type;\n const bodyParserStatus = (error as { status?: unknown }).status ?? (error as { statusCode?: unknown }).statusCode;\n if (typeof bodyParserType === 'string' && typeof bodyParserStatus === 'number' && bodyParserStatus >= 400 && bodyParserStatus < 500) {\n return bodyParserStatus === 413 ? ErrorType.PAYLOAD_TOO_LARGE : ErrorType.VALIDATION;\n }\n\n if (errorName === 'JsonWebTokenError' || errorName === 'TokenExpiredError') {\n return ErrorType.AUTHENTICATION;\n }\n\n if (errorName === 'MongoError' || errorName === 'MongooseError') {\n return ErrorType.DATABASE;\n }\n\n // Check message content for additional classification\n if (message.includes('validation') || message.includes('invalid')) {\n return ErrorType.VALIDATION;\n }\n\n if (message.includes('limit_file_size') || message.includes('file too large')) {\n return ErrorType.VALIDATION;\n }\n\n if (message.includes('not found')) {\n return ErrorType.NOT_FOUND;\n }\n\n if (message.includes('unauthorized')) {\n return ErrorType.AUTHENTICATION;\n }\n\n if (message.includes('forbidden') || message.includes('permission')) {\n return ErrorType.AUTHORIZATION;\n }\n\n if (message.includes('conflict') || message.includes('already exists')) {\n return ErrorType.CONFLICT;\n }\n\n if (message.includes('network')) {\n return ErrorType.NETWORK;\n }\n\n if (message.includes('rate limit') || message.includes('too many requests')) {\n return ErrorType.RATE_LIMIT;\n }\n\n if (message.includes('business rule') || message.includes('constraint')) {\n return ErrorType.BUSINESS_RULE;\n }\n\n // Default to INTERNAL for unclassified errors\n return ErrorType.INTERNAL;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"error-builder.backend.service.js","sourceRoot":"","sources":["../../../../src/errors/services/error-builder.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { injectable, inject } from 'inversify';\nimport {\n ErrorType,\n ErrorActionBackend,\n WildoError_Backend_Definition,\n WildoError_Backend,\n ErrorCustomMessageReference,\n ERROR_DEFINITIONS,\n ResourcesConfig_OperationPathUtils,\n ResourceConfiguration_Operation,\n ErrorHandling_Strategy,\n RetryPolicy_BackoffType,\n ErrorUserGuidance,\n isWildoBackendError,\n} from '@wildo-ai/saas-models';\nimport { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport { getCurrentCorrelationId } from '~wildo-backend-lib/runtime/models/request-context.als.backend';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\n\n\n/**\n * Backend Error Builder Service\n * Creates unified WildoError_Backend instances with ExecutionContext integration\n */\n@injectable()\nexport class ErrorBuilderBackendService {\n protected logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n constructor(\n\n @inject(SAAS_SERVICE_TYPES.Logger) private logger: LoggerService\n ) {\n this.logDebug = this.logger.debugByType('ErrorBuilderBackendService');\n this.logger.setDebugTypeLogging('ErrorBuilderBackendService', false);\n }\n\n /**\n * Build a WildoError_Backend with ExecutionContext integration\n */\n public buildError(\n errorType: ErrorType,\n executionContext?: ExecutionContext<any>,\n options: {\n customMessageReference?: ErrorCustomMessageReference,\n context?: Record<string, any>\n stack?: string;\n skipBackendActions?: boolean;\n skipBackendActionTypes?: readonly ErrorActionBackend[];\n } = {}\n ): WildoError_Backend {\n const errorDefinition = ERROR_DEFINITIONS[errorType];\n const statusCode = errorDefinition.statusCode;\n const effectiveBackendActions = options.skipBackendActions\n ? []\n : errorDefinition.backendActions.filter(\n action => !options.skipBackendActionTypes?.includes(action)\n );\n\n // Extract operation path from execution context\n const operationPathKey = (executionContext)\n ? ResourcesConfig_OperationPathUtils.buildOperationPathKeyFromOperation(executionContext.operation as ResourceConfiguration_Operation<any, any, any>)\n : undefined;\n\n\n // Build the WildoError_Backend (context preserved for backend logging;\n // sanitization happens at the HTTP serialization boundary in ErrorHandlerService)\n const wildoError: WildoError_Backend = {\n type: errorType,\n severity: errorDefinition.severity,\n operationPathKey,\n timestamp: new Date(),\n backendActions: effectiveBackendActions,\n customMessageReference: options.customMessageReference ?? errorDefinition.defaultCustomMessageReference,\n statusCode,\n errorHandlingStrategy: errorDefinition.errorHandlingStrategy ?? ErrorHandling_Strategy.STOP,\n retryPolicy: errorDefinition.retryPolicy ?? RetryPolicy_BackoffType.EXPONENTIAL,\n maxRetries: errorDefinition.maxRetries ?? 3,\n initialDelay: errorDefinition.initialDelay ?? 1000,\n baseDelay: errorDefinition.baseDelay ?? 1000,\n initiatorIds: executionContext?.initiatorIds ?? undefined,\n executionType: executionContext?.executionType ?? undefined,\n // Phase 3 — closes gap 3: prefer the threaded EC's id, but fall back to the ambient request-context\n // ALS frame when no EC was passed (the ~67% of buildError calls that pass `undefined`). This is what\n // makes an error built deep in a service — with no EC in hand — still attributable to its request.\n correlationId: executionContext?.correlationId ?? getCurrentCorrelationId(),\n stack: options.stack ?? undefined,\n context: options.context ?? undefined,\n };\n\n // Some callers (for example websocket handshake auth) need to reclassify an\n // expected failure locally instead of emitting the default backend warning.\n if (effectiveBackendActions.length > 0) {\n // Execute backend actions. do not await\n this.executeBackendActions(wildoError);\n }\n\n return wildoError;\n }\n\n public buildFromStandardError(error: unknown, executionContext?: ExecutionContext<any>, options: {\n customMessageReference?: ErrorCustomMessageReference,\n context?: Record<string, any>\n skipBackendActions?: boolean;\n skipBackendActionTypes?: readonly ErrorActionBackend[];\n } = {}): WildoError_Backend {\n // An ALREADY-CLASSIFIED backend error must never be re-derived from scratch here.\n //\n // `WildoError_Backend` is a Zod-INFERRED PLAIN OBJECT, not an `Error` subclass, so a\n // re-wrap fell into the `new Error('Unknown error')` branch below: the caught error's\n // `type`, its `context` (which is where every builder puts the real explanation — the\n // enumerated validation failures, the adapter name, the failing boundary) and its stack\n // were all discarded, and the wrapper was re-classified INTERNAL from a synthetic Error\n // whose only message was the literal string `Unknown error`.\n //\n // That is not a cosmetic loss. It is exactly how a boot failure reaches the log as\n // `{\"errorType\":\"INTERNAL\",\"msg\":\"Application initialization failed\"}` with a stack whose\n // top frame is this method — naming the wrapper and nothing about the cause. Measured\n // 2026-08-14 on `platform-apps-manager`, where a post-registry configuration validation\n // threw with its failing contracts enumerated in `context.message` and the operator saw\n // none of them.\n //\n // The caught error's classification wins: it was chosen deliberately by whoever built it,\n // and this seam's callers pass attribution (`service`, `operation`), not a reclassification.\n // Caller context still wins on key collision, matching the merge below.\n if (isWildoBackendError(error)) {\n return this.buildError(error.type, executionContext, {\n ...options,\n customMessageReference: options.customMessageReference ?? error.customMessageReference,\n context: { ...error.context, ...options.context },\n stack: error.stack,\n });\n }\n\n const err = error instanceof Error\n ? error\n : new Error(typeof error === 'string' ? error : 'Unknown error');\n\n const errorType = this.determineErrorType(err);\n\n // A RAW ZodError / Mongoose ValidationError can reach this global seam\n // (e.g. an express error boundary) WITHOUT having gone through the explicit\n // controller/service validation path, which is the only place that attaches\n // `context.zodIssues` itself. Such an error is still classified VALIDATION\n // by `determineErrorType` (via the name/message heuristics), but it arrives\n // here with no field-level detail — so the client would otherwise receive an\n // opaque `{ type: VALIDATION }` with the real message living only in the\n // (often inaccessible) backend log. Project the error's per-field issues into\n // the same `zodIssues` shape that `sendErrorResponse` surfaces as\n // `validationErrors`, so raw validation failures are debuggable from the API\n // response like the explicit-path ones are.\n //\n // Scoped strictly to VALIDATION-classified errors: no field detail is ever\n // attached to AUTHZ/INTERNAL/DATABASE/etc. errors, preserving the\n // `sanitizeErrorForClient` boundary that strips their context. Only the field\n // path + per-field message are lifted — both already client-safe (they ride\n // the `zodIssues` allowlist, and VALIDATION is a \"safe\" type). The internal\n // `err.message` / stack are deliberately NOT surfaced here.\n const fieldLevelDetail = errorType === ErrorType.VALIDATION\n ? this.extractFieldLevelValidationDetail(err)\n : undefined;\n\n // Caller-supplied context wins on key collision (an explicit path that set\n // `zodIssues` should not be overwritten by the duck-typed extraction).\n const mergedContext = fieldLevelDetail\n ? { ...fieldLevelDetail, ...options.context }\n : options.context;\n\n return this.buildError(errorType, executionContext, {\n ...options,\n context: mergedContext,\n stack: err.stack\n });\n }\n\n /**\n * Extract client-safe field-level detail from a RAW validation error — a plain\n * `ZodError` or a Mongoose `ValidationError` — that reached the global error\n * boundary without going through the explicit controller/service validation\n * path (which attaches `context.zodIssues` itself).\n *\n * Returns the detail in the `{ zodIssues }` shape that\n * `ErrorHandlerService.sendErrorResponse` reduces into the response\n * `validationErrors` map (`{ [fieldPath]: message }`). Only the field `path`\n * and per-field `message` are extracted — both already deemed client-safe (they\n * ride the `zodIssues` allowlist in `sanitizeErrorForClient`, and VALIDATION is\n * a \"safe\" error type). The error's own `message` / stack are NOT included, so\n * internal implementation detail never leaks to the client.\n *\n * Returns `undefined` when the error is not a recognisable field-level\n * validation error (e.g. a generic `Error` whose message merely contains the\n * substring \"invalid\", which `determineErrorType` still classifies VALIDATION)\n * — in that case no `zodIssues` are attached.\n */\n private extractFieldLevelValidationDetail(\n error: Error,\n ): { zodIssues: Array<{ path: (string | number)[]; message: string }> } | undefined {\n // Zod (any instance): duck-type on the `issues` array rather than\n // `instanceof z.ZodError`. Multiple Zod module instances can coexist in the\n // dependency graph, so a nominal `instanceof` check is unreliable at this\n // shared boundary — the shape check is the robust classifier.\n const zodIssues = (error as { issues?: unknown }).issues;\n if (error.name === 'ZodError' && Array.isArray(zodIssues)) {\n const mapped = zodIssues\n .filter(\n (issue): issue is { path: (string | number)[]; message: string } =>\n !!issue\n && typeof issue === 'object'\n && Array.isArray((issue as { path?: unknown }).path)\n && typeof (issue as { message?: unknown }).message === 'string',\n )\n .map(issue => ({ path: issue.path, message: issue.message }));\n return mapped.length > 0 ? { zodIssues: mapped } : undefined;\n }\n\n // Mongoose ValidationError: `errors` is a record keyed by field path, each\n // value a per-path sub-error carrying its own `message`.\n const mongooseErrors = (error as { errors?: unknown }).errors;\n if (\n error.name === 'ValidationError'\n && mongooseErrors\n && typeof mongooseErrors === 'object'\n && !Array.isArray(mongooseErrors)\n ) {\n const mapped = Object.entries(mongooseErrors as Record<string, unknown>).map(\n ([field, subError]) => {\n const message = (subError as { message?: unknown } | null)?.message;\n return {\n path: [field] as (string | number)[],\n message: typeof message === 'string' ? message : 'Invalid value',\n };\n },\n );\n return mapped.length > 0 ? { zodIssues: mapped } : undefined;\n }\n\n return undefined;\n }\n\n /**\n * @wildo_source:part:start saas.backend.error-builder.user-guidance facet:layer:backend facet:audience:app-developer\n *\n * Build an error with contextual user guidance.\n *\n * Reach for this instead of a bare `buildError` whenever the person who hits the failure could DO\n * something about it. A typed error tells a caller what went wrong; guidance tells a human what to\n * do next, and the frontend renders it from `ErrorResponse.error.userGuidance`.\n *\n * ⚠️ **Prefer `buildErrorWithGuidanceKey`.** The strings you pass here are rendered verbatim, so a\n * guidance written this way is English forever — the key variant resolves labels under\n * `errors_guidance.{guidanceKey}.{field}` and is translated like every other user-facing string.\n * Use the raw form only for a failure no user will read, or as the fallback beneath a key.\n *\n * The guidance is attached to the error and will be included in the\n * `ErrorResponse.error.userGuidance` field for the frontend to render.\n *\n * @example\n * ```\n * throw this.errorBuilder.buildErrorWithGuidance(\n * ErrorType.CONFIGURATION,\n * executionContext,\n * {\n * explanation: 'SMTP is not configured for this organization.',\n * resolution: 'Go to Settings → Email and configure your SMTP provider.',\n * nextAction: { label: 'Go to Settings', ref: '/settings/email', type: 'url' },\n * missingConfiguration: ['smtp_host', 'smtp_port'],\n * },\n * { customMessageReference: ErrorCustomMessageReference.GENERIC_DETAIL }\n * );\n * ```\n */\n public buildErrorWithGuidance(\n errorType: ErrorType,\n executionContext: ExecutionContext<any> | undefined,\n guidance: ErrorUserGuidance,\n options: {\n customMessageReference?: ErrorCustomMessageReference;\n context?: Record<string, any>;\n stack?: string;\n } = {}\n ): WildoError_Backend {\n const error = this.buildError(errorType, executionContext, options);\n error.userGuidance = guidance;\n return error;\n }\n\n /**\n * Build an error with a guidance key (i18n reference).\n *\n * Shorthand for `buildErrorWithGuidance` that sets the `guidanceKey` on the guidance object,\n * enabling i18n label resolution under `errors_guidance.{guidanceKey}.{field}`.\n *\n * @param errorType - The error type\n * @param executionContext - Current execution context\n * @param guidanceKey - i18n lookup key (resolves labels under `errors_guidance.{guidanceKey}.*`)\n * @param guidance - Guidance fields (explanation, resolution, etc.) — used as raw fallbacks\n * @param options - Additional error options\n */\n public buildErrorWithGuidanceKey(\n errorType: ErrorType,\n executionContext: ExecutionContext<any> | undefined,\n guidanceKey: string,\n guidance: Omit<ErrorUserGuidance, 'guidanceKey'> = {},\n options: {\n customMessageReference?: ErrorCustomMessageReference;\n context?: Record<string, any>;\n stack?: string;\n } = {}\n ): WildoError_Backend {\n return this.buildErrorWithGuidance(errorType, executionContext, { ...guidance, guidanceKey }, options);\n }\n /** @wildo_source:part:end saas.backend.error-builder.user-guidance */\n\n public wildoErrorToSimpleString(wildoError: any): string {\n\n const isWildoError = wildoError && typeof wildoError === 'object' && 'statusCode' in wildoError && 'backendActions' in wildoError;\n if(!isWildoError) {\n return wildoError instanceof Error ? wildoError.message : \"Unknown error\";\n }\n\n let errorMessage = `${wildoError.customMessageReference as string} - ${wildoError.type} - ${wildoError.severity}`;\n if(wildoError.context) {\n errorMessage += `: ${JSON.stringify(wildoError.context)}`;\n }\n return errorMessage;\n }\n\n /**\n * Sanitize an error for client-facing HTTP responses.\n * Called at the serialization boundary (ErrorHandlerService), NOT at build time,\n * so backend logging retains full context for diagnostics.\n *\n * - VALIDATION, CONFLICT, RATE_LIMIT: allowlist of frontend-useful context keys\n * - AUTHENTICATION: allows `authResponse` through (retry/lockout UI data)\n * - Everything else (AUTHZ, INTERNAL, DATABASE, etc.): strips context entirely\n */\n public sanitizeErrorForClient(wildoError: WildoError_Backend): WildoError_Backend {\n // Error types whose context is safe to expose to clients (field-level info needed by frontend)\n const safeTypes = new Set<ErrorType>([ErrorType.VALIDATION, ErrorType.CONFLICT, ErrorType.RATE_LIMIT]);\n\n if (safeTypes.has(wildoError.type)) {\n // For safe types: keep only frontend-relevant keys from context\n if (wildoError.context) {\n const allowedKeys = new Set([\n 'fieldName', 'duplicateValue', 'zodIssues', 'customErrorMessage',\n 'retryAfterSeconds', 'message', 'violations',\n 'versionConflict',\n // Stable, client-branchable error codes (e.g. CrossFrontendHandoffErrorCode).\n // These are non-PII enum values defined in shared schemas (`saas-models`)\n // and consumed by both first-party clients (saas-frontend-lib) and\n // out-of-tree clients (saas-technical-doc/docsAuthClient.ts) for switch-on-code\n // branching. Stripping them at the wire would force callers to regex-parse\n // the human-readable `message`, defeating the purpose of having a stable code\n // enum. See cross-app-jwt-propagation.md C-4 for the contract decision that\n // motivated promoting these keys (the docs-chat client must `import {\n // CrossFrontendHandoffErrorCode } from '@wildo-ai/saas-models'` and branch on\n // `error.details.code === CrossFrontendHandoffErrorCode.UNKNOWN_TARGET_FRONTEND`).\n 'code',\n // Identity selectors that scope a code to a specific resource/service. Already\n // present in the request the client made (so disclosure is a no-op), but echoing\n // them back lets the client emit useful diagnostics (\"target frontend `docs` is\n // not configured…\") without re-parsing its own request body. PII-safe by\n // construction: these are SaaS-config service keys, never user data.\n 'targetServiceKey',\n // ─────────────────────────────────────────────────────────────────────────\n // GENERAL RULE for future endpoints emitting stable client-branchable codes:\n // 1. Define the enum in `@wildo-ai/saas-models` (so frontend + backend share\n // the same source of truth) and reuse the `code` key above to carry it.\n // Do NOT invent a new \"errorKind\" / \"reason\" / \"type\" field — the docs-chat\n // and saas-frontend clients all switch on `error.details.code`.\n // 2. New per-endpoint identity selectors (analogous to `targetServiceKey`)\n // MAY be added to this allowlist when they are PII-safe enum values OR\n // direct echoes of caller-supplied input (i.e. zero net disclosure).\n // 3. NEVER add user-typed strings (emails, names, free-text) to this allowlist\n // — they belong in `customErrorMessage` / `message` and are already covered.\n // 4. NEVER promote an internal cause (`stackTrace`, `dbErrorCode`, `mongoMessage`)\n // — those go through the AUTHZ/INTERNAL/DATABASE branches below which strip\n // context entirely. Surface a stable Wildo enum from the issuing service if\n // the caller needs to branch.\n // ─────────────────────────────────────────────────────────────────────────\n ]);\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(wildoError.context)) {\n if (allowedKeys.has(key)) {\n sanitized[key] = value;\n }\n }\n return {\n ...wildoError,\n context: Object.keys(sanitized).length > 0 ? sanitized : undefined,\n };\n }\n return wildoError;\n }\n\n // AUTHENTICATION errors: allow the minimum safe retry/lockout UI\n // payload through. `authResponse` is the common case; for the\n // specific `AUTHENTICATION_ACCOUNT_LOCKED` envelope, the global\n // lockout bridge also needs `lockoutDurationMinutes`,\n // `retryAfterSeconds`, and its lockout-specific `message`.\n if (wildoError.type === ErrorType.AUTHENTICATION && wildoError.context) {\n const authAllowedKeys = new Set(['authResponse']);\n if (wildoError.customMessageReference === ErrorCustomMessageReference.AUTHENTICATION_ACCOUNT_LOCKED) {\n authAllowedKeys.add('lockoutDurationMinutes');\n authAllowedKeys.add('retryAfterSeconds');\n authAllowedKeys.add('message');\n }\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(wildoError.context)) {\n if (authAllowedKeys.has(key)) {\n sanitized[key] = value;\n }\n }\n return {\n ...wildoError,\n context: Object.keys(sanitized).length > 0 ? sanitized : undefined,\n };\n }\n\n // All other types (AUTHZ, INTERNAL, DATABASE, etc.): strip context entirely\n const { context, ...rest } = wildoError;\n return rest as WildoError_Backend;\n }\n\n\n\n\n private async executeBackendActions(wildoError: WildoError_Backend): Promise<void> {\n wildoError.backendActions.forEach(action => {\n try {\n switch (action) {\n case ErrorActionBackend.LOG:\n // Intentionally NOT logged at construction. Error logging is a\n // *handling-boundary* concern, not a *construction* concern: the\n // boundary (HTTP `expressErrorHandler`, batch/cron, websocket auth,\n // queue job-failure, response-DTO direct-send) is the only place\n // where the operational severity can be classified, the request\n // context (method/path/socketId/jobId) is available, and exactly\n // one line per error is guaranteed. Logging here as well produced a\n // double-log (and, historically, an unstructured multi-line blob).\n // Boundaries emit the line via\n // `logWildoBackendErrorAtClassifiedSeverity` /\n // `projectWildoBackendErrorLogFields`.\n break;\n case ErrorActionBackend.RECORD_METRICS:\n // Metrics recording would be handled by telemetry middleware\n break;\n case ErrorActionBackend.TRACE:\n // Tracing would be handled by telemetry middleware\n break;\n case ErrorActionBackend.ALERT:\n this.sendAlert(wildoError);\n break;\n case ErrorActionBackend.CIRCUIT_BREAK:\n // Circuit breaker logic would be implemented in specific services\n break;\n case ErrorActionBackend.GRACEFUL_DEGRADATION:\n // Graceful degradation would be handled by specific services\n break;\n }\n } catch (actionError) {\n // Don't let action execution errors break the main error flow\n this.logger.warn('Failed to execute error action', {\n action,\n originalError: wildoError,\n actionError: describeCaughtError(actionError)\n });\n }\n });\n }\n\n /**\n * Send alert for critical errors\n */\n private sendAlert(wildoError: WildoError_Backend): void {\n // todo implement it;\n }\n\n /**\n * Centralized error type determination based on error characteristics\n * This method provides consistent error type classification across all services\n */\n public determineErrorType(error: Error): ErrorType {\n const message = (error && typeof error.message === 'string') ? error.message.toLowerCase() : '';\n const errorName = (error && typeof error.name === 'string') ? error.name : '';\n\n // Check error name first for more specific classification\n if (errorName === 'ValidationError' || errorName === 'ZodError') {\n return ErrorType.VALIDATION;\n }\n\n if (errorName === 'MulterError') {\n return ErrorType.VALIDATION;\n }\n\n // Body-parser (express.json / urlencoded / raw-body) rejections — an oversized or malformed request\n // body — are CLIENT input problems, exactly like the MulterError case above (both are request-body\n // libraries). They surface as `http-errors` carrying a string `type` (`entity.too.large`,\n // `entity.parse.failed`, `charset.unsupported`, …) plus a well-known 4xx `status`/`statusCode`. Classify\n // VALIDATION so a benign bad body returns a clean 4xx instead of masquerading as an INTERNAL 500 — which\n // additionally mis-fires `severity:critical` alerting/SIEM on an ordinary bad request. Keyed on the\n // body-parser `type`+4xx-`status` signature (NOT a bare `SyntaxError`/`Error` name), so a generic\n // application error is never swept in, and the 5xx body-parser faults (`stream.not.readable`, …)\n // correctly fall through to INTERNAL. (The `/oauth` mount additionally has a dedicated translator that\n // preserves the exact status — see `applyOAuthBodyCap`. Framework-wide, an oversized body (413) classifies\n // as PAYLOAD_TOO_LARGE so EVERY route returns the precise 413; the other body-parser client errors\n // (malformed 400, unsupported-charset/encoding 415) fold into VALIDATION's 400 bucket.)\n const bodyParserType = (error as { type?: unknown }).type;\n const bodyParserStatus = (error as { status?: unknown }).status ?? (error as { statusCode?: unknown }).statusCode;\n if (typeof bodyParserType === 'string' && typeof bodyParserStatus === 'number' && bodyParserStatus >= 400 && bodyParserStatus < 500) {\n return bodyParserStatus === 413 ? ErrorType.PAYLOAD_TOO_LARGE : ErrorType.VALIDATION;\n }\n\n if (errorName === 'JsonWebTokenError' || errorName === 'TokenExpiredError') {\n return ErrorType.AUTHENTICATION;\n }\n\n if (errorName === 'MongoError' || errorName === 'MongooseError') {\n return ErrorType.DATABASE;\n }\n\n // Check message content for additional classification\n if (message.includes('validation') || message.includes('invalid')) {\n return ErrorType.VALIDATION;\n }\n\n if (message.includes('limit_file_size') || message.includes('file too large')) {\n return ErrorType.VALIDATION;\n }\n\n if (message.includes('not found')) {\n return ErrorType.NOT_FOUND;\n }\n\n if (message.includes('unauthorized')) {\n return ErrorType.AUTHENTICATION;\n }\n\n if (message.includes('forbidden') || message.includes('permission')) {\n return ErrorType.AUTHORIZATION;\n }\n\n if (message.includes('conflict') || message.includes('already exists')) {\n return ErrorType.CONFLICT;\n }\n\n if (message.includes('network')) {\n return ErrorType.NETWORK;\n }\n\n if (message.includes('rate limit') || message.includes('too many requests')) {\n return ErrorType.RATE_LIMIT;\n }\n\n if (message.includes('business rule') || message.includes('constraint')) {\n return ErrorType.BUSINESS_RULE;\n }\n\n // Default to INTERNAL for unclassified errors\n return ErrorType.INTERNAL;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.backend.service.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"error-handler.backend.service.d.ts","sourceRoot":"","sources":["../../../../src/errors/services/error-handler.backend.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAE7F,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAK7E,OAAO,EAIL,kBAAkB,EAInB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAG,MAAM,qEAAqE,CAAC;AAExG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,uCAAuC,EAAE,SAAS,MAAM,EAmBpE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4CAA4C,EAAE,SAAS,MAAM,EAoCzE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAI1E;AAED;;;GAGG;AACH,qBACa,mBAAmB;IAIO,OAAO,CAAC,MAAM;IACD,OAAO,CAAC,YAAY;IAJtE,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;gBAGpC,MAAM,EAAE,aAAa,EACR,YAAY,EAAE,0BAA0B;IAMlG;;;OAGG;IACH,mBAAmB,IAAI,CAAC,KAAK,EAAE,KAAK,GAAC,kBAAkB,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI;IAyCjH,0BAA0B,CAAC,KAAK,EAAE,KAAK,GAAC,kBAAkB,EAAE,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,IAAI;IAW3G,OAAO,CAAC,iBAAiB;IA4GzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,QAAQ,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI;IAMrF;;OAEG;IACH,wBAAwB,IAAI,IAAI;IAiBhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoDG;IACH,uBAAuB,IAAI,IAAI;IAsB/B;;OAEG;IACH,wBAAwB,IAAI,IAAI;CAKjC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.backend.service.js","sourceRoot":"","sources":["../../../../../src/errors/services/error-handler.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from 'express';\nimport { inject, injectable } from 'inversify';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { ErrorBuilderBackendService } from './error-builder.backend.service';\nimport { logWildoBackendErrorAtClassifiedSeverity, describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { getCurrentCorrelationId } from '~wildo-backend-lib/runtime/models/request-context.als.backend';\n\n// Import the unified error system\nimport {\n ErrorResponse,\n ErrorType,\n ExecutionContext_InitiatorIds,\n WildoError_Backend,\n ValidationErrors,\n ValidationErrorEntry,\n WildoHeaderKeys,\n} from '@wildo-ai/saas-models';\nimport { ExecutionContext, } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\n\n/**\n * The package-path segments that identify Wildo's OTLP **export pipeline** in a\n * stack trace: the signal processors that own the background flush timers, the\n * exporters they hand batches to, and the shared OTLP serialize/send layer\n * every exporter delegates into.\n *\n * The membership criterion is NOT \"is this an OpenTelemetry package\" — it is\n * **\"can a frame from this package ever appear in the stack of a HOST error?\"**\n * Every package listed here answers no: nothing in it invokes a caller-supplied\n * callback, so it is reached only from a telemetry export tick (or from\n * `sdk.shutdown()`). That is what makes a plain \"does the stack mention it\"\n * substring test sound: a frame from one of these packages cannot be\n * *routed through*, only *raised in*.\n *\n * `@opentelemetry/exporter-` is a PREFIX on purpose — it covers the three\n * exporters `otel-preload.ts` wires today (`exporter-trace-otlp-http`,\n * `exporter-metrics-otlp-http`, `exporter-logs-otlp-http`) and every transport\n * sibling (`-proto`, `-grpc`, zipkin, prometheus) a future provider selection\n * could swap in, without this list having to be revisited. Each is export-only\n * by construction.\n *\n * Kept in step with the package's real OpenTelemetry dependency set by the\n * totality pin in `__tests__/error-handler.backend.service.test.ts`, which\n * enumerates every `@opentelemetry/*` entry in this package's own\n * `package.json` and fails unless each one is either matched here or named in\n * {@link TELEMETRY_PACKAGES_DELIBERATELY_NOT_ISOLATED}. A name list with no\n * link to whatever owns those names is the drift this carve-out already had\n * once; the pin is that link. It is test-time rather than compile-time because\n * the owning vocabulary is a JSON manifest, not a TypeScript symbol.\n */\nexport const TELEMETRY_EXPORT_PIPELINE_STACK_MARKERS: readonly string[] = [\n // Log signal: `BatchLogRecordProcessor`'s periodic `_flushOneBatch` timer —\n // the frame the 2026-08-06 incident was raised in (see below).\n '@opentelemetry/sdk-logs',\n // Metric signal: `PeriodicExportingMetricReader`'s collect/export interval.\n // Safe as a whole-stack match only while this application declares no\n // OBSERVABLE instrument: an observable callback is host code invoked by the\n // reader, and would put host frames under an `sdk-metrics` frame. None exist\n // (no `createObservable*`/`addCallback` call site in engine/, platform/ or\n // examples/ as of 2026-09-09), and such a callback would in any case be\n // telemetry-collection code failing on the collection tick.\n '@opentelemetry/sdk-metrics',\n // Every OTLP/zipkin/prometheus exporter — see the prefix note above.\n '@opentelemetry/exporter-',\n // The shared OTLP serialize + send layer the exporters above delegate into,\n // and where a transport/serialization fault is actually raised.\n '@opentelemetry/otlp-exporter-base',\n '@opentelemetry/otlp-grpc-exporter-base',\n '@opentelemetry/otlp-transformer',\n];\n\n/**\n * The OpenTelemetry packages this carve-out deliberately does NOT isolate, each\n * with the reason. This is not a leftover list: it is the other half of the\n * totality pin, so that adding an OTel dependency forces a decision instead of\n * silently landing outside both sets.\n *\n * The reason is the same for the whole first group and it is the one that\n * matters: **these packages invoke host code**, so their frames appear in the\n * stack of ordinary host crashes. Matching them would not widen a telemetry\n * carve-out — it would suppress genuine host faults.\n */\nexport const TELEMETRY_PACKAGES_DELIBERATELY_NOT_ISOLATED: readonly string[] = [\n // --- Runs host code, so a host crash's stack passes through it ---\n // `Tracer.startActiveSpan(name, fn)` calls `fn` — the host's own work — so\n // under HTTP auto-instrumentation practically EVERY synchronous server-side\n // crash carries an `sdk-trace-base` frame. Matching it would carve out the\n // whole application. The consequence is a stated gap, not an oversight: a\n // fault raised INSIDE `BatchSpanProcessor` itself (the span-tier analogue of\n // the 2026-08-06 log-tier incident) still hard-exits. Closing it needs a\n // discriminator this predicate does not have — either \"raised in the TOP\n // frame\" or \"the stack shows a timer tick\" — and neither is worth the\n // false-negative risk until a span-tier incident is actually evidenced. The\n // span EXPORT half is already covered, via `exporter-trace-otlp-http`.\n '@opentelemetry/sdk-trace-base',\n '@opentelemetry/sdk-trace-node',\n // Instrumentation WRAPS host handlers, middleware and driver calls; its\n // frames sit directly beneath host frames on every instrumented request.\n '@opentelemetry/instrumentation',\n '@opentelemetry/instrumentation-express',\n '@opentelemetry/instrumentation-http',\n '@opentelemetry/instrumentation-mongoose',\n '@opentelemetry/instrumentation-redis',\n '@opentelemetry/auto-instrumentations-node',\n // `context.with(ctx, fn)` runs the host callback; the API/core/context tier\n // is on the synchronous path of anything traced.\n '@opentelemetry/api',\n '@opentelemetry/api-logs',\n '@opentelemetry/core',\n // --- Not an export tick ---\n // The SDK facade. Its one dangerous call, `sdk.start()`, is already guarded\n // where it happens (`otel-preload.ts`, Audit A-17) and is a BOOT failure: a\n // host that cannot start telemetry has no export tick to isolate.\n '@opentelemetry/sdk-node',\n // Static data / attribute helpers, resolved at startup. Nothing periodic to\n // isolate, and their frames appear during host bootstrap.\n '@opentelemetry/resources',\n '@opentelemetry/semantic-conventions',\n];\n\n/**\n * Isolates an uncaught exception RAISED INSIDE the OTLP export pipeline —\n * the background machinery that flushes logs, metrics and spans to the\n * collector on a timer, independent of any request — from every other uncaught\n * exception, which still hard-exits via the default path.\n *\n * WHAT THIS SUPPRESSES: a failure whose stack mentions one of\n * {@link TELEMETRY_EXPORT_PIPELINE_STACK_MARKERS}. Those packages never call\n * host code (see that constant's note), so a stack that mentions one of them\n * is a stack that was raised in one of them.\n *\n * WHAT IT MUST NOT SUPPRESS, and does not: anything raised in the host's own\n * request/business logic, anything raised in OTel INSTRUMENTATION (which wraps\n * host code), and anything in the trace/context tier a host stack routes\n * through — see {@link TELEMETRY_PACKAGES_DELIBERATELY_NOT_ISOLATED}. A\n * carve-out that swallowed a genuine fault into a silently degraded process\n * would be strictly worse than the crash it prevents, which is why the\n * criterion is \"cannot be on a host stack\" rather than \"is telemetry\".\n *\n * Root cause (2026-08-06): the timer callback in\n * `BatchLogRecordProcessorBase` does `this._flushOneBatch().then(...).catch(...)`\n * on a fixed interval, independent of any request. Observed in production dev\n * use as `TypeError: this._flushOneBatch(...).then(...).catch is not a\n * function`. The processor's own promise chain broke down before its internal\n * `globalErrorHandler` safety net could catch it, so the failure escaped as a\n * process-level uncaught exception — killing an otherwise-healthy host over a\n * background telemetry-export housekeeping tick.\n *\n * WIDENED 2026-09-09. The original predicate matched the single literal\n * `@opentelemetry/sdk-logs`, which is where that one incident happened to be\n * raised — so the identical promise-chain/transport failure arriving from the\n * METRIC reader or from ANY of the three OTLP exporters was not isolated and\n * hard-exited the host. Keying a carve-out on one package NAME makes its reach\n * an accident of which pipeline failed first; the property that actually\n * distinguishes the case is the export pipeline itself.\n */\nexport function isNonFatalTelemetryPipelineException(error: Error): boolean {\n if (typeof error.stack !== 'string') return false;\n const stack = error.stack;\n return TELEMETRY_EXPORT_PIPELINE_STACK_MARKERS.some((marker) => stack.includes(marker));\n}\n\n/**\n * Unified Error Handler Service\n * Handles all errors using the new unified error management system\n */\n@injectable()\nexport class ErrorHandlerService {\n protected logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private errorBuilder: ErrorBuilderBackendService\n ) {\n this.logDebug = this.logger.debugByType('ErrorHandlerService');\n this.logger.setDebugTypeLogging('ErrorHandlerService', false);\n }\n\n /**\n * Express error handling middleware with unified error system\n * Express requires exactly 4 parameters: (err, req, res, next)\n */\n expressErrorHandler(): (error: Error|WildoError_Backend, req: Request, res: Response, next: NextFunction) => void {\n return (error: Error|WildoError_Backend, req: Request, res: Response, next: NextFunction): void => {\n // Check if response has already been sent\n if (res.headersSent) {\n // If headers are already sent, delegate to Express default handler\n return next(error);\n }\n\n // Extract executionContext from request if available\n const executionContext = (req as any).executionContext as ExecutionContext<any> | undefined;\n\n const errorToHandle = error instanceof Error\n ? this.errorBuilder.buildFromStandardError(error, executionContext)\n : error;\n errorToHandle.ipAddress = this.getClientIpAddress(req);\n\n // Single, central log for every HTTP error — emitted at the *classified*\n // operational severity rather than a blanket `error`. This is the one\n // true HTTP error boundary (mounted globally in http-server and per\n // sub-router), so logging here guarantees exactly one line per failed\n // request: expected client conditions (e.g. an expired token the client\n // will refresh) stay at `debug`, genuine server faults stay at `error`\n // with a stack. Per-controller boundaries no longer log — they forward\n // here — which removes the historic double-logging and the noise flood.\n logWildoBackendErrorAtClassifiedSeverity(\n this.logger,\n 'HTTP request failed',\n errorToHandle,\n // Boundary-specific extras only — the error's own fields (errorType,\n // statusCode, customMessageReference, operationPath, …) are projected\n // by the helper.\n {\n method: req.method,\n path: req.path,\n },\n );\n\n this.sendErrorResponse(errorToHandle, res);\n };\n }\n\n handleBatchesCronjobsError(error: Error|WildoError_Backend, executionContext?: ExecutionContext<any>): void {\n const errorToHandle = error instanceof Error ? this.errorBuilder.buildFromStandardError(error, executionContext) : error;\n\n // Batch/cron is a non-HTTP boundary (no `expressErrorHandler` downstream),\n // so this is where the line must be emitted — at the classified severity.\n // The error's own fields are projected by the helper; the stack is attached\n // only when the level is `error`.\n logWildoBackendErrorAtClassifiedSeverity(this.logger, 'Batch/cronjob execution failed', errorToHandle);\n }\n\n\n private sendErrorResponse(saasError: WildoError_Backend, res: Response, initiatorIds?: ExecutionContext_InitiatorIds): void {\n // Double-check if headers are already sent\n if (res.headersSent) {\n this.logger.warn('Cannot send error response - headers already sent', {\n errorType: saasError.type,\n statusCode: saasError.statusCode\n });\n return;\n }\n\n try {\n // Build validationErrors for responses that carry field-level error information.\n // Values can be plain strings (Zod errors) or structured ValidationErrorEntry objects (unique constraints).\n //\n // C3: Intentional extraction order — validationErrors are extracted from the raw error\n // BEFORE sanitizeErrorForClient() runs. This is by design: zodIssues contain field-level\n // validation messages that must appear in the response for form UX, even though the\n // sanitization layer may strip them from `details`. If zodIssues are removed from the\n // sanitization allowlist in the future, validationErrors will still be included because\n // they are extracted independently above the sanitization call.\n let validationErrors: ValidationErrors | undefined;\n\n // CONFLICT (409): Unique constraint violations — use structured i18n entries\n if (saasError.type === ErrorType.CONFLICT && saasError.context?.fieldName) {\n const fieldName = saasError.context.fieldName as string;\n const duplicateValue = saasError.context.duplicateValue as string | undefined;\n const customErrorMessage = saasError.context.customErrorMessage as string | undefined;\n const fallbackMessage = customErrorMessage\n ? customErrorMessage.replace('{fieldName}', fieldName)\n : duplicateValue\n ? `\"${duplicateValue}\" already exists`\n : 'Value already exists';\n\n const entry: ValidationErrorEntry = {\n key: 'validation.unique.conflict',\n message: fallbackMessage,\n params: {\n fieldName,\n ...(duplicateValue ? { value: duplicateValue } : {}),\n },\n };\n validationErrors = { [fieldName]: entry };\n }\n\n // VALIDATION (400): Zod validation errors — plain strings (already localized by Zod)\n if (saasError.type === ErrorType.VALIDATION && saasError.context?.zodIssues) {\n const zodIssues = saasError.context.zodIssues as Array<{ path: (string | number)[]; message: string }>;\n validationErrors = zodIssues.reduce((acc, issue) => {\n const fieldPath = issue.path.join('.');\n acc[fieldPath] = issue.message;\n return acc;\n }, {} as ValidationErrors);\n }\n\n // H9 fix: Sanitize error at serialization boundary — backend logs retain full context,\n // but the HTTP response strips internal details (emails, stack traces, session IDs, etc.)\n const sanitizedError = this.errorBuilder.sanitizeErrorForClient(saasError);\n const retryAfterSeconds = sanitizedError.context?.retryAfterSeconds;\n if (\n (typeof retryAfterSeconds === 'number' || typeof retryAfterSeconds === 'string')\n && retryAfterSeconds !== ''\n && typeof res.getHeader === 'function'\n && typeof res.setHeader === 'function'\n && res.getHeader('Retry-After') === undefined\n ) {\n res.setHeader('Retry-After', String(retryAfterSeconds));\n }\n\n const response: ErrorResponse = {\n error: {\n type: saasError.type,\n severity: saasError.severity,\n message: saasError.customMessageReference,\n customMessage: saasError.customMessageReference,\n ...(saasError.customMessageReference && { customMessageReference: saasError.customMessageReference }),\n operationPath: saasError.operationPathKey,\n // A stable, operation-specific refusal code (e.g. `LAST_ORGANIZATION_OWNER`) is the\n // contract clients branch on. It is authored in `context.code` and allow-listed by the\n // sanitizer, so it also appears under `details.code`; hoisting it to the top-level field the\n // schema reserves is what lets the customer documentation say \"branch on `error.code`\".\n ...(typeof sanitizedError.context?.code === 'string' && { code: sanitizedError.context.code }),\n // Phase 3 (SD5) — a safe, non-PII support/trace id the user can quote; joins this response to\n // the backend logs + audit for the same request. The error's captured id, else the ambient frame.\n correlationId: saasError.correlationId ?? getCurrentCorrelationId(),\n timestamp: saasError.timestamp.toISOString(),\n initiatorIds: saasError.initiatorIds,\n // executionType: saasError.executionType,\n // stack: saasError.stack,\n ...(sanitizedError.context && { details: sanitizedError.context }),\n // FIX-P6-H1: Include validationErrors at top level for frontend parsing\n ...(validationErrors && { validationErrors }),\n // Phase 1b: Include user guidance if present on the error\n ...(saasError.userGuidance && { userGuidance: saasError.userGuidance }),\n }\n };\n\n res.status(saasError.statusCode).json(response);\n } catch (sendError) {\n // If sending the error response fails, log it but don't throw\n // This prevents Express default HTML error handler from being triggered\n this.logger.error('Failed to send error response', {\n originalError: saasError.type,\n sendError: describeCaughtError(sendError)\n });\n }\n }\n\n\n /**\n * Get client IP address\n */\n private getClientIpAddress(req: Request): string {\n const xForwardedFor = req.headers[WildoHeaderKeys.FORWARDED_FOR];\n if (xForwardedFor) {\n return Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor.split(',')[0];\n }\n\n return req.headers[WildoHeaderKeys.REAL_IP] as string ||\n req.connection?.remoteAddress ||\n req.socket?.remoteAddress ||\n 'unknown';\n }\n\n /**\n * Create async error wrapper for route handlers\n */\n asyncHandler(fn: Function): (req: Request, res: Response, next: NextFunction) => void {\n return (req: Request, res: Response, next: NextFunction): void => {\n Promise.resolve(fn(req, res, next)).catch(next);\n };\n }\n\n /**\n * Global unhandled rejection handler\n */\n handleUnhandledRejection(): void {\n process.on('unhandledRejection', (reason: any, promise: Promise<any>) => {\n const errorToHandle = this.errorBuilder.buildError(ErrorType.UNHANDLED_REJECTION, undefined, {\n stack: reason?.stack,\n context: {\n name: reason?.name,\n message: reason?.message,\n promise: promise.toString()\n }\n });\n this.logger.fatal('Unhandled Promise Rejection', { ...errorToHandle });\n\n // Graceful shutdown\n process.exit(1);\n });\n }\n\n /**\n * Global uncaught exception handler.\n *\n * Exits the process for every uncaught exception EXCEPT the narrow class\n * isolated by {@link isNonFatalTelemetryPipelineException}. Node's own\n * guidance (\"uncaught exception means unknown state, exit\") assumes the\n * failure came from the host's own request/business logic. A background\n * telemetry export tick (OTel's `BatchLogRecordProcessor` or\n * `PeriodicExportingMetricReader`, and the OTLP exporters they feed, ticking\n * every few seconds independently of any request) is a different failure\n * domain: its own state corruption says nothing about whether the host's\n * actual work is safe to continue, and `otel-preload.ts` already commits to\n * \"telemetry failures must never affect host availability\" for SDK-start\n * failures (Audit A-17) — this extends the same policy to a *runtime*\n * telemetry failure. Every other uncaught exception keeps today's hard-exit\n * behavior unchanged.\n *\n * NOTE: this method is not wired into any production entrypoint today (no\n * caller reaches `initializeGlobalHandlers`/`handleUncaughtException`) —\n * kept for any future/direct caller, and as the tested home of the shared\n * {@link isNonFatalTelemetryPipelineException} predicate. It cannot simply\n * become \"the\" global handler: it depends on DI (`ErrorBuilderBackendService`\n * via the container), so it is only constructible AFTER\n * `setupSaasBackendInjection()` — every real crash boundary below registers\n * a RAW `process.on(...)` listener at module load, before the container\n * exists, specifically so container-construction failures and early-startup\n * throws are still caught. The listeners that actually apply this predicate\n * in production, all against the SAME exported function:\n *\n * - `runPlatformServiceEntrypoint` (platform\n * `platform-shared-lib/src/core/startup/platform-service-process-boundary.ts`)\n * — protects `platform-apps-manager`, `platform-crontabs-batches-manager`,\n * `platform-module-registry`. This is the process that actually crashed\n * on 2026-08-06, on `this._flushOneBatch(...).then(...).catch is not a\n * function` inside `@opentelemetry/sdk-logs`'s batch timer.\n * - `WorkerShutdownManagerBackendService.registerSignalHandlers` (this\n * package, `queue/worker-shutdown-manager.backend.service.ts`) — the\n * engine-shared listener reached by every NON-PLATFORM host\n * (backend-api, workers, minions) that runs a queue worker OR has\n * telemetry active, via `StartApplicationBackendService`'s\n * `!isPlatformApplication`/`!isPlatformMode`-gated calls into\n * `ObservabilityBackendService.initialize`/`QueueWorkerInitializer.initialize`.\n * Platform hosts skip both gates entirely and are NOT covered by this\n * listener — they rely solely on the `runPlatformServiceEntrypoint` entry\n * above.\n * - The hand-rolled bootstrap `process.on('uncaughtException'/'unhandledRejection', ...)`\n * blocks in each application entrypoint (Wonder Todos:\n * `backend-api/src/index.ts`, `minions/marketing-scrapper/src/index.ts`,\n * `workers/my-node-worker/src/index.ts`) — these are hand-authored\n * per-app boilerplate, not generated from a shared template, so a future\n * app scaffolded the same way needs the same carve-out applied by hand\n * until this pattern is consolidated into a shared bootstrap helper.\n */\n handleUncaughtException(): void {\n process.on('uncaughtException', (error: Error) => {\n const errorToHandle = this.errorBuilder.buildError(ErrorType.UNCAUGHT_EXCEPTION, undefined, {\n stack: error.stack,\n context: {\n name: error.name,\n message: error.message,\n }\n });\n\n if (isNonFatalTelemetryPipelineException(error)) {\n this.logger.error('Uncaught exception isolated to the telemetry pipeline; host stays up', { ...errorToHandle });\n return;\n }\n\n this.logger.fatal('Uncaught Exception', { ...errorToHandle });\n\n // Graceful shutdown\n process.exit(1);\n });\n }\n\n /**\n * Initialize global error handlers\n */\n initializeGlobalHandlers(): void {\n this.handleUnhandledRejection();\n this.handleUncaughtException();\n }\n\n}\n"]}
|
|
1
|
+
{"version":3,"file":"error-handler.backend.service.js","sourceRoot":"","sources":["../../../../src/errors/services/error-handler.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from 'express';\nimport { inject, injectable } from 'inversify';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { ErrorBuilderBackendService } from './error-builder.backend.service';\nimport { logWildoBackendErrorAtClassifiedSeverity, describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { getCurrentCorrelationId } from '~wildo-backend-lib/runtime/models/request-context.als.backend';\n\n// Import the unified error system\nimport {\n ErrorResponse,\n ErrorType,\n ExecutionContext_InitiatorIds,\n WildoError_Backend,\n ValidationErrors,\n ValidationErrorEntry,\n WildoHeaderKeys,\n} from '@wildo-ai/saas-models';\nimport { ExecutionContext, } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\n\n/**\n * The package-path segments that identify Wildo's OTLP **export pipeline** in a\n * stack trace: the signal processors that own the background flush timers, the\n * exporters they hand batches to, and the shared OTLP serialize/send layer\n * every exporter delegates into.\n *\n * The membership criterion is NOT \"is this an OpenTelemetry package\" — it is\n * **\"can a frame from this package ever appear in the stack of a HOST error?\"**\n * Every package listed here answers no: nothing in it invokes a caller-supplied\n * callback, so it is reached only from a telemetry export tick (or from\n * `sdk.shutdown()`). That is what makes a plain \"does the stack mention it\"\n * substring test sound: a frame from one of these packages cannot be\n * *routed through*, only *raised in*.\n *\n * `@opentelemetry/exporter-` is a PREFIX on purpose — it covers the three\n * exporters `otel-preload.ts` wires today (`exporter-trace-otlp-http`,\n * `exporter-metrics-otlp-http`, `exporter-logs-otlp-http`) and every transport\n * sibling (`-proto`, `-grpc`, zipkin, prometheus) a future provider selection\n * could swap in, without this list having to be revisited. Each is export-only\n * by construction.\n *\n * Kept in step with the package's real OpenTelemetry dependency set by the\n * totality pin in `__tests__/error-handler.backend.service.test.ts`, which\n * enumerates every `@opentelemetry/*` entry in this package's own\n * `package.json` and fails unless each one is either matched here or named in\n * {@link TELEMETRY_PACKAGES_DELIBERATELY_NOT_ISOLATED}. A name list with no\n * link to whatever owns those names is the drift this carve-out already had\n * once; the pin is that link. It is test-time rather than compile-time because\n * the owning vocabulary is a JSON manifest, not a TypeScript symbol.\n */\nexport const TELEMETRY_EXPORT_PIPELINE_STACK_MARKERS: readonly string[] = [\n // Log signal: `BatchLogRecordProcessor`'s periodic `_flushOneBatch` timer —\n // the frame the 2026-08-06 incident was raised in (see below).\n '@opentelemetry/sdk-logs',\n // Metric signal: `PeriodicExportingMetricReader`'s collect/export interval.\n // Safe as a whole-stack match only while this application declares no\n // OBSERVABLE instrument: an observable callback is host code invoked by the\n // reader, and would put host frames under an `sdk-metrics` frame. None exist\n // (no `createObservable*`/`addCallback` call site in engine/, platform/ or\n // examples/ as of 2026-09-09), and such a callback would in any case be\n // telemetry-collection code failing on the collection tick.\n '@opentelemetry/sdk-metrics',\n // Every OTLP/zipkin/prometheus exporter — see the prefix note above.\n '@opentelemetry/exporter-',\n // The shared OTLP serialize + send layer the exporters above delegate into,\n // and where a transport/serialization fault is actually raised.\n '@opentelemetry/otlp-exporter-base',\n '@opentelemetry/otlp-grpc-exporter-base',\n '@opentelemetry/otlp-transformer',\n];\n\n/**\n * The OpenTelemetry packages this carve-out deliberately does NOT isolate, each\n * with the reason. This is not a leftover list: it is the other half of the\n * totality pin, so that adding an OTel dependency forces a decision instead of\n * silently landing outside both sets.\n *\n * The reason is the same for the whole first group and it is the one that\n * matters: **these packages invoke host code**, so their frames appear in the\n * stack of ordinary host crashes. Matching them would not widen a telemetry\n * carve-out — it would suppress genuine host faults.\n */\nexport const TELEMETRY_PACKAGES_DELIBERATELY_NOT_ISOLATED: readonly string[] = [\n // --- Runs host code, so a host crash's stack passes through it ---\n // `Tracer.startActiveSpan(name, fn)` calls `fn` — the host's own work — so\n // under HTTP auto-instrumentation practically EVERY synchronous server-side\n // crash carries an `sdk-trace-base` frame. Matching it would carve out the\n // whole application. The consequence is a stated gap, not an oversight: a\n // fault raised INSIDE `BatchSpanProcessor` itself (the span-tier analogue of\n // the 2026-08-06 log-tier incident) still hard-exits. Closing it needs a\n // discriminator this predicate does not have — either \"raised in the TOP\n // frame\" or \"the stack shows a timer tick\" — and neither is worth the\n // false-negative risk until a span-tier incident is actually evidenced. The\n // span EXPORT half is already covered, via `exporter-trace-otlp-http`.\n '@opentelemetry/sdk-trace-base',\n '@opentelemetry/sdk-trace-node',\n // Instrumentation WRAPS host handlers, middleware and driver calls; its\n // frames sit directly beneath host frames on every instrumented request.\n '@opentelemetry/instrumentation',\n '@opentelemetry/instrumentation-express',\n '@opentelemetry/instrumentation-http',\n '@opentelemetry/instrumentation-mongoose',\n '@opentelemetry/instrumentation-redis',\n '@opentelemetry/auto-instrumentations-node',\n // `context.with(ctx, fn)` runs the host callback; the API/core/context tier\n // is on the synchronous path of anything traced.\n '@opentelemetry/api',\n '@opentelemetry/api-logs',\n '@opentelemetry/core',\n // --- Not an export tick ---\n // The SDK facade. Its one dangerous call, `sdk.start()`, is already guarded\n // where it happens (`otel-preload.ts`, Audit A-17) and is a BOOT failure: a\n // host that cannot start telemetry has no export tick to isolate.\n '@opentelemetry/sdk-node',\n // Static data / attribute helpers, resolved at startup. Nothing periodic to\n // isolate, and their frames appear during host bootstrap.\n '@opentelemetry/resources',\n '@opentelemetry/semantic-conventions',\n];\n\n/**\n * Isolates an uncaught exception RAISED INSIDE the OTLP export pipeline —\n * the background machinery that flushes logs, metrics and spans to the\n * collector on a timer, independent of any request — from every other uncaught\n * exception, which still hard-exits via the default path.\n *\n * WHAT THIS SUPPRESSES: a failure whose stack mentions one of\n * {@link TELEMETRY_EXPORT_PIPELINE_STACK_MARKERS}. Those packages never call\n * host code (see that constant's note), so a stack that mentions one of them\n * is a stack that was raised in one of them.\n *\n * WHAT IT MUST NOT SUPPRESS, and does not: anything raised in the host's own\n * request/business logic, anything raised in OTel INSTRUMENTATION (which wraps\n * host code), and anything in the trace/context tier a host stack routes\n * through — see {@link TELEMETRY_PACKAGES_DELIBERATELY_NOT_ISOLATED}. A\n * carve-out that swallowed a genuine fault into a silently degraded process\n * would be strictly worse than the crash it prevents, which is why the\n * criterion is \"cannot be on a host stack\" rather than \"is telemetry\".\n *\n * Root cause (2026-08-06): the timer callback in\n * `BatchLogRecordProcessorBase` does `this._flushOneBatch().then(...).catch(...)`\n * on a fixed interval, independent of any request. Observed in production dev\n * use as `TypeError: this._flushOneBatch(...).then(...).catch is not a\n * function`. The processor's own promise chain broke down before its internal\n * `globalErrorHandler` safety net could catch it, so the failure escaped as a\n * process-level uncaught exception — killing an otherwise-healthy host over a\n * background telemetry-export housekeeping tick.\n *\n * WIDENED 2026-09-09. The original predicate matched the single literal\n * `@opentelemetry/sdk-logs`, which is where that one incident happened to be\n * raised — so the identical promise-chain/transport failure arriving from the\n * METRIC reader or from ANY of the three OTLP exporters was not isolated and\n * hard-exited the host. Keying a carve-out on one package NAME makes its reach\n * an accident of which pipeline failed first; the property that actually\n * distinguishes the case is the export pipeline itself.\n */\nexport function isNonFatalTelemetryPipelineException(error: Error): boolean {\n if (typeof error.stack !== 'string') return false;\n const stack = error.stack;\n return TELEMETRY_EXPORT_PIPELINE_STACK_MARKERS.some((marker) => stack.includes(marker));\n}\n\n/**\n * Unified Error Handler Service\n * Handles all errors using the new unified error management system\n */\n@injectable()\nexport class ErrorHandlerService {\n protected logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private errorBuilder: ErrorBuilderBackendService\n ) {\n this.logDebug = this.logger.debugByType('ErrorHandlerService');\n this.logger.setDebugTypeLogging('ErrorHandlerService', false);\n }\n\n /**\n * Express error handling middleware with unified error system\n * Express requires exactly 4 parameters: (err, req, res, next)\n */\n expressErrorHandler(): (error: Error|WildoError_Backend, req: Request, res: Response, next: NextFunction) => void {\n return (error: Error|WildoError_Backend, req: Request, res: Response, next: NextFunction): void => {\n // Check if response has already been sent\n if (res.headersSent) {\n // If headers are already sent, delegate to Express default handler\n return next(error);\n }\n\n // Extract executionContext from request if available\n const executionContext = (req as any).executionContext as ExecutionContext<any> | undefined;\n\n const errorToHandle = error instanceof Error\n ? this.errorBuilder.buildFromStandardError(error, executionContext)\n : error;\n errorToHandle.ipAddress = this.getClientIpAddress(req);\n\n // Single, central log for every HTTP error — emitted at the *classified*\n // operational severity rather than a blanket `error`. This is the one\n // true HTTP error boundary (mounted globally in http-server and per\n // sub-router), so logging here guarantees exactly one line per failed\n // request: expected client conditions (e.g. an expired token the client\n // will refresh) stay at `debug`, genuine server faults stay at `error`\n // with a stack. Per-controller boundaries no longer log — they forward\n // here — which removes the historic double-logging and the noise flood.\n logWildoBackendErrorAtClassifiedSeverity(\n this.logger,\n 'HTTP request failed',\n errorToHandle,\n // Boundary-specific extras only — the error's own fields (errorType,\n // statusCode, customMessageReference, operationPath, …) are projected\n // by the helper.\n {\n method: req.method,\n path: req.path,\n },\n );\n\n this.sendErrorResponse(errorToHandle, res);\n };\n }\n\n handleBatchesCronjobsError(error: Error|WildoError_Backend, executionContext?: ExecutionContext<any>): void {\n const errorToHandle = error instanceof Error ? this.errorBuilder.buildFromStandardError(error, executionContext) : error;\n\n // Batch/cron is a non-HTTP boundary (no `expressErrorHandler` downstream),\n // so this is where the line must be emitted — at the classified severity.\n // The error's own fields are projected by the helper; the stack is attached\n // only when the level is `error`.\n logWildoBackendErrorAtClassifiedSeverity(this.logger, 'Batch/cronjob execution failed', errorToHandle);\n }\n\n\n private sendErrorResponse(saasError: WildoError_Backend, res: Response, initiatorIds?: ExecutionContext_InitiatorIds): void {\n // Double-check if headers are already sent\n if (res.headersSent) {\n this.logger.warn('Cannot send error response - headers already sent', {\n errorType: saasError.type,\n statusCode: saasError.statusCode\n });\n return;\n }\n\n try {\n // Build validationErrors for responses that carry field-level error information.\n // Values can be plain strings (Zod errors) or structured ValidationErrorEntry objects (unique constraints).\n //\n // C3: Intentional extraction order — validationErrors are extracted from the raw error\n // BEFORE sanitizeErrorForClient() runs. This is by design: zodIssues contain field-level\n // validation messages that must appear in the response for form UX, even though the\n // sanitization layer may strip them from `details`. If zodIssues are removed from the\n // sanitization allowlist in the future, validationErrors will still be included because\n // they are extracted independently above the sanitization call.\n let validationErrors: ValidationErrors | undefined;\n\n // CONFLICT (409): Unique constraint violations — use structured i18n entries\n if (saasError.type === ErrorType.CONFLICT && saasError.context?.fieldName) {\n const fieldName = saasError.context.fieldName as string;\n const duplicateValue = saasError.context.duplicateValue as string | undefined;\n const customErrorMessage = saasError.context.customErrorMessage as string | undefined;\n const fallbackMessage = customErrorMessage\n ? customErrorMessage.replace('{fieldName}', fieldName)\n : duplicateValue\n ? `\"${duplicateValue}\" already exists`\n : 'Value already exists';\n\n const entry: ValidationErrorEntry = {\n key: 'validation.unique.conflict',\n message: fallbackMessage,\n params: {\n fieldName,\n ...(duplicateValue ? { value: duplicateValue } : {}),\n },\n };\n validationErrors = { [fieldName]: entry };\n }\n\n // VALIDATION (400): Zod validation errors — plain strings (already localized by Zod)\n if (saasError.type === ErrorType.VALIDATION && saasError.context?.zodIssues) {\n const zodIssues = saasError.context.zodIssues as Array<{ path: (string | number)[]; message: string }>;\n validationErrors = zodIssues.reduce((acc, issue) => {\n const fieldPath = issue.path.join('.');\n acc[fieldPath] = issue.message;\n return acc;\n }, {} as ValidationErrors);\n }\n\n // H9 fix: Sanitize error at serialization boundary — backend logs retain full context,\n // but the HTTP response strips internal details (emails, stack traces, session IDs, etc.)\n const sanitizedError = this.errorBuilder.sanitizeErrorForClient(saasError);\n const retryAfterSeconds = sanitizedError.context?.retryAfterSeconds;\n if (\n (typeof retryAfterSeconds === 'number' || typeof retryAfterSeconds === 'string')\n && retryAfterSeconds !== ''\n && typeof res.getHeader === 'function'\n && typeof res.setHeader === 'function'\n && res.getHeader('Retry-After') === undefined\n ) {\n res.setHeader('Retry-After', String(retryAfterSeconds));\n }\n\n const response: ErrorResponse = {\n error: {\n type: saasError.type,\n severity: saasError.severity,\n message: saasError.customMessageReference,\n customMessage: saasError.customMessageReference,\n ...(saasError.customMessageReference && { customMessageReference: saasError.customMessageReference }),\n operationPath: saasError.operationPathKey,\n // A stable, operation-specific refusal code (e.g. `LAST_ORGANIZATION_OWNER`) is the\n // contract clients branch on. It is authored in `context.code` and allow-listed by the\n // sanitizer, so it also appears under `details.code`; hoisting it to the top-level field the\n // schema reserves is what lets the customer documentation say \"branch on `error.code`\".\n ...(typeof sanitizedError.context?.code === 'string' && { code: sanitizedError.context.code }),\n // Phase 3 (SD5) — a safe, non-PII support/trace id the user can quote; joins this response to\n // the backend logs + audit for the same request. The error's captured id, else the ambient frame.\n correlationId: saasError.correlationId ?? getCurrentCorrelationId(),\n timestamp: saasError.timestamp.toISOString(),\n initiatorIds: saasError.initiatorIds,\n // executionType: saasError.executionType,\n // stack: saasError.stack,\n ...(sanitizedError.context && { details: sanitizedError.context }),\n // FIX-P6-H1: Include validationErrors at top level for frontend parsing\n ...(validationErrors && { validationErrors }),\n // Phase 1b: Include user guidance if present on the error\n ...(saasError.userGuidance && { userGuidance: saasError.userGuidance }),\n }\n };\n\n res.status(saasError.statusCode).json(response);\n } catch (sendError) {\n // If sending the error response fails, log it but don't throw\n // This prevents Express default HTML error handler from being triggered\n this.logger.error('Failed to send error response', {\n originalError: saasError.type,\n sendError: describeCaughtError(sendError)\n });\n }\n }\n\n\n /**\n * Get client IP address\n */\n private getClientIpAddress(req: Request): string {\n const xForwardedFor = req.headers[WildoHeaderKeys.FORWARDED_FOR];\n if (xForwardedFor) {\n return Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor.split(',')[0];\n }\n\n return req.headers[WildoHeaderKeys.REAL_IP] as string ||\n req.connection?.remoteAddress ||\n req.socket?.remoteAddress ||\n 'unknown';\n }\n\n /**\n * Create async error wrapper for route handlers\n */\n asyncHandler(fn: Function): (req: Request, res: Response, next: NextFunction) => void {\n return (req: Request, res: Response, next: NextFunction): void => {\n Promise.resolve(fn(req, res, next)).catch(next);\n };\n }\n\n /**\n * Global unhandled rejection handler\n */\n handleUnhandledRejection(): void {\n process.on('unhandledRejection', (reason: any, promise: Promise<any>) => {\n const errorToHandle = this.errorBuilder.buildError(ErrorType.UNHANDLED_REJECTION, undefined, {\n stack: reason?.stack,\n context: {\n name: reason?.name,\n message: reason?.message,\n promise: promise.toString()\n }\n });\n this.logger.fatal('Unhandled Promise Rejection', { ...errorToHandle });\n\n // Graceful shutdown\n process.exit(1);\n });\n }\n\n /**\n * Global uncaught exception handler.\n *\n * Exits the process for every uncaught exception EXCEPT the narrow class\n * isolated by {@link isNonFatalTelemetryPipelineException}. Node's own\n * guidance (\"uncaught exception means unknown state, exit\") assumes the\n * failure came from the host's own request/business logic. A background\n * telemetry export tick (OTel's `BatchLogRecordProcessor` or\n * `PeriodicExportingMetricReader`, and the OTLP exporters they feed, ticking\n * every few seconds independently of any request) is a different failure\n * domain: its own state corruption says nothing about whether the host's\n * actual work is safe to continue, and `otel-preload.ts` already commits to\n * \"telemetry failures must never affect host availability\" for SDK-start\n * failures (Audit A-17) — this extends the same policy to a *runtime*\n * telemetry failure. Every other uncaught exception keeps today's hard-exit\n * behavior unchanged.\n *\n * NOTE: this method is not wired into any production entrypoint today (no\n * caller reaches `initializeGlobalHandlers`/`handleUncaughtException`) —\n * kept for any future/direct caller, and as the tested home of the shared\n * {@link isNonFatalTelemetryPipelineException} predicate. It cannot simply\n * become \"the\" global handler: it depends on DI (`ErrorBuilderBackendService`\n * via the container), so it is only constructible AFTER\n * `setupSaasBackendInjection()` — every real crash boundary below registers\n * a RAW `process.on(...)` listener at module load, before the container\n * exists, specifically so container-construction failures and early-startup\n * throws are still caught. The listeners that actually apply this predicate\n * in production, all against the SAME exported function:\n *\n * - `runPlatformServiceEntrypoint` (platform\n * `platform-shared-lib/src/core/startup/platform-service-process-boundary.ts`)\n * — protects `platform-apps-manager`, `platform-crontabs-batches-manager`,\n * `platform-module-registry`. This is the process that actually crashed\n * on 2026-08-06, on `this._flushOneBatch(...).then(...).catch is not a\n * function` inside `@opentelemetry/sdk-logs`'s batch timer.\n * - `WorkerShutdownManagerBackendService.registerSignalHandlers` (this\n * package, `queue/worker-shutdown-manager.backend.service.ts`) — the\n * engine-shared listener reached by every NON-PLATFORM host\n * (backend-api, workers, minions) that runs a queue worker OR has\n * telemetry active, via `StartApplicationBackendService`'s\n * `!isPlatformApplication`/`!isPlatformMode`-gated calls into\n * `ObservabilityBackendService.initialize`/`QueueWorkerInitializer.initialize`.\n * Platform hosts skip both gates entirely and are NOT covered by this\n * listener — they rely solely on the `runPlatformServiceEntrypoint` entry\n * above.\n * - The hand-rolled bootstrap `process.on('uncaughtException'/'unhandledRejection', ...)`\n * blocks in each application entrypoint (Wonder Todos:\n * `backend-api/src/index.ts`, `minions/marketing-scrapper/src/index.ts`,\n * `workers/my-node-worker/src/index.ts`) — these are hand-authored\n * per-app boilerplate, not generated from a shared template, so a future\n * app scaffolded the same way needs the same carve-out applied by hand\n * until this pattern is consolidated into a shared bootstrap helper.\n */\n handleUncaughtException(): void {\n process.on('uncaughtException', (error: Error) => {\n const errorToHandle = this.errorBuilder.buildError(ErrorType.UNCAUGHT_EXCEPTION, undefined, {\n stack: error.stack,\n context: {\n name: error.name,\n message: error.message,\n }\n });\n\n if (isNonFatalTelemetryPipelineException(error)) {\n this.logger.error('Uncaught exception isolated to the telemetry pipeline; host stays up', { ...errorToHandle });\n return;\n }\n\n this.logger.fatal('Uncaught Exception', { ...errorToHandle });\n\n // Graceful shutdown\n process.exit(1);\n });\n }\n\n /**\n * Initialize global error handlers\n */\n initializeGlobalHandlers(): void {\n this.handleUnhandledRejection();\n this.handleUncaughtException();\n }\n\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.backend.service.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"rate-limit.backend.service.d.ts","sourceRoot":"","sources":["../../../../src/errors/services/rate-limit.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EACL,2BAA2B,EAC3B,SAAS,EACT,4BAA4B,EAE5B,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,YAAY,EAAE,MAAM,qDAAqD,CAAC;AAEnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,sEAAsE,CAAC;AAE/G,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AA0B7E,qBACa,uBAAuB;IAES,OAAO,CAAC,QAAQ,CAAC,YAAY;IACtB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAFpB,YAAY,EAAE,YAAY,EACnB,YAAY,EAAE,0BAA0B,EAC3C,gBAAgB,EAAE,uBAAuB;IAGzG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2DG;IACU,cAAc,CACzB,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,EACvB,eAAe,CAAC,EAAE,MAAM,EACxB,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,sBAAsB,CAAC,EAAE,2BAA2B,CAAC;QACrD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACxC,GACA,OAAO,CAAC,IAAI,CAAC;IA6BhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgEG;IACH,0EAA0E;IAC7D,WAAW,CACtB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,sBAAsB,EAC9B,QAAQ,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,MAAM,EACvB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC;IAiEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgDG;IACU,qBAAqB,CAChC,MAAM,EAAE,sBAAsB,EAC9B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC;IAehB;;;;;;;;;;;;;;OAcG;YACW,qBAAqB;IAoCnC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACU,qBAAqB,CAChC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE;QACP,QAAQ,CAAC,WAAW,EAAE,4BAA4B,CAAC;QACnD,QAAQ,CAAC,kBAAkB,EAAE,YAAY,CAAC;QAO1C,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;QACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,sBAAsB,CAAC;KAC7C,GACA,OAAO,CAAC,IAAI,CAAC;IAehB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,OAAO,CAAC,aAAa;IAsDrB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,uBAAuB;YAIjB,mBAAmB;CAmBlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.backend.service.js","sourceRoot":"","sources":["../../../../../src/errors/services/rate-limit.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Rate Limit Backend Service — CORE-9\n *\n * Single source of truth for controller-level rate limit checks. Three public\n * surfaces, layered:\n *\n * 1. `checkRateLimit(key, max, windowSeconds, organizationId?, messageOverride?, options?)`\n * — low-level primitive (fixed window via atomic Redis INCR+EXPIRE). The K-3\n * ESCAPE-HATCH surface, reserved for the FOUR engine-side call sites\n * (post-PR-8 + Step 7 F-23 sub-PR a + lockout modernization) where the\n * bucket key is NOT cheaply\n * derivable from HTTP-layer inputs:\n * - `AuthenticationOrchestrator.sendSMSOTP` (DB-resolved phone number),\n * - `AuthenticationOrchestrator.authenticatePassword` per-email + per-IP\n * (session-stored email + identify-time IP),\n * - `AuthenticationOrchestrator.sendEmailOTP` (session-resolved\n * userId; migrated from `redisService.incrementRateLimit` in Step 7),\n * - `AuthenticationOrchestrator.authenticatePassword` global lockout\n * counter (per-session email before `verifyPassword(...)`).\n * The lockout caller uses the `options` bridge added in Step 3.1 to swap\n * the thrown\n * error envelope from a 429 `RATE_LIMIT` to a 401 `AUTHENTICATION` +\n * `AUTHENTICATION_ACCOUNT_LOCKED`. The optional `messageOverride`\n * parameter preserves domain-specific UX (canonical use: the OTP-\n * specific phrasing the email-OTP site shipped pre-migration; the\n * lockout site's existing \"Account temporarily locked...\" phrasing).\n * The optional `options` parameter (`errorType` / `customMessageReference`\n * / `contextExtra`) lets the lockout-style caller mint a non-RATE_LIMIT\n * error envelope without forking the primitive; when omitted, behavior\n * is byte-identical to the pre-bridge call shape. Every other\n * rate-limited site reaches for `checkPolicy` or the resource-operation\n * `rateLimit?` field.\n *\n * 2. `checkPolicy(req, res, policy, scopeKey, organizationId?, clientIdOverride?)`\n * — declarative consumer for custom controllers (auth, SCIM, marketing\n * public endpoints). Issues one `RedisService.incrementRateLimit` call\n * per declared window (NOT a `checkRateLimit` call — `checkPolicy` needs\n * the post-increment count to compute `remaining` for headers, and must\n * always increment every window so quota accounting stays consistent\n * across windows; `checkRateLimit` would short-circuit the loop on the\n * first trip) and writes `X-RateLimit-*` headers from the tightest\n * active window. `clientIdOverride` swaps the default IP-keyed bucket\n * for an authenticated subject identifier (`token._id`, `userId`,\n * normalized email/phone) so IP rotation can't bypass per-subject caps.\n *\n * 3. `checkPolicyForVariant(req, res, variant)` — pre-flight consumer used\n * by `ControllerResourceBackendService.doOperation` BEFORE\n * execution-context creation, validation, and authorization. Early-returns\n * when the variant declares no `rateLimit?` policy (zero Redis traffic\n * on the no-policy fast path).\n *\n * Fail-closed (C-3): the underlying `RedisService.incrementRateLimit` throws\n * `ErrorType.DATABASE` when Redis is unavailable. Both `checkPolicy` and\n * `checkPolicyForVariant` propagate that error rather than silently passing\n * traffic. The global HTTP limiter\n * (`http-server.backend.service.ts:setupRateLimit`) keeps its in-memory\n * fail-open Map as the safety net at the perimeter — the per-endpoint\n * surface is the security boundary, not the noisy-neighbor preventer.\n *\n * @see `.cursor/plans/rate-limit-system-unification.md` (K-3, K-4, K-6, C-2, C-3)\n */\n\nimport 'reflect-metadata';\nimport { injectable, inject } from 'inversify';\nimport type { Request, Response } from 'express';\nimport {\n ErrorCustomMessageReference,\n ErrorType,\n ResourceOperationVariantType,\n WildoHeaderKeys,\n type RateLimitConfiguration,\n type ResourceType,\n} from '@wildo-ai/saas-models';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { RedisService } from '~wildo-backend-lib/databases/services/redis.service';\nimport { getClientIpFromRequest } from '~wildo-backend-lib/runtime/utils/request-client-ip.utils';\nimport { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';\nimport { resolveRateLimitEnvironmentMultiplier } from '~wildo-backend-lib/errors/utils/rate-limit-environment-relaxation.backend.utils';\nimport { ErrorBuilderBackendService } from './error-builder.backend.service';\n\n/**\n * Per-window enforcement record built from `RateLimitConfiguration`.\n *\n * - `name` is the Redis key suffix (`minute` / `hour` / `day`) and the\n * identifier used in JSDoc/log lines.\n * - `seconds` is the fixed-window length passed to `incrementRateLimit`.\n * Used as a fallback when Redis cannot report the remaining TTL.\n */\ninterface PolicyWindow {\n /**\n * Used as the trailing segment of the Redis key\n * (`<scope>:<clientId>:<name>`). Canonical names are `'minute'`,\n * `'hour'`, `'day'`. Custom windows derived from\n * `RateLimitConfiguration.customWindows` use `'custom:<seconds>s'`\n * (e.g. `'custom:300s'` for the 5-minute phone-verify window) — the\n * seconds value is embedded so two custom windows of different lengths\n * never collide on the same Redis key, and operators tailing Redis\n * traffic can read the window length straight from the key.\n */\n readonly name: string;\n readonly max: number;\n readonly seconds: number;\n}\n\n@injectable()\nexport class RateLimitBackendService {\n constructor(\n @inject(SAAS_SERVICE_TYPES.RedisService) private readonly redisService: RedisService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private readonly appConfigService: AppConfigurationService,\n ) {}\n\n /**\n * Low-level primitive: increment count for `key`, throw if exceeded.\n *\n * The K-3 escape-hatch surface — used directly only when the bucket key\n * is NOT cheaply derivable from HTTP-layer inputs. FOUR canonical sites\n * use this surface today (`sendSMSOTP` keying on a DB-resolved phone\n * number; `authenticatePassword` per-email + per-IP keying on a session-\n * stored email + IP captured at identify time; `sendEmailOTP`\n * keying on a session-resolved userId, preserving its OTP-specific 429\n * message via `messageOverride`; and the `authenticatePassword`\n * global lockout counter, using the `options` bridge added below to\n * swap the thrown error envelope\n * from a 429 `RATE_LIMIT` to a 401-shaped `AUTHENTICATION` +\n * `AUTHENTICATION_ACCOUNT_LOCKED` reference. Every other rate-limited\n * site should reach for `checkPolicy` (custom controllers) or the\n * resource-operation `rateLimit?` field (resource variants) instead —\n * those surfaces emit `X-RateLimit-*` headers and accept declarative\n * multi-window policies.\n *\n * @param key — identifier (e.g. `auth:reset:email:${email}`)\n * @param maxRequests — max allowed in window\n * @param windowSeconds — window duration in seconds\n * @param organizationId — optional tenant scope (folded into the Redis key)\n * @param messageOverride — optional custom error message for the\n * response. Defaults to the generic `'Too many requests. Please try\n * again later.'`. Pass a domain-specific message when the call site\n * has UX context the generic message would lose (e.g. the email-OTP\n * send cap migrated from `redisService.incrementRateLimit` in Step 7\n * F-23 sub-PR a — the original site shipped `'Too many OTP requests.\n * Please wait before requesting another code.'` so users understand\n * the wait is OTP-specific, not a global request cap; the lockout\n * site uses `'Account temporarily locked due to too many failed\n * attempts. Please try again later.'` to preserve its existing UX).\n * @param options — bridge parameters for callers that need to swap the\n * thrown error envelope (the K-3 escape-hatch's escape-hatch). Added\n * in the lockout-state-machine-modernization plan (Step 3.1) so the\n * global lockout counter — semantically a per-email cap, but\n * user-facing as an account-locked state — can ship the same\n * `ErrorType.AUTHENTICATION` + `AUTHENTICATION_ACCOUNT_LOCKED`\n * envelope its predecessor `_checkGlobalLockout` shipped, without\n * forking the primitive into two near-identical methods.\n * - `errorType` overrides the default `ErrorType.RATE_LIMIT` (the\n * lockout site uses `ErrorType.AUTHENTICATION` so it routes\n * through the same 401 handler chain as the existing\n * status-derived `AUTHENTICATION_ACCOUNT_LOCKED` throws).\n * - `customMessageReference` adds the `customMessageReference`\n * field to the built error (lockout uses\n * `AUTHENTICATION_ACCOUNT_LOCKED`). When omitted, the field is\n * not present in the built error options at all (preserves the\n * pre-bridge call shape for default K-3 sites).\n * - `contextExtra` adds extra fields to the error `context` (e.g.\n * `{ lockoutDurationMinutes: 30 }` for the lockout site).\n * Spread BEFORE the canonical `message` and `retryAfterSeconds`,\n * so those two always win on collision — use `messageOverride`\n * to swap the message, not `contextExtra.message`.\n * When `options` is omitted entirely (the only shape the 3 existing\n * K-3 sites use), the call is byte-identical to the pre-bridge\n * behavior: `ErrorType.RATE_LIMIT`, no `customMessageReference`,\n * bare `{ message, retryAfterSeconds }` context.\n */\n public async checkRateLimit(\n key: string,\n maxRequests: number,\n windowSeconds: number,\n organizationId?: string,\n messageOverride?: string,\n options?: {\n errorType?: ErrorType;\n customMessageReference?: ErrorCustomMessageReference;\n contextExtra?: Record<string, unknown>;\n },\n ): Promise<void> {\n const effectiveMaxRequests = maxRequests * this.resolveWindowMultiplier();\n const count = await this.redisService.incrementRateLimit(key, windowSeconds, organizationId);\n if (count > effectiveMaxRequests) {\n const retryAfterSeconds = await this.resolveRateLimitTtl(key, organizationId, windowSeconds);\n // Conditionally include `customMessageReference` so the built error\n // options object is byte-identical to the pre-bridge shape when\n // `options` is omitted (the default K-3 callers' contract).\n const buildOptions: {\n customMessageReference?: ErrorCustomMessageReference;\n context: Record<string, unknown>;\n } = {\n context: {\n ...options?.contextExtra,\n message: messageOverride ?? 'Too many requests. Please try again later.',\n retryAfterSeconds,\n },\n };\n if (options?.customMessageReference !== undefined) {\n buildOptions.customMessageReference = options.customMessageReference;\n }\n throw this.errorBuilder.buildError(\n options?.errorType ?? ErrorType.RATE_LIMIT,\n undefined,\n buildOptions,\n );\n }\n }\n\n /**\n * @wildo_source:part:start saas.backend.rate-limit-service.check-policy facet:layer:backend facet:family:rate-limit\n *\n * Declarative multi-window policy enforcement.\n *\n * Increments one Redis counter per declared window (so window accounting\n * stays consistent — a request that trips the per-minute window still\n * counts against the per-hour quota), then:\n *\n * - Writes `X-RateLimit-Limit` / `X-RateLimit-Remaining` / `X-RateLimit-Reset`\n * headers from the **tightest active window** (the one with the fewest\n * `remaining` slots). Matches the existing system-1 header contract (K-6).\n * - On 429, throws `ErrorType.RATE_LIMIT` with `retryAfterSeconds` from\n * the **latest tripped window**. Declared windows are AND-ed, so a retry\n * cannot succeed until every tripped counter has reset.\n *\n * Client identifier (the per-bucket key suffix, what makes one client's\n * counter independent from another's) defaults to `getClientIpFromRequest(req)`\n * — the canonical pre-auth identity at the controller seam, consistent\n * with the global HTTP limiter (system 1) which also keys on raw IP by\n * construction. Custom controllers that have already resolved a more\n * appropriate identity can pass `clientIdOverride` to bypass IP\n * derivation entirely:\n * - SCIM controller — `clientIdOverride: token._id` (per-token quota,\n * independent of which IP the IdP is calling from today).\n * - Authenticated user actions — `clientIdOverride: userId` (one user,\n * one bucket across all their devices/IPs — credential-stuffing-style\n * IP rotation can't bypass the per-user cap).\n * - Email-keyed flows (password reset, magic link) — `clientIdOverride:\n * email` (one email address, one bucket across all originating IPs).\n * The default IP-keyed mode is correct for pre-auth flows where no\n * better identity exists yet (the resource-controller pre-flight seam\n * via `checkPolicyForVariant`, anonymous-session init, etc.).\n *\n * `requestsPerMinute` / `requestsPerHour` / `requestsPerDay` AND any\n * entries in `customWindows` (D-3, Option A — for the rare endpoint\n * whose business semantics genuinely don't fit a minute / hour / day\n * grid, e.g. the SMS phone-verify family on a 5-minute window tied to\n * the OTP TTL) are all honored at this seam.\n *\n * @param req — express request. Used for IP extraction when\n * `clientIdOverride` is omitted; not read otherwise. Always required\n * so future enhancements (e.g. surfacing the IP in error context for\n * audit) don't need a signature change.\n * @param res — express response (headers written as side-effect)\n * @param policy — the declarative policy. A policy with no enforced\n * windows (all of `requestsPerMinute / Hour / Day` undefined and\n * `customWindows` either undefined or empty) is a no-op (no-policy\n * fast path; zero Redis traffic).\n * @param scopeKey — author-supplied namespace (e.g. `auth:password_change`,\n * `resource:INBOUND_CONTACTS:CREATE`, `scim:token`). Composed with the\n * client identifier to form the Redis key:\n * `${scopeKey}:${clientId}:${windowName}`.\n * @param organizationId — optional tenant scope. Forwarded to the underlying\n * `RedisService.incrementRateLimit` so per-tenant quotas don't collide\n * across orgs. Omit for single-tenant or pre-auth policies (the resource\n * pre-flight seam can't resolve a tenant yet by construction — C-5).\n * @param clientIdOverride — optional explicit client identifier. When\n * provided, replaces `getClientIpFromRequest(req)` as the per-bucket\n * key suffix. Use whenever the caller has resolved an authenticated\n * subject identifier (token id, user id, email) so the bucket can't\n * be bypassed by IP rotation.\n *\n * @remarks Import from `@wildo-ai/saas-backend-lib`.\n */\n /** @wildo_source:part:end saas.backend.rate-limit-service.check-policy */\n public async checkPolicy(\n req: Request,\n res: Response,\n policy: RateLimitConfiguration,\n scopeKey: string,\n organizationId?: string,\n clientIdOverride?: string,\n ): Promise<void> {\n const clientId = clientIdOverride ?? getClientIpFromRequest(req);\n const { tightestActive, latestTripped } = await this.evaluatePolicyWindows(policy, `${scopeKey}:${clientId}`, organizationId);\n\n if (tightestActive) {\n // F-9 compare-and-set guard. Multiple `checkPolicy` invocations can\n // run on the same response within a single request lifecycle — the\n // canonical case is a resource operation that BOTH carries a\n // declarative `rateLimit?` on its variant (enforced by the\n // pre-flight `checkPolicyForVariant` seam) AND triggers a\n // service-level call that runs its own `checkPolicy` (e.g.\n // `INBOUND_CONTACTS.CREATE` for an anonymous user → the\n // 5/min contact-create policy fires first, then\n // `createAnonymousUser`'s 10/min session-init policy fires).\n // Without this guard the second call would overwrite the first's\n // headers and the response would advertise the LOOSER policy,\n // hiding the binding constraint from the client. Preserve the\n // tighter (smaller `remaining`) window across calls so the\n // headers always reflect the binding quota.\n const existingRemainingHeader = res.getHeader(WildoHeaderKeys.RATE_LIMIT_REMAINING);\n const existingRemainingCandidate = existingRemainingHeader === undefined\n ? undefined\n : Number(existingRemainingHeader);\n const existingRemaining = existingRemainingCandidate === undefined || Number.isFinite(existingRemainingCandidate)\n ? existingRemainingCandidate\n : undefined;\n if (existingRemaining === undefined || tightestActive.remaining < existingRemaining) {\n res.setHeader(WildoHeaderKeys.RATE_LIMIT_LIMIT, String(tightestActive.max));\n res.setHeader(WildoHeaderKeys.RATE_LIMIT_REMAINING, String(tightestActive.remaining));\n res.setHeader(WildoHeaderKeys.RATE_LIMIT_RESET, String(tightestActive.resetSeconds));\n }\n }\n\n if (latestTripped) {\n // RFC 6585 `Retry-After` header — standard cue for clients/proxies\n // that don't parse the JSON error body. Set BEFORE throw so Express's\n // error middleware (which writes the body via `res.status(429).json`)\n // preserves it on the outbound response. Kept as a literal string\n // rather than a `WildoHeaderKeys` constant because `Retry-After` is\n // an IANA-registered header, not a Wildo-custom one; callers that\n // search the codebase will find it by its canonical spelling.\n // Same F-9 compare-and-set discipline as the `X-RateLimit-*` headers\n // above: when multiple `checkPolicy` calls trip on the same\n // response, prefer the LARGER hint because all active quotas must\n // recover before the request can succeed.\n const existingRetryHeader = res.getHeader('Retry-After');\n const existingRetryCandidate = existingRetryHeader === undefined\n ? undefined\n : Number(existingRetryHeader);\n const existingRetry = existingRetryCandidate === undefined || Number.isFinite(existingRetryCandidate)\n ? existingRetryCandidate\n : undefined;\n if (existingRetry === undefined || latestTripped.retryAfterSeconds > existingRetry) {\n res.setHeader('Retry-After', String(latestTripped.retryAfterSeconds));\n }\n throw this.errorBuilder.buildError(ErrorType.RATE_LIMIT, undefined, {\n customMessageReference: ErrorCustomMessageReference.RATE_LIMIT,\n context: {\n // diagnostic (log-only)\n retryAfterSeconds: latestTripped.retryAfterSeconds,\n },\n });\n }\n }\n\n /**\n * Enforce a declared policy for a caller that has NO express request/response —\n * the non-HTTP planes that dispatch a resource operation directly. There are TWO today, and\n * they do not share a core: the MCP `tools/call` plane\n * (`McpServerBackendService.assertOperationRateLimitPolicy`, plus any future transport that\n * re-uses that core) and the agent function-tool plane\n * (`assertDeclaredOperationRateLimit` in `function-tools.backend.definitions.ts`, reached from a\n * conversational turn and therefore from A2A). An earlier revision of this sentence named only\n * the first and framed the second as \"any future transport that re-uses\n * `McpServerBackendService`\" — which the function-tool plane does not, and that framing is part\n * of why it went unnoticed. Expect further planes, and expect them to arrive from elsewhere.\n *\n * ## Why a second entry point rather than a fabricated `req`/`res`\n *\n * {@link checkPolicy} is an HTTP-seam method in two load-bearing ways: it derives the\n * counter's client identifier from the request IP, and it publishes the outcome as\n * `X-RateLimit-*` / `Retry-After` RESPONSE HEADERS. Neither exists on a JSON-RPC tool\n * dispatch — the MCP core is deliberately transport-agnostic, so it holds no `res` to\n * write headers onto, and the IP is the wrong identity axis for a credentialed agent\n * anyway (see the subject-key discussion at the call site). Handing it a stub `req`/`res`\n * would make the throttle key on the literal string the IP extractor returns for a\n * request-shaped object it was never given — i.e. ONE bucket for every agent on the\n * planet, which is worse than no enforcement because it looks enforced.\n *\n * So the WINDOW ARITHMETIC is shared (`evaluatePolicyWindows` — the AND semantics, the\n * environment relaxation, the custom-window dedupe, the latest-tripped `Retry-After`\n * pick) and only the identity + reporting halves differ. There must never be a second\n * implementation of \"what does this policy mean\"; there are legitimately two answers to\n * \"who is the client, and how do we tell them\".\n *\n * ## Failure posture: the SAME as HTTP, deliberately\n *\n * A limiter outage propagates rather than being swallowed, exactly as it does for\n * {@link checkPolicy} / {@link checkPolicyForVariant}. An AUTHORED per-endpoint policy is\n * a statement the application made about that endpoint; degrading it to \"unbounded\" on\n * one plane and to a 500 on the other would make the same declaration mean two different\n * things. (Contrast `assertExternalTurnWithinRate`, the framework-default per-principal\n * abuse throttle, which fails OPEN — nobody declared it, so it must never be the reason\n * an external endpoint stops working.)\n *\n * @param policy — the declared policy. No enforced window ⇒ no-op, zero Redis traffic.\n * @param scopeKey — author-supplied namespace, composed with `subjectKey` into the Redis key.\n * @param subjectKey — WHO is counted. The caller owns this choice; it replaces the IP\n * that {@link checkPolicy} would derive, and it must be a server-verified identity —\n * never a value the caller (or a model) supplied.\n * @param organizationId — optional tenant scope forwarded to the Redis key namespace.\n * @throws RATE_LIMIT (429) carrying `context.retryAfterSeconds`, the same envelope the\n * HTTP seam throws, so one refusal vocabulary covers both planes.\n */\n public async checkPolicyForSubject(\n policy: RateLimitConfiguration,\n scopeKey: string,\n subjectKey: string,\n organizationId?: string,\n ): Promise<void> {\n const { latestTripped } = await this.evaluatePolicyWindows(policy, `${scopeKey}:${subjectKey}`, organizationId);\n if (!latestTripped) {\n return;\n }\n throw this.errorBuilder.buildError(ErrorType.RATE_LIMIT, undefined, {\n customMessageReference: ErrorCustomMessageReference.RATE_LIMIT,\n context: {\n // Diagnostic (log-only) on the HTTP seam; on a header-less plane it is ALSO the only\n // way the transport can learn the retry hint, so it is read back off the thrown error.\n retryAfterSeconds: latestTripped.retryAfterSeconds,\n },\n });\n }\n\n /**\n * Count one request against every window a policy declares, and report the two facts\n * every caller needs: the TIGHTEST still-active window (for `X-RateLimit-*`) and the\n * LATEST tripped one (for `Retry-After`).\n *\n * Extracted from {@link checkPolicy} when {@link checkPolicyForSubject} was added, so the\n * meaning of a declared policy has exactly one implementation. Declared windows are\n * AND-ed — recovery requires EVERY exceeded window to reset, not just the shortest — which\n * is why the retry hint is the latest reset rather than the first trip.\n *\n * A policy with no enforced window yields `{}` without touching Redis (the no-policy fast\n * path the resource-variant seam relies on, since most operations declare nothing).\n *\n * @param identifier — `${scopeKey}:${clientOrSubjectId}`; the window name is appended per key.\n */\n private async evaluatePolicyWindows(\n policy: RateLimitConfiguration,\n identifier: string,\n organizationId?: string,\n ): Promise<{\n tightestActive?: { max: number; remaining: number; resetSeconds: number };\n latestTripped?: { retryAfterSeconds: number };\n }> {\n const windows = this.deriveWindows(policy);\n if (windows.length === 0) {\n return {};\n }\n\n let tightestActive: { max: number; remaining: number; resetSeconds: number } | undefined;\n let latestTripped: { retryAfterSeconds: number } | undefined;\n\n for (const window of windows) {\n const key = `${identifier}:${window.name}`;\n const count = await this.redisService.incrementRateLimit(key, window.seconds, organizationId);\n const resetSeconds = await this.resolveRateLimitTtl(key, organizationId, window.seconds);\n const remaining = Math.max(0, window.max - count);\n\n if (count > window.max) {\n if (!latestTripped || resetSeconds > latestTripped.retryAfterSeconds) {\n latestTripped = { retryAfterSeconds: resetSeconds };\n }\n }\n\n if (!tightestActive || remaining < tightestActive.remaining) {\n tightestActive = { max: window.max, remaining, resetSeconds };\n }\n }\n\n return { tightestActive, latestTripped };\n }\n\n /**\n * Pre-flight enforcement for resource operations — the consumer behind\n * the `rateLimit?` field on `API_CALL` / `API_CALL_WITH_CALLBACK` variants.\n *\n * Called from `ControllerResourceBackendService.doOperation` BEFORE\n * execution-context creation, request-data validation, and authorization\n * (C-2). At this seam the authenticated identity is unknown by\n * construction, so the client identifier MUST be the IP — there is no\n * authenticated-user alternative.\n *\n * Early-returns (zero Redis traffic) when:\n * - The variant has no `rateLimit?` policy (the common case until\n * per-endpoint policies are adopted), OR\n * - The variant is not an HTTP variant (defensive guard — `doOperation`\n * today only routes API_CALL / API_CALL_WITH_CALLBACK, but the type\n * surface accepts the broader operation union).\n *\n * Auto-derives `scopeKey = resource:${resourceIdentifier}:${operationIdentifier}`\n * — keeps resource configurations free of bespoke Redis-key strings (K-4).\n *\n * @param req — express request\n * @param res — express response (for `X-RateLimit-*` header writes)\n * @param variant — the resolved operation about to execute\n */\n public async checkPolicyForVariant(\n req: Request,\n res: Response,\n variant: {\n readonly variantType: ResourceOperationVariantType;\n readonly resourceIdentifier: ResourceType;\n // The resolved operation type uses generic enum constraints\n // (`TCustomOperationEnum | TCoreOperationEnum`, both bounded by\n // `Record<string, string>`); at runtime the value is always a string\n // (the enum's value, not the enum object). `unknown` keeps the\n // structural surface broad enough to accept any operation variant\n // shape; the value is stringified for the Redis scope key.\n readonly operationIdentifier: unknown;\n readonly rateLimit?: RateLimitConfiguration;\n },\n ): Promise<void> {\n if (!variant.rateLimit) {\n return;\n }\n if (\n variant.variantType !== ResourceOperationVariantType.API_CALL\n && variant.variantType !== ResourceOperationVariantType.API_CALL_WITH_CALLBACK\n ) {\n return;\n }\n\n const scopeKey = `resource:${String(variant.resourceIdentifier)}:${String(variant.operationIdentifier)}`;\n await this.checkPolicy(req, res, variant.rateLimit, scopeKey);\n }\n\n /**\n * Build the enforced-window list from a declared policy. Includes\n * `customWindows` after the canonical three so AND-semantics treat\n * them identically to the named windows (D-3, Option A — custom\n * windows participate in the same `tightestActive` / `latestTripped`\n * picks as the canonical ones).\n *\n * Custom-window dedupe (F-16, PR 7-D-3 review fix): when an author\n * accidentally declares two `customWindows` entries with the same\n * `windowSeconds` (e.g. `[{ rpw: 3, ws: 300 }, { rpw: 5, ws: 300 }]`),\n * both would derive the SAME Redis key (`<scope>:<id>:custom:300s`)\n * and a single client request would silently double-increment the\n * counter, halving the effective cap. We resolve the misconfig\n * deterministically: keep the entry with the SMALLEST `requestsPerWindow`\n * (most restrictive interpretation = safest for the protected resource)\n * and emit a `console.warn` so authors see the misconfig in logs. Any\n * canonical-window collisions (e.g. `{ requestsPerMinute: 5,\n * customWindows: [{ rpw: 3, ws: 60 }] }`) are NOT deduped — they\n * derive different key suffixes (`:minute` vs `:custom:60s`) and\n * coexist correctly; the JSDoc on `RateLimitConfigurationSchema`\n * steers authors away from this awkward shape, but it isn't broken.\n */\n private deriveWindows(policy: RateLimitConfiguration): PolicyWindow[] {\n const multiplier = this.resolveWindowMultiplier();\n const windows: PolicyWindow[] = [];\n if (policy.requestsPerMinute !== undefined) {\n windows.push({ name: 'minute', max: policy.requestsPerMinute * multiplier, seconds: 60 });\n }\n if (policy.requestsPerHour !== undefined) {\n windows.push({ name: 'hour', max: policy.requestsPerHour * multiplier, seconds: 3600 });\n }\n if (policy.requestsPerDay !== undefined) {\n windows.push({ name: 'day', max: policy.requestsPerDay * multiplier, seconds: 86400 });\n }\n if (policy.customWindows && policy.customWindows.length > 0) {\n // Map by `windowSeconds`; on collision keep the smallest `max`\n // (most restrictive) and warn. Insertion order is preserved by\n // `Map`, so the canonical-then-custom emit order downstream is\n // unchanged for non-colliding cases.\n const byWindowSeconds = new Map<number, { max: number; seconds: number }>();\n for (const custom of policy.customWindows) {\n const existing = byWindowSeconds.get(custom.windowSeconds);\n if (existing === undefined) {\n byWindowSeconds.set(custom.windowSeconds, {\n max: custom.requestsPerWindow,\n seconds: custom.windowSeconds,\n });\n } else if (custom.requestsPerWindow < existing.max) {\n // eslint-disable-next-line no-console\n console.warn(\n '[rate-limit] Duplicate customWindows.windowSeconds detected; keeping the smaller (more restrictive) requestsPerWindow.',\n { windowSeconds: custom.windowSeconds, kept: custom.requestsPerWindow, dropped: existing.max },\n );\n byWindowSeconds.set(custom.windowSeconds, {\n max: custom.requestsPerWindow,\n seconds: custom.windowSeconds,\n });\n } else {\n // eslint-disable-next-line no-console\n console.warn(\n '[rate-limit] Duplicate customWindows.windowSeconds detected; keeping the smaller (more restrictive) requestsPerWindow.',\n { windowSeconds: custom.windowSeconds, kept: existing.max, dropped: custom.requestsPerWindow },\n );\n }\n }\n for (const [, custom] of byWindowSeconds) {\n windows.push({\n name: `custom:${custom.seconds}s`,\n max: custom.max * multiplier,\n seconds: custom.seconds,\n });\n }\n }\n return windows;\n }\n\n /**\n * Non-production window-max relaxation for every policy this service enforces\n * (register, login, MFA, magic-link, SCIM, marketing public endpoints, resource\n * `rateLimit?` variants — every `checkPolicy` / `checkPolicyForVariant` caller,\n * K-3/K-4).\n *\n * The branch itself lives in\n * {@link resolveRateLimitEnvironmentMultiplier} — this service is one of SIX\n * abuse-throttle sites in the engine and used to own a private copy of the\n * constant, which is exactly why the other five never got the relaxation. Do not\n * re-inline it here.\n */\n private resolveWindowMultiplier(): number {\n return resolveRateLimitEnvironmentMultiplier(this.appConfigService.applicationEnv);\n }\n\n private async resolveRateLimitTtl(\n identifier: string,\n organizationId: string | undefined,\n fallbackSeconds: number,\n ): Promise<number> {\n const getRateLimitTtl = (this.redisService as RedisService & {\n getRateLimitTtl?: (identifier: string, organizationId?: string) => Promise<number>;\n }).getRateLimitTtl;\n if (!getRateLimitTtl) {\n return fallbackSeconds;\n }\n\n try {\n const ttl = await getRateLimitTtl.call(this.redisService, identifier, organizationId);\n return ttl >= 0 ? ttl : fallbackSeconds;\n } catch {\n return fallbackSeconds;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rate-limit.backend.service.js","sourceRoot":"","sources":["../../../../src/errors/services/rate-limit.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Rate Limit Backend Service — CORE-9\n *\n * Single source of truth for controller-level rate limit checks. Three public\n * surfaces, layered:\n *\n * 1. `checkRateLimit(key, max, windowSeconds, organizationId?, messageOverride?, options?)`\n * — low-level primitive (fixed window via atomic Redis INCR+EXPIRE). The K-3\n * ESCAPE-HATCH surface, reserved for the FOUR engine-side call sites\n * (post-PR-8 + Step 7 F-23 sub-PR a + lockout modernization) where the\n * bucket key is NOT cheaply\n * derivable from HTTP-layer inputs:\n * - `AuthenticationOrchestrator.sendSMSOTP` (DB-resolved phone number),\n * - `AuthenticationOrchestrator.authenticatePassword` per-email + per-IP\n * (session-stored email + identify-time IP),\n * - `AuthenticationOrchestrator.sendEmailOTP` (session-resolved\n * userId; migrated from `redisService.incrementRateLimit` in Step 7),\n * - `AuthenticationOrchestrator.authenticatePassword` global lockout\n * counter (per-session email before `verifyPassword(...)`).\n * The lockout caller uses the `options` bridge added in Step 3.1 to swap\n * the thrown\n * error envelope from a 429 `RATE_LIMIT` to a 401 `AUTHENTICATION` +\n * `AUTHENTICATION_ACCOUNT_LOCKED`. The optional `messageOverride`\n * parameter preserves domain-specific UX (canonical use: the OTP-\n * specific phrasing the email-OTP site shipped pre-migration; the\n * lockout site's existing \"Account temporarily locked...\" phrasing).\n * The optional `options` parameter (`errorType` / `customMessageReference`\n * / `contextExtra`) lets the lockout-style caller mint a non-RATE_LIMIT\n * error envelope without forking the primitive; when omitted, behavior\n * is byte-identical to the pre-bridge call shape. Every other\n * rate-limited site reaches for `checkPolicy` or the resource-operation\n * `rateLimit?` field.\n *\n * 2. `checkPolicy(req, res, policy, scopeKey, organizationId?, clientIdOverride?)`\n * — declarative consumer for custom controllers (auth, SCIM, marketing\n * public endpoints). Issues one `RedisService.incrementRateLimit` call\n * per declared window (NOT a `checkRateLimit` call — `checkPolicy` needs\n * the post-increment count to compute `remaining` for headers, and must\n * always increment every window so quota accounting stays consistent\n * across windows; `checkRateLimit` would short-circuit the loop on the\n * first trip) and writes `X-RateLimit-*` headers from the tightest\n * active window. `clientIdOverride` swaps the default IP-keyed bucket\n * for an authenticated subject identifier (`token._id`, `userId`,\n * normalized email/phone) so IP rotation can't bypass per-subject caps.\n *\n * 3. `checkPolicyForVariant(req, res, variant)` — pre-flight consumer used\n * by `ControllerResourceBackendService.doOperation` BEFORE\n * execution-context creation, validation, and authorization. Early-returns\n * when the variant declares no `rateLimit?` policy (zero Redis traffic\n * on the no-policy fast path).\n *\n * Fail-closed (C-3): the underlying `RedisService.incrementRateLimit` throws\n * `ErrorType.DATABASE` when Redis is unavailable. Both `checkPolicy` and\n * `checkPolicyForVariant` propagate that error rather than silently passing\n * traffic. The global HTTP limiter\n * (`http-server.backend.service.ts:setupRateLimit`) keeps its in-memory\n * fail-open Map as the safety net at the perimeter — the per-endpoint\n * surface is the security boundary, not the noisy-neighbor preventer.\n *\n * @see `.cursor/plans/rate-limit-system-unification.md` (K-3, K-4, K-6, C-2, C-3)\n */\n\nimport 'reflect-metadata';\nimport { injectable, inject } from 'inversify';\nimport type { Request, Response } from 'express';\nimport {\n ErrorCustomMessageReference,\n ErrorType,\n ResourceOperationVariantType,\n WildoHeaderKeys,\n type RateLimitConfiguration,\n type ResourceType,\n} from '@wildo-ai/saas-models';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { RedisService } from '~wildo-backend-lib/databases/services/redis.service';\nimport { getClientIpFromRequest } from '~wildo-backend-lib/runtime/utils/request-client-ip.utils';\nimport { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';\nimport { resolveRateLimitEnvironmentMultiplier } from '~wildo-backend-lib/errors/utils/rate-limit-environment-relaxation.backend.utils';\nimport { ErrorBuilderBackendService } from './error-builder.backend.service';\n\n/**\n * Per-window enforcement record built from `RateLimitConfiguration`.\n *\n * - `name` is the Redis key suffix (`minute` / `hour` / `day`) and the\n * identifier used in JSDoc/log lines.\n * - `seconds` is the fixed-window length passed to `incrementRateLimit`.\n * Used as a fallback when Redis cannot report the remaining TTL.\n */\ninterface PolicyWindow {\n /**\n * Used as the trailing segment of the Redis key\n * (`<scope>:<clientId>:<name>`). Canonical names are `'minute'`,\n * `'hour'`, `'day'`. Custom windows derived from\n * `RateLimitConfiguration.customWindows` use `'custom:<seconds>s'`\n * (e.g. `'custom:300s'` for the 5-minute phone-verify window) — the\n * seconds value is embedded so two custom windows of different lengths\n * never collide on the same Redis key, and operators tailing Redis\n * traffic can read the window length straight from the key.\n */\n readonly name: string;\n readonly max: number;\n readonly seconds: number;\n}\n\n@injectable()\nexport class RateLimitBackendService {\n constructor(\n @inject(SAAS_SERVICE_TYPES.RedisService) private readonly redisService: RedisService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private readonly appConfigService: AppConfigurationService,\n ) {}\n\n /**\n * Low-level primitive: increment count for `key`, throw if exceeded.\n *\n * The K-3 escape-hatch surface — used directly only when the bucket key\n * is NOT cheaply derivable from HTTP-layer inputs. FOUR canonical sites\n * use this surface today (`sendSMSOTP` keying on a DB-resolved phone\n * number; `authenticatePassword` per-email + per-IP keying on a session-\n * stored email + IP captured at identify time; `sendEmailOTP`\n * keying on a session-resolved userId, preserving its OTP-specific 429\n * message via `messageOverride`; and the `authenticatePassword`\n * global lockout counter, using the `options` bridge added below to\n * swap the thrown error envelope\n * from a 429 `RATE_LIMIT` to a 401-shaped `AUTHENTICATION` +\n * `AUTHENTICATION_ACCOUNT_LOCKED` reference. Every other rate-limited\n * site should reach for `checkPolicy` (custom controllers) or the\n * resource-operation `rateLimit?` field (resource variants) instead —\n * those surfaces emit `X-RateLimit-*` headers and accept declarative\n * multi-window policies.\n *\n * @param key — identifier (e.g. `auth:reset:email:${email}`)\n * @param maxRequests — max allowed in window\n * @param windowSeconds — window duration in seconds\n * @param organizationId — optional tenant scope (folded into the Redis key)\n * @param messageOverride — optional custom error message for the\n * response. Defaults to the generic `'Too many requests. Please try\n * again later.'`. Pass a domain-specific message when the call site\n * has UX context the generic message would lose (e.g. the email-OTP\n * send cap migrated from `redisService.incrementRateLimit` in Step 7\n * F-23 sub-PR a — the original site shipped `'Too many OTP requests.\n * Please wait before requesting another code.'` so users understand\n * the wait is OTP-specific, not a global request cap; the lockout\n * site uses `'Account temporarily locked due to too many failed\n * attempts. Please try again later.'` to preserve its existing UX).\n * @param options — bridge parameters for callers that need to swap the\n * thrown error envelope (the K-3 escape-hatch's escape-hatch). Added\n * in the lockout-state-machine-modernization plan (Step 3.1) so the\n * global lockout counter — semantically a per-email cap, but\n * user-facing as an account-locked state — can ship the same\n * `ErrorType.AUTHENTICATION` + `AUTHENTICATION_ACCOUNT_LOCKED`\n * envelope its predecessor `_checkGlobalLockout` shipped, without\n * forking the primitive into two near-identical methods.\n * - `errorType` overrides the default `ErrorType.RATE_LIMIT` (the\n * lockout site uses `ErrorType.AUTHENTICATION` so it routes\n * through the same 401 handler chain as the existing\n * status-derived `AUTHENTICATION_ACCOUNT_LOCKED` throws).\n * - `customMessageReference` adds the `customMessageReference`\n * field to the built error (lockout uses\n * `AUTHENTICATION_ACCOUNT_LOCKED`). When omitted, the field is\n * not present in the built error options at all (preserves the\n * pre-bridge call shape for default K-3 sites).\n * - `contextExtra` adds extra fields to the error `context` (e.g.\n * `{ lockoutDurationMinutes: 30 }` for the lockout site).\n * Spread BEFORE the canonical `message` and `retryAfterSeconds`,\n * so those two always win on collision — use `messageOverride`\n * to swap the message, not `contextExtra.message`.\n * When `options` is omitted entirely (the only shape the 3 existing\n * K-3 sites use), the call is byte-identical to the pre-bridge\n * behavior: `ErrorType.RATE_LIMIT`, no `customMessageReference`,\n * bare `{ message, retryAfterSeconds }` context.\n */\n public async checkRateLimit(\n key: string,\n maxRequests: number,\n windowSeconds: number,\n organizationId?: string,\n messageOverride?: string,\n options?: {\n errorType?: ErrorType;\n customMessageReference?: ErrorCustomMessageReference;\n contextExtra?: Record<string, unknown>;\n },\n ): Promise<void> {\n const effectiveMaxRequests = maxRequests * this.resolveWindowMultiplier();\n const count = await this.redisService.incrementRateLimit(key, windowSeconds, organizationId);\n if (count > effectiveMaxRequests) {\n const retryAfterSeconds = await this.resolveRateLimitTtl(key, organizationId, windowSeconds);\n // Conditionally include `customMessageReference` so the built error\n // options object is byte-identical to the pre-bridge shape when\n // `options` is omitted (the default K-3 callers' contract).\n const buildOptions: {\n customMessageReference?: ErrorCustomMessageReference;\n context: Record<string, unknown>;\n } = {\n context: {\n ...options?.contextExtra,\n message: messageOverride ?? 'Too many requests. Please try again later.',\n retryAfterSeconds,\n },\n };\n if (options?.customMessageReference !== undefined) {\n buildOptions.customMessageReference = options.customMessageReference;\n }\n throw this.errorBuilder.buildError(\n options?.errorType ?? ErrorType.RATE_LIMIT,\n undefined,\n buildOptions,\n );\n }\n }\n\n /**\n * @wildo_source:part:start saas.backend.rate-limit-service.check-policy facet:layer:backend facet:family:rate-limit\n *\n * Declarative multi-window policy enforcement.\n *\n * Increments one Redis counter per declared window (so window accounting\n * stays consistent — a request that trips the per-minute window still\n * counts against the per-hour quota), then:\n *\n * - Writes `X-RateLimit-Limit` / `X-RateLimit-Remaining` / `X-RateLimit-Reset`\n * headers from the **tightest active window** (the one with the fewest\n * `remaining` slots). Matches the existing system-1 header contract (K-6).\n * - On 429, throws `ErrorType.RATE_LIMIT` with `retryAfterSeconds` from\n * the **latest tripped window**. Declared windows are AND-ed, so a retry\n * cannot succeed until every tripped counter has reset.\n *\n * Client identifier (the per-bucket key suffix, what makes one client's\n * counter independent from another's) defaults to `getClientIpFromRequest(req)`\n * — the canonical pre-auth identity at the controller seam, consistent\n * with the global HTTP limiter (system 1) which also keys on raw IP by\n * construction. Custom controllers that have already resolved a more\n * appropriate identity can pass `clientIdOverride` to bypass IP\n * derivation entirely:\n * - SCIM controller — `clientIdOverride: token._id` (per-token quota,\n * independent of which IP the IdP is calling from today).\n * - Authenticated user actions — `clientIdOverride: userId` (one user,\n * one bucket across all their devices/IPs — credential-stuffing-style\n * IP rotation can't bypass the per-user cap).\n * - Email-keyed flows (password reset, magic link) — `clientIdOverride:\n * email` (one email address, one bucket across all originating IPs).\n * The default IP-keyed mode is correct for pre-auth flows where no\n * better identity exists yet (the resource-controller pre-flight seam\n * via `checkPolicyForVariant`, anonymous-session init, etc.).\n *\n * `requestsPerMinute` / `requestsPerHour` / `requestsPerDay` AND any\n * entries in `customWindows` (D-3, Option A — for the rare endpoint\n * whose business semantics genuinely don't fit a minute / hour / day\n * grid, e.g. the SMS phone-verify family on a 5-minute window tied to\n * the OTP TTL) are all honored at this seam.\n *\n * @param req — express request. Used for IP extraction when\n * `clientIdOverride` is omitted; not read otherwise. Always required\n * so future enhancements (e.g. surfacing the IP in error context for\n * audit) don't need a signature change.\n * @param res — express response (headers written as side-effect)\n * @param policy — the declarative policy. A policy with no enforced\n * windows (all of `requestsPerMinute / Hour / Day` undefined and\n * `customWindows` either undefined or empty) is a no-op (no-policy\n * fast path; zero Redis traffic).\n * @param scopeKey — author-supplied namespace (e.g. `auth:password_change`,\n * `resource:INBOUND_CONTACTS:CREATE`, `scim:token`). Composed with the\n * client identifier to form the Redis key:\n * `${scopeKey}:${clientId}:${windowName}`.\n * @param organizationId — optional tenant scope. Forwarded to the underlying\n * `RedisService.incrementRateLimit` so per-tenant quotas don't collide\n * across orgs. Omit for single-tenant or pre-auth policies (the resource\n * pre-flight seam can't resolve a tenant yet by construction — C-5).\n * @param clientIdOverride — optional explicit client identifier. When\n * provided, replaces `getClientIpFromRequest(req)` as the per-bucket\n * key suffix. Use whenever the caller has resolved an authenticated\n * subject identifier (token id, user id, email) so the bucket can't\n * be bypassed by IP rotation.\n *\n * @remarks Import from `@wildo-ai/saas-backend-lib`.\n */\n /** @wildo_source:part:end saas.backend.rate-limit-service.check-policy */\n public async checkPolicy(\n req: Request,\n res: Response,\n policy: RateLimitConfiguration,\n scopeKey: string,\n organizationId?: string,\n clientIdOverride?: string,\n ): Promise<void> {\n const clientId = clientIdOverride ?? getClientIpFromRequest(req);\n const { tightestActive, latestTripped } = await this.evaluatePolicyWindows(policy, `${scopeKey}:${clientId}`, organizationId);\n\n if (tightestActive) {\n // F-9 compare-and-set guard. Multiple `checkPolicy` invocations can\n // run on the same response within a single request lifecycle — the\n // canonical case is a resource operation that BOTH carries a\n // declarative `rateLimit?` on its variant (enforced by the\n // pre-flight `checkPolicyForVariant` seam) AND triggers a\n // service-level call that runs its own `checkPolicy` (e.g.\n // `INBOUND_CONTACTS.CREATE` for an anonymous user → the\n // 5/min contact-create policy fires first, then\n // `createAnonymousUser`'s 10/min session-init policy fires).\n // Without this guard the second call would overwrite the first's\n // headers and the response would advertise the LOOSER policy,\n // hiding the binding constraint from the client. Preserve the\n // tighter (smaller `remaining`) window across calls so the\n // headers always reflect the binding quota.\n const existingRemainingHeader = res.getHeader(WildoHeaderKeys.RATE_LIMIT_REMAINING);\n const existingRemainingCandidate = existingRemainingHeader === undefined\n ? undefined\n : Number(existingRemainingHeader);\n const existingRemaining = existingRemainingCandidate === undefined || Number.isFinite(existingRemainingCandidate)\n ? existingRemainingCandidate\n : undefined;\n if (existingRemaining === undefined || tightestActive.remaining < existingRemaining) {\n res.setHeader(WildoHeaderKeys.RATE_LIMIT_LIMIT, String(tightestActive.max));\n res.setHeader(WildoHeaderKeys.RATE_LIMIT_REMAINING, String(tightestActive.remaining));\n res.setHeader(WildoHeaderKeys.RATE_LIMIT_RESET, String(tightestActive.resetSeconds));\n }\n }\n\n if (latestTripped) {\n // RFC 6585 `Retry-After` header — standard cue for clients/proxies\n // that don't parse the JSON error body. Set BEFORE throw so Express's\n // error middleware (which writes the body via `res.status(429).json`)\n // preserves it on the outbound response. Kept as a literal string\n // rather than a `WildoHeaderKeys` constant because `Retry-After` is\n // an IANA-registered header, not a Wildo-custom one; callers that\n // search the codebase will find it by its canonical spelling.\n // Same F-9 compare-and-set discipline as the `X-RateLimit-*` headers\n // above: when multiple `checkPolicy` calls trip on the same\n // response, prefer the LARGER hint because all active quotas must\n // recover before the request can succeed.\n const existingRetryHeader = res.getHeader('Retry-After');\n const existingRetryCandidate = existingRetryHeader === undefined\n ? undefined\n : Number(existingRetryHeader);\n const existingRetry = existingRetryCandidate === undefined || Number.isFinite(existingRetryCandidate)\n ? existingRetryCandidate\n : undefined;\n if (existingRetry === undefined || latestTripped.retryAfterSeconds > existingRetry) {\n res.setHeader('Retry-After', String(latestTripped.retryAfterSeconds));\n }\n throw this.errorBuilder.buildError(ErrorType.RATE_LIMIT, undefined, {\n customMessageReference: ErrorCustomMessageReference.RATE_LIMIT,\n context: {\n // diagnostic (log-only)\n retryAfterSeconds: latestTripped.retryAfterSeconds,\n },\n });\n }\n }\n\n /**\n * Enforce a declared policy for a caller that has NO express request/response —\n * the non-HTTP planes that dispatch a resource operation directly. There are TWO today, and\n * they do not share a core: the MCP `tools/call` plane\n * (`McpServerBackendService.assertOperationRateLimitPolicy`, plus any future transport that\n * re-uses that core) and the agent function-tool plane\n * (`assertDeclaredOperationRateLimit` in `function-tools.backend.definitions.ts`, reached from a\n * conversational turn and therefore from A2A). An earlier revision of this sentence named only\n * the first and framed the second as \"any future transport that re-uses\n * `McpServerBackendService`\" — which the function-tool plane does not, and that framing is part\n * of why it went unnoticed. Expect further planes, and expect them to arrive from elsewhere.\n *\n * ## Why a second entry point rather than a fabricated `req`/`res`\n *\n * {@link checkPolicy} is an HTTP-seam method in two load-bearing ways: it derives the\n * counter's client identifier from the request IP, and it publishes the outcome as\n * `X-RateLimit-*` / `Retry-After` RESPONSE HEADERS. Neither exists on a JSON-RPC tool\n * dispatch — the MCP core is deliberately transport-agnostic, so it holds no `res` to\n * write headers onto, and the IP is the wrong identity axis for a credentialed agent\n * anyway (see the subject-key discussion at the call site). Handing it a stub `req`/`res`\n * would make the throttle key on the literal string the IP extractor returns for a\n * request-shaped object it was never given — i.e. ONE bucket for every agent on the\n * planet, which is worse than no enforcement because it looks enforced.\n *\n * So the WINDOW ARITHMETIC is shared (`evaluatePolicyWindows` — the AND semantics, the\n * environment relaxation, the custom-window dedupe, the latest-tripped `Retry-After`\n * pick) and only the identity + reporting halves differ. There must never be a second\n * implementation of \"what does this policy mean\"; there are legitimately two answers to\n * \"who is the client, and how do we tell them\".\n *\n * ## Failure posture: the SAME as HTTP, deliberately\n *\n * A limiter outage propagates rather than being swallowed, exactly as it does for\n * {@link checkPolicy} / {@link checkPolicyForVariant}. An AUTHORED per-endpoint policy is\n * a statement the application made about that endpoint; degrading it to \"unbounded\" on\n * one plane and to a 500 on the other would make the same declaration mean two different\n * things. (Contrast `assertExternalTurnWithinRate`, the framework-default per-principal\n * abuse throttle, which fails OPEN — nobody declared it, so it must never be the reason\n * an external endpoint stops working.)\n *\n * @param policy — the declared policy. No enforced window ⇒ no-op, zero Redis traffic.\n * @param scopeKey — author-supplied namespace, composed with `subjectKey` into the Redis key.\n * @param subjectKey — WHO is counted. The caller owns this choice; it replaces the IP\n * that {@link checkPolicy} would derive, and it must be a server-verified identity —\n * never a value the caller (or a model) supplied.\n * @param organizationId — optional tenant scope forwarded to the Redis key namespace.\n * @throws RATE_LIMIT (429) carrying `context.retryAfterSeconds`, the same envelope the\n * HTTP seam throws, so one refusal vocabulary covers both planes.\n */\n public async checkPolicyForSubject(\n policy: RateLimitConfiguration,\n scopeKey: string,\n subjectKey: string,\n organizationId?: string,\n ): Promise<void> {\n const { latestTripped } = await this.evaluatePolicyWindows(policy, `${scopeKey}:${subjectKey}`, organizationId);\n if (!latestTripped) {\n return;\n }\n throw this.errorBuilder.buildError(ErrorType.RATE_LIMIT, undefined, {\n customMessageReference: ErrorCustomMessageReference.RATE_LIMIT,\n context: {\n // Diagnostic (log-only) on the HTTP seam; on a header-less plane it is ALSO the only\n // way the transport can learn the retry hint, so it is read back off the thrown error.\n retryAfterSeconds: latestTripped.retryAfterSeconds,\n },\n });\n }\n\n /**\n * Count one request against every window a policy declares, and report the two facts\n * every caller needs: the TIGHTEST still-active window (for `X-RateLimit-*`) and the\n * LATEST tripped one (for `Retry-After`).\n *\n * Extracted from {@link checkPolicy} when {@link checkPolicyForSubject} was added, so the\n * meaning of a declared policy has exactly one implementation. Declared windows are\n * AND-ed — recovery requires EVERY exceeded window to reset, not just the shortest — which\n * is why the retry hint is the latest reset rather than the first trip.\n *\n * A policy with no enforced window yields `{}` without touching Redis (the no-policy fast\n * path the resource-variant seam relies on, since most operations declare nothing).\n *\n * @param identifier — `${scopeKey}:${clientOrSubjectId}`; the window name is appended per key.\n */\n private async evaluatePolicyWindows(\n policy: RateLimitConfiguration,\n identifier: string,\n organizationId?: string,\n ): Promise<{\n tightestActive?: { max: number; remaining: number; resetSeconds: number };\n latestTripped?: { retryAfterSeconds: number };\n }> {\n const windows = this.deriveWindows(policy);\n if (windows.length === 0) {\n return {};\n }\n\n let tightestActive: { max: number; remaining: number; resetSeconds: number } | undefined;\n let latestTripped: { retryAfterSeconds: number } | undefined;\n\n for (const window of windows) {\n const key = `${identifier}:${window.name}`;\n const count = await this.redisService.incrementRateLimit(key, window.seconds, organizationId);\n const resetSeconds = await this.resolveRateLimitTtl(key, organizationId, window.seconds);\n const remaining = Math.max(0, window.max - count);\n\n if (count > window.max) {\n if (!latestTripped || resetSeconds > latestTripped.retryAfterSeconds) {\n latestTripped = { retryAfterSeconds: resetSeconds };\n }\n }\n\n if (!tightestActive || remaining < tightestActive.remaining) {\n tightestActive = { max: window.max, remaining, resetSeconds };\n }\n }\n\n return { tightestActive, latestTripped };\n }\n\n /**\n * Pre-flight enforcement for resource operations — the consumer behind\n * the `rateLimit?` field on `API_CALL` / `API_CALL_WITH_CALLBACK` variants.\n *\n * Called from `ControllerResourceBackendService.doOperation` BEFORE\n * execution-context creation, request-data validation, and authorization\n * (C-2). At this seam the authenticated identity is unknown by\n * construction, so the client identifier MUST be the IP — there is no\n * authenticated-user alternative.\n *\n * Early-returns (zero Redis traffic) when:\n * - The variant has no `rateLimit?` policy (the common case until\n * per-endpoint policies are adopted), OR\n * - The variant is not an HTTP variant (defensive guard — `doOperation`\n * today only routes API_CALL / API_CALL_WITH_CALLBACK, but the type\n * surface accepts the broader operation union).\n *\n * Auto-derives `scopeKey = resource:${resourceIdentifier}:${operationIdentifier}`\n * — keeps resource configurations free of bespoke Redis-key strings (K-4).\n *\n * @param req — express request\n * @param res — express response (for `X-RateLimit-*` header writes)\n * @param variant — the resolved operation about to execute\n */\n public async checkPolicyForVariant(\n req: Request,\n res: Response,\n variant: {\n readonly variantType: ResourceOperationVariantType;\n readonly resourceIdentifier: ResourceType;\n // The resolved operation type uses generic enum constraints\n // (`TCustomOperationEnum | TCoreOperationEnum`, both bounded by\n // `Record<string, string>`); at runtime the value is always a string\n // (the enum's value, not the enum object). `unknown` keeps the\n // structural surface broad enough to accept any operation variant\n // shape; the value is stringified for the Redis scope key.\n readonly operationIdentifier: unknown;\n readonly rateLimit?: RateLimitConfiguration;\n },\n ): Promise<void> {\n if (!variant.rateLimit) {\n return;\n }\n if (\n variant.variantType !== ResourceOperationVariantType.API_CALL\n && variant.variantType !== ResourceOperationVariantType.API_CALL_WITH_CALLBACK\n ) {\n return;\n }\n\n const scopeKey = `resource:${String(variant.resourceIdentifier)}:${String(variant.operationIdentifier)}`;\n await this.checkPolicy(req, res, variant.rateLimit, scopeKey);\n }\n\n /**\n * Build the enforced-window list from a declared policy. Includes\n * `customWindows` after the canonical three so AND-semantics treat\n * them identically to the named windows (D-3, Option A — custom\n * windows participate in the same `tightestActive` / `latestTripped`\n * picks as the canonical ones).\n *\n * Custom-window dedupe (F-16, PR 7-D-3 review fix): when an author\n * accidentally declares two `customWindows` entries with the same\n * `windowSeconds` (e.g. `[{ rpw: 3, ws: 300 }, { rpw: 5, ws: 300 }]`),\n * both would derive the SAME Redis key (`<scope>:<id>:custom:300s`)\n * and a single client request would silently double-increment the\n * counter, halving the effective cap. We resolve the misconfig\n * deterministically: keep the entry with the SMALLEST `requestsPerWindow`\n * (most restrictive interpretation = safest for the protected resource)\n * and emit a `console.warn` so authors see the misconfig in logs. Any\n * canonical-window collisions (e.g. `{ requestsPerMinute: 5,\n * customWindows: [{ rpw: 3, ws: 60 }] }`) are NOT deduped — they\n * derive different key suffixes (`:minute` vs `:custom:60s`) and\n * coexist correctly; the JSDoc on `RateLimitConfigurationSchema`\n * steers authors away from this awkward shape, but it isn't broken.\n */\n private deriveWindows(policy: RateLimitConfiguration): PolicyWindow[] {\n const multiplier = this.resolveWindowMultiplier();\n const windows: PolicyWindow[] = [];\n if (policy.requestsPerMinute !== undefined) {\n windows.push({ name: 'minute', max: policy.requestsPerMinute * multiplier, seconds: 60 });\n }\n if (policy.requestsPerHour !== undefined) {\n windows.push({ name: 'hour', max: policy.requestsPerHour * multiplier, seconds: 3600 });\n }\n if (policy.requestsPerDay !== undefined) {\n windows.push({ name: 'day', max: policy.requestsPerDay * multiplier, seconds: 86400 });\n }\n if (policy.customWindows && policy.customWindows.length > 0) {\n // Map by `windowSeconds`; on collision keep the smallest `max`\n // (most restrictive) and warn. Insertion order is preserved by\n // `Map`, so the canonical-then-custom emit order downstream is\n // unchanged for non-colliding cases.\n const byWindowSeconds = new Map<number, { max: number; seconds: number }>();\n for (const custom of policy.customWindows) {\n const existing = byWindowSeconds.get(custom.windowSeconds);\n if (existing === undefined) {\n byWindowSeconds.set(custom.windowSeconds, {\n max: custom.requestsPerWindow,\n seconds: custom.windowSeconds,\n });\n } else if (custom.requestsPerWindow < existing.max) {\n // eslint-disable-next-line no-console\n console.warn(\n '[rate-limit] Duplicate customWindows.windowSeconds detected; keeping the smaller (more restrictive) requestsPerWindow.',\n { windowSeconds: custom.windowSeconds, kept: custom.requestsPerWindow, dropped: existing.max },\n );\n byWindowSeconds.set(custom.windowSeconds, {\n max: custom.requestsPerWindow,\n seconds: custom.windowSeconds,\n });\n } else {\n // eslint-disable-next-line no-console\n console.warn(\n '[rate-limit] Duplicate customWindows.windowSeconds detected; keeping the smaller (more restrictive) requestsPerWindow.',\n { windowSeconds: custom.windowSeconds, kept: existing.max, dropped: custom.requestsPerWindow },\n );\n }\n }\n for (const [, custom] of byWindowSeconds) {\n windows.push({\n name: `custom:${custom.seconds}s`,\n max: custom.max * multiplier,\n seconds: custom.seconds,\n });\n }\n }\n return windows;\n }\n\n /**\n * Non-production window-max relaxation for every policy this service enforces\n * (register, login, MFA, magic-link, SCIM, marketing public endpoints, resource\n * `rateLimit?` variants — every `checkPolicy` / `checkPolicyForVariant` caller,\n * K-3/K-4).\n *\n * The branch itself lives in\n * {@link resolveRateLimitEnvironmentMultiplier} — this service is one of SIX\n * abuse-throttle sites in the engine and used to own a private copy of the\n * constant, which is exactly why the other five never got the relaxation. Do not\n * re-inline it here.\n */\n private resolveWindowMultiplier(): number {\n return resolveRateLimitEnvironmentMultiplier(this.appConfigService.applicationEnv);\n }\n\n private async resolveRateLimitTtl(\n identifier: string,\n organizationId: string | undefined,\n fallbackSeconds: number,\n ): Promise<number> {\n const getRateLimitTtl = (this.redisService as RedisService & {\n getRateLimitTtl?: (identifier: string, organizationId?: string) => Promise<number>;\n }).getRateLimitTtl;\n if (!getRateLimitTtl) {\n return fallbackSeconds;\n }\n\n try {\n const ttl = await getRateLimitTtl.call(this.redisService, identifier, organizationId);\n return ttl >= 0 ? ttl : fallbackSeconds;\n } catch {\n return fallbackSeconds;\n }\n }\n}\n"]}
|