@wildo-ai/saas-models 1.1.7 → 1.1.8
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__/setup.d.ts.map +1 -1
- package/dist/esm/__tests__/setup.js.map +1 -1
- package/dist/esm/_inspect.d.ts.map +1 -1
- package/dist/esm/_inspect.js.map +1 -1
- package/dist/esm/applications/application-metadata.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/applications/application-metadata.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/applications/application-subject.shared.schemas.d.ts.map +1 -1
- package/dist/esm/applications/application-subject.shared.schemas.js.map +1 -1
- package/dist/esm/applications/application-versions.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/applications/application-versions.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications-context.schemas.js.map +1 -1
- package/dist/esm/applications/applications.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/applications/applications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-account.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/billing-account.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-account.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-configuration.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-configuration.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-enums.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-enums.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-types.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-types.shared.schemas.js.map +1 -1
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/credit-pool.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/credit-pool.shared.schemas.js.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.schemas.js.map +1 -1
- package/dist/esm/billing/price.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/price.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/price.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/price.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product-behavior-policy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product-behavior-policy.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product-definition.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product-definition.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/product.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product.shared.schemas.js.map +1 -1
- package/dist/esm/billing/promotions.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/promotions.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/promotions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/promotions.shared.schemas.js.map +1 -1
- package/dist/esm/billing/public-pricing-catalog.shared.atoms.d.ts.map +1 -1
- package/dist/esm/billing/public-pricing-catalog.shared.atoms.js.map +1 -1
- package/dist/esm/billing/public-pricing-catalog.shared.d.ts.map +1 -1
- package/dist/esm/billing/public-pricing-catalog.shared.js.map +1 -1
- package/dist/esm/billing/referral-reward.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/referral-reward.shared.schemas.js.map +1 -1
- package/dist/esm/billing/referral.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/referral.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/referral.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/referral.shared.schemas.js.map +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/subscription.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/subscription.shared.schemas.js.map +1 -1
- package/dist/esm/billing/usage-flush-evidence.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-flush-evidence.shared.schemas.js.map +1 -1
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
- package/dist/esm/charts/aggregation-query.shared.schemas.d.ts.map +1 -1
- package/dist/esm/charts/aggregation-query.shared.schemas.js.map +1 -1
- package/dist/esm/charts/aggregation.shared.definitions.d.ts.map +1 -1
- package/dist/esm/charts/aggregation.shared.definitions.js.map +1 -1
- package/dist/esm/charts/chart-definition-builder.shared.d.ts.map +1 -1
- package/dist/esm/charts/chart-definition-builder.shared.js.map +1 -1
- package/dist/esm/companion/artifact-placement.shared.definitions.d.ts.map +1 -1
- package/dist/esm/companion/artifact-placement.shared.definitions.js.map +1 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.d.ts.map +1 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.js.map +1 -1
- package/dist/esm/companion/shared-library-companion.shared.definitions.d.ts.map +1 -1
- package/dist/esm/companion/shared-library-companion.shared.definitions.js.map +1 -1
- package/dist/esm/companion-exports.d.ts.map +1 -1
- package/dist/esm/companion-exports.js.map +1 -1
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-actor.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-actor.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-export-projection.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-export-projection.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-log-sink.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-log-sink.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
- package/dist/esm/compliance/data-classification/data-classification.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/data-classification/data-classification.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/documents/governed-document-interactions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/documents/governed-document-interactions.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/documents/governed-documents.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/documents/governed-documents.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/ai-use-posture.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/ai-use-posture.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/capability-consent-purposes.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/capability-consent-purposes.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/client-storage.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/client-storage.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/consent-gate-vocabulary.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/consent-gate-vocabulary.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/consent-purposes.shared.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/consent-purposes.shared.js.map +1 -1
- package/dist/esm/compliance/privacy/data-subject-rights.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/data-subject-rights.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/legal-hold-subject-attribution.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/legal-hold-subject-attribution.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/legal-holds.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/legal-holds.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/legal-holds.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/legal-holds.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/personal-data-category.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/personal-data-category.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/personal-data-declaration.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/personal-data-declaration.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/privacy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/privacy.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/provider-capability-disclosure.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/provider-capability-disclosure.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/purpose-ref.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/purpose-ref.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-binding.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-binding.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-enforcement-records.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-enforcement-records.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-schedule.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-schedule.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-scope-deleted.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-scope-deleted.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/sharing.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/sharing.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-data-recipients.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-data-recipients.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-erasure-lane-evidence.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-erasure-lane-evidence.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-erasure.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-erasure.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-export-render.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-export-render.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/review-cadence.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/review-cadence.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/risk-posture.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/risk-posture.shared.schemas.js.map +1 -1
- package/dist/esm/config/analytics-value-moments.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/analytics-value-moments.shared.schemas.js.map +1 -1
- package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/app-configuration-shared.shared.schemas.js.map +1 -1
- package/dist/esm/config/app-frontend-type.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/app-frontend-type.shared.schemas.js.map +1 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.d.ts.map +1 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.js.map +1 -1
- package/dist/esm/config/brand-assets.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/brand-assets.shared.schemas.js.map +1 -1
- package/dist/esm/config/configuration-validation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/configuration-validation.shared.schemas.js.map +1 -1
- package/dist/esm/config/entity-identity-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/entity-identity-config.shared.schemas.js.map +1 -1
- package/dist/esm/config/frontend/chart-definition.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/frontend/chart-definition.shared.schemas.js.map +1 -1
- package/dist/esm/config/frontend/chart-registration-alignment.shared.d.ts.map +1 -1
- package/dist/esm/config/frontend/chart-registration-alignment.shared.js.map +1 -1
- package/dist/esm/config/frontend/navigation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/frontend/navigation.shared.schemas.js.map +1 -1
- package/dist/esm/config/frontend/onboarding.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/frontend/onboarding.shared.schemas.js.map +1 -1
- package/dist/esm/config/postgresql.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/postgresql.shared.schemas.js.map +1 -1
- package/dist/esm/config/registration-acquisition-policy.shared.utils.d.ts.map +1 -1
- package/dist/esm/config/registration-acquisition-policy.shared.utils.js.map +1 -1
- package/dist/esm/config-authoring.entry.d.ts.map +1 -1
- package/dist/esm/config-authoring.entry.js.map +1 -1
- package/dist/esm/crdt/crdt-merge.shared.utils.d.ts.map +1 -1
- package/dist/esm/crdt/crdt-merge.shared.utils.js.map +1 -1
- package/dist/esm/data-seeding/data-seeding-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/data-seeding/data-seeding-config.shared.schemas.js.map +1 -1
- package/dist/esm/errors/caught-error-description.shared.utils.d.ts.map +1 -1
- package/dist/esm/errors/caught-error-description.shared.utils.js.map +1 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
- package/dist/esm/errors/errors.shared.definitions.d.ts.map +1 -1
- package/dist/esm/errors/errors.shared.definitions.js.map +1 -1
- package/dist/esm/errors/errors.shared.schemas.d.ts.map +1 -1
- package/dist/esm/errors/errors.shared.schemas.js.map +1 -1
- package/dist/esm/errors/errors.shared.utils.d.ts.map +1 -1
- package/dist/esm/errors/errors.shared.utils.js.map +1 -1
- package/dist/esm/errors/resource-access-forbidden.shared.error.d.ts.map +1 -1
- package/dist/esm/errors/resource-access-forbidden.shared.error.js.map +1 -1
- package/dist/esm/errors/thrown-value-description.shared.utils.d.ts.map +1 -1
- package/dist/esm/errors/thrown-value-description.shared.utils.js.map +1 -1
- package/dist/esm/errors/zod-issue-formatting.shared.utils.d.ts.map +1 -1
- package/dist/esm/errors/zod-issue-formatting.shared.utils.js.map +1 -1
- package/dist/esm/exports/tabular-csv.shared.utils.d.ts.map +1 -1
- package/dist/esm/exports/tabular-csv.shared.utils.js.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-description.shared.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-description.shared.js.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-pass-mode.shared.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-pass-mode.shared.js.map +1 -1
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
- package/dist/esm/external-data/external-data-provenance.shared.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-provenance.shared.js.map +1 -1
- package/dist/esm/external-data.exports.d.ts.map +1 -1
- package/dist/esm/external-data.exports.js.map +1 -1
- package/dist/esm/external-providers/compose-provider-registry.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/compose-provider-registry.shared.js.map +1 -1
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
- package/dist/esm/external-providers/engine-capability-surface.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capability-surface.shared.js.map +1 -1
- package/dist/esm/external-providers/external-providers.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/external-providers.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.js.map +1 -1
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/frontend-provider-public-config.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-provider-public-config.shared.js.map +1 -1
- package/dist/esm/external-providers/model-cost-accounting-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/model-cost-accounting-config.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-address-lookup-contract.shared.types.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-address-lookup-contract.shared.types.js.map +1 -1
- package/dist/esm/external-providers/provider-augmentation-opt-ins.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-augmentation-opt-ins.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-authentication-assurance.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-authentication-assurance.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-browser-operations.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-browser-operations.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-frontend-component-contract.shared.types.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-frontend-component-contract.shared.types.js.map +1 -1
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-metadata.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-metadata.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-package-allow-list.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-package-allow-list.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-protocol.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-protocol.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-scope-reauthorization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-scope-reauthorization.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-shared-connections.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-shared-connections.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.js.map +1 -1
- package/dist/esm/external-providers/provider-usage-cost.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-usage-cost.shared.js.map +1 -1
- package/dist/esm/external-providers/provider-usage-pricing.example.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-usage-pricing.example.js.map +1 -1
- package/dist/esm/external-providers/provider-usage-pricing.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-usage-pricing.shared.schemas.js.map +1 -1
- package/dist/esm/features/application-features.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/features/application-features.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/features/connected-feature.example.d.ts.map +1 -1
- package/dist/esm/features/connected-feature.example.js.map +1 -1
- package/dist/esm/features/core-feature-definitions.shared.d.ts.map +1 -1
- package/dist/esm/features/core-feature-definitions.shared.js.map +1 -1
- package/dist/esm/features/feature-builders.shared.d.ts.map +1 -1
- package/dist/esm/features/feature-builders.shared.js.map +1 -1
- package/dist/esm/features/feature-definition.shared.schemas.d.ts.map +1 -1
- package/dist/esm/features/feature-definition.shared.schemas.js.map +1 -1
- package/dist/esm/features/feature-registry.shared.d.ts.map +1 -1
- package/dist/esm/features/feature-registry.shared.js.map +1 -1
- package/dist/esm/features/feature-resolution.shared.schemas.d.ts.map +1 -1
- package/dist/esm/features/feature-resolution.shared.schemas.js.map +1 -1
- package/dist/esm/features/scope-features.shared.schemas.d.ts.map +1 -1
- package/dist/esm/features/scope-features.shared.schemas.js.map +1 -1
- package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/features/user-features.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/files/file-remote-reference-link.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/file-remote-reference-link.shared.schemas.js.map +1 -1
- package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -1
- package/dist/esm/files/files.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/files/files.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/files.shared.schemas.js.map +1 -1
- package/dist/esm/files/files.shared.utils.d.ts.map +1 -1
- package/dist/esm/files/files.shared.utils.js.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/actors.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/actors.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agent-traceability.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agent-traceability.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agent-work-decisions.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agent-work-decisions.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agent-work-decisions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agent-work-decisions.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agents.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agents.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/autonomous-agents.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/autonomous-agents.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/deliberation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/deliberation.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/execution-plan-readiness.shared.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/execution-plan-readiness.shared.utils.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.configuration.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.configuration.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.frontend.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.frontend.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.definitions.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/human-decision.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/human-decision.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-call-attributions.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-call-attributions.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-call-attributions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-call-attributions.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-cost-period-aggregates.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-cost-period-aggregates.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-cost-period-aggregates.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-cost-period-aggregates.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-cost-summary.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-cost-summary.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/prompt-ir.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/prompt-ir.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/provider-call-records.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/provider-call-records.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/provider-call-records.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/provider-call-records.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/review-deadlines.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/review-deadlines.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/tasks.actors.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/tasks.actors.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/work-attribution.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/work-attribution.shared.schemas.js.map +1 -1
- package/dist/esm/frontend-definitions/frontend-notification-custom-message-ref.definitions.d.ts.map +1 -1
- package/dist/esm/frontend-definitions/frontend-notification-custom-message-ref.definitions.js.map +1 -1
- package/dist/esm/frontend-definitions/settings-destination-ref.definitions.d.ts.map +1 -1
- package/dist/esm/frontend-definitions/settings-destination-ref.definitions.js.map +1 -1
- package/dist/esm/guidance/guidance-flow.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-flow.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.utils.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.utils.js.map +1 -1
- package/dist/esm/guidance/lifecycle-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/lifecycle-config.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/milestone-builders.shared.d.ts.map +1 -1
- package/dist/esm/guidance/milestone-builders.shared.js.map +1 -1
- package/dist/esm/guidance/milestone-definition.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/milestone-definition.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/progression-presentation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-presentation.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding-id.shared.utils.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding-id.shared.utils.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-erasure-stance.shared.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-erasure-stance.shared.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-rest-write-operations.shared.schemas.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-rest-write-operations.shared.schemas.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-transport-dialect.shared.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-transport-dialect.shared.js.map +1 -1
- package/dist/esm/http-api-binding/read-through-engine-anchors.shared.d.ts.map +1 -1
- package/dist/esm/http-api-binding/read-through-engine-anchors.shared.js.map +1 -1
- package/dist/esm/i18n/application-config-vocabulary.shared.d.ts.map +1 -1
- package/dist/esm/i18n/application-config-vocabulary.shared.js.map +1 -1
- package/dist/esm/i18n/engine-open-vocabulary-values.shared.d.ts.map +1 -1
- package/dist/esm/i18n/engine-open-vocabulary-values.shared.js.map +1 -1
- package/dist/esm/i18n/engine-open-vocabulary.shared.d.ts.map +1 -1
- package/dist/esm/i18n/engine-open-vocabulary.shared.js.map +1 -1
- package/dist/esm/i18n/interpolate-label-params.shared.utils.d.ts.map +1 -1
- package/dist/esm/i18n/interpolate-label-params.shared.utils.js.map +1 -1
- package/dist/esm/i18n/labelling.dto.shared.schemas.d.ts.map +1 -1
- package/dist/esm/i18n/labelling.dto.shared.schemas.js.map +1 -1
- package/dist/esm/inbound/conversation-threads.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/conversation-threads.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/inbound/conversation-threads.shared.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/conversation-threads.shared.schemas.js.map +1 -1
- package/dist/esm/inbound/inbound-channels.shared.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/inbound-channels.shared.schemas.js.map +1 -1
- package/dist/esm/inbound/inbound-delivery.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/inbound-delivery.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/inbound/inbound-delivery.shared.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/inbound-delivery.shared.schemas.js.map +1 -1
- package/dist/esm/inbound/inbound-endpoint-env.shared.d.ts.map +1 -1
- package/dist/esm/inbound/inbound-endpoint-env.shared.js.map +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/meta-workflows/actions.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/actions.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/catalog.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/catalog.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/coding-tasks.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/coding-tasks.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/context-selection.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/context-selection.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/decisions.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/decisions.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/orchestration.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/orchestration.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/portable-primitives.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/portable-primitives.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows.exports.d.ts.map +1 -1
- package/dist/esm/meta-workflows.exports.js.map +1 -1
- package/dist/esm/monitoring/monitoring.shared.schemas.d.ts.map +1 -1
- package/dist/esm/monitoring/monitoring.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/email/email-context.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-context.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/email/email-submission.shared.enums.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-submission.shared.enums.js.map +1 -1
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/email/email-template.shared.enums.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-template.shared.enums.js.map +1 -1
- package/dist/esm/notifications/inbound-email/inbound-email.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/inbound-email/inbound-email.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/inbound-email/inbound-email.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/inbound-email/inbound-email.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/notification-badges.core.definitions.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.core.definitions.js.map +1 -1
- package/dist/esm/notifications/notification-badges.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.schemas.js.map +1 -1
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/notifications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notifications.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/application-owner-organization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/application-owner-organization.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-features.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-features.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-features.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-features.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-members.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-members.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-unit-inheritance.shared.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-inheritance.shared.js.map +1 -1
- package/dist/esm/organizations/organization-unit-members.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-members.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-unit-members.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-members.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing-decision.shared.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing-decision.shared.js.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.example.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.example.js.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.shared.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.shared.js.map +1 -1
- package/dist/esm/organizations/organization-units.shared.path.d.ts.map +1 -1
- package/dist/esm/organizations/organization-units.shared.path.js.map +1 -1
- package/dist/esm/organizations/organization-units.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-units.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-units.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-units.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organizations.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organizations.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-activity-feed.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-activity-feed.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-activity-feed.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-activity-feed.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-capability-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-capability-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-capability-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-capability-grants.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-client-controls.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-client-controls.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-relationships.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-relationships.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-relationships.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-relationships.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/tenant-teardown-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/tenant-teardown-config.shared.schemas.js.map +1 -1
- package/dist/esm/provider-registration-runtime.exports.d.ts.map +1 -1
- package/dist/esm/provider-registration-runtime.exports.js.map +1 -1
- package/dist/esm/public-runtime/index.d.ts.map +1 -1
- package/dist/esm/public-runtime/index.js.map +1 -1
- package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/queue/jobs.shared.schemas.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.schemas.js.map +1 -1
- package/dist/esm/queue/jobs.shared.utils.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.utils.js.map +1 -1
- package/dist/esm/queue/queues.shared.schemas.d.ts.map +1 -1
- package/dist/esm/queue/queues.shared.schemas.js.map +1 -1
- package/dist/esm/queue/queues.shared.utils.d.ts.map +1 -1
- package/dist/esm/queue/queues.shared.utils.js.map +1 -1
- package/dist/esm/queue/rabbitmq-queue-args.shared.d.ts.map +1 -1
- package/dist/esm/queue/rabbitmq-queue-args.shared.js.map +1 -1
- package/dist/esm/rag/rag-retrieval-health.shared.d.ts.map +1 -1
- package/dist/esm/rag/rag-retrieval-health.shared.js.map +1 -1
- package/dist/esm/requests/header-keys.shared.d.ts.map +1 -1
- package/dist/esm/requests/header-keys.shared.js.map +1 -1
- package/dist/esm/requests/http-requests.shared.d.ts.map +1 -1
- package/dist/esm/requests/http-requests.shared.js.map +1 -1
- package/dist/esm/requests/idempotency-key.shared.d.ts.map +1 -1
- package/dist/esm/requests/idempotency-key.shared.js.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-documentation.d.ts.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-documentation.js.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-urls.d.ts.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-urls.js.map +1 -1
- package/dist/esm/requests/rate-limits.shared.schemas.d.ts.map +1 -1
- package/dist/esm/requests/rate-limits.shared.schemas.js.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
- package/dist/esm/resources/child-operations.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/child-operations.shared.schemas.js.map +1 -1
- package/dist/esm/resources/collection-query-parameters.shared.d.ts.map +1 -1
- package/dist/esm/resources/collection-query-parameters.shared.js.map +1 -1
- package/dist/esm/resources/context-policy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/context-policy.shared.schemas.js.map +1 -1
- package/dist/esm/resources/embedded-resource-mark.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/embedded-resource-mark.shared.utils.js.map +1 -1
- package/dist/esm/resources/relationship-display.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/relationship-display.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources-registry.shared.core.definitions.d.ts.map +1 -1
- package/dist/esm/resources/resources-registry.shared.core.definitions.js.map +1 -1
- package/dist/esm/resources/resources-relationships.shared.factory.d.ts.map +1 -1
- package/dist/esm/resources/resources-relationships.shared.factory.js.map +1 -1
- package/dist/esm/resources/resources-serialization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources-serialization.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources.shared.core.definitions.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.core.definitions.js.map +1 -1
- package/dist/esm/resources/resources.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/collection-export.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/collection-export.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/composition-cascade-deletability.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/composition-cascade-deletability.validation.js.map +1 -1
- package/dist/esm/resources/utils/composition-seedability.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/composition-seedability.validation.js.map +1 -1
- package/dist/esm/resources/utils/context-addressed-composition-singleton.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/context-addressed-composition-singleton.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/dependent-lifecycle-classification.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/dependent-lifecycle-classification.validation.js.map +1 -1
- package/dist/esm/resources/utils/duplicate-relationship-registration.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/duplicate-relationship-registration.validation.js.map +1 -1
- package/dist/esm/resources/utils/field-value-disclosure.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/field-value-disclosure.utils.js.map +1 -1
- package/dist/esm/resources/utils/http-api-write-declaration.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/http-api-write-declaration.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/initiator-stamped-field-satisfiability.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/initiator-stamped-field-satisfiability.validation.js.map +1 -1
- package/dist/esm/resources/utils/no-subject-data-stance-coherence.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/no-subject-data-stance-coherence.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/persistence-adapter-discrimination.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/persistence-adapter-discrimination.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/populated-file-fields.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/populated-file-fields.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/repository-dto-builder.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/repository-dto-builder.utils.js.map +1 -1
- package/dist/esm/resources/utils/request-schema-field-carriage.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/request-schema-field-carriage.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/required-fk-fillability.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/required-fk-fillability.validation.js.map +1 -1
- package/dist/esm/resources/utils/resource-operation-type-guards.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-operation-type-guards.utils.js.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.factory.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.factory.js.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.relationships.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.relationships.js.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.schemas.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.schemas.js.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.utils.js.map +1 -1
- package/dist/esm/resources/utils/resource-subtree.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-subtree.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-context-needs.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-context-needs.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-naming.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-naming.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.path.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.path.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.urls-builder.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.urls-builder.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-serialization.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-serialization.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-summary.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-summary.utils.js.map +1 -1
- package/dist/esm/resources/utils/schema-family-builder.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/schema-family-builder.utils.js.map +1 -1
- package/dist/esm/resources/utils/schema-type-inference.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/schema-type-inference.utils.js.map +1 -1
- package/dist/esm/resources/utils/schema-type-utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/schema-type-utils.js.map +1 -1
- package/dist/esm/resources/utils/schema-variant-resolver.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/schema-variant-resolver.utils.js.map +1 -1
- package/dist/esm/resources/utils/shared-persistence-collection.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/shared-persistence-collection.utils.js.map +1 -1
- package/dist/esm/resources/utils/templatable-file-fields.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/templatable-file-fields.shared.utils.js.map +1 -1
- package/dist/esm/resources/work-unit.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/work-unit.shared.schemas.js.map +1 -1
- package/dist/esm/runtime/domain-module.shared.definitions.d.ts.map +1 -1
- package/dist/esm/runtime/domain-module.shared.definitions.js.map +1 -1
- package/dist/esm/runtime/execution-context.shared.schemas.d.ts.map +1 -1
- package/dist/esm/runtime/execution-context.shared.schemas.js.map +1 -1
- package/dist/esm/runtime/runtime.shared.schemas.d.ts.map +1 -1
- package/dist/esm/runtime/runtime.shared.schemas.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/anonymous-session/anonymous-session.shared.contract.d.ts.map +1 -1
- package/dist/esm/security/authentications/anonymous-session/anonymous-session.shared.contract.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.utils.js.map +1 -1
- package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/consumable-token.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/cross-frontend-handoff.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/cross-frontend-handoff.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts.map +1 -1
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js.map +1 -1
- package/dist/esm/security/authentications/password-blocklist.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/password-blocklist.shared.utils.js.map +1 -1
- package/dist/esm/security/authentications/password-reset.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/password-reset.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/registration.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/registration.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/same-origin-redirect-path.shared.d.ts.map +1 -1
- package/dist/esm/security/authentications/same-origin-redirect-path.shared.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-organization-unit-mapping.shared.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-organization-unit-mapping.shared.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-tokens.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-tokens.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-tokens.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-tokens.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/service-provider-client-authentication.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/service-provider-client-authentication.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-export-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-export-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-export-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-export-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/administrative-continuity.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/administrative-continuity.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/application-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/application-access-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/application-access-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/application-access-grants.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.defaults.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.defaults.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.utils.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-connection-listing.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/provider-connection-listing.shared.schemas.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.js.map +1 -1
- package/dist/esm/security/credential-rotation-grace.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/credential-rotation-grace.shared.utils.js.map +1 -1
- package/dist/esm/security/crypto-keys/crypto-keys.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/crypto-keys/crypto-keys.shared.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-resource-server.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-resource-server.shared.schemas.js.map +1 -1
- package/dist/esm/security/outbound-target-control.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/outbound-target-control.shared.schemas.js.map +1 -1
- package/dist/esm/security/submission-challenge/submission-challenge.shared.d.ts.map +1 -1
- package/dist/esm/security/submission-challenge/submission-challenge.shared.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-actions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-actions.shared.schemas.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-credential-kind.shared.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-credential-kind.shared.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-declaration.shared.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-declaration.shared.schemas.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-env.shared.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-env.shared.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-error-codes.shared.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-error-codes.shared.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-facet.shared.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-facet.shared.schemas.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.schemas.js.map +1 -1
- package/dist/esm/testing/resource-config-builders.d.ts.map +1 -1
- package/dist/esm/testing/resource-config-builders.js.map +1 -1
- package/dist/esm/testing.d.ts.map +1 -1
- package/dist/esm/testing.js.map +1 -1
- package/dist/esm/users/anonymous-user-marketing-metadata.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/anonymous-user-marketing-metadata.shared.schemas.js.map +1 -1
- package/dist/esm/users/anonymous-users.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/anonymous-users.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/anonymous-users.shared.schema.d.ts.map +1 -1
- package/dist/esm/users/anonymous-users.shared.schema.js.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-consent-decision.shared.utils.d.ts.map +1 -1
- package/dist/esm/users/user-consent-decision.shared.utils.js.map +1 -1
- package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-credentials.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-credentials.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-credentials.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-identity-links.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-identity-links.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-preferences-reset.shared.utils.d.ts.map +1 -1
- package/dist/esm/users/user-preferences-reset.shared.utils.js.map +1 -1
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-profiles.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-self.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/users.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/users.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/users.shared.schemas.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-resource-server.shared.schemas.js","sourceRoot":"","sources":["../../../../src/security/oauth-clients/oauth-resource-server.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,+CAA+C,CAAC;AAEzF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAN,IAAY,kBAOX;AAPD,WAAY,kBAAkB;IAC5B,uFAAuF;IACvF,iCAAW,CAAA;IACX,gGAAgG;IAChG,iCAAW,CAAA;IACX,uGAAuG;IACvG,iCAAW,CAAA;AACb,CAAC,EAPW,kBAAkB,KAAlB,kBAAkB,QAO7B;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAGpC;IACF,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,wBAAwB,CAAC,SAAS;IAC5D,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,wBAAwB,CAAC,YAAY;CAChE,CAAC;AAEF;yGACyG;AACzG,MAAM,CAAC,MAAM,gCAAgC,GAAkC;IAC7E,kBAAkB,CAAC,GAAG;IACtB,kBAAkB,CAAC,GAAG;CACvB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAkC;IAC3E,kBAAkB,CAAC,GAAG;IACtB,kBAAkB,CAAC,GAAG;IACtB,kBAAkB,CAAC,GAAG;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAkC;IAC1E,kBAAkB,CAAC,GAAG;IACtB,kBAAkB,CAAC,GAAG;CACvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,MAAM,iCAAiC,GAAG;IACxC,oGAAoG;IACpG,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,sBAAsB,EAAE,gDAAgD,CAAC;IACtG,kGAAkG;IAClG,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,+FAA+F;IAC/F,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,GAAG,iCAAiC;IACpC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC;CACxC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,GAAG,iCAAiC;IACpC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC;IACvC;;;;OAIG;IACH,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,6GAA6G,CAAC,CAAC,QAAQ,EAAE;CACtK,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,uBAAuB,EAAE,sBAAsB,CAAC,CAAC,CAAC;AAQ5H,kEAAkE","sourcesContent":["import { z } from 'zod';\nimport { ManualControllerRouteKey } from '../../requests/manual-controllers-routes-urls';\n\n/**\n * OAuth 2.0 **Resource Servers** exposed by a Wildo app — the token-CONSUMING surfaces, each\n * with its OWN canonical audience URI (RFC 8707 §2, \"Resource Indicators for OAuth 2.0\").\n *\n * ## What this is (and is NOT)\n *\n * A `ResourceServerKind` identifies WHICH endpoint may consume a token — it is an\n * **audience / transport** concept, a confused-deputy + token-replay defense\n * (RFC 8707: \"an audience-restricted access token … cannot then be taken by that resource\n * and presented elsewhere\"). It is **NOT** an authorization axis: it never decides WHAT a\n * token may do at a surface. Authorization at every resource server is **roles-only** — the\n * framework's RBAC (scope-based authorization was removed 2026-07-21). So:\n *\n * - **Audience** (this enum) answers *\"at which door may this token be presented?\"*\n * - **Roles** answer *\"what may it do once through that door?\"*\n *\n * The two compose; they are not competing vocabularies.\n *\n * ## The three resource servers\n *\n * | Kind | Surface | Canonical audience (`aud`) |\n * |-------|-------------------------------------------|-------------------------------------|\n * | `API` | generic HTTP resource API (CRUD) | `<appPublicBase>/api/v1` |\n * | `A2A` | Agent2Agent endpoint (external agents) | `<API audience>/a2a` |\n * | `MCP` | Model Context Protocol tool endpoint | `<API audience>/mcp` |\n *\n * ## Standards\n *\n * - **RFC 8707** — a token is minted `aud`-bound to the resource server it targets; the AS is\n * told the target via the `resource` request parameter.\n * - **RFC 9728** (Protected Resource Metadata) — each server publishes\n * `/.well-known/oauth-protected-resource` advertising its trusted authorization server.\n * - **MCP / A2A authorization specs** — the MCP server (and A2A agent) MUST verify a received\n * token is `aud`-restricted to ITSELF and MUST reject tokens not issued for it.\n *\n * Resolve a kind's canonical audience via\n * `AppConfigurationService.resolveResourceServerAudience(kind)` (backend) — the SINGLE SOURCE\n * OF TRUTH so minting and validation cannot drift.\n */\nexport enum ResourceServerKind {\n /** The generic HTTP resource API (CRUD on resources), mounted at the API base path. */\n API = 'api',\n /** The Agent2Agent (A2A) endpoint — external agents acting on behalf of a user or a machine. */\n A2A = 'a2a',\n /** The Model Context Protocol (MCP) endpoint — a curated subset of operations exposed as MCP tools. */\n MCP = 'mcp',\n}\n\n/**\n * The mount-path route each NON-`API` resource server appends to the API audience to form its\n * canonical audience URI (see {@link ResourceServerKind}). `API` is the API base itself, so it\n * is intentionally absent here. Keeping the mapping in `_core` next to the enum guarantees the\n * audience derivation is identical everywhere it is computed.\n */\nexport const RESOURCE_SERVER_MOUNT_ROUTE: Record<\n Exclude<ResourceServerKind, ResourceServerKind.API>,\n ManualControllerRouteKey\n> = {\n [ResourceServerKind.A2A]: ManualControllerRouteKey.A2A_TASKS,\n [ResourceServerKind.MCP]: ManualControllerRouteKey.MCP_ENDPOINT,\n};\n\n/** The resource servers that a USER-DELEGATED token may legitimately target (never the main API —\n * a delegated token must be confined to an agent surface, per B-S2 / the audience-confinement rule). */\nexport const DELEGATED_TOKEN_RESOURCE_SERVERS: readonly ResourceServerKind[] = [\n ResourceServerKind.A2A,\n ResourceServerKind.MCP,\n];\n\n/**\n * The resource servers a MACHINE (client-credentials) token may be audience-bound to — ALL of them.\n * Unlike a user-delegated token (confined to agent surfaces), a machine principal legitimately calls\n * the generic API directly AND the A2A / MCP endpoints. The `client_credentials` token endpoint\n * validates the requested RFC 8707 `resource` against this set and mints an `aud`-bound token for the\n * named surface (an absent `resource` deliberately selects the generic API audience). Each resource server then accepts\n * a token bound to its OWN audience (per-endpoint, tight) — the confused-deputy / token-passthrough\n * defense — while the main API accepts only the API audience, so a per-endpoint token cannot be\n * replayed there.\n */\nexport const MACHINE_TOKEN_RESOURCE_SERVERS: readonly ResourceServerKind[] = [\n ResourceServerKind.API,\n ResourceServerKind.A2A,\n ResourceServerKind.MCP,\n];\n\n/**\n * The resource-server kinds that support MULTIPLE NAMED INSTANCES (R-2). `API` is excluded: there is\n * exactly one generic resource API per app, so an instance ref never applies to it.\n */\nexport const INSTANCEABLE_RESOURCE_SERVERS: readonly ResourceServerKind[] = [\n ResourceServerKind.A2A,\n ResourceServerKind.MCP,\n];\n\n/**\n * @wildo_source:part:start saas.models.resource-server-instance facet:layer:shared facet:family:external-access\n *\n * A NAMED resource-server instance — one addressable external surface of a given\n * {@link ResourceServerKind}, with its OWN URL segment, RFC 8707 audience, discovery document, and\n * curated content. Declare instances on `ApplicationInitializationConfig.resourceServerInstances`\n * (your backend's initialization config). Import path: `@wildo-ai/saas-models`.\n *\n * This is a DISCRIMINATED UNION on `kind`, so the two surfaces cannot be confused at authoring time:\n * an MCP server has no `actorSystemRefs` (its membership is declared per-operation), and `kind: API`\n * is unrepresentable (there is exactly one generic resource API per app — see\n * {@link INSTANCEABLE_RESOURCE_SERVERS}). Both were previously only caught at startup, if at all.\n *\n * ## Why instances exist\n *\n * - **MCP** has no grouping primitive: a server exposes ONE flat `tools/list` and a client is\n * configured with ONE URL. Multiple named servers are therefore the only way to offer curated tool\n * subsets per consumer (e.g. a read-only `support` server vs a write-capable `ops` server) — which\n * also keeps tool counts small enough for reliable agent tool-choice.\n * - **A2A** groups SKILLS inside one agent card (a request targets one via `metadata.skillId`).\n * Multiple named agents therefore express distinct agent IDENTITIES (own card, own audience, own\n * skill subset) — skills remain the routing mechanism WITHIN an agent.\n *\n * ## What a named instance IS, and what it is NOT\n *\n * Each instance's canonical audience is `resolveResourceServerAudience(kind, ref)` → `…/<mount>/<ref>`.\n * An access token is RFC 8707 bound to exactly ONE instance, so **a token minted for one instance is\n * REJECTED at another** (the 2026-07-29 strict-audience flip makes this real, not advisory). That is a\n * TOKEN-REPLAY boundary: a leaked or misdirected token cannot be used on a sibling surface.\n *\n * It is **NOT a per-client capability grant**. Any client the app authorizes for a grant may request any\n * audience the app declares, exactly as at the generic API. What a caller may DO once through the door is\n * decided by **roles**, uniformly:\n *\n * > **MCP/A2A exposure can only ever be a SUBSET of what roles already permit — it never widens.**\n * > `mcp.exposed` and `mcp.servers` are CURATION applied BEFORE authorization, never instead of it: they\n * > decide which operations are shaped as agent tools and which surface advertises them. Every\n * > `tools/call` still re-runs the same role authorization the REST API runs, and primary scope resolves\n * > identically (a USER_SELF operation reaches the delegating user's own row; an ORG/APPLICATION-scoped\n * > operation runs in the machine token's or delegating user's scope).\n *\n * So curate a surface to make an agent's tool-choice reliable and to confine a token — and use ROLES when\n * a caller must be unable to perform an operation at all.\n *\n * ## Membership (deliberately asymmetric — the units differ)\n *\n * - **MCP**: the OPERATION opts in (`operation.mcp.servers`), beside its existing `mcp.exposed`.\n * - **A2A**: the AGENT lists its skills ({@link A2aAgentInstance.actorSystemRefs}), because the card is\n * itself the grouping primitive and actor systems carry no a2a config.\n *\n * Both membership lists follow the same rule: OMITTED means \"the default\", PRESENT means \"exactly these,\n * and there must be at least one\". An empty array is rejected rather than silently meaning \"all\" on one\n * side and \"the default\" on the other.\n *\n * `ref` is the URL/audience segment: keep it short, stable and URL-safe — renaming it changes the\n * instance's audience and invalidates tokens minted for the old name.\n */\nconst resourceServerInstanceCommonShape = {\n /** URL + audience segment (`…/mcp/<ref>`). Short, stable, URL-safe; renaming invalidates tokens. */\n ref: z.string().min(1).regex(/^[a-z0-9][a-z0-9-]*$/, 'ref must be lowercase alphanumeric with dashes'),\n /** Human/agent-facing name — surfaced in the instance's discovery document (PRM / agent card). */\n displayName: z.string().min(1),\n /** What this surface is for; surfaced in discovery so a client can pick the right instance. */\n description: z.string(),\n};\n\n/**\n * A named **MCP server**: its own `/mcp/<ref>` URL, RFC 8707 audience, protected-resource metadata and\n * curated tool catalog. Membership is declared on the OPERATION (`operation.mcp.servers`), never here —\n * which is why this branch carries no membership list of its own.\n */\nexport const McpServerInstanceSchema = z.object({\n ...resourceServerInstanceCommonShape,\n kind: z.literal(ResourceServerKind.MCP),\n});\n\n/**\n * A named **A2A agent**: its own `/a2a/<ref>` URL, RFC 8707 audience, agent card and skill subset. A\n * distinct agent IDENTITY, not a view onto the default card.\n */\nexport const A2aAgentInstanceSchema = z.object({\n ...resourceServerInstanceCommonShape,\n kind: z.literal(ResourceServerKind.A2A),\n /**\n * The actor systems exposed as THIS agent's skills. OMITTED ⇒ every exposable system (the default\n * single-card behavior). PRESENT ⇒ exactly these, and at least one — an empty list is rejected at\n * startup rather than being read as \"all\", which would turn a typo into a silently WIDER agent.\n */\n actorSystemRefs: z.array(z.string()).min(1, 'actorSystemRefs must name at least one actor system when present — omit it to expose every exposable system').optional(),\n});\n\nexport const ResourceServerInstanceSchema = z.discriminatedUnion('kind', [McpServerInstanceSchema, A2aAgentInstanceSchema]);\n\n/** A named MCP server instance (see {@link McpServerInstanceSchema}). */\nexport type McpServerInstance = z.infer<typeof McpServerInstanceSchema>;\n/** A named A2A agent instance (see {@link A2aAgentInstanceSchema}). */\nexport type A2aAgentInstance = z.infer<typeof A2aAgentInstanceSchema>;\n/** Any named resource-server instance — narrow on `kind` to reach the kind-specific fields. */\nexport type ResourceServerInstance = z.infer<typeof ResourceServerInstanceSchema>;\n/** @wildo_source:part:end saas.models.resource-server-instance */\n"]}
|
|
1
|
+
{"version":3,"file":"oauth-resource-server.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/security/oauth-clients/oauth-resource-server.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,+CAA+C,CAAC;AAEzF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAN,IAAY,kBAOX;AAPD,WAAY,kBAAkB;IAC5B,uFAAuF;IACvF,iCAAW,CAAA;IACX,gGAAgG;IAChG,iCAAW,CAAA;IACX,uGAAuG;IACvG,iCAAW,CAAA;AACb,CAAC,EAPW,kBAAkB,KAAlB,kBAAkB,QAO7B;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAGpC;IACF,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,wBAAwB,CAAC,SAAS;IAC5D,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,wBAAwB,CAAC,YAAY;CAChE,CAAC;AAEF;yGACyG;AACzG,MAAM,CAAC,MAAM,gCAAgC,GAAkC;IAC7E,kBAAkB,CAAC,GAAG;IACtB,kBAAkB,CAAC,GAAG;CACvB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAkC;IAC3E,kBAAkB,CAAC,GAAG;IACtB,kBAAkB,CAAC,GAAG;IACtB,kBAAkB,CAAC,GAAG;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAkC;IAC1E,kBAAkB,CAAC,GAAG;IACtB,kBAAkB,CAAC,GAAG;CACvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,MAAM,iCAAiC,GAAG;IACxC,oGAAoG;IACpG,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,sBAAsB,EAAE,gDAAgD,CAAC;IACtG,kGAAkG;IAClG,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,+FAA+F;IAC/F,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,GAAG,iCAAiC;IACpC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC;CACxC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,GAAG,iCAAiC;IACpC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC;IACvC;;;;OAIG;IACH,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,6GAA6G,CAAC,CAAC,QAAQ,EAAE;CACtK,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,uBAAuB,EAAE,sBAAsB,CAAC,CAAC,CAAC;AAQ5H,kEAAkE","sourcesContent":["import { z } from 'zod';\nimport { ManualControllerRouteKey } from '../../requests/manual-controllers-routes-urls';\n\n/**\n * OAuth 2.0 **Resource Servers** exposed by a Wildo app — the token-CONSUMING surfaces, each\n * with its OWN canonical audience URI (RFC 8707 §2, \"Resource Indicators for OAuth 2.0\").\n *\n * ## What this is (and is NOT)\n *\n * A `ResourceServerKind` identifies WHICH endpoint may consume a token — it is an\n * **audience / transport** concept, a confused-deputy + token-replay defense\n * (RFC 8707: \"an audience-restricted access token … cannot then be taken by that resource\n * and presented elsewhere\"). It is **NOT** an authorization axis: it never decides WHAT a\n * token may do at a surface. Authorization at every resource server is **roles-only** — the\n * framework's RBAC (scope-based authorization was removed 2026-07-21). So:\n *\n * - **Audience** (this enum) answers *\"at which door may this token be presented?\"*\n * - **Roles** answer *\"what may it do once through that door?\"*\n *\n * The two compose; they are not competing vocabularies.\n *\n * ## The three resource servers\n *\n * | Kind | Surface | Canonical audience (`aud`) |\n * |-------|-------------------------------------------|-------------------------------------|\n * | `API` | generic HTTP resource API (CRUD) | `<appPublicBase>/api/v1` |\n * | `A2A` | Agent2Agent endpoint (external agents) | `<API audience>/a2a` |\n * | `MCP` | Model Context Protocol tool endpoint | `<API audience>/mcp` |\n *\n * ## Standards\n *\n * - **RFC 8707** — a token is minted `aud`-bound to the resource server it targets; the AS is\n * told the target via the `resource` request parameter.\n * - **RFC 9728** (Protected Resource Metadata) — each server publishes\n * `/.well-known/oauth-protected-resource` advertising its trusted authorization server.\n * - **MCP / A2A authorization specs** — the MCP server (and A2A agent) MUST verify a received\n * token is `aud`-restricted to ITSELF and MUST reject tokens not issued for it.\n *\n * Resolve a kind's canonical audience via\n * `AppConfigurationService.resolveResourceServerAudience(kind)` (backend) — the SINGLE SOURCE\n * OF TRUTH so minting and validation cannot drift.\n */\nexport enum ResourceServerKind {\n /** The generic HTTP resource API (CRUD on resources), mounted at the API base path. */\n API = 'api',\n /** The Agent2Agent (A2A) endpoint — external agents acting on behalf of a user or a machine. */\n A2A = 'a2a',\n /** The Model Context Protocol (MCP) endpoint — a curated subset of operations exposed as MCP tools. */\n MCP = 'mcp',\n}\n\n/**\n * The mount-path route each NON-`API` resource server appends to the API audience to form its\n * canonical audience URI (see {@link ResourceServerKind}). `API` is the API base itself, so it\n * is intentionally absent here. Keeping the mapping in `_core` next to the enum guarantees the\n * audience derivation is identical everywhere it is computed.\n */\nexport const RESOURCE_SERVER_MOUNT_ROUTE: Record<\n Exclude<ResourceServerKind, ResourceServerKind.API>,\n ManualControllerRouteKey\n> = {\n [ResourceServerKind.A2A]: ManualControllerRouteKey.A2A_TASKS,\n [ResourceServerKind.MCP]: ManualControllerRouteKey.MCP_ENDPOINT,\n};\n\n/** The resource servers that a USER-DELEGATED token may legitimately target (never the main API —\n * a delegated token must be confined to an agent surface, per B-S2 / the audience-confinement rule). */\nexport const DELEGATED_TOKEN_RESOURCE_SERVERS: readonly ResourceServerKind[] = [\n ResourceServerKind.A2A,\n ResourceServerKind.MCP,\n];\n\n/**\n * The resource servers a MACHINE (client-credentials) token may be audience-bound to — ALL of them.\n * Unlike a user-delegated token (confined to agent surfaces), a machine principal legitimately calls\n * the generic API directly AND the A2A / MCP endpoints. The `client_credentials` token endpoint\n * validates the requested RFC 8707 `resource` against this set and mints an `aud`-bound token for the\n * named surface (an absent `resource` deliberately selects the generic API audience). Each resource server then accepts\n * a token bound to its OWN audience (per-endpoint, tight) — the confused-deputy / token-passthrough\n * defense — while the main API accepts only the API audience, so a per-endpoint token cannot be\n * replayed there.\n */\nexport const MACHINE_TOKEN_RESOURCE_SERVERS: readonly ResourceServerKind[] = [\n ResourceServerKind.API,\n ResourceServerKind.A2A,\n ResourceServerKind.MCP,\n];\n\n/**\n * The resource-server kinds that support MULTIPLE NAMED INSTANCES (R-2). `API` is excluded: there is\n * exactly one generic resource API per app, so an instance ref never applies to it.\n */\nexport const INSTANCEABLE_RESOURCE_SERVERS: readonly ResourceServerKind[] = [\n ResourceServerKind.A2A,\n ResourceServerKind.MCP,\n];\n\n/**\n * @wildo_source:part:start saas.models.resource-server-instance facet:layer:shared facet:family:external-access\n *\n * A NAMED resource-server instance — one addressable external surface of a given\n * {@link ResourceServerKind}, with its OWN URL segment, RFC 8707 audience, discovery document, and\n * curated content. Declare instances on `ApplicationInitializationConfig.resourceServerInstances`\n * (your backend's initialization config). Import path: `@wildo-ai/saas-models`.\n *\n * This is a DISCRIMINATED UNION on `kind`, so the two surfaces cannot be confused at authoring time:\n * an MCP server has no `actorSystemRefs` (its membership is declared per-operation), and `kind: API`\n * is unrepresentable (there is exactly one generic resource API per app — see\n * {@link INSTANCEABLE_RESOURCE_SERVERS}). Both were previously only caught at startup, if at all.\n *\n * ## Why instances exist\n *\n * - **MCP** has no grouping primitive: a server exposes ONE flat `tools/list` and a client is\n * configured with ONE URL. Multiple named servers are therefore the only way to offer curated tool\n * subsets per consumer (e.g. a read-only `support` server vs a write-capable `ops` server) — which\n * also keeps tool counts small enough for reliable agent tool-choice.\n * - **A2A** groups SKILLS inside one agent card (a request targets one via `metadata.skillId`).\n * Multiple named agents therefore express distinct agent IDENTITIES (own card, own audience, own\n * skill subset) — skills remain the routing mechanism WITHIN an agent.\n *\n * ## What a named instance IS, and what it is NOT\n *\n * Each instance's canonical audience is `resolveResourceServerAudience(kind, ref)` → `…/<mount>/<ref>`.\n * An access token is RFC 8707 bound to exactly ONE instance, so **a token minted for one instance is\n * REJECTED at another** (the 2026-07-29 strict-audience flip makes this real, not advisory). That is a\n * TOKEN-REPLAY boundary: a leaked or misdirected token cannot be used on a sibling surface.\n *\n * It is **NOT a per-client capability grant**. Any client the app authorizes for a grant may request any\n * audience the app declares, exactly as at the generic API. What a caller may DO once through the door is\n * decided by **roles**, uniformly:\n *\n * > **MCP/A2A exposure can only ever be a SUBSET of what roles already permit — it never widens.**\n * > `mcp.exposed` and `mcp.servers` are CURATION applied BEFORE authorization, never instead of it: they\n * > decide which operations are shaped as agent tools and which surface advertises them. Every\n * > `tools/call` still re-runs the same role authorization the REST API runs, and primary scope resolves\n * > identically (a USER_SELF operation reaches the delegating user's own row; an ORG/APPLICATION-scoped\n * > operation runs in the machine token's or delegating user's scope).\n *\n * So curate a surface to make an agent's tool-choice reliable and to confine a token — and use ROLES when\n * a caller must be unable to perform an operation at all.\n *\n * ## Membership (deliberately asymmetric — the units differ)\n *\n * - **MCP**: the OPERATION opts in (`operation.mcp.servers`), beside its existing `mcp.exposed`.\n * - **A2A**: the AGENT lists its skills ({@link A2aAgentInstance.actorSystemRefs}), because the card is\n * itself the grouping primitive and actor systems carry no a2a config.\n *\n * Both membership lists follow the same rule: OMITTED means \"the default\", PRESENT means \"exactly these,\n * and there must be at least one\". An empty array is rejected rather than silently meaning \"all\" on one\n * side and \"the default\" on the other.\n *\n * `ref` is the URL/audience segment: keep it short, stable and URL-safe — renaming it changes the\n * instance's audience and invalidates tokens minted for the old name.\n */\nconst resourceServerInstanceCommonShape = {\n /** URL + audience segment (`…/mcp/<ref>`). Short, stable, URL-safe; renaming invalidates tokens. */\n ref: z.string().min(1).regex(/^[a-z0-9][a-z0-9-]*$/, 'ref must be lowercase alphanumeric with dashes'),\n /** Human/agent-facing name — surfaced in the instance's discovery document (PRM / agent card). */\n displayName: z.string().min(1),\n /** What this surface is for; surfaced in discovery so a client can pick the right instance. */\n description: z.string(),\n};\n\n/**\n * A named **MCP server**: its own `/mcp/<ref>` URL, RFC 8707 audience, protected-resource metadata and\n * curated tool catalog. Membership is declared on the OPERATION (`operation.mcp.servers`), never here —\n * which is why this branch carries no membership list of its own.\n */\nexport const McpServerInstanceSchema = z.object({\n ...resourceServerInstanceCommonShape,\n kind: z.literal(ResourceServerKind.MCP),\n});\n\n/**\n * A named **A2A agent**: its own `/a2a/<ref>` URL, RFC 8707 audience, agent card and skill subset. A\n * distinct agent IDENTITY, not a view onto the default card.\n */\nexport const A2aAgentInstanceSchema = z.object({\n ...resourceServerInstanceCommonShape,\n kind: z.literal(ResourceServerKind.A2A),\n /**\n * The actor systems exposed as THIS agent's skills. OMITTED ⇒ every exposable system (the default\n * single-card behavior). PRESENT ⇒ exactly these, and at least one — an empty list is rejected at\n * startup rather than being read as \"all\", which would turn a typo into a silently WIDER agent.\n */\n actorSystemRefs: z.array(z.string()).min(1, 'actorSystemRefs must name at least one actor system when present — omit it to expose every exposable system').optional(),\n});\n\nexport const ResourceServerInstanceSchema = z.discriminatedUnion('kind', [McpServerInstanceSchema, A2aAgentInstanceSchema]);\n\n/** A named MCP server instance (see {@link McpServerInstanceSchema}). */\nexport type McpServerInstance = z.infer<typeof McpServerInstanceSchema>;\n/** A named A2A agent instance (see {@link A2aAgentInstanceSchema}). */\nexport type A2aAgentInstance = z.infer<typeof A2aAgentInstanceSchema>;\n/** Any named resource-server instance — narrow on `kind` to reach the kind-specific fields. */\nexport type ResourceServerInstance = z.infer<typeof ResourceServerInstanceSchema>;\n/** @wildo_source:part:end saas.models.resource-server-instance */\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbound-target-control.shared.schemas.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"outbound-target-control.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/security/outbound-target-control.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,oBAAY,mBAAmB;IAC7B,0EAA0E;IAC1E,oBAAoB,yBAAyB;IAC7C,+FAA+F;IAC/F,8BAA8B,mCAAmC;IACjE;;;;OAIG;IACH,cAAc,mBAAmB;IACjC,8FAA8F;IAC9F,8BAA8B,mCAAmC;IACjE;;;;OAIG;IACH,2BAA2B,gCAAgC;IAC3D;;;OAGG;IACH,UAAU,eAAe;IACzB;;;;OAIG;IACH,0BAA0B,+BAA+B;CAC1D;AAED;;;;;;;GAOG;AACH,oBAAY,+BAA+B;IACzC,0GAA0G;IAC1G,IAAI,SAAS;IACb,4GAA4G;IAC5G,aAAa,kBAAkB;IAC/B,0GAA0G;IAC1G,eAAe,oBAAoB;CACpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbound-target-control.shared.schemas.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"outbound-target-control.shared.schemas.js","sourceRoot":"","sources":["../../../../src/security/outbound-target-control.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAN,IAAY,mBA8BX;AA9BD,WAAY,mBAAmB;IAC7B,0EAA0E;IAC1E,oEAA6C,CAAA;IAC7C,+FAA+F;IAC/F,wFAAiE,CAAA;IACjE;;;;OAIG;IACH,wDAAiC,CAAA;IACjC,8FAA8F;IAC9F,wFAAiE,CAAA;IACjE;;;;OAIG;IACH,kFAA2D,CAAA;IAC3D;;;OAGG;IACH,gDAAyB,CAAA;IACzB;;;;OAIG;IACH,gFAAyD,CAAA;AAC3D,CAAC,EA9BW,mBAAmB,KAAnB,mBAAmB,QA8B9B;AAED;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,+BAOX;AAPD,WAAY,+BAA+B;IACzC,0GAA0G;IAC1G,gDAAa,CAAA;IACb,4GAA4G;IAC5G,kEAA+B,CAAA;IAC/B,0GAA0G;IAC1G,sEAAmC,CAAA;AACrC,CAAC,EAPW,+BAA+B,KAA/B,+BAA+B,QAO1C","sourcesContent":["/**\n * The classes of server-side request whose DESTINATION is chosen by somebody other than the\n * deployment that makes the request — and how much of the private network each may reach.\n *\n * ## Why the class, and not the call site, is the unit\n *\n * The request-forgery question is never \"is this URL safe?\" in the abstract. It is \"who picked this\n * destination, and are they allowed to point this server at its own network?\". An organization\n * administrator who authors a webhook endpoint, an A2A client registering a push target, and an\n * unauthenticated stranger presenting an OAuth `client_id` URL all answer it differently — and the\n * application developer who writes a provider endpoint into the backend's own configuration is not a\n * request-forgery threat at all, because they already own the server.\n *\n * So the vocabulary names the CLASS of destination, by who authors it. Every engine site that issues\n * such a request declares which class it is serving, and the admission follows from the class plus\n * the operator-declared runtime environment — never from anything the destination's author can set.\n *\n * ## What is deliberately NOT a class\n *\n * Destinations the application's own code declares — a provider API endpoint, an `httpApiBinding`\n * base URL — are trusted as authored. What those sites must still refuse is a REMOTE server\n * re-pointing the request (a redirect), which is a property of the transport, not an admission.\n * Platform topology (the apps-manager, the module registry, infrastructure sidecars) is operator\n * configuration and private by design.\n */\nexport enum OutboundTargetClass {\n /** An M2M webhook endpoint. Authored by an organization administrator. */\n M2M_WEBHOOK_ENDPOINT = 'm2m_webhook_endpoint',\n /** An A2A push-notification target. Supplied by the external A2A client that registered it. */\n A2A_PUSH_NOTIFICATION_ENDPOINT = 'a2a_push_notification_endpoint',\n /**\n * A SIEM collector. Authored by an organization administrator; the one class the operator may\n * admit onto a private network, because a self-hosted collector on the same network is a supported\n * deployment shape.\n */\n SIEM_COLLECTOR = 'siem_collector',\n /** An OAuth client metadata document. Its URL is presented by an UNAUTHENTICATED stranger. */\n OAUTH_CLIENT_METADATA_DOCUMENT = 'oauth_client_metadata_document',\n /**\n * A federated identity provider's endpoints — OIDC discovery, token, userinfo, profile extension,\n * JWKS, SAML metadata and the SAML SSO/SLO reachability checks. Authored by an organization\n * administrator on an SSO connection, or discovered from a document that administrator's IdP serves.\n */\n FEDERATED_IDENTITY_PROVIDER = 'federated_identity_provider',\n /**\n * A remote MCP server an agent calls. Declared by the application, but it is a THIRD PARTY's\n * service, reached with the agent's delegated credentials, and its answers can re-point a request.\n */\n MCP_SERVER = 'mcp_server',\n /**\n * A download link an EMAIL provider hands back at runtime — the original bytes of a received message, an\n * attachment (#1600). The application declared the provider, but the VENDOR chose this URL, so it is admitted\n * only against the hosts the provider's contract declares, and never re-pointed by a redirect.\n */\n EMAIL_PROVIDER_CONTENT_URL = 'email_provider_content_url',\n}\n\n/**\n * How much of the network an outbound request may reach beyond the public internet.\n *\n * Three members rather than a boolean, because the useful middle is not \"private\" and not \"public\":\n * local development and automated test runs legitimately reach doubles on LOOPBACK, and nothing about\n * that justifies reaching the cloud instance-metadata address (link-local) or a cluster-internal\n * service (RFC 1918), which are the addresses a request-forgery attack actually wants.\n */\nexport enum OutboundPrivateAddressAdmission {\n /** Public addresses only. The default, and the only posture a stranger-supplied destination ever gets. */\n NONE = 'none',\n /** Public addresses plus loopback (`127.0.0.0/8`, `::1`, `localhost`). Never link-local, never RFC 1918. */\n LOOPBACK_ONLY = 'loopback_only',\n /** Any address. Only by an explicit operator declaration, and only for a class the operator may admit. */\n PRIVATE_NETWORK = 'private_network',\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submission-challenge.shared.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"submission-challenge.shared.d.ts","sourceRoot":"","sources":["../../../../../src/security/submission-challenge/submission-challenge.shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,iDAAiD;AACjD,oBAAY,+BAA+B;IACzC,0GAA0G;IAC1G,cAAc,mBAAmB;IACjC,qDAAqD;IACrD,aAAa,kBAAkB;CAChC;AAED;;;;;;;;GAQG;AACH,oBAAY,yBAAyB;IACnC,0DAA0D;IAC1D,eAAe,oBAAoB;CACpC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,mCAAmC,QAA4B,CAAC;AAE7E,gIAAgI;AAChI,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE/E;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,oCAAoC;IACnD,yHAAyH;IACzH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,4FAA4F;AAC5F,oBAAY,oBAAoB;IAC9B,OAAO,YAAY;CACpB;AAED,8GAA8G;AAC9G,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;IACzC,kGAAkG;IAClG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,kJAAkJ;IAClJ,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,4GAA4G;AAC5G,MAAM,MAAM,2BAA2B,GACnC;IACA,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC,cAAc,CAAC;IAC9D,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,GACC;IACA,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC,aAAa,CAAC;IAC7D,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;IACzC,oCAAoC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEJ;;;;GAIG;AACH,eAAO,MAAM,uCAAuC,yCAAyC,CAAC;AAE9F;;;;GAIG;AACH,oBAAY,8BAA8B;IACxC,kEAAkE;IAClE,QAAQ,kCAAkC;IAC1C,2CAA2C;IAC3C,OAAO,iCAAiC;CACzC;AAED,oGAAoG;AACpG,eAAO,MAAM,wCAAwC,OAAO,CAAC;AAE7D,+CAA+C;AAC/C,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,2BAA2B,GAAG,MAAM,CAE/F;AAMD,6FAA6F;AAC7F,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG5F;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,oBAAoB,EAC/B,OAAO,GAAE;IAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GAC5E,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC,CAUlD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submission-challenge.shared.js","sourceRoot":"","sources":["../../../../src/security/submission-challenge/submission-challenge.shared.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The challenge a public submission answers before the backend accepts it (#1735).\n *\n * ## Why two kinds, and why the second one is not optional\n *\n * A captcha vendor that analyses visitors for its own purposes needs their consent (Google reCAPTCHA:\n * CNIL Délibération SAN-2023-003, recorded on the frontend consent classification), so a visitor who\n * declines must still be able to submit. If declining meant \"no challenge\", a bot would decline too and\n * the captcha would protect nothing. So an application that protects a form accepts EITHER:\n *\n * - a vendor token (`PROVIDER_TOKEN`) — obtained by the consented vendor's browser part and verified by its\n * backend part (reCAPTCHA `siteverify`);\n * - a proof of work (`PROOF_OF_WORK`) — the engine's own challenge, consent-exempt because nothing leaves\n * the application and nothing is stored in the visitor's browser: the backend issues a salted SHA-256\n * puzzle signed with an application key, the browser searches for the number, the backend re-derives it.\n * It makes each submission cost the sender CPU time instead of identifying anyone.\n *\n * A submission with neither, or with one that fails, is refused: the challenge fails CLOSED.\n *\n * The proof-of-work scheme is ALTCHA's: challenge = SHA-256(salt + number), the client iterates numbers until the hash\n * matches. The signature here covers the salt as well as the hash (HMAC(salt + \"\\n\" + challenge)): the hash input has\n * no separator and the salt ends in its expiry digits, so a signature over the hash alone would let digits move from\n * the number onto the salt and forge a later expiry.\n * spec-cite: https://altcha.org/docs/proof-of-work/ (read through its search summary 2026-09-29) — the scheme\n * is described, not quoted; the field names below are this framework's own.\n *\n * ## Browser-safe on purpose\n *\n * The website's contact form encodes and solves challenges in the visitor's browser, so this file imports\n * nothing and uses only `globalThis.crypto.subtle`, which both browsers and Node provide.\n */\n\n/** Which kind of answer a submission carries. */\nexport enum SubmissionChallengeResponseKind {\n /** A token from a consented captcha vendor's browser part, verified by the same vendor's backend part. */\n PROVIDER_TOKEN = 'provider_token',\n /** The engine's own consent-exempt proof of work. */\n PROOF_OF_WORK = 'proof_of_work',\n}\n\n/**\n * The actions the ENGINE's own protected operations are bound to. A vendor token is minted for an action and the\n * backend refuses one minted for another, so a token solved on one form cannot be replayed on another.\n *\n * This enum names the engine's actions only. An application protects its OWN anonymous operation by declaring\n * `submissionChallenge: { action: '<its action>' }` on the operation variant (#1985), with an action it names in its\n * own vocabulary; see {@link ResourceOperationSubmissionChallenge} for why the declaration takes a name rather than a\n * member of this enum.\n */\nexport enum SubmissionChallengeAction {\n /** The public contact form (`POST /inbound-contacts`). */\n INBOUND_CONTACT = 'inbound_contact',\n}\n\n/**\n * The names a submission-challenge action may take: letters, digits, underscores and slashes, 1 to 100 characters.\n *\n * The character set is the captcha vendor's. The action is sent to Google reCAPTCHA as the `action` a token is minted\n * for and checked against on `siteverify`, and reCAPTCHA v3 states \"Actions might contain only alphanumeric\n * characters, slashes, and underscores.\" A name outside it would be minted by no vendor, so every token for it would\n * be refused. The 100-character bound is this framework's own: nothing longer is a name a person reads in a console.\n * spec-cite: https://developers.google.com/recaptcha/docs/v3 §\"Actions\" (fetched 2026-09-29)\n */\nexport const SUBMISSION_CHALLENGE_ACTION_PATTERN = /^[A-Za-z0-9_/]{1,100}$/u;\n\n/** Whether `value` is an action name a captcha vendor can mint a token for. See {@link SUBMISSION_CHALLENGE_ACTION_PATTERN}. */\nexport function isSubmissionChallengeActionName(value: unknown): value is string {\n return typeof value === 'string' && SUBMISSION_CHALLENGE_ACTION_PATTERN.test(value);\n}\n\n/**\n * An operation variant's declaration that an UNAUTHENTICATED caller answers a submission challenge (#1985).\n *\n * `action` is a NAME (an open identifier), not a member of {@link SubmissionChallengeAction}, so an application can\n * protect its own anonymous create (a waitlist, a quote request) without the engine growing a member for it. The\n * engine's own operations pass their enum member; an application passes a member of its own enum. What keeps the name\n * honest is the grammar ({@link SUBMISSION_CHALLENGE_ACTION_PATTERN}), which the resource factory enforces.\n *\n * Rejected alternatives, recorded because each was on the table:\n * - A closed engine enum grown one member per protected operation. The engine cannot know an application's forms, so\n * an application's own create could never be protected: exactly the gap this declaration closes.\n * - Deriving the action from the operation (`<resource>/<operation>`). It needs no authoring, but a resource or variant\n * identifier may carry characters the vendor refuses (a hyphen), so the derivation would have to rewrite them, and two\n * operations could then collide on one action with nothing saying so. A declared name is visible, reviewable and fixed.\n */\nexport interface ResourceOperationSubmissionChallenge {\n /** The action a vendor token must have been minted for. Name one per form: sharing it lets a token move between them. */\n readonly action: string;\n}\n\n/** The only hash the proof of work uses. Named so the wire value has one runtime source. */\nexport enum ProofOfWorkAlgorithm {\n SHA_256 = 'SHA-256',\n}\n\n/** A proof-of-work challenge as the backend issues it. Every field is echoed back unchanged in the answer. */\nexport interface ProofOfWorkChallenge {\n readonly algorithm: ProofOfWorkAlgorithm;\n /** Random, and carries the expiry (`<hex>?expires=<unix seconds>`) so the signature covers it. */\n readonly salt: string;\n /** Hex SHA-256 of `salt + number` for the secret number. */\n readonly challenge: string;\n /** The largest number the search has to try. */\n readonly maxNumber: number;\n /** Hex HMAC-SHA-256 of `salt`, a newline and `challenge`, under the application's challenge key — so the salt and its expiry cannot be edited. */\n readonly signature: string;\n}\n\n/** What a submission sends, in the `WildoHeaderKeys.SUBMISSION_CHALLENGE_RESPONSE` header, JSON-encoded. */\nexport type SubmissionChallengeResponse =\n | {\n readonly kind: SubmissionChallengeResponseKind.PROVIDER_TOKEN;\n /** The captcha provider whose browser part minted the token (`recaptcha`). */\n readonly providerRef: string;\n readonly token: string;\n }\n | {\n readonly kind: SubmissionChallengeResponseKind.PROOF_OF_WORK;\n readonly challenge: ProofOfWorkChallenge;\n /** The number the browser found. */\n readonly number: number;\n };\n\n/**\n * Where a browser asks for a proof-of-work challenge, under the API base path. The ONE source of this path: the\n * backend's route table (`MANUAL_CONTROLLER_ROUTES_URLS`) reads it from here, so a browser form can reach it without\n * pulling that whole table into its bundle.\n */\nexport const SUBMISSION_CHALLENGE_PROOF_OF_WORK_PATH = '/submission-challenges/proof-of-work';\n\n/**\n * The stable `error.code` of a refused public submission — what a client branches on (the engine hoists an error's\n * `context.code` to the top-level `error.code` of its response). A form answers either one again, with the proof of\n * work.\n */\nexport enum SubmissionChallengeRefusalCode {\n /** No answer was sent, and the application protects this form. */\n REQUIRED = 'SUBMISSION_CHALLENGE_REQUIRED',\n /** An answer was sent and not accepted. */\n REFUSED = 'SUBMISSION_CHALLENGE_REFUSED',\n}\n\n/** The largest encoded answer the backend reads; anything longer is refused before it is parsed. */\nexport const SUBMISSION_CHALLENGE_RESPONSE_MAX_LENGTH = 8192;\n\n/** Encode an answer for the request header. */\nexport function encodeSubmissionChallengeResponse(response: SubmissionChallengeResponse): string {\n return JSON.stringify(response);\n}\n\nfunction toHex(buffer: ArrayBuffer): string {\n return Array.from(new Uint8Array(buffer), (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\n/** Hex SHA-256 of `salt + number` — the one hash both the solver and the backend compute. */\nexport async function hashProofOfWorkCandidate(salt: string, number: number): Promise<string> {\n const digest = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(`${salt}${number}`));\n return toHex(digest);\n}\n\n/**\n * Find the number a challenge was built from, or `undefined` when none up to `maxNumber` matches (a\n * challenge not issued by this scheme). Yields to the event loop every `yieldEvery` tries so a page stays\n * responsive while it searches.\n */\nexport async function solveProofOfWorkChallenge(\n challenge: ProofOfWorkChallenge,\n options: { readonly yieldEvery?: number; readonly signal?: AbortSignal } = {},\n): Promise<SubmissionChallengeResponse | undefined> {\n const yieldEvery = options.yieldEvery ?? 1000;\n for (let number = 0; number <= challenge.maxNumber; number += 1) {\n if (options.signal?.aborted) return undefined;\n if (await hashProofOfWorkCandidate(challenge.salt, number) === challenge.challenge) {\n return { kind: SubmissionChallengeResponseKind.PROOF_OF_WORK, challenge, number };\n }\n if (number % yieldEvery === yieldEvery - 1) await new Promise((resolve) => setTimeout(resolve, 0));\n }\n return undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"submission-challenge.shared.js","sourceRoot":"","sources":["../../../../../src/security/submission-challenge/submission-challenge.shared.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The challenge a public submission answers before the backend accepts it (#1735).\n *\n * ## Why two kinds, and why the second one is not optional\n *\n * A captcha vendor that analyses visitors for its own purposes needs their consent (Google reCAPTCHA:\n * CNIL Délibération SAN-2023-003, recorded on the frontend consent classification), so a visitor who\n * declines must still be able to submit. If declining meant \"no challenge\", a bot would decline too and\n * the captcha would protect nothing. So an application that protects a form accepts EITHER:\n *\n * - a vendor token (`PROVIDER_TOKEN`) — obtained by the consented vendor's browser part and verified by its\n * backend part (reCAPTCHA `siteverify`);\n * - a proof of work (`PROOF_OF_WORK`) — the engine's own challenge, consent-exempt because nothing leaves\n * the application and nothing is stored in the visitor's browser: the backend issues a salted SHA-256\n * puzzle signed with an application key, the browser searches for the number, the backend re-derives it.\n * It makes each submission cost the sender CPU time instead of identifying anyone.\n *\n * A submission with neither, or with one that fails, is refused: the challenge fails CLOSED.\n *\n * The proof-of-work scheme is ALTCHA's: challenge = SHA-256(salt + number), the client iterates numbers until the hash\n * matches. The signature here covers the salt as well as the hash (HMAC(salt + \"\\n\" + challenge)): the hash input has\n * no separator and the salt ends in its expiry digits, so a signature over the hash alone would let digits move from\n * the number onto the salt and forge a later expiry.\n * spec-cite: https://altcha.org/docs/proof-of-work/ (read through its search summary 2026-09-29) — the scheme\n * is described, not quoted; the field names below are this framework's own.\n *\n * ## Browser-safe on purpose\n *\n * The website's contact form encodes and solves challenges in the visitor's browser, so this file imports\n * nothing and uses only `globalThis.crypto.subtle`, which both browsers and Node provide.\n */\n\n/** Which kind of answer a submission carries. */\nexport enum SubmissionChallengeResponseKind {\n /** A token from a consented captcha vendor's browser part, verified by the same vendor's backend part. */\n PROVIDER_TOKEN = 'provider_token',\n /** The engine's own consent-exempt proof of work. */\n PROOF_OF_WORK = 'proof_of_work',\n}\n\n/**\n * The actions the ENGINE's own protected operations are bound to. A vendor token is minted for an action and the\n * backend refuses one minted for another, so a token solved on one form cannot be replayed on another.\n *\n * This enum names the engine's actions only. An application protects its OWN anonymous operation by declaring\n * `submissionChallenge: { action: '<its action>' }` on the operation variant (#1985), with an action it names in its\n * own vocabulary; see {@link ResourceOperationSubmissionChallenge} for why the declaration takes a name rather than a\n * member of this enum.\n */\nexport enum SubmissionChallengeAction {\n /** The public contact form (`POST /inbound-contacts`). */\n INBOUND_CONTACT = 'inbound_contact',\n}\n\n/**\n * The names a submission-challenge action may take: letters, digits, underscores and slashes, 1 to 100 characters.\n *\n * The character set is the captcha vendor's. The action is sent to Google reCAPTCHA as the `action` a token is minted\n * for and checked against on `siteverify`, and reCAPTCHA v3 states \"Actions might contain only alphanumeric\n * characters, slashes, and underscores.\" A name outside it would be minted by no vendor, so every token for it would\n * be refused. The 100-character bound is this framework's own: nothing longer is a name a person reads in a console.\n * spec-cite: https://developers.google.com/recaptcha/docs/v3 §\"Actions\" (fetched 2026-09-29)\n */\nexport const SUBMISSION_CHALLENGE_ACTION_PATTERN = /^[A-Za-z0-9_/]{1,100}$/u;\n\n/** Whether `value` is an action name a captcha vendor can mint a token for. See {@link SUBMISSION_CHALLENGE_ACTION_PATTERN}. */\nexport function isSubmissionChallengeActionName(value: unknown): value is string {\n return typeof value === 'string' && SUBMISSION_CHALLENGE_ACTION_PATTERN.test(value);\n}\n\n/**\n * An operation variant's declaration that an UNAUTHENTICATED caller answers a submission challenge (#1985).\n *\n * `action` is a NAME (an open identifier), not a member of {@link SubmissionChallengeAction}, so an application can\n * protect its own anonymous create (a waitlist, a quote request) without the engine growing a member for it. The\n * engine's own operations pass their enum member; an application passes a member of its own enum. What keeps the name\n * honest is the grammar ({@link SUBMISSION_CHALLENGE_ACTION_PATTERN}), which the resource factory enforces.\n *\n * Rejected alternatives, recorded because each was on the table:\n * - A closed engine enum grown one member per protected operation. The engine cannot know an application's forms, so\n * an application's own create could never be protected: exactly the gap this declaration closes.\n * - Deriving the action from the operation (`<resource>/<operation>`). It needs no authoring, but a resource or variant\n * identifier may carry characters the vendor refuses (a hyphen), so the derivation would have to rewrite them, and two\n * operations could then collide on one action with nothing saying so. A declared name is visible, reviewable and fixed.\n */\nexport interface ResourceOperationSubmissionChallenge {\n /** The action a vendor token must have been minted for. Name one per form: sharing it lets a token move between them. */\n readonly action: string;\n}\n\n/** The only hash the proof of work uses. Named so the wire value has one runtime source. */\nexport enum ProofOfWorkAlgorithm {\n SHA_256 = 'SHA-256',\n}\n\n/** A proof-of-work challenge as the backend issues it. Every field is echoed back unchanged in the answer. */\nexport interface ProofOfWorkChallenge {\n readonly algorithm: ProofOfWorkAlgorithm;\n /** Random, and carries the expiry (`<hex>?expires=<unix seconds>`) so the signature covers it. */\n readonly salt: string;\n /** Hex SHA-256 of `salt + number` for the secret number. */\n readonly challenge: string;\n /** The largest number the search has to try. */\n readonly maxNumber: number;\n /** Hex HMAC-SHA-256 of `salt`, a newline and `challenge`, under the application's challenge key — so the salt and its expiry cannot be edited. */\n readonly signature: string;\n}\n\n/** What a submission sends, in the `WildoHeaderKeys.SUBMISSION_CHALLENGE_RESPONSE` header, JSON-encoded. */\nexport type SubmissionChallengeResponse =\n | {\n readonly kind: SubmissionChallengeResponseKind.PROVIDER_TOKEN;\n /** The captcha provider whose browser part minted the token (`recaptcha`). */\n readonly providerRef: string;\n readonly token: string;\n }\n | {\n readonly kind: SubmissionChallengeResponseKind.PROOF_OF_WORK;\n readonly challenge: ProofOfWorkChallenge;\n /** The number the browser found. */\n readonly number: number;\n };\n\n/**\n * Where a browser asks for a proof-of-work challenge, under the API base path. The ONE source of this path: the\n * backend's route table (`MANUAL_CONTROLLER_ROUTES_URLS`) reads it from here, so a browser form can reach it without\n * pulling that whole table into its bundle.\n */\nexport const SUBMISSION_CHALLENGE_PROOF_OF_WORK_PATH = '/submission-challenges/proof-of-work';\n\n/**\n * The stable `error.code` of a refused public submission — what a client branches on (the engine hoists an error's\n * `context.code` to the top-level `error.code` of its response). A form answers either one again, with the proof of\n * work.\n */\nexport enum SubmissionChallengeRefusalCode {\n /** No answer was sent, and the application protects this form. */\n REQUIRED = 'SUBMISSION_CHALLENGE_REQUIRED',\n /** An answer was sent and not accepted. */\n REFUSED = 'SUBMISSION_CHALLENGE_REFUSED',\n}\n\n/** The largest encoded answer the backend reads; anything longer is refused before it is parsed. */\nexport const SUBMISSION_CHALLENGE_RESPONSE_MAX_LENGTH = 8192;\n\n/** Encode an answer for the request header. */\nexport function encodeSubmissionChallengeResponse(response: SubmissionChallengeResponse): string {\n return JSON.stringify(response);\n}\n\nfunction toHex(buffer: ArrayBuffer): string {\n return Array.from(new Uint8Array(buffer), (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\n/** Hex SHA-256 of `salt + number` — the one hash both the solver and the backend compute. */\nexport async function hashProofOfWorkCandidate(salt: string, number: number): Promise<string> {\n const digest = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(`${salt}${number}`));\n return toHex(digest);\n}\n\n/**\n * Find the number a challenge was built from, or `undefined` when none up to `maxNumber` matches (a\n * challenge not issued by this scheme). Yields to the event loop every `yieldEvery` tries so a page stays\n * responsive while it searches.\n */\nexport async function solveProofOfWorkChallenge(\n challenge: ProofOfWorkChallenge,\n options: { readonly yieldEvery?: number; readonly signal?: AbortSignal } = {},\n): Promise<SubmissionChallengeResponse | undefined> {\n const yieldEvery = options.yieldEvery ?? 1000;\n for (let number = 0; number <= challenge.maxNumber; number += 1) {\n if (options.signal?.aborted) return undefined;\n if (await hashProofOfWorkCandidate(challenge.salt, number) === challenge.challenge) {\n return { kind: SubmissionChallengeResponseKind.PROOF_OF_WORK, challenge, number };\n }\n if (number % yieldEvery === yieldEvery - 1) await new Promise((resolve) => setTimeout(resolve, 0));\n }\n return undefined;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-of-record-actions.shared.schemas.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"system-of-record-actions.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/systems-of-record/system-of-record-actions.shared.schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-of-record-actions.shared.schemas.js","sourceRoot":"","sources":["../../../src/systems-of-record/system-of-record-actions.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Declared ACTIONS of a system of record (#1678) — the named vendor operations an application may run against the\n * ERP it reads, beside the row reads and row writes its read-through bindings already open.\n *\n * Posting an invoice (Odoo `account.move` `action_post`), confirming a sales order, an OData bound or unbound action:\n * none of them is a row write, and before this nothing declared one and nothing executed one. The only thing that\n * could run one was the systems-of-record registry's raw access hand-out, which returns an instance's credentials and\n * records nothing (#1738 withdrew it from every application-facing door).\n *\n * ## The decision these declarations implement (Paul, 2026-09-25, on #1677/#1678)\n *\n * One vendor may serve two roles through two SEPARATE lanes. The system-of-record lane declares named actions and runs\n * them under the INSTANCE's service identity, confined to the owner organization and to the member's partition, with\n * its own audit event. The same vendor may also be a classical provider with its own user or organization connections.\n * The two share a vendor identity for display and compliance, and never a credential or a runtime object (#1049 D10).\n * There is no Odoo provider package, and a provider operation can never name a system-of-record instance.\n *\n * ## WHERE an action is declared, and the placement that was rejected\n *\n * On a read-through BINDING (`httpApiBinding.actions`), both kinds:\n *\n * - a RECORD-targeted action on the binding of the entity it acts on, which supplies the key codec that decodes the\n * target id and the resource whose read gates decide whether the caller may reach that record;\n * - a RECORD-FREE action on the binding of the entity whose model (Odoo) or service (OData) the call is made against.\n *\n * Rejected: record-free actions on the INSTANCE (`systemsOfRecord.<name>.actions` in `wildo.saas.config.ts`). Three\n * reasons, any one sufficient. An action declares a Zod INPUT schema, and the saas configuration is parsed by the CLI\n * and the companion as data, where a schema object is not representable. An action declares the ROLES admitted to it,\n * which are the same role keys the resource's operations declare in `shared-lib`, and a second home for them would\n * drift. And the HTTP exposure of an action is a custom operation on a read-through resource, which lives in the\n * resource configuration anyway; the instance declaration is not in scope there (it lives in the application root, not\n * in `shared-lib`). What the instance keeps is what only the instance knows: whether its data is partitioned, which is\n * why a record-free action's partition stance is checked at boot, where both are visible.\n *\n * ## What is checked where\n *\n * - HERE, at authoring (the resource factory, through `assertHttpApiBindingDialectCoherence`): the call shape against\n * the binding's dialect, the target against the call shape, the refused vendor methods, the stance's placement.\n * - At BOOT (the resources registry, where the instance and the vendor facet are visible): the facet declares the call\n * shape, a record-free action on a PARTITIONED instance states its partition stance, and action names are unique per\n * instance.\n * - Per REQUEST (the system-of-record action executor): who may run it, on which record, and what it sends.\n */\nimport { z } from 'zod';\nimport { isZodObject } from '@wildo-ai/zod-decorators';\n\nimport { HttpApiTransportDialect } from '../http-api-binding/http-api-transport-dialect.shared';\n\n/** @wildo_source:part:start saas.models.system-of-record-actions facet:layer:shared facet:audience:app-developer */\n\n/**\n * The wire SHAPE of a vendor action — how the engine calls it. Declared by the VENDOR FACET (which shapes its product\n * supports, `actionCallShapes`) and chosen per action by its declaration.\n *\n * REST_JSON has no member: an arbitrary REST surface has no action convention to compile against, and a declared method\n * plus path template is a design of its own. A REST_JSON binding declaring an action is refused by name. (REST_JSON\n * ROW writes are declared per verb since #1728 — `operations.create` / `update` / `delete` — because a row write has a\n * fixed meaning a method and a path can carry; an action's meaning is the vendor's, and has no such shape.)\n */\nexport enum SystemOfRecordActionCallShape {\n /**\n * Odoo's `object.execute_kw(db, uid, key, model, method, positional, keyword)` — any public model method, the\n * credential inside the RPC arguments. A record-targeted call passes the record ids as its first positional\n * argument, which is how Odoo addresses a recordset method such as `action_post`.\n *\n * spec-cite: Odoo 18.0 developer documentation, External API — \"Calling methods\" (the execute_kw argument layout).\n */\n ODOO_EXECUTE_KW = 'odoo-execute-kw',\n /**\n * An OData v4 BOUND action: `POST <EntitySet>(<key>)/<Namespace>.<Action>`, parameters in the JSON body.\n *\n * spec-cite: OData Version 4.01 Part 1: Protocol §11.5.5 (Actions) and §11.5.5.1 (Invoking an Action).\n */\n ODATA_BOUND_ACTION = 'odata-bound-action',\n /**\n * An OData v4 UNBOUND action reached through its action import: `POST /<ActionImport>`, parameters in the JSON body.\n *\n * spec-cite: OData Version 4.01 Part 1: Protocol §11.5.5.1 (Invoking an Action).\n */\n ODATA_UNBOUND_ACTION = 'odata-unbound-action',\n}\n\n/**\n * The dialect each call shape is spoken over. Total over {@link SystemOfRecordActionCallShape}, so a new shape is a\n * compile error here until somebody says which dialect it belongs to.\n */\nexport const SYSTEM_OF_RECORD_ACTION_CALL_SHAPE_DIALECT: Readonly<Record<SystemOfRecordActionCallShape, HttpApiTransportDialect>> = Object.freeze({\n [SystemOfRecordActionCallShape.ODOO_EXECUTE_KW]: HttpApiTransportDialect.ODOO_JSONRPC,\n [SystemOfRecordActionCallShape.ODATA_BOUND_ACTION]: HttpApiTransportDialect.ODATA,\n [SystemOfRecordActionCallShape.ODATA_UNBOUND_ACTION]: HttpApiTransportDialect.ODATA,\n});\n\n/** What an action acts ON. */\nexport enum SystemOfRecordActionTarget {\n /**\n * ONE record of the binding's entity, addressed by its synthesized id. The record is READ FIRST through the binding's\n * read gates (owner organization, partition), so a caller can act only on a record it could see — and a record\n * outside its partition answers as absent, exactly as a read answers.\n */\n RECORD = 'record',\n /** No record: a model-level Odoo method (`create`) or an OData unbound action. */\n NONE = 'none',\n}\n\n/** Where an Odoo action's validated input goes in the `execute_kw` call. */\nexport enum SystemOfRecordOdooActionInputPlacement {\n /** The input object is the keyword-argument dict. The default: most recordset methods take options by keyword. */\n KEYWORD_ARGUMENTS = 'keyword-arguments',\n /**\n * The input object is the (next) POSITIONAL argument — after the id list on a record-targeted action, first on a\n * record-free one. `create(vals)` is the canonical case.\n */\n POSITIONAL = 'positional',\n /** The method takes nothing beyond its records (`action_post`). The declared input must then be empty. */\n NONE = 'none',\n}\n\n/**\n * How a RECORD-FREE action relates to the instance's partitions (#1058), required at boot when the instance is\n * partitioned. A record-targeted action needs none: the record it reads first carries its partition.\n */\nexport enum SystemOfRecordActionPartitionStanceKind {\n /**\n * The action touches no partitioned data — a lookup of a vendor setting, an action whose effect no partition owns.\n * The declaration must say WHY in `reason`, because a claim nothing checks has to be one a reviewer can read.\n */\n PARTITION_NEUTRAL = 'partition-neutral',\n /**\n * The action CARRIES the partition as one of its inputs, and the engine derives it from the caller's organization\n * unit exactly as a read-through create is placed (#1679): a member of one unit lands in its partition, a member of\n * several names the unit, and a caller may never supply the partition value itself.\n */\n MEMBER_UNIT_PARTITION = 'member-unit-partition',\n}\n\nexport const SystemOfRecordActionPartitionStanceSchema = z.discriminatedUnion('kind', [\n z.strictObject({\n kind: z.literal(SystemOfRecordActionPartitionStanceKind.PARTITION_NEUTRAL),\n /** Why no partition is reached. Read by a reviewer; nothing can verify it, which is why it is required. */\n reason: z.string().trim().min(20, 'Say why this action reaches no partitioned data — a reviewer reads this.'),\n }),\n z.strictObject({\n kind: z.literal(SystemOfRecordActionPartitionStanceKind.MEMBER_UNIT_PARTITION),\n /**\n * The REMOTE parameter the placed partition value is written into (`company_id`): a key of the Odoo keyword\n * arguments or of the positional input object, or a member of the OData body. The caller's input may not carry it.\n */\n parameter: z.string().min(1).max(120),\n }),\n]);\nexport type SystemOfRecordActionPartitionStance = z.infer<typeof SystemOfRecordActionPartitionStanceSchema>;\n\nexport const SystemOfRecordActionCallSchema = z.discriminatedUnion('shape', [\n z.strictObject({\n shape: z.literal(SystemOfRecordActionCallShape.ODOO_EXECUTE_KW),\n /** The model method, in Odoo's own spelling (`action_post`, `create`). */\n method: z.string().regex(/^[a-z_][a-z0-9_]*$/, 'An Odoo method name is snake_case.').max(120),\n /**\n * The model the call is made on, for a RECORD-FREE action only. A record-targeted action acts on the binding's own\n * model — the one its key codec and read gates describe — so naming another would decode the id against the wrong\n * entity. Absent means the binding's `entityRef`.\n */\n model: z.string().regex(/^[a-z_][a-z0-9_.]*$/, 'An Odoo model name is dotted snake_case.').max(120).optional(),\n inputPlacement: z.enum(SystemOfRecordOdooActionInputPlacement).default(SystemOfRecordOdooActionInputPlacement.KEYWORD_ARGUMENTS),\n }),\n z.strictObject({\n shape: z.literal(SystemOfRecordActionCallShape.ODATA_BOUND_ACTION),\n /** The namespace-qualified action name (`Microsoft.Dynamics.CRM.WinOpportunity`). */\n qualifiedName: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)+$/, 'A bound action is named Namespace.Action.').max(200),\n }),\n z.strictObject({\n shape: z.literal(SystemOfRecordActionCallShape.ODATA_UNBOUND_ACTION),\n /** The action import's name, as the service root exposes it. */\n actionImport: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/, 'An action import is a simple identifier.').max(200),\n }),\n]);\nexport type SystemOfRecordActionCall = z.infer<typeof SystemOfRecordActionCallSchema>;\n\n/**\n * The application's NAME for an action — lowerCamelCase, and distinct from the vendor's method name on purpose: the\n * name is what code, roles and audit rows speak (`postInvoice`), the call is what the vendor understands\n * (`account.move` `action_post`). Unique per INSTANCE across every binding, checked at boot, because callers address an\n * action by `(system, action)`.\n */\nexport const SYSTEM_OF_RECORD_ACTION_NAME_PATTERN = /^[a-z][a-zA-Z0-9]*$/;\nexport const SystemOfRecordActionNameSchema = z.string().regex(SYSTEM_OF_RECORD_ACTION_NAME_PATTERN, 'An action name is lowerCamelCase.').max(64);\n\n/** A Zod OBJECT schema carried as a value — an action's input contract. */\nconst zodObjectSchemaValue = z.custom<z.ZodObject<z.ZodRawShape>>(\n (value) => value !== null && typeof value === 'object' && isZodObject(value as z.ZodTypeAny),\n { message: 'An action input is a Zod object schema (z.object({...})).' },\n);\n/** Any Zod schema carried as a value — an action's output contract. */\nconst zodSchemaValue = z.custom<z.ZodTypeAny>(\n (value) => value !== null && typeof value === 'object' && typeof (value as { safeParse?: unknown }).safeParse === 'function',\n { message: 'An action output is a Zod schema.' },\n);\n\n/** ONE declared action. */\nexport const SystemOfRecordActionDeclarationSchema = z.strictObject({\n target: z.enum(SystemOfRecordActionTarget),\n call: SystemOfRecordActionCallSchema,\n /**\n * The input contract, validated BEFORE anything is sent. Strict parsing is the caller's contract: a key the schema\n * does not declare is refused rather than forwarded, so nothing reaches the vendor that the author did not name.\n */\n input: zodObjectSchemaValue,\n /**\n * The result contract. When declared, the vendor's answer is parsed through it and only the parsed value is returned;\n * an answer it rejects after the vendor APPLIED the action is reported as an unknown outcome, never as \"not done\".\n * Absent means the result is returned as the vendor sent it.\n */\n output: zodSchemaValue.optional(),\n /**\n * Whether the action CHANGES remote state. A writing action must carry an Idempotency-Key from EVERY caller, because a\n * remote change cannot be rolled back, and its interrupted attempts are reported as an unknown outcome rather than as\n * a failure. A non-writing action (a vendor computation that changes nothing) needs neither.\n */\n writes: z.boolean(),\n /**\n * Whether the VENDOR makes a repeated call harmless, so the transport may re-send it after a timeout or a 5xx. False\n * unless the vendor offers an idempotency mechanism for this call; Odoo offers none, so no Odoo action is retry-safe.\n * A writing action is never re-sent without an Idempotency-Key, whatever this says.\n */\n retrySafe: z.boolean().default(false),\n /**\n * The role keys admitted to run it, held in the OWNER organization (an organization role) or at application scope. A\n * role held only inside an organization UNIT admits the action on that unit's partition alone.\n */\n roles: z.array(z.string().min(1)).min(1),\n /**\n * Whether a context with NO user and no machine principal — the engine's own batch, cron and queue work, a webhook, an\n * autonomous agent with nobody behind it — may run it. Such a context then acts ORGANIZATION-WIDE on the owner\n * organization's behalf, which is exactly why it is off unless declared.\n */\n admitsSystemInitiation: z.boolean().default(false),\n /** A record-free action's relation to the instance's partitions; see {@link SystemOfRecordActionPartitionStanceKind}. */\n partitionStance: SystemOfRecordActionPartitionStanceSchema.optional(),\n /**\n * The resource operation that is this action's HTTP door, when it has one: a custom operation of the SAME resource\n * whose implementation hands the request to the system-of-record action executor. Absent means the action is reached\n * from code only.\n *\n * Naming the door HERE is what lets the resource factory tell an action from a row write. Without it, the only thing the\n * factory can see is the verb the operation borrows, and both available borrows were wrong (#1678 review, F1):\n *\n * - borrowing READ made a state-changing route a GET, and its required Idempotency-Key was refused at boot, because a\n * read-shaped operation claims its repeat changes nothing — Wonder Todos' backend could not start;\n * - borrowing UPDATE read as a ROW write, so the factory demanded `writableVerbs: [update]` — a door onto the bound\n * entity's rows that nobody asked for.\n *\n * A named door is exempt from the row-write rules and held to the action's own instead: a WRITING action's door borrows\n * a single-row mutation verb (so its route is not a GET and a retry is keyed), requires the key on every variant, and\n * runs INLINE. See `assertHttpApiWriteDeclarationCoherence`.\n */\n operation: z.string().min(1).optional(),\n});\nexport type SystemOfRecordActionDeclaration = z.infer<typeof SystemOfRecordActionDeclarationSchema>;\n/** What an author writes — defaulted fields optional. */\nexport type SystemOfRecordActionDeclarationAuthored = z.input<typeof SystemOfRecordActionDeclarationSchema>;\n\n/** Every action a binding declares, keyed by the application's action name. */\nexport const SystemOfRecordActionDeclarationsSchema = z.record(SystemOfRecordActionNameSchema, SystemOfRecordActionDeclarationSchema);\nexport type SystemOfRecordActionDeclarations = z.infer<typeof SystemOfRecordActionDeclarationsSchema>;\n\n/** @wildo_source:part:end saas.models.system-of-record-actions */\n\n/**\n * Odoo methods that READ, refused as actions.\n *\n * An action's answer is returned to its caller, and it is not confined the way the read lane confines rows: a\n * `search_read` declared as an action would hand a unit-confined member every company's rows. Reads go through the\n * read-through resource, whose pushdown and key-addressed admission are the confinement. A deny-list cannot be\n * complete — Odoo lets any public method be called — so an author reviews what a declared method returns; these are the\n * methods whose whole purpose is to return rows.\n */\nexport const ODOO_READ_METHODS_REFUSED_AS_ACTIONS: ReadonlySet<string> = new Set([\n 'read', 'search', 'search_read', 'search_count', 'read_group', 'name_search', 'name_get', 'fields_get',\n 'web_read', 'web_search_read', 'web_read_group', 'export_data', 'get_views', 'load_views', 'default_get',\n]);\n\n/**\n * Odoo methods that are ROW WRITES of the binding's own entity, refused as record-targeted actions: `write` and\n * `unlink` on the bound model are exactly what `writableVerbs` opens (#1679), with its payload rules and its field-level\n * trail. Declaring them as actions would open a second door onto the same change, one that skips both.\n */\nexport const ODOO_ROW_WRITE_METHODS_REFUSED_AS_RECORD_ACTIONS: ReadonlySet<string> = new Set(['write', 'unlink']);\n\n/**\n * Refuse every action declaration the engine could not honour, at AUTHORING (#1678). Throws a plain `Error` naming the\n * action and the fix; the resource factory wraps it with the resource identifier.\n *\n * What is NOT decidable here, and why: whether the vendor's facet supports the call shape and whether the instance is\n * partitioned both need the saas configuration and the facet map, which `shared-lib` does not see. Those are the boot\n * checks (`collectSystemOfRecordActionDeclarationViolations` in the backend).\n */\nexport function assertSystemOfRecordActionDeclarationsCoherence(params: {\n readonly dialect: HttpApiTransportDialect;\n readonly actions: SystemOfRecordActionDeclarations | undefined;\n}): void {\n const { dialect, actions } = params;\n for (const [actionName, action] of Object.entries(actions ?? {})) {\n const refuse = (why: string): never => {\n throw new Error(`actions.${actionName}: ${why}`);\n };\n if (dialect === HttpApiTransportDialect.REST_JSON) {\n refuse(\n 'a REST_JSON binding cannot declare actions: an arbitrary REST surface has no action convention for the engine to '\n + 'compile (its row writes are declared per verb in `operations`; an action has no such fixed shape). Declare the '\n + 'action on an Odoo or OData binding, or remove it.',\n );\n }\n const shapeDialect = SYSTEM_OF_RECORD_ACTION_CALL_SHAPE_DIALECT[action.call.shape];\n if (shapeDialect !== dialect) {\n refuse(`the call shape '${action.call.shape}' is spoken over ${shapeDialect}, and this binding speaks ${dialect}.`);\n }\n if (action.target === SystemOfRecordActionTarget.RECORD && action.call.shape === SystemOfRecordActionCallShape.ODATA_UNBOUND_ACTION) {\n refuse('an UNBOUND OData action acts on no record; declare target: none, or use a bound action.');\n }\n if (action.target === SystemOfRecordActionTarget.NONE && action.call.shape === SystemOfRecordActionCallShape.ODATA_BOUND_ACTION) {\n refuse('a BOUND OData action is invoked on a record; declare target: record, or use the unbound action import.');\n }\n if (action.target === SystemOfRecordActionTarget.RECORD && action.partitionStance !== undefined) {\n refuse(\n 'a record-targeted action takes its partition from the record it reads first, so a partition stance would be a second, '\n + 'unchecked answer to the same question. Remove partitionStance.',\n );\n }\n if (action.call.shape === SystemOfRecordActionCallShape.ODOO_EXECUTE_KW) {\n if (ODOO_READ_METHODS_REFUSED_AS_ACTIONS.has(action.call.method)) {\n refuse(\n `'${action.call.method}' reads rows, and an action's answer is not confined the way the read lane confines rows. `\n + 'Read through the read-through resource instead.',\n );\n }\n if (action.target === SystemOfRecordActionTarget.RECORD && action.call.model !== undefined) {\n refuse(\n 'a record-targeted action acts on the binding\\'s own model, whose key codec and read gates address the record; '\n + 'declare the action on the binding of the model it acts on, or make it record-free.',\n );\n }\n if (action.target === SystemOfRecordActionTarget.RECORD && ODOO_ROW_WRITE_METHODS_REFUSED_AS_RECORD_ACTIONS.has(action.call.method)) {\n refuse(`'${action.call.method}' is a row write of this binding's entity; open it through writableVerbs instead (#1679).`);\n }\n if (\n action.call.inputPlacement === SystemOfRecordOdooActionInputPlacement.NONE\n && Object.keys(action.input.shape).length > 0\n ) {\n refuse('inputPlacement \\'none\\' sends no input, so the declared input must be an empty object (z.object({})).');\n }\n }\n if (action.partitionStance?.kind === SystemOfRecordActionPartitionStanceKind.MEMBER_UNIT_PARTITION) {\n const parameter = action.partitionStance.parameter;\n if (Object.prototype.hasOwnProperty.call(action.input.shape, parameter)) {\n refuse(\n `the partition parameter '${parameter}' is placed by the engine from the caller's organization unit, so the input `\n + 'may not declare it — a caller who could send it would choose which company the action lands in.',\n );\n }\n if (action.call.shape === SystemOfRecordActionCallShape.ODOO_EXECUTE_KW\n && action.call.inputPlacement === SystemOfRecordOdooActionInputPlacement.NONE) {\n refuse('a member-unit partition is written into the input, and inputPlacement \\'none\\' sends no input.');\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"system-of-record-actions.shared.schemas.js","sourceRoot":"","sources":["../../../../src/systems-of-record/system-of-record-actions.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Declared ACTIONS of a system of record (#1678) — the named vendor operations an application may run against the\n * ERP it reads, beside the row reads and row writes its read-through bindings already open.\n *\n * Posting an invoice (Odoo `account.move` `action_post`), confirming a sales order, an OData bound or unbound action:\n * none of them is a row write, and before this nothing declared one and nothing executed one. The only thing that\n * could run one was the systems-of-record registry's raw access hand-out, which returns an instance's credentials and\n * records nothing (#1738 withdrew it from every application-facing door).\n *\n * ## The decision these declarations implement (Paul, 2026-09-25, on #1677/#1678)\n *\n * One vendor may serve two roles through two SEPARATE lanes. The system-of-record lane declares named actions and runs\n * them under the INSTANCE's service identity, confined to the owner organization and to the member's partition, with\n * its own audit event. The same vendor may also be a classical provider with its own user or organization connections.\n * The two share a vendor identity for display and compliance, and never a credential or a runtime object (#1049 D10).\n * There is no Odoo provider package, and a provider operation can never name a system-of-record instance.\n *\n * ## WHERE an action is declared, and the placement that was rejected\n *\n * On a read-through BINDING (`httpApiBinding.actions`), both kinds:\n *\n * - a RECORD-targeted action on the binding of the entity it acts on, which supplies the key codec that decodes the\n * target id and the resource whose read gates decide whether the caller may reach that record;\n * - a RECORD-FREE action on the binding of the entity whose model (Odoo) or service (OData) the call is made against.\n *\n * Rejected: record-free actions on the INSTANCE (`systemsOfRecord.<name>.actions` in `wildo.saas.config.ts`). Three\n * reasons, any one sufficient. An action declares a Zod INPUT schema, and the saas configuration is parsed by the CLI\n * and the companion as data, where a schema object is not representable. An action declares the ROLES admitted to it,\n * which are the same role keys the resource's operations declare in `shared-lib`, and a second home for them would\n * drift. And the HTTP exposure of an action is a custom operation on a read-through resource, which lives in the\n * resource configuration anyway; the instance declaration is not in scope there (it lives in the application root, not\n * in `shared-lib`). What the instance keeps is what only the instance knows: whether its data is partitioned, which is\n * why a record-free action's partition stance is checked at boot, where both are visible.\n *\n * ## What is checked where\n *\n * - HERE, at authoring (the resource factory, through `assertHttpApiBindingDialectCoherence`): the call shape against\n * the binding's dialect, the target against the call shape, the refused vendor methods, the stance's placement.\n * - At BOOT (the resources registry, where the instance and the vendor facet are visible): the facet declares the call\n * shape, a record-free action on a PARTITIONED instance states its partition stance, and action names are unique per\n * instance.\n * - Per REQUEST (the system-of-record action executor): who may run it, on which record, and what it sends.\n */\nimport { z } from 'zod';\nimport { isZodObject } from '@wildo-ai/zod-decorators';\n\nimport { HttpApiTransportDialect } from '../http-api-binding/http-api-transport-dialect.shared';\n\n/** @wildo_source:part:start saas.models.system-of-record-actions facet:layer:shared facet:audience:app-developer */\n\n/**\n * The wire SHAPE of a vendor action — how the engine calls it. Declared by the VENDOR FACET (which shapes its product\n * supports, `actionCallShapes`) and chosen per action by its declaration.\n *\n * REST_JSON has no member: an arbitrary REST surface has no action convention to compile against, and a declared method\n * plus path template is a design of its own. A REST_JSON binding declaring an action is refused by name. (REST_JSON\n * ROW writes are declared per verb since #1728 — `operations.create` / `update` / `delete` — because a row write has a\n * fixed meaning a method and a path can carry; an action's meaning is the vendor's, and has no such shape.)\n */\nexport enum SystemOfRecordActionCallShape {\n /**\n * Odoo's `object.execute_kw(db, uid, key, model, method, positional, keyword)` — any public model method, the\n * credential inside the RPC arguments. A record-targeted call passes the record ids as its first positional\n * argument, which is how Odoo addresses a recordset method such as `action_post`.\n *\n * spec-cite: Odoo 18.0 developer documentation, External API — \"Calling methods\" (the execute_kw argument layout).\n */\n ODOO_EXECUTE_KW = 'odoo-execute-kw',\n /**\n * An OData v4 BOUND action: `POST <EntitySet>(<key>)/<Namespace>.<Action>`, parameters in the JSON body.\n *\n * spec-cite: OData Version 4.01 Part 1: Protocol §11.5.5 (Actions) and §11.5.5.1 (Invoking an Action).\n */\n ODATA_BOUND_ACTION = 'odata-bound-action',\n /**\n * An OData v4 UNBOUND action reached through its action import: `POST /<ActionImport>`, parameters in the JSON body.\n *\n * spec-cite: OData Version 4.01 Part 1: Protocol §11.5.5.1 (Invoking an Action).\n */\n ODATA_UNBOUND_ACTION = 'odata-unbound-action',\n}\n\n/**\n * The dialect each call shape is spoken over. Total over {@link SystemOfRecordActionCallShape}, so a new shape is a\n * compile error here until somebody says which dialect it belongs to.\n */\nexport const SYSTEM_OF_RECORD_ACTION_CALL_SHAPE_DIALECT: Readonly<Record<SystemOfRecordActionCallShape, HttpApiTransportDialect>> = Object.freeze({\n [SystemOfRecordActionCallShape.ODOO_EXECUTE_KW]: HttpApiTransportDialect.ODOO_JSONRPC,\n [SystemOfRecordActionCallShape.ODATA_BOUND_ACTION]: HttpApiTransportDialect.ODATA,\n [SystemOfRecordActionCallShape.ODATA_UNBOUND_ACTION]: HttpApiTransportDialect.ODATA,\n});\n\n/** What an action acts ON. */\nexport enum SystemOfRecordActionTarget {\n /**\n * ONE record of the binding's entity, addressed by its synthesized id. The record is READ FIRST through the binding's\n * read gates (owner organization, partition), so a caller can act only on a record it could see — and a record\n * outside its partition answers as absent, exactly as a read answers.\n */\n RECORD = 'record',\n /** No record: a model-level Odoo method (`create`) or an OData unbound action. */\n NONE = 'none',\n}\n\n/** Where an Odoo action's validated input goes in the `execute_kw` call. */\nexport enum SystemOfRecordOdooActionInputPlacement {\n /** The input object is the keyword-argument dict. The default: most recordset methods take options by keyword. */\n KEYWORD_ARGUMENTS = 'keyword-arguments',\n /**\n * The input object is the (next) POSITIONAL argument — after the id list on a record-targeted action, first on a\n * record-free one. `create(vals)` is the canonical case.\n */\n POSITIONAL = 'positional',\n /** The method takes nothing beyond its records (`action_post`). The declared input must then be empty. */\n NONE = 'none',\n}\n\n/**\n * How a RECORD-FREE action relates to the instance's partitions (#1058), required at boot when the instance is\n * partitioned. A record-targeted action needs none: the record it reads first carries its partition.\n */\nexport enum SystemOfRecordActionPartitionStanceKind {\n /**\n * The action touches no partitioned data — a lookup of a vendor setting, an action whose effect no partition owns.\n * The declaration must say WHY in `reason`, because a claim nothing checks has to be one a reviewer can read.\n */\n PARTITION_NEUTRAL = 'partition-neutral',\n /**\n * The action CARRIES the partition as one of its inputs, and the engine derives it from the caller's organization\n * unit exactly as a read-through create is placed (#1679): a member of one unit lands in its partition, a member of\n * several names the unit, and a caller may never supply the partition value itself.\n */\n MEMBER_UNIT_PARTITION = 'member-unit-partition',\n}\n\nexport const SystemOfRecordActionPartitionStanceSchema = z.discriminatedUnion('kind', [\n z.strictObject({\n kind: z.literal(SystemOfRecordActionPartitionStanceKind.PARTITION_NEUTRAL),\n /** Why no partition is reached. Read by a reviewer; nothing can verify it, which is why it is required. */\n reason: z.string().trim().min(20, 'Say why this action reaches no partitioned data — a reviewer reads this.'),\n }),\n z.strictObject({\n kind: z.literal(SystemOfRecordActionPartitionStanceKind.MEMBER_UNIT_PARTITION),\n /**\n * The REMOTE parameter the placed partition value is written into (`company_id`): a key of the Odoo keyword\n * arguments or of the positional input object, or a member of the OData body. The caller's input may not carry it.\n */\n parameter: z.string().min(1).max(120),\n }),\n]);\nexport type SystemOfRecordActionPartitionStance = z.infer<typeof SystemOfRecordActionPartitionStanceSchema>;\n\nexport const SystemOfRecordActionCallSchema = z.discriminatedUnion('shape', [\n z.strictObject({\n shape: z.literal(SystemOfRecordActionCallShape.ODOO_EXECUTE_KW),\n /** The model method, in Odoo's own spelling (`action_post`, `create`). */\n method: z.string().regex(/^[a-z_][a-z0-9_]*$/, 'An Odoo method name is snake_case.').max(120),\n /**\n * The model the call is made on, for a RECORD-FREE action only. A record-targeted action acts on the binding's own\n * model — the one its key codec and read gates describe — so naming another would decode the id against the wrong\n * entity. Absent means the binding's `entityRef`.\n */\n model: z.string().regex(/^[a-z_][a-z0-9_.]*$/, 'An Odoo model name is dotted snake_case.').max(120).optional(),\n inputPlacement: z.enum(SystemOfRecordOdooActionInputPlacement).default(SystemOfRecordOdooActionInputPlacement.KEYWORD_ARGUMENTS),\n }),\n z.strictObject({\n shape: z.literal(SystemOfRecordActionCallShape.ODATA_BOUND_ACTION),\n /** The namespace-qualified action name (`Microsoft.Dynamics.CRM.WinOpportunity`). */\n qualifiedName: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)+$/, 'A bound action is named Namespace.Action.').max(200),\n }),\n z.strictObject({\n shape: z.literal(SystemOfRecordActionCallShape.ODATA_UNBOUND_ACTION),\n /** The action import's name, as the service root exposes it. */\n actionImport: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/, 'An action import is a simple identifier.').max(200),\n }),\n]);\nexport type SystemOfRecordActionCall = z.infer<typeof SystemOfRecordActionCallSchema>;\n\n/**\n * The application's NAME for an action — lowerCamelCase, and distinct from the vendor's method name on purpose: the\n * name is what code, roles and audit rows speak (`postInvoice`), the call is what the vendor understands\n * (`account.move` `action_post`). Unique per INSTANCE across every binding, checked at boot, because callers address an\n * action by `(system, action)`.\n */\nexport const SYSTEM_OF_RECORD_ACTION_NAME_PATTERN = /^[a-z][a-zA-Z0-9]*$/;\nexport const SystemOfRecordActionNameSchema = z.string().regex(SYSTEM_OF_RECORD_ACTION_NAME_PATTERN, 'An action name is lowerCamelCase.').max(64);\n\n/** A Zod OBJECT schema carried as a value — an action's input contract. */\nconst zodObjectSchemaValue = z.custom<z.ZodObject<z.ZodRawShape>>(\n (value) => value !== null && typeof value === 'object' && isZodObject(value as z.ZodTypeAny),\n { message: 'An action input is a Zod object schema (z.object({...})).' },\n);\n/** Any Zod schema carried as a value — an action's output contract. */\nconst zodSchemaValue = z.custom<z.ZodTypeAny>(\n (value) => value !== null && typeof value === 'object' && typeof (value as { safeParse?: unknown }).safeParse === 'function',\n { message: 'An action output is a Zod schema.' },\n);\n\n/** ONE declared action. */\nexport const SystemOfRecordActionDeclarationSchema = z.strictObject({\n target: z.enum(SystemOfRecordActionTarget),\n call: SystemOfRecordActionCallSchema,\n /**\n * The input contract, validated BEFORE anything is sent. Strict parsing is the caller's contract: a key the schema\n * does not declare is refused rather than forwarded, so nothing reaches the vendor that the author did not name.\n */\n input: zodObjectSchemaValue,\n /**\n * The result contract. When declared, the vendor's answer is parsed through it and only the parsed value is returned;\n * an answer it rejects after the vendor APPLIED the action is reported as an unknown outcome, never as \"not done\".\n * Absent means the result is returned as the vendor sent it.\n */\n output: zodSchemaValue.optional(),\n /**\n * Whether the action CHANGES remote state. A writing action must carry an Idempotency-Key from EVERY caller, because a\n * remote change cannot be rolled back, and its interrupted attempts are reported as an unknown outcome rather than as\n * a failure. A non-writing action (a vendor computation that changes nothing) needs neither.\n */\n writes: z.boolean(),\n /**\n * Whether the VENDOR makes a repeated call harmless, so the transport may re-send it after a timeout or a 5xx. False\n * unless the vendor offers an idempotency mechanism for this call; Odoo offers none, so no Odoo action is retry-safe.\n * A writing action is never re-sent without an Idempotency-Key, whatever this says.\n */\n retrySafe: z.boolean().default(false),\n /**\n * The role keys admitted to run it, held in the OWNER organization (an organization role) or at application scope. A\n * role held only inside an organization UNIT admits the action on that unit's partition alone.\n */\n roles: z.array(z.string().min(1)).min(1),\n /**\n * Whether a context with NO user and no machine principal — the engine's own batch, cron and queue work, a webhook, an\n * autonomous agent with nobody behind it — may run it. Such a context then acts ORGANIZATION-WIDE on the owner\n * organization's behalf, which is exactly why it is off unless declared.\n */\n admitsSystemInitiation: z.boolean().default(false),\n /** A record-free action's relation to the instance's partitions; see {@link SystemOfRecordActionPartitionStanceKind}. */\n partitionStance: SystemOfRecordActionPartitionStanceSchema.optional(),\n /**\n * The resource operation that is this action's HTTP door, when it has one: a custom operation of the SAME resource\n * whose implementation hands the request to the system-of-record action executor. Absent means the action is reached\n * from code only.\n *\n * Naming the door HERE is what lets the resource factory tell an action from a row write. Without it, the only thing the\n * factory can see is the verb the operation borrows, and both available borrows were wrong (#1678 review, F1):\n *\n * - borrowing READ made a state-changing route a GET, and its required Idempotency-Key was refused at boot, because a\n * read-shaped operation claims its repeat changes nothing — Wonder Todos' backend could not start;\n * - borrowing UPDATE read as a ROW write, so the factory demanded `writableVerbs: [update]` — a door onto the bound\n * entity's rows that nobody asked for.\n *\n * A named door is exempt from the row-write rules and held to the action's own instead: a WRITING action's door borrows\n * a single-row mutation verb (so its route is not a GET and a retry is keyed), requires the key on every variant, and\n * runs INLINE. See `assertHttpApiWriteDeclarationCoherence`.\n */\n operation: z.string().min(1).optional(),\n});\nexport type SystemOfRecordActionDeclaration = z.infer<typeof SystemOfRecordActionDeclarationSchema>;\n/** What an author writes — defaulted fields optional. */\nexport type SystemOfRecordActionDeclarationAuthored = z.input<typeof SystemOfRecordActionDeclarationSchema>;\n\n/** Every action a binding declares, keyed by the application's action name. */\nexport const SystemOfRecordActionDeclarationsSchema = z.record(SystemOfRecordActionNameSchema, SystemOfRecordActionDeclarationSchema);\nexport type SystemOfRecordActionDeclarations = z.infer<typeof SystemOfRecordActionDeclarationsSchema>;\n\n/** @wildo_source:part:end saas.models.system-of-record-actions */\n\n/**\n * Odoo methods that READ, refused as actions.\n *\n * An action's answer is returned to its caller, and it is not confined the way the read lane confines rows: a\n * `search_read` declared as an action would hand a unit-confined member every company's rows. Reads go through the\n * read-through resource, whose pushdown and key-addressed admission are the confinement. A deny-list cannot be\n * complete — Odoo lets any public method be called — so an author reviews what a declared method returns; these are the\n * methods whose whole purpose is to return rows.\n */\nexport const ODOO_READ_METHODS_REFUSED_AS_ACTIONS: ReadonlySet<string> = new Set([\n 'read', 'search', 'search_read', 'search_count', 'read_group', 'name_search', 'name_get', 'fields_get',\n 'web_read', 'web_search_read', 'web_read_group', 'export_data', 'get_views', 'load_views', 'default_get',\n]);\n\n/**\n * Odoo methods that are ROW WRITES of the binding's own entity, refused as record-targeted actions: `write` and\n * `unlink` on the bound model are exactly what `writableVerbs` opens (#1679), with its payload rules and its field-level\n * trail. Declaring them as actions would open a second door onto the same change, one that skips both.\n */\nexport const ODOO_ROW_WRITE_METHODS_REFUSED_AS_RECORD_ACTIONS: ReadonlySet<string> = new Set(['write', 'unlink']);\n\n/**\n * Refuse every action declaration the engine could not honour, at AUTHORING (#1678). Throws a plain `Error` naming the\n * action and the fix; the resource factory wraps it with the resource identifier.\n *\n * What is NOT decidable here, and why: whether the vendor's facet supports the call shape and whether the instance is\n * partitioned both need the saas configuration and the facet map, which `shared-lib` does not see. Those are the boot\n * checks (`collectSystemOfRecordActionDeclarationViolations` in the backend).\n */\nexport function assertSystemOfRecordActionDeclarationsCoherence(params: {\n readonly dialect: HttpApiTransportDialect;\n readonly actions: SystemOfRecordActionDeclarations | undefined;\n}): void {\n const { dialect, actions } = params;\n for (const [actionName, action] of Object.entries(actions ?? {})) {\n const refuse = (why: string): never => {\n throw new Error(`actions.${actionName}: ${why}`);\n };\n if (dialect === HttpApiTransportDialect.REST_JSON) {\n refuse(\n 'a REST_JSON binding cannot declare actions: an arbitrary REST surface has no action convention for the engine to '\n + 'compile (its row writes are declared per verb in `operations`; an action has no such fixed shape). Declare the '\n + 'action on an Odoo or OData binding, or remove it.',\n );\n }\n const shapeDialect = SYSTEM_OF_RECORD_ACTION_CALL_SHAPE_DIALECT[action.call.shape];\n if (shapeDialect !== dialect) {\n refuse(`the call shape '${action.call.shape}' is spoken over ${shapeDialect}, and this binding speaks ${dialect}.`);\n }\n if (action.target === SystemOfRecordActionTarget.RECORD && action.call.shape === SystemOfRecordActionCallShape.ODATA_UNBOUND_ACTION) {\n refuse('an UNBOUND OData action acts on no record; declare target: none, or use a bound action.');\n }\n if (action.target === SystemOfRecordActionTarget.NONE && action.call.shape === SystemOfRecordActionCallShape.ODATA_BOUND_ACTION) {\n refuse('a BOUND OData action is invoked on a record; declare target: record, or use the unbound action import.');\n }\n if (action.target === SystemOfRecordActionTarget.RECORD && action.partitionStance !== undefined) {\n refuse(\n 'a record-targeted action takes its partition from the record it reads first, so a partition stance would be a second, '\n + 'unchecked answer to the same question. Remove partitionStance.',\n );\n }\n if (action.call.shape === SystemOfRecordActionCallShape.ODOO_EXECUTE_KW) {\n if (ODOO_READ_METHODS_REFUSED_AS_ACTIONS.has(action.call.method)) {\n refuse(\n `'${action.call.method}' reads rows, and an action's answer is not confined the way the read lane confines rows. `\n + 'Read through the read-through resource instead.',\n );\n }\n if (action.target === SystemOfRecordActionTarget.RECORD && action.call.model !== undefined) {\n refuse(\n 'a record-targeted action acts on the binding\\'s own model, whose key codec and read gates address the record; '\n + 'declare the action on the binding of the model it acts on, or make it record-free.',\n );\n }\n if (action.target === SystemOfRecordActionTarget.RECORD && ODOO_ROW_WRITE_METHODS_REFUSED_AS_RECORD_ACTIONS.has(action.call.method)) {\n refuse(`'${action.call.method}' is a row write of this binding's entity; open it through writableVerbs instead (#1679).`);\n }\n if (\n action.call.inputPlacement === SystemOfRecordOdooActionInputPlacement.NONE\n && Object.keys(action.input.shape).length > 0\n ) {\n refuse('inputPlacement \\'none\\' sends no input, so the declared input must be an empty object (z.object({})).');\n }\n }\n if (action.partitionStance?.kind === SystemOfRecordActionPartitionStanceKind.MEMBER_UNIT_PARTITION) {\n const parameter = action.partitionStance.parameter;\n if (Object.prototype.hasOwnProperty.call(action.input.shape, parameter)) {\n refuse(\n `the partition parameter '${parameter}' is placed by the engine from the caller's organization unit, so the input `\n + 'may not declare it — a caller who could send it would choose which company the action lands in.',\n );\n }\n if (action.call.shape === SystemOfRecordActionCallShape.ODOO_EXECUTE_KW\n && action.call.inputPlacement === SystemOfRecordOdooActionInputPlacement.NONE) {\n refuse('a member-unit partition is written into the input, and inputPlacement \\'none\\' sends no input.');\n }\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-of-record-credential-kind.shared.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"system-of-record-credential-kind.shared.d.ts","sourceRoot":"","sources":["../../../../src/systems-of-record/system-of-record-credential-kind.shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAEH;;;;;GAKG;AACH,oBAAY,4BAA4B;IACtC;;;;;;;;OAQG;IACH,oBAAoB,yBAAyB;IAE7C;;;;;;;;OAQG;IACH,cAAc,mBAAmB;IAEjC;;;;;;;;;OASG;IACH,aAAa,kBAAkB;IAE/B;;;;;;;;;;;OAWG;IACH,KAAK,UAAU;IAEf;;;;;;;;OAQG;IACH,gCAAgC,qCAAqC;IAErE;;;;;;;;;;;;;;;;OAgBG;IACH,qCAAqC,0CAA0C;IAE/E;;;;;;;;;OASG;IACH,iBAAiB,sBAAsB;CACxC;AAED,uGAAuG;AACvG,wBAAgB,sCAAsC,CAAC,IAAI,EAAE,4BAA4B,GAAG,OAAO,CAIlG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-of-record-credential-kind.shared.js","sourceRoot":"","sources":["../../../src/systems-of-record/system-of-record-credential-kind.shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAEH;;;;;GAKG;AACH,MAAM,CAAN,IAAY,4BA0FX;AA1FD,WAAY,4BAA4B;IACtC;;;;;;;;OAQG;IACH,6EAA6C,CAAA;IAE7C;;;;;;;;OAQG;IACH,iEAAiC,CAAA;IAEjC;;;;;;;;;OASG;IACH,+DAA+B,CAAA;IAE/B;;;;;;;;;;;OAWG;IACH,+CAAe,CAAA;IAEf;;;;;;;;OAQG;IACH,qGAAqE,CAAA;IAErE;;;;;;;;;;;;;;;;OAgBG;IACH,+GAA+E,CAAA;IAE/E;;;;;;;;;OASG;IACH,uEAAuC,CAAA;AACzC,CAAC,EA1FW,4BAA4B,KAA5B,4BAA4B,QA0FvC;AAED,uGAAuG;AACvG,MAAM,UAAU,sCAAsC,CAAC,IAAkC;IACvF,OAAO,IAAI,KAAK,4BAA4B,CAAC,gCAAgC;WACxE,IAAI,KAAK,4BAA4B,CAAC,qCAAqC;WAC3E,IAAI,KAAK,4BAA4B,CAAC,iBAAiB,CAAC;AAC/D,CAAC","sourcesContent":["/**\n * `SystemOfRecordCredentialKind` — HOW the engine authenticates to a system of record.\n *\n * A root-exported boundary module, for the same package-contract reason as its sibling\n * `HttpApiTransportDialect` (#1055 R3): the ROOT-exported application-configuration contract\n * (`systemsOfRecord.<name>.credential.kind`) names this vocabulary, and a TypeScript `enum` is\n * NOMINAL — a root-only consumer that cannot reach the declaring module through a public specifier\n * gets `TS2742`/`TS2883`. `.claude/rules/package-public-entrypoints.md` prescribes moving the\n * boundary rather than re-exporting across it, so the `external-data` subpath does NOT re-export\n * this module.\n *\n * ## Why it is a separate vocabulary from the dialect\n *\n * A dialect says how to SPEAK (query protocol, envelope, filter language); a credential kind says\n * how to PROVE WHO YOU ARE. Odoo happens to pair one with the other today, and that coincidence is\n * exactly what `CLAUDE.md` forbids merging on: an OData v4 service reached with a bearer token and\n * the same service reached with client-credentials OAuth2 differ in the second axis and not the\n * first. Keeping them apart costs one enum and stops the pairing from being baked into the model.\n *\n * ## What a kind OWNS (#1055 R15, the slot-ownership decision)\n *\n * The kind owns the inputs IT needs — its secret slots, and any address slot that exists only\n * because of the kind. `OAUTH2_CLIENT_CREDENTIALS_SECRET` owns `tokenUrl`, which no vendor would\n * declare if it were reached with a static key. The FACET owns the vendor's own address slots and\n * the OFFERS it makes (a kind plus that vendor's policy for it); the INSTANCE chooses one offer.\n *\n * A third owner arrived with #1056 and is worth naming, because two of the three are easy to\n * confuse: the FACET also owns everything about a kind that varies BY VENDOR but not by deployment —\n * which header carries a static key, whether a token answer omits `expires_in`, whether an assertion\n * header needs a supplied `kid` or a derived `x5t`. Those are not slots: nobody types them per\n * environment, and asking an operator for them would be asking a question the facet already holds\n * the answer to (`derive-before-you-ask.md`).\n * The contracts themselves live beside the facet schema, on the `external-data` subpath, because\n * nothing root-exported needs to name a slot SHAPE — only the kind's NAME.\n *\n * ## How the catalogue grew, and what is still missing from it\n *\n * #1055 shipped ONE member, the one kind its one facet offered. #1056 added the six a service\n * identity actually needs across the vendors epic #1049 §4.6 surveyed — two static-key placements,\n * HTTP Basic, and three OAuth2 shapes. A member here with no entry in\n * `SYSTEM_OF_RECORD_CREDENTIAL_KIND_CONTRACTS` is a compile error, so the two cannot drift.\n *\n * `MTLS_CLIENT_CERTIFICATE` is deliberately ABSENT and is #1263. It is not a seventh variation on\n * composing a request: every kind here decides what to put IN a request, and mTLS decides how the\n * CONNECTION is made, which `HttpApiFetchLike` has no channel for (its `init` carries no\n * dispatcher). Adding it means widening the one outbound seam both this lane and the connector lane\n * run on — a different blast radius, and the reason SAP is declared unsupported-by-kind in #1057\n * rather than every other vendor waiting behind it.\n *\n * ## The root-only probe, measured 2026-09-15\n *\n * `package-public-entrypoints.md` asks for a measurement rather than a category judgement. A\n * consumer importing ONLY the package root, deriving values from this enum and emitting with\n * `declaration: true`:\n *\n * ```\n * export declare const declaredKind = SystemOfRecordCredentialKind.ODOO_API_KEY_IN_ARGS;\n * export declare function pickInstance(): { kind: SystemOfRecordCredentialKind; dialect: HttpApiTransportDialect };\n * ```\n *\n * Zero errors, and the emitted declaration NAMES the enum through the root specifier rather than a\n * `node_modules/.../dist/esm/...` path. The probe's negative control — importing\n * `SystemOfRecordVendorFacetSchema`, which is deliberately subpath-only — fails with `TS2305`, so\n * the probe discriminates rather than passing everything.\n */\n\n/**\n * How the engine proves its identity to a system of record. Closed vocabulary — a system of record\n * spends the APPLICATION's own service identity (D12), so nothing here is ever a person's lent\n * credential; those live on the connected-accounts lane and are deliberately not reachable from\n * this one (`pnpm check:systems-of-record-separation`).\n */\nexport enum SystemOfRecordCredentialKind {\n /**\n * Odoo's classic external API: the credential travels INSIDE the RPC arguments rather than in an\n * HTTP header. The adapter performs `common.authenticate(db, login, apiKey, {})` for a uid and\n * then passes `(db, uid, apiKey, …)` as the leading positional arguments of every `execute_kw`.\n *\n * Its inputs are the API key (a secret slot, owned here) plus the database and login (vendor\n * address slots, owned by the Odoo facet — they identify WHICH Odoo and WHICH user, and would\n * still be needed by a hypothetical second Odoo credential kind).\n */\n ODOO_API_KEY_IN_ARGS = 'odoo-api-key-in-args',\n\n /**\n * A static key presented in an HTTP request header.\n *\n * The SECRET is the key; WHICH header carries it and what prefixes it (`Bearer `, `ApiKey `, or\n * nothing at all) are the VENDOR's facts, so they are declared on the facet's offer rather than\n * asked of the operator who authors an instance. An operator who has to be told their vendor's\n * header name is being asked a question the facet already holds the answer to\n * (`derive-before-you-ask.md`).\n */\n API_KEY_HEADER = 'api-key-header',\n\n /**\n * A static key presented as a query-string parameter.\n *\n * Weaker than a header by construction — a URL reaches access logs, proxy logs and `Referer`\n * headers — and offered only because some vendors accept nothing else. The parameter NAME is the\n * vendor's fact, like the header name above.\n *\n * The key is appended by the transport at dispatch, never baked into a stored `baseUrl`: a base\n * URL is printed in diagnostics and a credential must not ride in it.\n */\n API_KEY_QUERY = 'api-key-query',\n\n /**\n * HTTP Basic (RFC 7617): `Authorization: Basic base64(username \":\" password)`.\n *\n * SAP's communication user is the case this exists for. The username is a SECRET slot rather than\n * an address slot even though it is not confidential on its own — it is half of one credential,\n * it is rotated with the other half, and splitting a credential across the address channel and\n * the secret channel makes rotation two operations that can disagree.\n *\n * A username containing `:` is unrepresentable in this scheme (the colon is the delimiter and the\n * RFC forbids it), so it is refused where it is authored rather than producing a credential that\n * decodes to a different pair than the one typed.\n */\n BASIC = 'basic',\n\n /**\n * OAuth 2.0 client credentials (RFC 6749 §4.4) with a shared secret: `grant_type=client_credentials`\n * plus `client_id` and `client_secret`.\n *\n * An APP-ONLY identity — no person, no consent screen, no refresh token. That is the whole of D12:\n * a system of record is the operator's own deployment, reached as the application, so a\n * user-delegated flow would be authenticating the wrong party. The connector lane owns the\n * authorization-code exchange and is not reachable from here.\n */\n OAUTH2_CLIENT_CREDENTIALS_SECRET = 'oauth2-client-credentials-secret',\n\n /**\n * OAuth 2.0 client credentials with a CLIENT ASSERTION signed by a private key (RFC 7523 §2.2):\n * `grant_type=client_credentials` with\n * `client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer`.\n *\n * NetSuite and Microsoft Entra's certificate credential are both this, and NetSuite is the reason\n * it is separate from {@link OAUTH2_JWT_BEARER}: its documentation states the grant type is\n * *always* `client_credentials`, so it is client AUTHENTICATION by assertion rather than the\n * assertion GRANT (#1056 R1 corrected an earlier reading that had NetSuite under the grant).\n *\n * spec-cite: RFC 7523 §2.2 (Using JWTs for Client Authentication); NetSuite OAuth 2.0\n * client-credentials help, https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_162755359851.html\n *\n * The assertion's protected HEADER differs by vendor — NetSuite carries a vendor-assigned `kid`,\n * Entra wants an `x5t` thumbprint — so the header policy is declared on the facet's offer (R2). A\n * generic \"sign it with the private key\" is rejected by both.\n */\n OAUTH2_CLIENT_CREDENTIALS_CERTIFICATE = 'oauth2-client-credentials-certificate',\n\n /**\n * The OAuth 2.0 JWT BEARER GRANT (RFC 7523 §2.1):\n * `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer` with a signed `assertion`.\n *\n * Salesforce only, among the vendors surveyed. Distinct from the kind above in the one field that\n * decides how the token endpoint reads the request — the grant type — which is exactly the kind of\n * distinction `CLAUDE.md` forbids collapsing because two shapes look similar.\n *\n * spec-cite: RFC 7523 §2.1 (Using JWTs as Authorization Grants).\n */\n OAUTH2_JWT_BEARER = 'oauth2-jwt-bearer',\n}\n\n/** Whether a kind obtains a token from a token endpoint — the three that need a minter and a cache. */\nexport function systemOfRecordCredentialKindMintsToken(kind: SystemOfRecordCredentialKind): boolean {\n return kind === SystemOfRecordCredentialKind.OAUTH2_CLIENT_CREDENTIALS_SECRET\n || kind === SystemOfRecordCredentialKind.OAUTH2_CLIENT_CREDENTIALS_CERTIFICATE\n || kind === SystemOfRecordCredentialKind.OAUTH2_JWT_BEARER;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"system-of-record-credential-kind.shared.js","sourceRoot":"","sources":["../../../../src/systems-of-record/system-of-record-credential-kind.shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAEH;;;;;GAKG;AACH,MAAM,CAAN,IAAY,4BA0FX;AA1FD,WAAY,4BAA4B;IACtC;;;;;;;;OAQG;IACH,6EAA6C,CAAA;IAE7C;;;;;;;;OAQG;IACH,iEAAiC,CAAA;IAEjC;;;;;;;;;OASG;IACH,+DAA+B,CAAA;IAE/B;;;;;;;;;;;OAWG;IACH,+CAAe,CAAA;IAEf;;;;;;;;OAQG;IACH,qGAAqE,CAAA;IAErE;;;;;;;;;;;;;;;;OAgBG;IACH,+GAA+E,CAAA;IAE/E;;;;;;;;;OASG;IACH,uEAAuC,CAAA;AACzC,CAAC,EA1FW,4BAA4B,KAA5B,4BAA4B,QA0FvC;AAED,uGAAuG;AACvG,MAAM,UAAU,sCAAsC,CAAC,IAAkC;IACvF,OAAO,IAAI,KAAK,4BAA4B,CAAC,gCAAgC;WACxE,IAAI,KAAK,4BAA4B,CAAC,qCAAqC;WAC3E,IAAI,KAAK,4BAA4B,CAAC,iBAAiB,CAAC;AAC/D,CAAC","sourcesContent":["/**\n * `SystemOfRecordCredentialKind` — HOW the engine authenticates to a system of record.\n *\n * A root-exported boundary module, for the same package-contract reason as its sibling\n * `HttpApiTransportDialect` (#1055 R3): the ROOT-exported application-configuration contract\n * (`systemsOfRecord.<name>.credential.kind`) names this vocabulary, and a TypeScript `enum` is\n * NOMINAL — a root-only consumer that cannot reach the declaring module through a public specifier\n * gets `TS2742`/`TS2883`. `.claude/rules/package-public-entrypoints.md` prescribes moving the\n * boundary rather than re-exporting across it, so the `external-data` subpath does NOT re-export\n * this module.\n *\n * ## Why it is a separate vocabulary from the dialect\n *\n * A dialect says how to SPEAK (query protocol, envelope, filter language); a credential kind says\n * how to PROVE WHO YOU ARE. Odoo happens to pair one with the other today, and that coincidence is\n * exactly what `CLAUDE.md` forbids merging on: an OData v4 service reached with a bearer token and\n * the same service reached with client-credentials OAuth2 differ in the second axis and not the\n * first. Keeping them apart costs one enum and stops the pairing from being baked into the model.\n *\n * ## What a kind OWNS (#1055 R15, the slot-ownership decision)\n *\n * The kind owns the inputs IT needs — its secret slots, and any address slot that exists only\n * because of the kind. `OAUTH2_CLIENT_CREDENTIALS_SECRET` owns `tokenUrl`, which no vendor would\n * declare if it were reached with a static key. The FACET owns the vendor's own address slots and\n * the OFFERS it makes (a kind plus that vendor's policy for it); the INSTANCE chooses one offer.\n *\n * A third owner arrived with #1056 and is worth naming, because two of the three are easy to\n * confuse: the FACET also owns everything about a kind that varies BY VENDOR but not by deployment —\n * which header carries a static key, whether a token answer omits `expires_in`, whether an assertion\n * header needs a supplied `kid` or a derived `x5t`. Those are not slots: nobody types them per\n * environment, and asking an operator for them would be asking a question the facet already holds\n * the answer to (`derive-before-you-ask.md`).\n * The contracts themselves live beside the facet schema, on the `external-data` subpath, because\n * nothing root-exported needs to name a slot SHAPE — only the kind's NAME.\n *\n * ## How the catalogue grew, and what is still missing from it\n *\n * #1055 shipped ONE member, the one kind its one facet offered. #1056 added the six a service\n * identity actually needs across the vendors epic #1049 §4.6 surveyed — two static-key placements,\n * HTTP Basic, and three OAuth2 shapes. A member here with no entry in\n * `SYSTEM_OF_RECORD_CREDENTIAL_KIND_CONTRACTS` is a compile error, so the two cannot drift.\n *\n * `MTLS_CLIENT_CERTIFICATE` is deliberately ABSENT and is #1263. It is not a seventh variation on\n * composing a request: every kind here decides what to put IN a request, and mTLS decides how the\n * CONNECTION is made, which `HttpApiFetchLike` has no channel for (its `init` carries no\n * dispatcher). Adding it means widening the one outbound seam both this lane and the connector lane\n * run on — a different blast radius, and the reason SAP is declared unsupported-by-kind in #1057\n * rather than every other vendor waiting behind it.\n *\n * ## The root-only probe, measured 2026-09-15\n *\n * `package-public-entrypoints.md` asks for a measurement rather than a category judgement. A\n * consumer importing ONLY the package root, deriving values from this enum and emitting with\n * `declaration: true`:\n *\n * ```\n * export declare const declaredKind = SystemOfRecordCredentialKind.ODOO_API_KEY_IN_ARGS;\n * export declare function pickInstance(): { kind: SystemOfRecordCredentialKind; dialect: HttpApiTransportDialect };\n * ```\n *\n * Zero errors, and the emitted declaration NAMES the enum through the root specifier rather than a\n * `node_modules/.../dist/esm/...` path. The probe's negative control — importing\n * `SystemOfRecordVendorFacetSchema`, which is deliberately subpath-only — fails with `TS2305`, so\n * the probe discriminates rather than passing everything.\n */\n\n/**\n * How the engine proves its identity to a system of record. Closed vocabulary — a system of record\n * spends the APPLICATION's own service identity (D12), so nothing here is ever a person's lent\n * credential; those live on the connected-accounts lane and are deliberately not reachable from\n * this one (`pnpm check:systems-of-record-separation`).\n */\nexport enum SystemOfRecordCredentialKind {\n /**\n * Odoo's classic external API: the credential travels INSIDE the RPC arguments rather than in an\n * HTTP header. The adapter performs `common.authenticate(db, login, apiKey, {})` for a uid and\n * then passes `(db, uid, apiKey, …)` as the leading positional arguments of every `execute_kw`.\n *\n * Its inputs are the API key (a secret slot, owned here) plus the database and login (vendor\n * address slots, owned by the Odoo facet — they identify WHICH Odoo and WHICH user, and would\n * still be needed by a hypothetical second Odoo credential kind).\n */\n ODOO_API_KEY_IN_ARGS = 'odoo-api-key-in-args',\n\n /**\n * A static key presented in an HTTP request header.\n *\n * The SECRET is the key; WHICH header carries it and what prefixes it (`Bearer `, `ApiKey `, or\n * nothing at all) are the VENDOR's facts, so they are declared on the facet's offer rather than\n * asked of the operator who authors an instance. An operator who has to be told their vendor's\n * header name is being asked a question the facet already holds the answer to\n * (`derive-before-you-ask.md`).\n */\n API_KEY_HEADER = 'api-key-header',\n\n /**\n * A static key presented as a query-string parameter.\n *\n * Weaker than a header by construction — a URL reaches access logs, proxy logs and `Referer`\n * headers — and offered only because some vendors accept nothing else. The parameter NAME is the\n * vendor's fact, like the header name above.\n *\n * The key is appended by the transport at dispatch, never baked into a stored `baseUrl`: a base\n * URL is printed in diagnostics and a credential must not ride in it.\n */\n API_KEY_QUERY = 'api-key-query',\n\n /**\n * HTTP Basic (RFC 7617): `Authorization: Basic base64(username \":\" password)`.\n *\n * SAP's communication user is the case this exists for. The username is a SECRET slot rather than\n * an address slot even though it is not confidential on its own — it is half of one credential,\n * it is rotated with the other half, and splitting a credential across the address channel and\n * the secret channel makes rotation two operations that can disagree.\n *\n * A username containing `:` is unrepresentable in this scheme (the colon is the delimiter and the\n * RFC forbids it), so it is refused where it is authored rather than producing a credential that\n * decodes to a different pair than the one typed.\n */\n BASIC = 'basic',\n\n /**\n * OAuth 2.0 client credentials (RFC 6749 §4.4) with a shared secret: `grant_type=client_credentials`\n * plus `client_id` and `client_secret`.\n *\n * An APP-ONLY identity — no person, no consent screen, no refresh token. That is the whole of D12:\n * a system of record is the operator's own deployment, reached as the application, so a\n * user-delegated flow would be authenticating the wrong party. The connector lane owns the\n * authorization-code exchange and is not reachable from here.\n */\n OAUTH2_CLIENT_CREDENTIALS_SECRET = 'oauth2-client-credentials-secret',\n\n /**\n * OAuth 2.0 client credentials with a CLIENT ASSERTION signed by a private key (RFC 7523 §2.2):\n * `grant_type=client_credentials` with\n * `client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer`.\n *\n * NetSuite and Microsoft Entra's certificate credential are both this, and NetSuite is the reason\n * it is separate from {@link OAUTH2_JWT_BEARER}: its documentation states the grant type is\n * *always* `client_credentials`, so it is client AUTHENTICATION by assertion rather than the\n * assertion GRANT (#1056 R1 corrected an earlier reading that had NetSuite under the grant).\n *\n * spec-cite: RFC 7523 §2.2 (Using JWTs for Client Authentication); NetSuite OAuth 2.0\n * client-credentials help, https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_162755359851.html\n *\n * The assertion's protected HEADER differs by vendor — NetSuite carries a vendor-assigned `kid`,\n * Entra wants an `x5t` thumbprint — so the header policy is declared on the facet's offer (R2). A\n * generic \"sign it with the private key\" is rejected by both.\n */\n OAUTH2_CLIENT_CREDENTIALS_CERTIFICATE = 'oauth2-client-credentials-certificate',\n\n /**\n * The OAuth 2.0 JWT BEARER GRANT (RFC 7523 §2.1):\n * `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer` with a signed `assertion`.\n *\n * Salesforce only, among the vendors surveyed. Distinct from the kind above in the one field that\n * decides how the token endpoint reads the request — the grant type — which is exactly the kind of\n * distinction `CLAUDE.md` forbids collapsing because two shapes look similar.\n *\n * spec-cite: RFC 7523 §2.1 (Using JWTs as Authorization Grants).\n */\n OAUTH2_JWT_BEARER = 'oauth2-jwt-bearer',\n}\n\n/** Whether a kind obtains a token from a token endpoint — the three that need a minter and a cache. */\nexport function systemOfRecordCredentialKindMintsToken(kind: SystemOfRecordCredentialKind): boolean {\n return kind === SystemOfRecordCredentialKind.OAUTH2_CLIENT_CREDENTIALS_SECRET\n || kind === SystemOfRecordCredentialKind.OAUTH2_CLIENT_CREDENTIALS_CERTIFICATE\n || kind === SystemOfRecordCredentialKind.OAUTH2_JWT_BEARER;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-of-record-declaration.shared.schemas.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"system-of-record-declaration.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/systems-of-record/system-of-record-declaration.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AAChG,OAAO,EAAE,4BAA4B,EAAE,MAAM,2CAA2C,CAAC;AAEzF,6GAA6G;AAE7G;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,QAAsB,CAAC;AAEjE,qGAAqG;AACrG,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAEnD;;;;;;;;;;;;;;;;GAgBG;AACH,oBAAY,gCAAgC;IAC1C,sMAAsM;IACtM,8BAA8B,mCAAmC;IACjE,mJAAmJ;IACnJ,oCAAoC,yCAAyC;CAC9E;AAED,eAAO,MAAM,wBAAwB,aAGG,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,6BAA6B,sBAAsB,CAAC;AAEjE;;;;;;;;;GASG;AACH,wBAAgB,sCAAsC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,6BAA6B;AAC7B,eAAO,MAAM,+BAA+B;IAC1C;;;;;OAKG;;IAGH;;;;;;;;;;;;;;;;;;;;OAoBG;;IAGH;;;;;;;;;;;;OAYG;;;;IAGH;;;;;;;;;;;;;;;OAeG;;IAGH;;;;;;;;;;;;;;;;;;;;OAoBG;;IAGH;;;;;;;;;;;;OAYG;;IAMH;;;;;OAKG;;kBAEH,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B;IA1HtC;;;;;OAKG;;IAGH;;;;;;;;;;;;;;;;;;;;OAoBG;;IAGH;;;;;;;;;;;;OAYG;;;;IAGH;;;;;;;;;;;;;;;OAeG;;IAGH;;;;;;;;;;;;;;;;;;;;OAoBG;;IAGH;;;;;;;;;;;;OAYG;;IAMH;;;;;OAKG;;mBAwBD,CAAC;AACL,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChF,2DAA2D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-of-record-declaration.shared.schemas.js","sourceRoot":"","sources":["../../../src/systems-of-record/system-of-record-declaration.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `systemsOfRecord` — the application's declared INSTANCES of the systems it reads its own business\n * rows out of.\n *\n * ```ts\n * systemsOfRecord: {\n * odoo: { vendor: 'odoo', dialect: HttpApiTransportDialect.ODOO_JSONRPC },\n * }\n * ```\n *\n * ## The name is the whole point\n *\n * Before this, a resource addressed a remote system by `httpApiBinding.providerRef` — a free string\n * naming a PROVIDER whose env-var names were literals inside its module, so one ref was one\n * deployment and a second Odoo could not be expressed at all. A name here is an INSTANCE: two\n * (`odoo-fr`, `odoo-de`) share one vendor facet and differ only in their addresses and secrets.\n *\n * The name is also the stem of every environment variable the instance needs —\n * `WILDO_SOR_<NAME>__<SLOT>` — which is why it is capped at 32 characters and admits only\n * lower-kebab-case. Renaming an instance therefore renames its variables, and there is deliberately\n * no rename door for secrets: `wildo config sync` reports every now-missing slot and an operator\n * re-authors them (#1055 E6).\n *\n * ## What is validated HERE, and what is not\n *\n * Here: the SHAPE, and only what a single configuration file can see. That `vendor` names a facet\n * the deployment actually ships, and that `dialect` is one the facet speaks, are checked at BOOT by\n * the systems-of-record registry — the earliest place where the declaration and the facet map are in\n * the same scope. Splitting it that way is the same honest split `httpApiBinding` already makes:\n * the factory checks shape, the registry checks agreement.\n *\n * Also not here: that the environment actually supplies each slot. The saas config and the infra env\n * config parse independently, so cross-file coherence is checked at the seams where both are in\n * scope — `wildo config sync` and the backend startup validator.\n *\n * ## Why declaring one requires an owner organization (#1054)\n *\n * A system of record is read with the APPLICATION's own service identity, and its rows are stamped\n * with the owning organization's id so the per-row tenant gate passes without an exemption. An\n * application that declares no organization type carrying `ownsApplication` has no organization to\n * stamp with, so every read of every bound resource would refuse at request time. That refusal is\n * a statement about two top-level blocks, so it lives in `WildoSaasConfigSchema`'s own refinement,\n * where both are visible.\n */\nimport { z } from 'zod';\nimport { HttpApiTransportDialect } from '../http-api-binding/http-api-transport-dialect.shared';\nimport { SystemOfRecordCredentialKind } from './system-of-record-credential-kind.shared';\n\n/** @wildo_source:part:start saas.models.systems-of-record facet:layer:shared facet:audience:app-developer */\n\n/**\n * The charset law for an instance name, exported because the environment-variable derivation and\n * every tool that parses a derived name back into a `(name, slot)` pair depend on it: a name may\n * not contain `_`, so the `__` delimiter is unambiguous (#1055 R4).\n */\nexport const SYSTEM_OF_RECORD_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;\n\n/** 32 characters, because the name is a stem of an environment-variable name rather than a label. */\nexport const SYSTEM_OF_RECORD_NAME_MAX_LENGTH = 32;\n\n/**\n * Whether the personal data held in a system-of-record INSTANCE can have originated from publicly\n * accessible sources (#1745) — the half of GDPR Art. 14(2)(f) nothing else in an application can\n * derive.\n *\n * A privacy notice owes, for personal data not collected from the person, \"from which source the\n * personal data originate, and if applicable, whether it came from publicly accessible sources\".\n * spec-cite: GDPR Art. 14(2)(f), https://gdpr-info.eu/art-14-gdpr/.\n * The binding already makes the first half true: the source is this instance, a deployment the\n * operator runs. The second half is about how records got INTO that deployment — an ERP contact\n * may have been typed in from a public register, a website or a bought list — and only the\n * operator knows. So the operator states it here, once per instance, as a typed value a reviewer\n * can diff, rather than answering a question or leaving it to a drafter's guess.\n *\n * Omitting it is legitimate and is NOT read as \"no\": the notice's source statement then marks the\n * public-origin half owed for every resource read from the instance.\n */\nexport enum SystemOfRecordPersonalDataOrigin {\n /** Every person's data in this instance was collected by the operator — from the person, their organisation or the operator's own dealings with them — and none from a publicly accessible source. */\n NO_PUBLICLY_ACCESSIBLE_SOURCES = 'no-publicly-accessible-sources',\n /** Some of it may come from publicly accessible sources: company registers, websites, social profiles, enrichment services. The notice says so. */\n INCLUDES_PUBLICLY_ACCESSIBLE_SOURCES = 'includes-publicly-accessible-sources',\n}\n\nexport const SystemOfRecordNameSchema = z\n .string()\n .regex(SYSTEM_OF_RECORD_NAME_PATTERN, 'A system-of-record name is lower-kebab-case, starting with a letter.')\n .max(SYSTEM_OF_RECORD_NAME_MAX_LENGTH);\n\n/**\n * The i18n bucket holding every instance's display words — the first segment of\n * {@link buildSystemOfRecordDisplayNameLabelKey}'s keys.\n */\nexport const SYSTEM_OF_RECORD_LABEL_BUCKET = 'systems_of_record';\n\n/**\n * The label key naming ONE declared instance to a person: `systems_of_record.<name>.displayName` (#1997).\n *\n * An instance NAME is an environment-variable stem (`odoo`, `sap-fr`), not words: it cannot be translated, and the\n * words a reader recognises (\"Odoo\", \"SAP France\") are not derivable from it. So a surface that names an instance —\n * the provenance cue on a field a pipeline wrote, \"synced from Odoo\" — resolves this key, and the labelling pipeline\n * plans it for every declared instance, total over `systemsOfRecord`. There is deliberately no `displayName` on the\n * declaration: display text comes from the i18n tree, never from configuration. A key nobody generated renders the\n * raw name, which is the missing label looking missing.\n */\nexport function buildSystemOfRecordDisplayNameLabelKey(name: string): string {\n return `${SYSTEM_OF_RECORD_LABEL_BUCKET}.${name}.displayName`;\n}\n\n/** ONE declared instance. */\nexport const SystemOfRecordDeclarationSchema = z.strictObject({\n /**\n * Which vendor this is an instance of — the `vendor` of a facet the deployment ships: the framework's facets\n * come from the opt-in library `@wildo-ai/systems-of-record`, which `wildo config sync` declares on the backend\n * as soon as an instance is declared (#2013). Refused at boot when no facet answers to it, rather than here,\n * because the facet map is not in scope in `wildo.saas.config.ts`.\n */\n vendor: z.string().regex(/^[a-z][a-z0-9-]*$/, 'A vendor id is lower-kebab-case.').max(40),\n\n /**\n * How this instance is READ. Declared per instance rather than taken from the facet because a\n * vendor may speak several dialects — a service reachable over both OData v4 and a bespoke REST\n * surface is one vendor and two ways in. The facet's `dialects` is the closed set this must belong\n * to, checked at boot.\n *\n * ## One instance per SERVICE ROOT — so a system serving OData v2 and v4 is two instances (#1687)\n *\n * An instance has ONE dialect and ONE base URL, and for OData that URL is a service root: an SAP\n * system's `/sap/opu/odata/sap/API_BUSINESS_PARTNER` (v2) and `/sap/opu/odata4/sap/<service>/…` (v4)\n * are different roots, as two v4 services of the same system already are. So a system reached over\n * both versions is declared as two instances, one per root, each with its own dialect, credential\n * and `maxRequestsPerMinute`.\n *\n * Decided rather than asked, because the model already answered it: an instance naming several roots\n * would need a root per binding, which is what two instances are, and a budget SHARED across\n * instances would be a new cross-instance ledger for a ceiling the operator can already honour by\n * splitting it between the instances' `maxRequestsPerMinute`. Both were rejected on that ground.\n * The cost, stated: two instances against one vendor account are paced separately, so their sum —\n * not either one — is what must stay under the vendor's allowance.\n */\n dialect: z.enum(HttpApiTransportDialect),\n\n /**\n * How the engine proves who it is.\n *\n * OPTIONAL, and the absence is DERIVED rather than defaulted: when the instance's facet offers\n * exactly one credential kind there is nothing for an author to decide, so the registry takes it;\n * when a facet offers more than one and the instance names none, boot refuses and lists them.\n * The framework derives before it asks: a declaration with one legal value is a question whose\n * answer the mechanism already holds.\n *\n * This stays additive when #1056 widens the facet set: an instance that omitted the field is\n * refused on the day its facet gains a second kind, which is exactly the day its author acquires a\n * real decision.\n */\n credential: z.strictObject({ kind: z.enum(SystemOfRecordCredentialKind) }).optional(),\n\n /**\n * The pace this deployment may call the instance at, across EVERY resource bound to it (#1056 §3).\n *\n * Per INSTANCE because that is the unit the vendor accounts for: two resources bound to one\n * Dataverse are one application user to Dataverse, so two independent per-binding budgets would\n * each believe they were within a limit the pair together exceeds.\n *\n * A binding's own `remoteCallSemantics.maxRequestsPerMinute` stays, and becomes a CEILING UNDER\n * this one: it answers a different question — how much of the shared allowance may ONE resource\n * take — which matters when a pipeline load and an interactive read share an instance. Both are\n * consumed for every call, and a call proceeds only if both have room.\n *\n * Omitted means unlimited HERE, which is the honest default: the framework does not know the\n * vendor's contract, and inventing a number would either throttle a deployment that paid for more\n * or fail to protect one that has less.\n */\n maxRequestsPerMinute: z.number().int().min(1).max(600_000).optional(),\n\n /**\n * Whether THIS deployment's data is partitioned, and its rows therefore confined to organization\n * units of the owner organization (#1058).\n *\n * ## The reservation this replaces\n *\n * #1055 declared this field `z.never()` and refused it by name, because accepting a declaration the\n * mechanism could not honour would let an author believe their rows were narrowed while every\n * member still saw every row. That refusal did its job and is now lifted.\n *\n * ## Why the VENDOR says how and the INSTANCE says whether\n *\n * How a vendor partitions — which field, what shape, what codec — is a property of the vendor and\n * lives on its facet. Whether a given deployment's data is partitioned is a property of the\n * deployment: a single-company Odoo has a `company_id` on every row and nothing to confine, and\n * asking its operator to restate the field name would be asking a question the facet answers.\n *\n * Opting in against a facet that declares no partitioning is refused at boot, naming the vendor —\n * the alternative is a `true` that does nothing, which is the shape the reservation existed to\n * prevent in the first place.\n */\n partition: z.boolean().optional(),\n\n /**\n * The PACKAGES whose facet augmentation applies to this instance (#1675) — npm package names, each of which\n * must ship an augmentation for this instance's vendor from its `./systems-of-record` export.\n *\n * An explicit opt-in per INSTANCE, never implied by installation, because what an augmentation adds can be a\n * partition declaration, and the facet is the single authority on how a tenant's rows are confined. Two\n * instances of one vendor may therefore differ: one opts a package's partition in, the other does not.\n * A package named here that ships no augmentation for the vendor refuses at startup, naming it.\n *\n * Naming a package here is also what ADMITS its `./systems-of-record` module to discovery (#2013): apart from the\n * framework library `@wildo-ai/systems-of-record`, a facet module is recorded only from a package some instance\n * names. The package must still be walked — named `<scope>/provider-*`, or listed in `providers.packages`.\n */\n facetAugmentations: z.array(z.string().min(1).max(214)).min(1).refine(\n (packages) => new Set(packages).size === packages.length,\n 'A package is named twice in facetAugmentations.',\n ).optional(),\n\n /**\n * Whether the personal data in THIS deployment can have come from publicly accessible sources — see\n * {@link SystemOfRecordPersonalDataOrigin}. A property of the deployment, not the vendor: two Odoo\n * instances may be fed differently. Optional; omitted, the privacy notice marks that statement owed\n * for every resource read from this instance, and never states \"not from public sources\" by default.\n */\n personalDataOrigin: z.enum(SystemOfRecordPersonalDataOrigin).optional(),\n});\nexport type SystemOfRecordDeclaration = z.infer<typeof SystemOfRecordDeclarationSchema>;\n\n/**\n * Every instance this application declares, keyed by name.\n *\n * Optional as a whole: an application that reads nothing out of another system declares nothing, and\n * declaring this block is what ENABLES the external-data lane (#1055 D3) rather than an engine\n * capability flag — the lane has no meaning without an instance to point at.\n */\nexport const SystemsOfRecordConfigSchema = z\n .record(SystemOfRecordNameSchema, SystemOfRecordDeclarationSchema)\n .superRefine((systemsOfRecord, ctx) => {\n if (Object.keys(systemsOfRecord).length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: [],\n message:\n 'An empty `systemsOfRecord` declares nothing and enables nothing. Omit the block entirely, or declare the '\n + 'instance the application reads.',\n });\n }\n });\nexport type SystemsOfRecordConfig = z.infer<typeof SystemsOfRecordConfigSchema>;\n/** @wildo_source:part:end saas.models.systems-of-record */\n"]}
|
|
1
|
+
{"version":3,"file":"system-of-record-declaration.shared.schemas.js","sourceRoot":"","sources":["../../../../src/systems-of-record/system-of-record-declaration.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `systemsOfRecord` — the application's declared INSTANCES of the systems it reads its own business\n * rows out of.\n *\n * ```ts\n * systemsOfRecord: {\n * odoo: { vendor: 'odoo', dialect: HttpApiTransportDialect.ODOO_JSONRPC },\n * }\n * ```\n *\n * ## The name is the whole point\n *\n * Before this, a resource addressed a remote system by `httpApiBinding.providerRef` — a free string\n * naming a PROVIDER whose env-var names were literals inside its module, so one ref was one\n * deployment and a second Odoo could not be expressed at all. A name here is an INSTANCE: two\n * (`odoo-fr`, `odoo-de`) share one vendor facet and differ only in their addresses and secrets.\n *\n * The name is also the stem of every environment variable the instance needs —\n * `WILDO_SOR_<NAME>__<SLOT>` — which is why it is capped at 32 characters and admits only\n * lower-kebab-case. Renaming an instance therefore renames its variables, and there is deliberately\n * no rename door for secrets: `wildo config sync` reports every now-missing slot and an operator\n * re-authors them (#1055 E6).\n *\n * ## What is validated HERE, and what is not\n *\n * Here: the SHAPE, and only what a single configuration file can see. That `vendor` names a facet\n * the deployment actually ships, and that `dialect` is one the facet speaks, are checked at BOOT by\n * the systems-of-record registry — the earliest place where the declaration and the facet map are in\n * the same scope. Splitting it that way is the same honest split `httpApiBinding` already makes:\n * the factory checks shape, the registry checks agreement.\n *\n * Also not here: that the environment actually supplies each slot. The saas config and the infra env\n * config parse independently, so cross-file coherence is checked at the seams where both are in\n * scope — `wildo config sync` and the backend startup validator.\n *\n * ## Why declaring one requires an owner organization (#1054)\n *\n * A system of record is read with the APPLICATION's own service identity, and its rows are stamped\n * with the owning organization's id so the per-row tenant gate passes without an exemption. An\n * application that declares no organization type carrying `ownsApplication` has no organization to\n * stamp with, so every read of every bound resource would refuse at request time. That refusal is\n * a statement about two top-level blocks, so it lives in `WildoSaasConfigSchema`'s own refinement,\n * where both are visible.\n */\nimport { z } from 'zod';\nimport { HttpApiTransportDialect } from '../http-api-binding/http-api-transport-dialect.shared';\nimport { SystemOfRecordCredentialKind } from './system-of-record-credential-kind.shared';\n\n/** @wildo_source:part:start saas.models.systems-of-record facet:layer:shared facet:audience:app-developer */\n\n/**\n * The charset law for an instance name, exported because the environment-variable derivation and\n * every tool that parses a derived name back into a `(name, slot)` pair depend on it: a name may\n * not contain `_`, so the `__` delimiter is unambiguous (#1055 R4).\n */\nexport const SYSTEM_OF_RECORD_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;\n\n/** 32 characters, because the name is a stem of an environment-variable name rather than a label. */\nexport const SYSTEM_OF_RECORD_NAME_MAX_LENGTH = 32;\n\n/**\n * Whether the personal data held in a system-of-record INSTANCE can have originated from publicly\n * accessible sources (#1745) — the half of GDPR Art. 14(2)(f) nothing else in an application can\n * derive.\n *\n * A privacy notice owes, for personal data not collected from the person, \"from which source the\n * personal data originate, and if applicable, whether it came from publicly accessible sources\".\n * spec-cite: GDPR Art. 14(2)(f), https://gdpr-info.eu/art-14-gdpr/.\n * The binding already makes the first half true: the source is this instance, a deployment the\n * operator runs. The second half is about how records got INTO that deployment — an ERP contact\n * may have been typed in from a public register, a website or a bought list — and only the\n * operator knows. So the operator states it here, once per instance, as a typed value a reviewer\n * can diff, rather than answering a question or leaving it to a drafter's guess.\n *\n * Omitting it is legitimate and is NOT read as \"no\": the notice's source statement then marks the\n * public-origin half owed for every resource read from the instance.\n */\nexport enum SystemOfRecordPersonalDataOrigin {\n /** Every person's data in this instance was collected by the operator — from the person, their organisation or the operator's own dealings with them — and none from a publicly accessible source. */\n NO_PUBLICLY_ACCESSIBLE_SOURCES = 'no-publicly-accessible-sources',\n /** Some of it may come from publicly accessible sources: company registers, websites, social profiles, enrichment services. The notice says so. */\n INCLUDES_PUBLICLY_ACCESSIBLE_SOURCES = 'includes-publicly-accessible-sources',\n}\n\nexport const SystemOfRecordNameSchema = z\n .string()\n .regex(SYSTEM_OF_RECORD_NAME_PATTERN, 'A system-of-record name is lower-kebab-case, starting with a letter.')\n .max(SYSTEM_OF_RECORD_NAME_MAX_LENGTH);\n\n/**\n * The i18n bucket holding every instance's display words — the first segment of\n * {@link buildSystemOfRecordDisplayNameLabelKey}'s keys.\n */\nexport const SYSTEM_OF_RECORD_LABEL_BUCKET = 'systems_of_record';\n\n/**\n * The label key naming ONE declared instance to a person: `systems_of_record.<name>.displayName` (#1997).\n *\n * An instance NAME is an environment-variable stem (`odoo`, `sap-fr`), not words: it cannot be translated, and the\n * words a reader recognises (\"Odoo\", \"SAP France\") are not derivable from it. So a surface that names an instance —\n * the provenance cue on a field a pipeline wrote, \"synced from Odoo\" — resolves this key, and the labelling pipeline\n * plans it for every declared instance, total over `systemsOfRecord`. There is deliberately no `displayName` on the\n * declaration: display text comes from the i18n tree, never from configuration. A key nobody generated renders the\n * raw name, which is the missing label looking missing.\n */\nexport function buildSystemOfRecordDisplayNameLabelKey(name: string): string {\n return `${SYSTEM_OF_RECORD_LABEL_BUCKET}.${name}.displayName`;\n}\n\n/** ONE declared instance. */\nexport const SystemOfRecordDeclarationSchema = z.strictObject({\n /**\n * Which vendor this is an instance of — the `vendor` of a facet the deployment ships: the framework's facets\n * come from the opt-in library `@wildo-ai/systems-of-record`, which `wildo config sync` declares on the backend\n * as soon as an instance is declared (#2013). Refused at boot when no facet answers to it, rather than here,\n * because the facet map is not in scope in `wildo.saas.config.ts`.\n */\n vendor: z.string().regex(/^[a-z][a-z0-9-]*$/, 'A vendor id is lower-kebab-case.').max(40),\n\n /**\n * How this instance is READ. Declared per instance rather than taken from the facet because a\n * vendor may speak several dialects — a service reachable over both OData v4 and a bespoke REST\n * surface is one vendor and two ways in. The facet's `dialects` is the closed set this must belong\n * to, checked at boot.\n *\n * ## One instance per SERVICE ROOT — so a system serving OData v2 and v4 is two instances (#1687)\n *\n * An instance has ONE dialect and ONE base URL, and for OData that URL is a service root: an SAP\n * system's `/sap/opu/odata/sap/API_BUSINESS_PARTNER` (v2) and `/sap/opu/odata4/sap/<service>/…` (v4)\n * are different roots, as two v4 services of the same system already are. So a system reached over\n * both versions is declared as two instances, one per root, each with its own dialect, credential\n * and `maxRequestsPerMinute`.\n *\n * Decided rather than asked, because the model already answered it: an instance naming several roots\n * would need a root per binding, which is what two instances are, and a budget SHARED across\n * instances would be a new cross-instance ledger for a ceiling the operator can already honour by\n * splitting it between the instances' `maxRequestsPerMinute`. Both were rejected on that ground.\n * The cost, stated: two instances against one vendor account are paced separately, so their sum —\n * not either one — is what must stay under the vendor's allowance.\n */\n dialect: z.enum(HttpApiTransportDialect),\n\n /**\n * How the engine proves who it is.\n *\n * OPTIONAL, and the absence is DERIVED rather than defaulted: when the instance's facet offers\n * exactly one credential kind there is nothing for an author to decide, so the registry takes it;\n * when a facet offers more than one and the instance names none, boot refuses and lists them.\n * The framework derives before it asks: a declaration with one legal value is a question whose\n * answer the mechanism already holds.\n *\n * This stays additive when #1056 widens the facet set: an instance that omitted the field is\n * refused on the day its facet gains a second kind, which is exactly the day its author acquires a\n * real decision.\n */\n credential: z.strictObject({ kind: z.enum(SystemOfRecordCredentialKind) }).optional(),\n\n /**\n * The pace this deployment may call the instance at, across EVERY resource bound to it (#1056 §3).\n *\n * Per INSTANCE because that is the unit the vendor accounts for: two resources bound to one\n * Dataverse are one application user to Dataverse, so two independent per-binding budgets would\n * each believe they were within a limit the pair together exceeds.\n *\n * A binding's own `remoteCallSemantics.maxRequestsPerMinute` stays, and becomes a CEILING UNDER\n * this one: it answers a different question — how much of the shared allowance may ONE resource\n * take — which matters when a pipeline load and an interactive read share an instance. Both are\n * consumed for every call, and a call proceeds only if both have room.\n *\n * Omitted means unlimited HERE, which is the honest default: the framework does not know the\n * vendor's contract, and inventing a number would either throttle a deployment that paid for more\n * or fail to protect one that has less.\n */\n maxRequestsPerMinute: z.number().int().min(1).max(600_000).optional(),\n\n /**\n * Whether THIS deployment's data is partitioned, and its rows therefore confined to organization\n * units of the owner organization (#1058).\n *\n * ## The reservation this replaces\n *\n * #1055 declared this field `z.never()` and refused it by name, because accepting a declaration the\n * mechanism could not honour would let an author believe their rows were narrowed while every\n * member still saw every row. That refusal did its job and is now lifted.\n *\n * ## Why the VENDOR says how and the INSTANCE says whether\n *\n * How a vendor partitions — which field, what shape, what codec — is a property of the vendor and\n * lives on its facet. Whether a given deployment's data is partitioned is a property of the\n * deployment: a single-company Odoo has a `company_id` on every row and nothing to confine, and\n * asking its operator to restate the field name would be asking a question the facet answers.\n *\n * Opting in against a facet that declares no partitioning is refused at boot, naming the vendor —\n * the alternative is a `true` that does nothing, which is the shape the reservation existed to\n * prevent in the first place.\n */\n partition: z.boolean().optional(),\n\n /**\n * The PACKAGES whose facet augmentation applies to this instance (#1675) — npm package names, each of which\n * must ship an augmentation for this instance's vendor from its `./systems-of-record` export.\n *\n * An explicit opt-in per INSTANCE, never implied by installation, because what an augmentation adds can be a\n * partition declaration, and the facet is the single authority on how a tenant's rows are confined. Two\n * instances of one vendor may therefore differ: one opts a package's partition in, the other does not.\n * A package named here that ships no augmentation for the vendor refuses at startup, naming it.\n *\n * Naming a package here is also what ADMITS its `./systems-of-record` module to discovery (#2013): apart from the\n * framework library `@wildo-ai/systems-of-record`, a facet module is recorded only from a package some instance\n * names. The package must still be walked — named `<scope>/provider-*`, or listed in `providers.packages`.\n */\n facetAugmentations: z.array(z.string().min(1).max(214)).min(1).refine(\n (packages) => new Set(packages).size === packages.length,\n 'A package is named twice in facetAugmentations.',\n ).optional(),\n\n /**\n * Whether the personal data in THIS deployment can have come from publicly accessible sources — see\n * {@link SystemOfRecordPersonalDataOrigin}. A property of the deployment, not the vendor: two Odoo\n * instances may be fed differently. Optional; omitted, the privacy notice marks that statement owed\n * for every resource read from this instance, and never states \"not from public sources\" by default.\n */\n personalDataOrigin: z.enum(SystemOfRecordPersonalDataOrigin).optional(),\n});\nexport type SystemOfRecordDeclaration = z.infer<typeof SystemOfRecordDeclarationSchema>;\n\n/**\n * Every instance this application declares, keyed by name.\n *\n * Optional as a whole: an application that reads nothing out of another system declares nothing, and\n * declaring this block is what ENABLES the external-data lane (#1055 D3) rather than an engine\n * capability flag — the lane has no meaning without an instance to point at.\n */\nexport const SystemsOfRecordConfigSchema = z\n .record(SystemOfRecordNameSchema, SystemOfRecordDeclarationSchema)\n .superRefine((systemsOfRecord, ctx) => {\n if (Object.keys(systemsOfRecord).length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: [],\n message:\n 'An empty `systemsOfRecord` declares nothing and enables nothing. Omit the block entirely, or declare the '\n + 'instance the application reads.',\n });\n }\n });\nexport type SystemsOfRecordConfig = z.infer<typeof SystemsOfRecordConfigSchema>;\n/** @wildo_source:part:end saas.models.systems-of-record */\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-of-record-env.shared.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"system-of-record-env.shared.d.ts","sourceRoot":"","sources":["../../../../src/systems-of-record/system-of-record-env.shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,+FAA+F;AAC/F,eAAO,MAAM,2BAA2B,eAAe,CAAC;AAExD,qGAAqG;AACrG,eAAO,MAAM,8BAA8B,OAAO,CAAC;AAEnD,mGAAmG;AACnG,eAAO,MAAM,kCAAkC,QAAwB,CAAC;AAExE;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,YAAY,CAAC;AAYvD;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ7F;AAED;;;;;GAKG;AACH,wBAAgB,qCAAqC,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAElF;AAQD,gDAAgD;AAChD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,yBAAyB,GAAG,IAAI,CAgBlG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-of-record-env.shared.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"system-of-record-env.shared.js","sourceRoot":"","sources":["../../../../src/systems-of-record/system-of-record-env.shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,6BAA6B,EAAE,MAAM,+CAA+C,CAAC;AAE9F,+FAA+F;AAC/F,MAAM,CAAC,MAAM,2BAA2B,GAAG,YAAY,CAAC;AAExD,qGAAqG;AACrG,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,CAAC;AAEnD,mGAAmG;AACnG,MAAM,CAAC,MAAM,kCAAkC,GAAG,qBAAqB,CAAC;AAExE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,SAAS,CAAC;AAEvD,uEAAuE;AACvE,SAAS,kBAAkB,CAAC,YAAoB;IAC9C,OAAO,YAAY,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC;AAED,mGAAmG;AACnG,SAAS,cAAc,CAAC,QAAgB;IACtC,OAAO,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,8BAA8B,CAAC,YAAoB,EAAE,QAAgB;IACnF,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,IAAI,YAAY,6FAA6F,CAAC,CAAC;IACjI,CAAC;IACD,IAAI,CAAC,kCAAkC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,IAAI,QAAQ,8EAA8E,CAAC,CAAC;IAC9G,CAAC;IACD,OAAO,GAAG,2BAA2B,GAAG,kBAAkB,CAAC,YAAY,CAAC,GAAG,8BAA8B,GAAG,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;AACzI,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qCAAqC,CAAC,YAAoB;IACxE,OAAO,8BAA8B,CAAC,YAAY,EAAE,6BAA6B,CAAC,CAAC;AACrF,CAAC;AAED,wGAAwG;AACxG,SAAS,cAAc,CAAC,OAAe;IACrC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzD,OAAO,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrH,CAAC;AAQD;;;;;;;;;GASG;AACH,MAAM,UAAU,6BAA6B,CAAC,UAAkB;IAC9D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,2BAA2B,CAAC;QAAE,OAAO,IAAI,CAAC;IACrE,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC;IAClE,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;IACpE,IAAI,cAAc,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACtF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,8BAA8B,CAAC,MAAM,CAAC,CAAC;IACvF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,uFAAuF;IACvF,IAAI,WAAW,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtE,MAAM,QAAQ,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,kCAAkC,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzH,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;AACpC,CAAC","sourcesContent":["/**\n * `WILDO_SOR_<NAME>__<SLOT>` — the ONE derivation of a system-of-record environment-variable name.\n *\n * ## Derived, never authored, and why that is the whole design\n *\n * The lane this replaces put the variable NAMES in the vendor's module — `ODOO_BASE_URL`,\n * `ODOO_DB`, `ODOO_LOGIN`, `ODOO_API_KEY` — so a second Odoo was unrepresentable: the name space was\n * the vendor's, not the instance's. Deriving from the instance NAME instead means two instances of\n * one vendor cost nothing (`WILDO_SOR_ODOO_FR__BASE_URL` beside `WILDO_SOR_ODOO_DE__BASE_URL`), and\n * an author never invents a variable name that some other layer then has to guess.\n *\n * ## Why the delimiter is a DOUBLE underscore (#1055 R4)\n *\n * The pair must be RECOVERABLE — the secrets section is a flat map keyed by variable name (R5), and\n * per-instance structure is recovered by parsing the key back. With a single underscore,\n * `odoo-api` + `key` and `odoo` + `apiKey` both derive `WILDO_SOR_ODOO_API_KEY` and nothing could\n * tell them apart. `__` cannot be produced by either half: an instance name admits only\n * `[a-z0-9-]` and a slot slug only `[a-zA-Z0-9]`, so neither can emit an underscore at all, and the\n * only `__` in a derived name is the delimiter. The collision is impossible by construction rather\n * than checked for.\n *\n * That property is load-bearing, so the two charset laws are not cosmetic: widening either one\n * silently reintroduces the ambiguity. `SYSTEM_OF_RECORD_NAME_PATTERN` and the slot-slug regex are\n * pinned against this file's round trip for that reason.\n *\n * ## Four readers, one authority\n *\n * The backend `.env` writer, the k8s secrets generator, the CI secret collector and the backend\n * registry all need the same name, and three of them live in different packages. Re-deriving it at\n * each would be the enumeration failure `invariant-call-site-enumeration.md` records — so this module\n * is the authority and every one of them imports it.\n */\n\nimport { SYSTEM_OF_RECORD_NAME_PATTERN } from './system-of-record-declaration.shared.schemas';\n\n/** Every system-of-record variable starts here, which is what makes a prefix scan possible. */\nexport const SYSTEM_OF_RECORD_ENV_PREFIX = 'WILDO_SOR_';\n\n/** The delimiter between the instance name and the slot. See the module header for why it is two. */\nexport const SYSTEM_OF_RECORD_ENV_DELIMITER = '__';\n\n/** The charset law for a slot slug, shared with the facet schema so the two cannot drift apart. */\nexport const SYSTEM_OF_RECORD_SLOT_SLUG_PATTERN = /^[a-z][a-zA-Z0-9]*$/;\n\n/**\n * The slot slug an instance may never declare, because the environment builder emits it itself.\n *\n * `WILDO_SOR_<NAME>__ENABLED=false` is how an environment says it has NO access to this system —\n * a developer laptop, a staging with no ERP (#1055 E3, R6). A facet declaring a slot named `enabled`\n * would produce the same variable and make \"declared absent\" indistinguishable from \"an address slot\n * whose value happens to be false\", so the name is reserved and the facet schema refuses it.\n */\nexport const SYSTEM_OF_RECORD_ENABLED_SLOT = 'enabled';\n\n/** `odoo-fr` → `ODOO_FR`. The only transformation a name undergoes. */\nfunction encodeInstanceName(instanceName: string): string {\n return instanceName.toUpperCase().replaceAll('-', '_');\n}\n\n/** `apiKey` → `API_KEY`, `baseUrl` → `BASE_URL`. lowerCamelCase to UPPER_SNAKE, and back below. */\nfunction encodeSlotSlug(slotSlug: string): string {\n return slotSlug.replace(/([A-Z])/g, '_$1').toUpperCase();\n}\n\n/**\n * The name of the environment variable carrying one slot of one instance.\n *\n * Throws on a name or slug outside its charset law rather than emitting a name that cannot be parsed\n * back: both halves are validated where they are authored, so reaching here with a bad one means a\n * caller skipped a schema, and a silently unparseable variable is worse than a loud refusal.\n */\nexport function deriveSystemOfRecordEnvVarName(instanceName: string, slotSlug: string): string {\n if (!SYSTEM_OF_RECORD_NAME_PATTERN.test(instanceName)) {\n throw new Error(`\"${instanceName}\" is not a valid system-of-record instance name (lower-kebab-case, starting with a letter).`);\n }\n if (!SYSTEM_OF_RECORD_SLOT_SLUG_PATTERN.test(slotSlug)) {\n throw new Error(`\"${slotSlug}\" is not a valid system-of-record slot slug (lowerCamelCase, no separators).`);\n }\n return `${SYSTEM_OF_RECORD_ENV_PREFIX}${encodeInstanceName(instanceName)}${SYSTEM_OF_RECORD_ENV_DELIMITER}${encodeSlotSlug(slotSlug)}`;\n}\n\n/**\n * `WILDO_SOR_<NAME>__ENABLED` — present and `false` when an environment declares it has no access to\n * this instance (E3). Its ABSENCE, with required slots missing, is the different and louder case:\n * an environment that simply forgot (E4). Silence is never a declaration, which is why the two are\n * distinguishable at all.\n */\nexport function deriveSystemOfRecordEnabledEnvVarName(instanceName: string): string {\n return deriveSystemOfRecordEnvVarName(instanceName, SYSTEM_OF_RECORD_ENABLED_SLOT);\n}\n\n/** `API_KEY` → `apiKey`. The inverse of `encodeSlotSlug`, exact because a slug carries no separator. */\nfunction decodeSlotSlug(encoded: string): string {\n const [head, ...rest] = encoded.toLowerCase().split('_');\n return [head, ...rest.map((part) => (part.length === 0 ? part : part[0]!.toUpperCase() + part.slice(1)))].join('');\n}\n\n/** What a derived variable name was made of. */\nexport interface SystemOfRecordEnvVarParts {\n readonly instanceName: string;\n readonly slotSlug: string;\n}\n\n/**\n * Recover the `(instance, slot)` pair from a derived variable name, or `null` when the name is not\n * one of ours.\n *\n * `null` rather than a throw because the callers scan a MIXED environment — every variable a\n * deployment carries goes past this function, and most of them are not system-of-record variables.\n * A name that starts with the prefix and still does not parse is also `null`: it is not ours either,\n * and refusing an operator's unrelated `WILDO_SOR_SOMETHING` would be this module deciding what an\n * environment may contain.\n */\nexport function parseSystemOfRecordEnvVarName(envVarName: string): SystemOfRecordEnvVarParts | null {\n if (!envVarName.startsWith(SYSTEM_OF_RECORD_ENV_PREFIX)) return null;\n const body = envVarName.slice(SYSTEM_OF_RECORD_ENV_PREFIX.length);\n const delimiterIndex = body.indexOf(SYSTEM_OF_RECORD_ENV_DELIMITER);\n if (delimiterIndex <= 0) return null;\n\n const instanceName = body.slice(0, delimiterIndex).toLowerCase().replaceAll('_', '-');\n const encodedSlot = body.slice(delimiterIndex + SYSTEM_OF_RECORD_ENV_DELIMITER.length);\n if (encodedSlot.length === 0) return null;\n // A second delimiter means the name was not produced here: neither half can emit `__`.\n if (encodedSlot.includes(SYSTEM_OF_RECORD_ENV_DELIMITER)) return null;\n\n const slotSlug = decodeSlotSlug(encodedSlot);\n if (!SYSTEM_OF_RECORD_NAME_PATTERN.test(instanceName) || !SYSTEM_OF_RECORD_SLOT_SLUG_PATTERN.test(slotSlug)) return null;\n\n return { instanceName, slotSlug };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-of-record-error-codes.shared.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"system-of-record-error-codes.shared.d.ts","sourceRoot":"","sources":["../../../../src/systems-of-record/system-of-record-error-codes.shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;GAMG;AACH,oBAAY,uBAAuB;IACjC;;;;;;;OAOG;IACH,mBAAmB,yCAAyC;IAE5D;;;;;OAKG;IACH,2BAA2B,iDAAiD;IAE5E;;;;;;;OAOG;IACH,4BAA4B,kDAAkD;IAE9E;;;;OAIG;IACH,0BAA0B,gDAAgD;IAE1E;;;;;OAKG;IACH,mBAAmB,yCAAyC;IAE5D;;;;;OAKG;IACH,2BAA2B,iDAAiD;IAE5E;;;;;;OAMG;IACH,4BAA4B,kDAAkD;IAE9E;;OAEG;IACH,2BAA2B,iDAAiD;IAE5E;;;;;OAKG;IACH,yBAAyB,+CAA+C;IAExE;;;;;;;OAOG;IACH,qBAAqB,2CAA2C;IAEhE;;;;;;OAMG;IACH,+BAA+B,qDAAqD;IAEpF;;;;;;OAMG;IACH,qCAAqC,2DAA2D;IAEhG;;;;;;OAMG;IACH,0BAA0B,gDAAgD;IAE1E;;;;;;;;OAQG;IACH,yBAAyB,+CAA+C;IAExE;;;;;;;;;;;;;OAaG;IACH,iBAAiB,uCAAuC;IAExD;;;;;;;;;OASG;IACH,4BAA4B,kDAAkD;IAE9E;;;;;;;OAOG;IACH,iCAAiC,uDAAuD;IAExF;;;;;;;;;OASG;IACH,0BAA0B,gDAAgD;IAS1E;;;;;;;OAOG;IACH,6BAA6B,mDAAmD;IAEhF;;;;;;;OAOG;IACH,4BAA4B,kDAAkD;IAE9E;;;;;;;OAOG;IACH,6BAA6B,mDAAmD;IAEhF;;;OAGG;IACH,uBAAuB,6CAA6C;IAEpE;;;;;;;OAOG;IACH,wBAAwB,8CAA8C;IAEtE;;;;;;;OAOG;IACH,qBAAqB,2CAA2C;IAEhE;;;;;OAKG;IACH,iBAAiB,uCAAuC;IAExD;;;;;;;;;;;;OAYG;IACH,4BAA4B,kDAAkD;IAE9E;;;;;;;OAOG;IACH,8BAA8B,oDAAoD;IAUlF;;;;OAIG;IACH,yCAAyC,+DAA+D;IAExG;;;;OAIG;IACH,sBAAsB,4CAA4C;IAElE;;;;;;;;OAQG;IACH,mBAAmB,yCAAyC;IAE5D;;;;;;OAMG;IACH,4BAA4B,kDAAkD;IAQ9E;;;;;;;;;OASG;IACH,yBAAyB,+CAA+C;IAExE;;;;OAIG;IACH,gCAAgC,sDAAsD;IAQtF;;;OAGG;IACH,yCAAyC,+DAA+D;IAExG;;;;OAIG;IACH,gCAAgC,sDAAsD;IAEtF,yHAAyH;IACzH,sBAAsB,4CAA4C;IAElE,6EAA6E;IAC7E,mBAAmB,yCAAyC;IAE5D;;;;OAIG;IACH,8BAA8B,oDAAoD;IAElF;;;OAGG;IACH,6BAA6B,mDAAmD;IAEhF,mGAAmG;IACnG,oBAAoB,0CAA0C;IAE9D,+GAA+G;IAC/G,oBAAoB,0CAA0C;IAE9D;;;OAGG;IACH,+BAA+B,qDAAqD;IAEpF;;;OAGG;IACH,8BAA8B,oDAAoD;IAElF;;;OAGG;IACH,wBAAwB,8CAA8C;IAEtE;;;;OAIG;IACH,2BAA2B,iDAAiD;IAE5E,qGAAqG;IACrG,qBAAqB,2CAA2C;IAEhE;;;;;OAKG;IACH,eAAe,qCAAqC;CACrD;AAED;;;;;;GAMG;AACH,oBAAY,mCAAmC;IAC7C,wEAAwE;IACxE,kBAAkB,uBAAuB;IACzC,qGAAqG;IACrG,qBAAqB,0BAA0B;IAC/C;;;;OAIG;IACH,2BAA2B,gCAAgC;IAC3D,2GAA2G;IAC3G,wBAAwB,6BAA6B;IACrD,mHAAmH;IACnH,gBAAgB,qBAAqB;IACrC;;;OAGG;IACH,gCAAgC,qCAAqC;CACtE;AACD,sEAAsE;AAEtE;;;GAGG;AACH,eAAO,MAAM,4CAA4C,QAEqD,CAAC"}
|