@cosmicdrift/kumiko-framework 0.389.0 → 0.390.1
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/AGENTS.md +9 -4
- package/README.md +1 -1
- package/agents/examples/apex-surface-auth.md +2 -3
- package/agents/examples/api-worker-split.md +9 -2
- package/agents/examples/auth-claims.md +1 -1
- package/agents/examples/cross-feature-events.md +12 -12
- package/agents/examples/crypto-shredding-hr.md +2 -2
- package/agents/examples/encrypted-tenant-config.md +1 -1
- package/agents/examples/error-contract.md +12 -7
- package/agents/examples/event-sourcing.md +29 -29
- package/agents/examples/files-post-processing.md +10 -8
- package/agents/examples/inbound-mail-triage.md +1 -0
- package/agents/examples/lane-routing.md +2 -1
- package/agents/examples/legal-pages.md +2 -2
- package/agents/examples/lifecycle-hooks.md +3 -3
- package/agents/examples/managed-config.md +4 -4
- package/agents/examples/managed-pages.md +1 -1
- package/agents/examples/relations.md +19 -4
- package/agents/examples/search.md +4 -4
- package/agents/examples/secrets-demo.md +9 -6
- package/agents/examples/state-machine.md +2 -2
- package/agents/examples/tenant-settings.md +1 -1
- package/agents/examples/user-data-rights.md +3 -6
- package/agents/examples/workflow-engine.md +53 -47
- package/agents/examples.md +4 -4
- package/agents/features.md +1 -1
- package/dist/api/auth-middleware.js +1 -1
- package/dist/api/auth-routes-invite.js +2 -1
- package/dist/api/entity-read-access.d.ts +3 -1
- package/dist/api/export/export-columns.d.ts +3 -1
- package/dist/api/export/export-route.js +3 -2
- package/dist/api/export/export-screen.d.ts +2 -1
- package/dist/api/extra-route.d.ts +3 -1
- package/dist/api/index.d.ts +23 -27
- package/dist/api/index.js +13 -15
- package/dist/api/jwt.js +1 -1
- package/dist/api/observability-middleware.d.ts +1 -1
- package/dist/api/observability-middleware.js +2 -1
- package/dist/api/request-context-internals.d.ts +31 -0
- package/dist/api/request-context-internals.js +11 -0
- package/dist/api/request-context-scopes.d.ts +14 -0
- package/dist/api/request-context-scopes.js +69 -0
- package/dist/api/request-context.d.ts +1 -40
- package/dist/api/request-context.js +22 -51
- package/dist/api/request-id-middleware.d.ts +1 -1
- package/dist/api/route-registrars.d.ts +2 -1
- package/dist/api/route-registrars.js +1 -1
- package/dist/api/routes.js +7 -3
- package/dist/api/server-boot-checks.d.ts +1 -1
- package/dist/api/server-boot-checks.js +2 -2
- package/dist/api/server-event-dispatcher.d.ts +6 -1
- package/dist/api/server-event-dispatcher.js +3 -4
- package/dist/api/server-extra-routes.d.ts +1 -1
- package/dist/api/server-extra-routes.js +2 -1
- package/dist/api/server-middleware.js +3 -1
- package/dist/api/server-routes.d.ts +2 -1
- package/dist/api/server-wiring.js +6 -4
- package/dist/api/server.d.ts +2 -1
- package/dist/api/sse-route.d.ts +2 -1
- package/dist/api/tenant-scoped-secrets.d.ts +2 -0
- package/dist/api/tenant-scoped-secrets.js +13 -0
- package/dist/api/websocket-route.d.ts +1 -1
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/roles.d.ts +0 -5
- package/dist/compliance/duration-spec.d.ts +0 -1
- package/dist/compliance/duration-spec.js +0 -5
- package/dist/compliance/index.d.ts +4 -4
- package/dist/compliance/index.js +2 -2
- package/dist/compliance/profiles.d.ts +0 -15
- package/dist/compliance/profiles.js +0 -23
- package/dist/config/index.d.ts +10 -10
- package/dist/config/index.js +13 -1
- package/dist/config/internals.d.ts +9 -0
- package/dist/config/internals.js +1 -0
- package/dist/consumer-cli-internals.d.ts +4 -0
- package/dist/consumer-cli-internals.js +1 -0
- package/dist/consumer-cli.d.ts +1 -4
- package/dist/consumer-cli.js +5 -1
- package/dist/crypto/event-pii.js +1 -1
- package/dist/crypto/index.d.ts +8 -9
- package/dist/crypto/index.js +7 -8
- package/dist/crypto/pg-kms-adapter.js +6 -1
- package/dist/db/apply-entity-event.d.ts +1 -1
- package/dist/db/apply-entity-event.js +15 -47
- package/dist/db/blind-index-cleanup.js +91 -77
- package/dist/db/collect-table-metas.js +1 -1
- package/dist/db/compound-types.d.ts +1 -1
- package/dist/db/compound-types.js +0 -7
- package/dist/db/config-seed.d.ts +2 -1
- package/dist/db/config-seed.js +6 -1
- package/dist/db/connection.d.ts +3 -1
- package/dist/db/connection.js +15 -5
- package/dist/db/cross-tenant-reads.d.ts +1 -1
- package/dist/db/cross-tenant-reads.js +1 -1
- package/dist/db/dialect.d.ts +0 -5
- package/dist/db/dialect.js +0 -3
- package/dist/db/driver-value-preparation.js +23 -2
- package/dist/db/eagerload.d.ts +2 -1
- package/dist/db/entity-field-encryption.d.ts +1 -1
- package/dist/db/entity-table-meta.d.ts +1 -1
- package/dist/db/event-store-executor-context.d.ts +3 -1
- package/dist/db/event-store-executor-context.js +4 -3
- package/dist/db/event-store-executor-read-filter.d.ts +1 -1
- package/dist/db/event-store-executor-read-rows.d.ts +2 -1
- package/dist/db/event-store-executor-read-search.d.ts +2 -1
- package/dist/db/event-store-executor-read-sort.d.ts +2 -1
- package/dist/db/event-store-executor-read.js +2 -2
- package/dist/db/event-store-executor-write-atomic.js +8 -7
- package/dist/db/event-store-executor-write-steps.d.ts +3 -2
- package/dist/db/event-store-executor-write.js +7 -4
- package/dist/db/event-store-executor.d.ts +1 -1
- package/dist/db/executor-managed-tables.d.ts +7 -1
- package/dist/db/executor-managed-tables.js +11 -2
- package/dist/db/index.d.ts +29 -28
- package/dist/db/index.js +22 -20
- package/dist/db/known-table-names.d.ts +6 -0
- package/dist/db/known-table-names.js +21 -0
- package/dist/db/list-aggregate-labels.d.ts +1 -1
- package/dist/db/located-timestamp.d.ts +1 -1
- package/dist/db/located-timestamp.js +0 -5
- package/dist/db/migrate-generator.d.ts +17 -1
- package/dist/db/migrate-generator.js +50 -20
- package/dist/db/migrate-primary-key.d.ts +12 -0
- package/dist/db/migrate-primary-key.js +45 -0
- package/dist/db/migrate-rls-diff.d.ts +20 -0
- package/dist/db/migrate-rls-diff.js +61 -0
- package/dist/db/migrate-runner.js +4 -0
- package/dist/db/money.d.ts +1 -1
- package/dist/db/money.js +1 -1
- package/dist/db/parent-ref-clause.d.ts +2 -1
- package/dist/db/pg-error.d.ts +2 -0
- package/dist/db/pg-error.js +11 -0
- package/dist/db/queries/ddl.d.ts +3 -0
- package/dist/db/queries/ddl.js +34 -1
- package/dist/db/queries/event-store.js +4 -2
- package/dist/db/queries/event-tenants.d.ts +2 -0
- package/dist/db/queries/event-tenants.js +17 -0
- package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
- package/dist/db/queries/rebuild-rls-guard.js +29 -0
- package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
- package/dist/db/queries/rls-boot-catalog.js +39 -0
- package/dist/db/queries/rls-catalog.d.ts +6 -0
- package/dist/db/queries/rls-catalog.js +82 -0
- package/dist/db/queries/rls-scope.d.ts +3 -0
- package/dist/db/queries/rls-scope.js +17 -0
- package/dist/db/queries/rls-shape.d.ts +10 -0
- package/dist/db/queries/rls-shape.js +42 -0
- package/dist/db/queries/session-advisory-lock.d.ts +2 -0
- package/dist/db/queries/session-advisory-lock.js +23 -0
- package/dist/db/queries/shadow-swap.d.ts +1 -2
- package/dist/db/queries/shadow-swap.js +9 -25
- package/dist/db/queries/test-stack.d.ts +4 -1
- package/dist/db/queries/test-stack.js +84 -2
- package/dist/db/query.js +11 -7
- package/dist/db/reference-data.d.ts +1 -1
- package/dist/db/reference-data.js +6 -1
- package/dist/db/render-ddl.d.ts +6 -2
- package/dist/db/render-ddl.js +7 -7
- package/dist/db/render-rls-ddl.d.ts +35 -0
- package/dist/db/render-rls-ddl.js +127 -0
- package/dist/db/replay-migration-sql.d.ts +3 -1
- package/dist/db/replay-migration-sql.js +22 -5
- package/dist/db/replay-rls.d.ts +25 -0
- package/dist/db/replay-rls.js +156 -0
- package/dist/db/row-level-security-boot-check.d.ts +6 -0
- package/dist/db/row-level-security-boot-check.js +86 -0
- package/dist/db/row-level-security-connection.d.ts +3 -0
- package/dist/db/row-level-security-connection.js +213 -0
- package/dist/db/row-level-security-scope.d.ts +33 -0
- package/dist/db/row-level-security-scope.js +127 -0
- package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
- package/dist/db/scope-tenant-db-to-tenant.js +14 -0
- package/dist/db/sql-identifier.d.ts +1 -0
- package/dist/db/sql-identifier.js +3 -0
- package/dist/db/table-builder.d.ts +2 -1
- package/dist/db/table-builder.js +1 -1
- package/dist/db/table-info.js +1 -1
- package/dist/db/table-push.d.ts +11 -2
- package/dist/db/table-push.js +15 -2
- package/dist/db/tenant-db-runner.d.ts +3 -1
- package/dist/db/tenant-db-runner.js +4 -3
- package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
- package/dist/db/tenant-db-scoped-rebind.js +33 -0
- package/dist/db/tenant-db-statement-runner.d.ts +13 -0
- package/dist/db/tenant-db-statement-runner.js +48 -0
- package/dist/db/tenant-db.d.ts +17 -12
- package/dist/db/tenant-db.js +49 -120
- package/dist/db/tenant-id-filter.d.ts +3 -0
- package/dist/db/tenant-id-filter.js +30 -0
- package/dist/db/transaction-serialization.d.ts +6 -0
- package/dist/db/transaction-serialization.js +60 -0
- package/dist/derivatives/delete-stored-file.js +1 -1
- package/dist/derivatives/index.d.ts +2 -5
- package/dist/derivatives/index.js +2 -3
- package/dist/engine/access.d.ts +2 -1
- package/dist/engine/access.js +1 -1
- package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
- package/dist/engine/boot-validator/entity-handler.js +1 -1
- package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +1 -1
- package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +1 -1
- package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +2 -1
- package/dist/engine/boot-validator/nav.d.ts +3 -1
- package/dist/engine/boot-validator/nav.js +1 -1
- package/dist/engine/boot-validator/ownership.d.ts +2 -1
- package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
- package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
- package/dist/engine/boot-validator/query-refs.d.ts +2 -1
- package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
- package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
- package/dist/engine/boot-validator/screens.d.ts +2 -1
- package/dist/engine/boot-validator/workspaces.d.ts +3 -1
- package/dist/engine/bridge-stub.d.ts +5 -2
- package/dist/engine/bridge-stub.js +39 -24
- package/dist/engine/config-helpers.d.ts +2 -2
- package/dist/engine/config-helpers.js +0 -9
- package/dist/engine/constants.d.ts +0 -10
- package/dist/engine/constants.js +0 -8
- package/dist/engine/create-app.js +1 -1
- package/dist/engine/define-feature.d.ts +2 -1
- package/dist/engine/define-feature.js +1 -2
- package/dist/engine/define-handler.d.ts +1 -1
- package/dist/engine/define-step.d.ts +0 -1
- package/dist/engine/define-step.js +0 -3
- package/dist/engine/embedded-derived.d.ts +1 -1
- package/dist/engine/entity-handlers.d.ts +2 -1
- package/dist/engine/entity-handlers.js +7 -7
- package/dist/engine/entity-list-runtime-options.js +3 -1
- package/dist/engine/entity-list-searchability.d.ts +2 -1
- package/dist/engine/event-def.d.ts +2 -1
- package/dist/engine/event-helpers.d.ts +3 -1
- package/dist/engine/event-helpers.js +3 -3
- package/dist/engine/extension-names.d.ts +2 -8
- package/dist/engine/extension-names.js +2 -2
- package/dist/engine/extension-selector-plugins.d.ts +1 -1
- package/dist/engine/extensions/storage-provider.d.ts +1 -2
- package/dist/engine/extensions/user-data.d.ts +0 -8
- package/dist/engine/factories.d.ts +2 -1
- package/dist/engine/feature-builder-state.d.ts +8 -1
- package/dist/engine/feature-changelog.d.ts +1 -1
- package/dist/engine/feature-config-events-jobs.d.ts +4 -1
- package/dist/engine/feature-entity-handlers.d.ts +5 -1
- package/dist/engine/feature-manifest.js +1 -1
- package/dist/engine/feature-ui-extensions.d.ts +7 -1
- package/dist/engine/feature-ui-extensions.js +6 -4
- package/dist/engine/field-access.d.ts +2 -1
- package/dist/engine/handler-field-references.d.ts +0 -4
- package/dist/engine/index.d.ts +57 -54
- package/dist/engine/index.js +22 -27
- package/dist/engine/instruction-fields.d.ts +1 -1
- package/dist/engine/personal-data-fields.d.ts +1 -1
- package/dist/engine/qualified-name.d.ts +0 -1
- package/dist/engine/read-claim.d.ts +2 -1
- package/dist/engine/registry-facade.js +0 -3
- package/dist/engine/registry-ingest.d.ts +2 -1
- package/dist/engine/registry-ingest.js +1 -2
- package/dist/engine/registry-state.d.ts +12 -2
- package/dist/engine/registry-state.js +2 -3
- package/dist/engine/registry-validate.d.ts +3 -1
- package/dist/engine/registry-validate.js +7 -7
- package/dist/engine/run-in.d.ts +1 -1
- package/dist/engine/run-in.js +0 -1
- package/dist/engine/schema-builder.d.ts +1 -1
- package/dist/engine/schema-builder.js +1 -1
- package/dist/engine/screen-filter-ops.d.ts +2 -1
- package/dist/engine/screen-filter-ops.js +0 -5
- package/dist/engine/soft-delete-cleanup.d.ts +1 -1
- package/dist/engine/soft-delete-cleanup.js +4 -4
- package/dist/engine/state-machine.js +2 -1
- package/dist/engine/steps/_read-source.js +1 -1
- package/dist/engine/steps/aggregate-append-event.js +2 -2
- package/dist/engine/steps/call-feature.js +2 -2
- package/dist/engine/steps/mail-send.js +1 -1
- package/dist/engine/steps/retry.js +1 -1
- package/dist/engine/steps/wait-for-event.js +1 -1
- package/dist/engine/steps/wait.js +1 -1
- package/dist/engine/steps/webhook-send.js +1 -1
- package/dist/engine/template-variables.d.ts +2 -1
- package/dist/engine/transfer-adjacency.d.ts +1 -1
- package/dist/engine/types/index.d.ts +8 -31
- package/dist/engine/types/index.js +2 -10
- package/dist/engine/validation.d.ts +2 -1
- package/dist/entrypoint/index.d.ts +7 -35
- package/dist/entrypoint/index.js +7 -1
- package/dist/entrypoint/internals.d.ts +40 -0
- package/dist/entrypoint/internals.js +1 -0
- package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
- package/dist/entrypoint/row-level-security-mode-check.js +19 -0
- package/dist/env/dry-run-internals.d.ts +10 -0
- package/dist/env/dry-run-internals.js +1 -0
- package/dist/env/dry-run.d.ts +1 -10
- package/dist/env/dry-run.js +2 -1
- package/dist/env/index.d.ts +1 -85
- package/dist/env/index.js +6 -50
- package/dist/env/internals.d.ts +87 -0
- package/dist/env/internals.js +53 -0
- package/dist/errors/classes.js +2 -2
- package/dist/errors/index.d.ts +5 -14
- package/dist/errors/index.js +4 -9
- package/dist/errors/member-resolution.js +1 -1
- package/dist/errors/reasons.d.ts +0 -1
- package/dist/errors/reasons.js +7 -7
- package/dist/errors/serialize.d.ts +0 -18
- package/dist/errors/serialize.js +0 -27
- package/dist/es-ops/index.d.ts +4 -4
- package/dist/es-ops/index.js +2 -2
- package/dist/es-ops/operations-schema.d.ts +1 -1
- package/dist/es-ops/types.d.ts +4 -5
- package/dist/event-store/admin-api-internals.d.ts +14 -0
- package/dist/event-store/admin-api-internals.js +1 -0
- package/dist/event-store/admin-api.d.ts +1 -14
- package/dist/event-store/admin-api.js +11 -6
- package/dist/event-store/archive.js +4 -2
- package/dist/event-store/errors.js +2 -2
- package/dist/event-store/event-store.js +41 -34
- package/dist/event-store/events-schema.js +4 -1
- package/dist/event-store/index.d.ts +11 -13
- package/dist/event-store/index.js +7 -9
- package/dist/event-store/rebuild-dead-letter.js +4 -2
- package/dist/event-store/snapshot.js +4 -3
- package/dist/event-store/stream-scope.d.ts +2 -0
- package/dist/event-store/stream-scope.js +6 -0
- package/dist/event-store/upcaster-dead-letter.js +4 -2
- package/dist/event-store/upcaster.d.ts +2 -1
- package/dist/files/action-form-upload.d.ts +2 -1
- package/dist/files/action-form-upload.js +1 -1
- package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
- package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
- package/dist/files/bind-pending-file-refs.d.ts +2 -1
- package/dist/files/bind-pending-file-refs.js +2 -1
- package/dist/files/bind-referenced-files.write.js +1 -1
- package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
- package/dist/files/create-file-ref-from-bytes.js +3 -3
- package/dist/files/create-file-ref.d.ts +3 -2
- package/dist/files/create-file-ref.js +2 -2
- package/dist/files/dispose-removed-file-refs.d.ts +2 -1
- package/dist/files/dispose-removed-file-refs.js +1 -1
- package/dist/files/feature.js +2 -2
- package/dist/files/file-handle.js +1 -1
- package/dist/files/file-routes.d.ts +1 -1
- package/dist/files/file-routes.js +12 -2
- package/dist/files/index.d.ts +11 -13
- package/dist/files/index.js +5 -7
- package/dist/files/load-save-file-refs.d.ts +2 -1
- package/dist/files/load-save-file-refs.js +1 -1
- package/dist/files/provider-resolver.d.ts +5 -4
- package/dist/files/provider-resolver.js +4 -4
- package/dist/files/storage-tracking.js +4 -2
- package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
- package/dist/files/sweep-orphaned-uploads.js +1 -1
- package/dist/i18n/index.d.ts +2 -8
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/internals.d.ts +7 -0
- package/dist/i18n/internals.js +1 -0
- package/dist/i18n/required-surface-keys.d.ts +4 -1
- package/dist/internal/row-level-security.d.ts +3 -0
- package/dist/internal/row-level-security.js +3 -0
- package/dist/internal/stack-support.d.ts +1 -1
- package/dist/internal/stack-support.js +1 -1
- package/dist/internal/testing.d.ts +1 -0
- package/dist/internal/testing.js +9 -5
- package/dist/jobs/index.d.ts +1 -1
- package/dist/jobs/job-append-event.d.ts +12 -0
- package/dist/jobs/job-append-event.js +30 -0
- package/dist/jobs/job-runner-context.d.ts +2 -2
- package/dist/jobs/job-runner-context.js +46 -16
- package/dist/jobs/job-runner-execution.d.ts +1 -1
- package/dist/jobs/job-runner-execution.js +6 -4
- package/dist/jobs/job-runner-gates.d.ts +1 -1
- package/dist/jobs/job-runner-gates.js +0 -1
- package/dist/jobs/job-runner-helpers.d.ts +11 -4
- package/dist/jobs/job-runner-helpers.js +10 -1
- package/dist/jobs/job-runner-scope.d.ts +5 -2
- package/dist/jobs/job-runner-types.d.ts +2 -1
- package/dist/jobs/job-runner.js +19 -6
- package/dist/jobs/max-per-tenant.d.ts +1 -1
- package/dist/logging/index.d.ts +1 -2
- package/dist/logging/index.js +1 -1
- package/dist/logging/pino-logger.js +1 -1
- package/dist/logging/utils.d.ts +1 -0
- package/dist/logging/utils.js +6 -0
- package/dist/migrations/index.d.ts +3 -3
- package/dist/migrations/index.js +3 -3
- package/dist/migrations/pending-rebuilds.d.ts +1 -1
- package/dist/migrations/pending-rebuilds.js +1 -1
- package/dist/migrations/pii-event-backfill.js +4 -1
- package/dist/observability/escape-hatch-report.d.ts +2 -1
- package/dist/observability/index.d.ts +7 -15
- package/dist/observability/index.js +4 -12
- package/dist/observability/metric-validator.js +1 -1
- package/dist/observability/metrics-handle.d.ts +0 -1
- package/dist/observability/metrics-handle.js +2 -15
- package/dist/observability/recording-tracer.d.ts +1 -2
- package/dist/observability/recording-tracer.js +0 -6
- package/dist/observability/sensitive-filter.d.ts +0 -2
- package/dist/observability/sensitive-filter.js +0 -29
- package/dist/pipeline/active-membership.d.ts +2 -1
- package/dist/pipeline/active-membership.js +6 -2
- package/dist/pipeline/append-event-core.d.ts +2 -1
- package/dist/pipeline/append-event-core.js +2 -2
- package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
- package/dist/pipeline/attach-outside-transaction.js +13 -0
- package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
- package/dist/pipeline/cascade-handler.d.ts +2 -1
- package/dist/pipeline/cascade-handler.js +3 -2
- package/dist/pipeline/config-accessor-factory.d.ts +1 -1
- package/dist/pipeline/config-accessor-factory.js +1 -1
- package/dist/pipeline/context-services.d.ts +56 -0
- package/dist/pipeline/context-services.js +73 -0
- package/dist/pipeline/dispatch-batch.d.ts +2 -1
- package/dist/pipeline/dispatch-batch.js +31 -18
- package/dist/pipeline/dispatch-query.js +5 -4
- package/dist/pipeline/dispatch-scope.d.ts +6 -0
- package/dist/pipeline/dispatch-scope.js +27 -0
- package/dist/pipeline/dispatch-shared.d.ts +13 -9
- package/dist/pipeline/dispatch-shared.js +75 -198
- package/dist/pipeline/dispatch-stream.js +8 -4
- package/dist/pipeline/dispatch-write.d.ts +2 -1
- package/dist/pipeline/dispatch-write.js +10 -8
- package/dist/pipeline/dispatcher-utils.d.ts +3 -1
- package/dist/pipeline/dispatcher-utils.js +8 -2
- package/dist/pipeline/dispatcher.d.ts +3 -2
- package/dist/pipeline/dispatcher.js +4 -3
- package/dist/pipeline/event-consumer-state.d.ts +0 -1
- package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
- package/dist/pipeline/event-dispatcher-delivery.js +4 -2
- package/dist/pipeline/event-dispatcher.d.ts +2 -2
- package/dist/pipeline/event-dispatcher.js +7 -3
- package/dist/pipeline/event-retention.js +59 -56
- package/dist/pipeline/handler-access-error.js +2 -1
- package/dist/pipeline/handler-context-auth.d.ts +5 -6
- package/dist/pipeline/handler-context-auth.js +7 -4
- package/dist/pipeline/handler-context-config.d.ts +2 -5
- package/dist/pipeline/handler-context-config.js +2 -2
- package/dist/pipeline/handler-context-db.d.ts +32 -7
- package/dist/pipeline/handler-context-db.js +26 -17
- package/dist/pipeline/handler-context-dispatch.d.ts +13 -7
- package/dist/pipeline/handler-context-dispatch.js +9 -8
- package/dist/pipeline/handler-context-events.d.ts +22 -36
- package/dist/pipeline/handler-context-events.js +36 -31
- package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
- package/dist/pipeline/handler-context-member-resolution.js +110 -0
- package/dist/pipeline/handler-context-notify.d.ts +3 -2
- package/dist/pipeline/handler-context-notify.js +1 -1
- package/dist/pipeline/handler-context-observability.d.ts +2 -4
- package/dist/pipeline/handler-context-observability.js +7 -5
- package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
- package/dist/pipeline/handler-context-phase-denials.js +98 -0
- package/dist/pipeline/handler-context-scope.d.ts +7 -10
- package/dist/pipeline/handler-context-scope.js +18 -20
- package/dist/pipeline/index.d.ts +9 -21
- package/dist/pipeline/index.js +5 -7
- package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
- package/dist/pipeline/irreversible-operation-gate.js +2 -2
- package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
- package/dist/pipeline/lifecycle-pipeline.js +9 -15
- package/dist/pipeline/member-read-only-transaction.js +11 -3
- package/dist/pipeline/member-reader.d.ts +1 -1
- package/dist/pipeline/member-reader.js +2 -2
- package/dist/pipeline/msp-rebuild.js +5 -3
- package/dist/pipeline/multi-stream-apply-context.js +3 -2
- package/dist/pipeline/notify-scope.d.ts +2 -1
- package/dist/pipeline/pre-handler-gates.d.ts +2 -1
- package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
- package/dist/pipeline/pre-transaction-reservations.js +9 -7
- package/dist/pipeline/projection-rebuild.js +12 -5
- package/dist/pipeline/projection-state.d.ts +0 -6
- package/dist/pipeline/projection-state.js +0 -5
- package/dist/pipeline/projections-runner.d.ts +2 -1
- package/dist/pipeline/projections-runner.js +10 -6
- package/dist/pipeline/system-hooks.d.ts +3 -1
- package/dist/pipeline/system-hooks.js +6 -4
- package/dist/pipeline/system-identity-switch.d.ts +4 -2
- package/dist/pipeline/system-identity-switch.js +51 -36
- package/dist/pipeline/typed-append-event.d.ts +2 -0
- package/dist/pipeline/typed-append-event.js +4 -0
- package/dist/pipeline/write-origin.js +2 -2
- package/dist/pipeline/write-result-masking.d.ts +1 -1
- package/dist/random/index.d.ts +1 -2
- package/dist/random/index.js +1 -2
- package/dist/rate-limit/bucket.d.ts +2 -1
- package/dist/rate-limit/middleware.js +2 -1
- package/dist/redis/index.d.ts +3 -4
- package/dist/redis/index.js +2 -2
- package/dist/schema-cli/apply-command.js +5 -2
- package/dist/schema-cli/baseline-command.js +7 -2
- package/dist/schema-cli/generate-command.js +7 -9
- package/dist/schema-cli/shared.d.ts +12 -2
- package/dist/schema-cli/shared.js +24 -2
- package/dist/schema-cli/status-command.js +8 -2
- package/dist/schema-cli/validate-command.js +48 -4
- package/dist/schema-cli.d.ts +0 -1
- package/dist/search/configure-tenant-index.d.ts +1 -3
- package/dist/search/configure-tenant-index.js +0 -4
- package/dist/search/index.d.ts +1 -4
- package/dist/search/index.js +0 -2
- package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
- package/dist/search/meilisearch-adapter-internals.js +9 -0
- package/dist/search/meilisearch-adapter.d.ts +1 -8
- package/dist/search/meilisearch-adapter.js +6 -7
- package/dist/search/meilisearch-peer.d.ts +2 -0
- package/dist/search/meilisearch-peer.js +5 -0
- package/dist/search/reindex-entity.js +93 -87
- package/dist/secrets/index.d.ts +3 -4
- package/dist/secrets/index.js +2 -3
- package/dist/seeding/index.d.ts +2 -2
- package/dist/seeding/index.js +1 -2
- package/dist/time/index.d.ts +2 -2
- package/dist/time/index.js +1 -1
- package/dist/time/tz-context.d.ts +0 -5
- package/dist/time/tz-context.js +0 -9
- package/dist/ui-types/index.d.ts +8 -11
- package/dist/ui-types/index.js +3 -3
- package/dist/upgrade-changelog.d.ts +3 -2
- package/dist/upgrade-changelog.js +12 -8
- package/dist/upgrade-cli-internals.d.ts +8 -0
- package/dist/upgrade-cli-internals.js +63 -0
- package/dist/upgrade-cli.d.ts +2 -9
- package/dist/upgrade-cli.js +28 -70
- package/dist/utils/import-optional-peer.d.ts +6 -0
- package/dist/utils/import-optional-peer.js +19 -0
- package/dist/utils/index.d.ts +1 -4
- package/dist/utils/index.js +1 -4
- package/package.json +23 -19
- package/src/changes.json +236 -0
- package/dist/crypto/request-kms-cache.d.ts +0 -8
- package/dist/crypto/request-kms-cache.js +0 -21
- package/dist/engine/codemod/index.d.ts +0 -2
- package/dist/engine/codemod/index.js +0 -1
- package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
- package/dist/engine/codemod/pipeline-codemod.js +0 -536
- package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
- package/dist/engine/feature-ast/entity-field-types.js +0 -35
- package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
- package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
- package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
- package/dist/engine/feature-ast/extractors/events.js +0 -275
- package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
- package/dist/engine/feature-ast/extractors/handlers.js +0 -358
- package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
- package/dist/engine/feature-ast/extractors/hooks.js +0 -248
- package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
- package/dist/engine/feature-ast/extractors/index.js +0 -13
- package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
- package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
- package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
- package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
- package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
- package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
- package/dist/engine/feature-ast/extractors/round1.d.ts +0 -11
- package/dist/engine/feature-ast/extractors/round1.js +0 -87
- package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
- package/dist/engine/feature-ast/extractors/round2.js +0 -191
- package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
- package/dist/engine/feature-ast/extractors/round3.js +0 -292
- package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
- package/dist/engine/feature-ast/extractors/round5.js +0 -68
- package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
- package/dist/engine/feature-ast/extractors/round6.js +0 -17
- package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
- package/dist/engine/feature-ast/extractors/shared.js +0 -343
- package/dist/engine/feature-ast/index.d.ts +0 -16
- package/dist/engine/feature-ast/index.js +0 -10
- package/dist/engine/feature-ast/parse.d.ts +0 -31
- package/dist/engine/feature-ast/parse.js +0 -485
- package/dist/engine/feature-ast/patch.d.ts +0 -212
- package/dist/engine/feature-ast/patch.js +0 -611
- package/dist/engine/feature-ast/patcher.d.ts +0 -217
- package/dist/engine/feature-ast/patcher.js +0 -281
- package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1238
- package/dist/engine/feature-ast/pattern-change-schema.js +0 -1072
- package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
- package/dist/engine/feature-ast/pattern-id-matchers.js +0 -211
- package/dist/engine/feature-ast/pattern-id-schema.d.ts +0 -251
- package/dist/engine/feature-ast/pattern-id-schema.js +0 -166
- package/dist/engine/feature-ast/patterns.d.ts +0 -322
- package/dist/engine/feature-ast/patterns.js +0 -107
- package/dist/engine/feature-ast/render.d.ts +0 -47
- package/dist/engine/feature-ast/render.js +0 -666
- package/dist/engine/feature-ast/source-location.d.ts +0 -17
- package/dist/engine/feature-ast/source-location.js +0 -27
- package/dist/engine/pattern-library/index.d.ts +0 -2
- package/dist/engine/pattern-library/index.js +0 -3
- package/dist/engine/pattern-library/library.d.ts +0 -14
- package/dist/engine/pattern-library/library.js +0 -94
- package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
- package/dist/engine/pattern-library/mixed-schemas.js +0 -559
- package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
- package/dist/engine/pattern-library/opaque-schemas.js +0 -115
- package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
- package/dist/engine/pattern-library/shared-fields.js +0 -88
- package/dist/engine/pattern-library/static-schemas.d.ts +0 -21
- package/dist/engine/pattern-library/static-schemas.js +0 -487
- package/dist/engine/pattern-library/types.d.ts +0 -158
- package/dist/engine/pattern-library/types.js +0 -36
- package/dist/engine/resolve-config-or-param.d.ts +0 -18
- package/dist/engine/resolve-config-or-param.js +0 -76
- package/src/scripts/codemod/README.md +0 -187
- package/src/scripts/codemod/codemod-support.ts +0 -334
- package/src/scripts/codemod/collect-source-files.ts +0 -48
- package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
- package/src/scripts/codemod/db-factory.ts +0 -810
- package/src/scripts/codemod/feature-factory.ts +0 -429
- package/src/scripts/codemod/feature-layout.ts +0 -424
- package/src/scripts/codemod/import-extensions.ts +0 -118
- package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
- package/src/scripts/codemod/migrate-db-raw.ts +0 -401
- package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
- package/src/scripts/codemod/object-form.ts +0 -746
- package/src/scripts/codemod/package-merge.ts +0 -299
- package/src/scripts/codemod/pii-personal-migration.ts +0 -816
- package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
- package/src/scripts/codemod/s3-imports.ts +0 -236
- package/src/scripts/codemod/tenant-db-options.ts +0 -454
- package/src/scripts/codemod/testing-injection.ts +0 -215
- package/src/scripts/codemod/testing-move-targets.ts +0 -161
- package/src/scripts/codemod/testing-move.ts +0 -542
- package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
|
@@ -4,8 +4,11 @@ import { instructionFieldNames } from "../engine/instruction-fields.js";
|
|
|
4
4
|
import { userCanCreateFieldRow, userCanWriteFieldRow } from "../engine/ownership.js";
|
|
5
5
|
import { buildInsertSchema, buildUpdateSchema } from "../engine/schema-builder.js";
|
|
6
6
|
import { findUnavailableSelectOptions, isRecordLocked, isUnchangedValue, } from "../engine/screen-helpers.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { IdempotentReplayError, PreconditionFailedError, RecordLockedError, } from "../errors/classes.js";
|
|
8
|
+
import { AccessDeniedError, VersionConflictError as FrameworkVersionConflict, InternalError, NotFoundError, UnprocessableError, writeFailure, } from "../errors/index.js";
|
|
9
|
+
import { isSubjectErasedConflict } from "../errors/subject-erased.js";
|
|
10
|
+
import { IdempotentAppendConflictError as EventStoreIdempotentAppendConflict } from "../event-store/errors.js";
|
|
11
|
+
import { append, VersionConflictError as EventStoreVersionConflict, getStreamVersion, } from "../event-store/index.js";
|
|
9
12
|
import { assertInstructionFieldWriteAllowed, assertIrreversibleOperationAllowed, isIrreversibleEntityVerb, } from "../pipeline/irreversible-operation-gate.js";
|
|
10
13
|
import { generateId } from "../utils/index.js";
|
|
11
14
|
import { applyEntityEvent } from "./apply-entity-event.js";
|
|
@@ -131,7 +134,7 @@ export function createWriteVerbs(ctx) {
|
|
|
131
134
|
}
|
|
132
135
|
throw error;
|
|
133
136
|
}
|
|
134
|
-
// Stream-version is authoritative, not row.version. `ctx.
|
|
137
|
+
// Stream-version is authoritative, not row.version. `ctx.events.append`
|
|
135
138
|
// can bump the stream between CRUD writes (domain event on the same
|
|
136
139
|
// aggregate); a stale row.version here would make the next CRUD write
|
|
137
140
|
// trip `events_aggregate_version_uq` (tenant_id, aggregate_id, version)
|
|
@@ -251,7 +254,7 @@ export function createWriteVerbs(ctx) {
|
|
|
251
254
|
// internal_error at commit time instead of the version_conflict this
|
|
252
255
|
// catch classifies. runInSavepointIfSupported confines the failed
|
|
253
256
|
// INSERT to a nested scope that rolls back on its own (same pattern as
|
|
254
|
-
// ctx.
|
|
257
|
+
// ctx.events.tryAppend), and falls back to a plain call when the runner
|
|
255
258
|
// is a bare pool connection with no active transaction to poison
|
|
256
259
|
// (seeds/tests calling the executor directly).
|
|
257
260
|
const event = await runInSavepointIfSupported(runner, async (sp) => append(sp, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EventStoreExecutor } from "@cosmicdrift/kumiko-types/event-store-executor-types";
|
|
2
|
+
import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
|
|
2
3
|
import type { LocalKeyKmsAdapter } from "../crypto/index.ts";
|
|
3
|
-
import type { EntityDefinition } from "../engine/types/index.ts";
|
|
4
4
|
import type { EntityCache } from "../pipeline/entity-cache.ts";
|
|
5
5
|
import type { SearchAdapter } from "../search/types.ts";
|
|
6
6
|
import type { EnvelopeCipher } from "../secrets/envelope-cipher.ts";
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { ExecutorManagedWriteCapability, Writable } from "@cosmicdrift/kumiko-types/executor-brand";
|
|
2
|
+
import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
|
|
2
3
|
import { AccessDeniedError } from "../errors/index.ts";
|
|
3
|
-
export
|
|
4
|
+
export type ExecutorManagedEntitySource = {
|
|
5
|
+
readonly entityName: string;
|
|
6
|
+
readonly entity: EntityDefinition;
|
|
7
|
+
};
|
|
8
|
+
export declare function markExecutorManagedTable(table: object, entitySource?: ExecutorManagedEntitySource): void;
|
|
9
|
+
export declare function executorManagedEntitySourceOf(table: unknown): ExecutorManagedEntitySource | undefined;
|
|
4
10
|
export declare function isExecutorManagedTable(table: unknown): boolean;
|
|
5
11
|
export declare function registerExecutorManagedWriteRunner(runner: object): void;
|
|
6
12
|
export declare function hasExecutorManagedWriteCapability(runner: unknown): runner is ExecutorManagedWriteCapability;
|
|
@@ -2,11 +2,20 @@ import { AccessDeniedError, InternalError } from "../errors/index.js";
|
|
|
2
2
|
import { asEntityTableMeta, tableNameOf } from "./table-introspection.js";
|
|
3
3
|
const executorManagedTables = new WeakSet();
|
|
4
4
|
const executorManagedWriteRunners = new WeakSet();
|
|
5
|
-
|
|
5
|
+
const entitySourceByTable = new WeakMap();
|
|
6
|
+
// Projection tables (r.projection) have no entity source; only entity tables can take a created event.
|
|
7
|
+
export function markExecutorManagedTable(table, entitySource) {
|
|
6
8
|
executorManagedTables.add(table);
|
|
7
9
|
const meta = asEntityTableMeta(table);
|
|
8
10
|
if (meta !== undefined)
|
|
9
11
|
executorManagedTables.add(meta);
|
|
12
|
+
if (entitySource !== undefined)
|
|
13
|
+
entitySourceByTable.set(table, entitySource);
|
|
14
|
+
}
|
|
15
|
+
export function executorManagedEntitySourceOf(table) {
|
|
16
|
+
if (typeof table !== "object" || table === null)
|
|
17
|
+
return undefined;
|
|
18
|
+
return entitySourceByTable.get(table);
|
|
10
19
|
}
|
|
11
20
|
export function isExecutorManagedTable(table) {
|
|
12
21
|
if (typeof table !== "object" || table === null)
|
|
@@ -34,7 +43,7 @@ export function executorManagedWriteDenied(runner, table, operation) {
|
|
|
34
43
|
const tableName = tableNameOf(table);
|
|
35
44
|
return new AccessDeniedError({
|
|
36
45
|
message: `${operation}(${tableName}): "${tableName}" is fed by events (r.entity / r.projection). ` +
|
|
37
|
-
"Write it through the entity executor (r.crud, ctx.write, createEventStoreExecutor) or inside a " +
|
|
46
|
+
"Write it through the entity executor (r.crud, ctx.dispatch.write, createEventStoreExecutor) or inside a " +
|
|
38
47
|
"projection apply; a direct write drifts from the event stream and a rebuild drops or resurrects the row.",
|
|
39
48
|
});
|
|
40
49
|
}
|
package/dist/db/index.d.ts
CHANGED
|
@@ -3,44 +3,45 @@ export { applyEntityEvent } from "./apply-entity-event.ts";
|
|
|
3
3
|
export { assertExistsIn } from "./assert-exists-in.ts";
|
|
4
4
|
export { nullBlindIndexesForSubject, recordEventsOwnedExclusivelyByTenant, recordRowExistsInTenant, recordRowOwningTenantId, subjectRowExistsInTenant, } from "./blind-index-cleanup.ts";
|
|
5
5
|
export { collectTableMetas } from "./collect-table-metas.ts";
|
|
6
|
-
export { flattenCompoundTypes, rehydrateCompoundTypes } from "./compound-types.ts";
|
|
7
6
|
export { seedConfigValues } from "./config-seed.ts";
|
|
8
|
-
export type {
|
|
7
|
+
export type { DbConnection, DbRow, DbRunner, DbTx, } from "./connection.ts";
|
|
9
8
|
export { createDbConnection, DEFAULT_OUTSIDE_TRANSACTION_POOL_MAX, dbConnectionOptionsFromEnv, outsideTransactionPoolOptionsFromEnv, serverTimeoutOptionsFromEnv, } from "./connection.ts";
|
|
10
|
-
export type { CursorQueryOptions, CursorResult, DecodedKeysetCursor } from "./cursor.ts";
|
|
11
9
|
export { decodeCursor, decodeKeysetCursor, encodeCursor, encodeKeysetCursor } from "./cursor.ts";
|
|
12
|
-
export type { SchemaTable
|
|
13
|
-
export {
|
|
10
|
+
export type { SchemaTable } from "./dialect.ts";
|
|
11
|
+
export { boolean, extractTableName, index, instant, integer, jsonb, primaryKey, serial, sql, table, text, timestamp, uniqueIndex, uuid, } from "./dialect.ts";
|
|
14
12
|
export { instantToTimestamptzParam } from "./driver-value-preparation.ts";
|
|
15
|
-
export
|
|
16
|
-
export { collectReferenceFields, enrichRowWithReferences, enrichWithReferences, } from "./eagerload.ts";
|
|
17
|
-
export { collectEncryptedFieldNames, configuredEntityFieldEncryption, configureEntityFieldEncryption, decryptEntityFieldValues, encryptEntityFieldValues, } from "./entity-field-encryption.ts";
|
|
13
|
+
export { collectEncryptedFieldNames, configuredEntityFieldEncryption, configureEntityFieldEncryption, decryptEntityFieldValues, } from "./entity-field-encryption.ts";
|
|
18
14
|
export { entityTableFromRegistry } from "./entity-table-from-registry.ts";
|
|
19
|
-
export type {
|
|
15
|
+
export type { ColumnMeta, EntityTableMeta, } from "./entity-table-meta.ts";
|
|
20
16
|
export { defineUnmanagedTable, deriveEntityTableMeta, } from "./entity-table-meta.ts";
|
|
21
|
-
export type {
|
|
17
|
+
export type { EventStoreExecutor, WritePurpose, } from "./event-store-executor.ts";
|
|
22
18
|
export { createEventStoreExecutor, entityEventName, WritePurposes, } from "./event-store-executor.ts";
|
|
23
|
-
export { enumerateFeatureTableSources
|
|
24
|
-
export {
|
|
25
|
-
export {
|
|
26
|
-
export {
|
|
27
|
-
export {
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
19
|
+
export { enumerateFeatureTableSources } from "./feature-table-sources.ts";
|
|
20
|
+
export { type KnownTables, knownTablesOf } from "./known-table-names.ts";
|
|
21
|
+
export { answerListAggregate } from "./list-aggregate-labels.ts";
|
|
22
|
+
export { generateMigration, loadSnapshotJson, writeSnapshotJson, } from "./migrate-generator.ts";
|
|
23
|
+
export { runMigrationsFromDir } from "./migrate-runner.ts";
|
|
24
|
+
export { type MoneyRead, rehydrateMoney } from "./money.ts";
|
|
25
|
+
export { extractPgError, isUndefinedTable, isUniqueViolation, } from "./pg-error.ts";
|
|
30
26
|
export { acquireNamespacedAdvisoryLock } from "./queries/advisory-lock.ts";
|
|
31
27
|
export { readDatabaseNow } from "./queries/database-now.ts";
|
|
28
|
+
export { listEventTenantIds } from "./queries/event-tenants.ts";
|
|
32
29
|
export { toPostgresArrayLiteral } from "./queries/postgres-array-literal.ts";
|
|
33
|
-
export { executeRawQuery
|
|
34
|
-
export
|
|
35
|
-
export {
|
|
36
|
-
export {
|
|
30
|
+
export { executeRawQuery } from "./queries/raw-sql.ts";
|
|
31
|
+
export { withSessionAdvisoryLock } from "./queries/session-advisory-lock.ts";
|
|
32
|
+
export type { JsonTextMatch, SelectOptions, WhereObject, } from "./query.ts";
|
|
33
|
+
export { aggregateWhere, asEntityTableMeta, asRawClient, countWhere, deleteMany, deleteManyBatched, fetchOne, incrementCounter, insertMany, insertOnConflictDoNothing, insertOne, requireEntityTableMeta, runInSavepointIfSupported, runnerCanBeginTransaction, selectInnerJoin, selectMany, transaction, unsafeReadRetrying, updateMany, upsertByPk, upsertOnConflict, } from "./query.ts";
|
|
37
34
|
export { seedReferenceData } from "./reference-data.ts";
|
|
38
|
-
export {
|
|
39
|
-
export {
|
|
40
|
-
export {
|
|
35
|
+
export { renderTablesDdl } from "./render-ddl.ts";
|
|
36
|
+
export { ROW_LEVEL_SECURITY_MODES, type RowLevelSecurityMode } from "./render-rls-ddl.ts";
|
|
37
|
+
export { assertRowLevelSecurityBootState, assertRowLevelSecurityTableState, } from "./row-level-security-boot-check.ts";
|
|
38
|
+
export { rowLevelSecurityModeOf } from "./row-level-security-connection.ts";
|
|
39
|
+
export type { RowLevelSecurityScope } from "./row-level-security-scope.ts";
|
|
40
|
+
export { assertNoActiveRowLevelSecurityScope } from "./row-level-security-scope.ts";
|
|
41
41
|
export { tableExists } from "./schema-inspection.ts";
|
|
42
|
-
export {
|
|
43
|
-
export { buildBaseColumns, buildEntityTable, declareGlobalTenancy, type
|
|
42
|
+
export { scopeTenantDbToTenant } from "./scope-tenant-db-to-tenant.ts";
|
|
43
|
+
export { buildBaseColumns, buildEntityTable, declareGlobalTenancy, type EntityTable, type ExecutorManagedRunner, physicalColumnName, type WritableSchemaTable, type WritableTable, } from "./table-builder.ts";
|
|
44
44
|
export { extractTableInfo, type TableInfo } from "./table-info.ts";
|
|
45
|
-
export type {
|
|
46
|
-
export { castTenantRows, createSystemDbView, createTenantDataDestroyDb, createTenantDb,
|
|
45
|
+
export type { ExecutorManagedTenantDb, TenantDb, UncheckedSystemDb, } from "./tenant-db.ts";
|
|
46
|
+
export { castTenantRows, createSystemDbView, createTenantDataDestroyDb, createTenantDb, } from "./tenant-db.ts";
|
|
47
|
+
export { runInOwnTransaction } from "./tenant-db-scoped-rebind.ts";
|
package/dist/db/index.js
CHANGED
|
@@ -3,36 +3,38 @@ export { applyEntityEvent } from "./apply-entity-event.js";
|
|
|
3
3
|
export { assertExistsIn } from "./assert-exists-in.js";
|
|
4
4
|
export { nullBlindIndexesForSubject, recordEventsOwnedExclusivelyByTenant, recordRowExistsInTenant, recordRowOwningTenantId, subjectRowExistsInTenant, } from "./blind-index-cleanup.js";
|
|
5
5
|
export { collectTableMetas } from "./collect-table-metas.js";
|
|
6
|
-
export { flattenCompoundTypes, rehydrateCompoundTypes } from "./compound-types.js";
|
|
7
6
|
export { seedConfigValues } from "./config-seed.js";
|
|
8
7
|
export { createDbConnection, DEFAULT_OUTSIDE_TRANSACTION_POOL_MAX, dbConnectionOptionsFromEnv, outsideTransactionPoolOptionsFromEnv, serverTimeoutOptionsFromEnv, } from "./connection.js";
|
|
9
8
|
export { decodeCursor, decodeKeysetCursor, encodeCursor, encodeKeysetCursor } from "./cursor.js";
|
|
10
|
-
export {
|
|
9
|
+
export { boolean, extractTableName, index, instant, integer, jsonb, primaryKey, serial, sql, table, text, timestamp, uniqueIndex, uuid, } from "./dialect.js";
|
|
11
10
|
export { instantToTimestamptzParam } from "./driver-value-preparation.js";
|
|
12
|
-
export {
|
|
13
|
-
export { collectEncryptedFieldNames, configuredEntityFieldEncryption, configureEntityFieldEncryption, decryptEntityFieldValues, encryptEntityFieldValues, } from "./entity-field-encryption.js";
|
|
11
|
+
export { collectEncryptedFieldNames, configuredEntityFieldEncryption, configureEntityFieldEncryption, decryptEntityFieldValues, } from "./entity-field-encryption.js";
|
|
14
12
|
export { entityTableFromRegistry } from "./entity-table-from-registry.js";
|
|
15
13
|
export { defineUnmanagedTable, deriveEntityTableMeta, } from "./entity-table-meta.js";
|
|
16
14
|
export { createEventStoreExecutor, entityEventName, WritePurposes, } from "./event-store-executor.js";
|
|
17
|
-
export { enumerateFeatureTableSources
|
|
18
|
-
export {
|
|
19
|
-
export {
|
|
20
|
-
export {
|
|
21
|
-
export {
|
|
22
|
-
export {
|
|
23
|
-
export {
|
|
15
|
+
export { enumerateFeatureTableSources } from "./feature-table-sources.js";
|
|
16
|
+
export { knownTablesOf } from "./known-table-names.js";
|
|
17
|
+
export { answerListAggregate } from "./list-aggregate-labels.js";
|
|
18
|
+
export { generateMigration, loadSnapshotJson, writeSnapshotJson, } from "./migrate-generator.js";
|
|
19
|
+
export { runMigrationsFromDir } from "./migrate-runner.js";
|
|
20
|
+
export { rehydrateMoney } from "./money.js";
|
|
21
|
+
export { extractPgError, isUndefinedTable, isUniqueViolation, } from "./pg-error.js";
|
|
24
22
|
export { acquireNamespacedAdvisoryLock } from "./queries/advisory-lock.js";
|
|
25
23
|
export { readDatabaseNow } from "./queries/database-now.js";
|
|
24
|
+
export { listEventTenantIds } from "./queries/event-tenants.js";
|
|
26
25
|
export { toPostgresArrayLiteral } from "./queries/postgres-array-literal.js";
|
|
27
|
-
export { executeRawQuery
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
26
|
+
export { executeRawQuery } from "./queries/raw-sql.js";
|
|
27
|
+
export { withSessionAdvisoryLock } from "./queries/session-advisory-lock.js";
|
|
28
|
+
export { aggregateWhere, asEntityTableMeta, asRawClient, countWhere, deleteMany, deleteManyBatched, fetchOne, incrementCounter, insertMany, insertOnConflictDoNothing, insertOne, requireEntityTableMeta, runInSavepointIfSupported, runnerCanBeginTransaction, selectInnerJoin, selectMany, transaction, unsafeReadRetrying, updateMany, upsertByPk, upsertOnConflict, } from "./query.js";
|
|
30
29
|
export { seedReferenceData } from "./reference-data.js";
|
|
31
|
-
export {
|
|
32
|
-
export {
|
|
33
|
-
export {
|
|
30
|
+
export { renderTablesDdl } from "./render-ddl.js";
|
|
31
|
+
export { ROW_LEVEL_SECURITY_MODES } from "./render-rls-ddl.js";
|
|
32
|
+
export { assertRowLevelSecurityBootState, assertRowLevelSecurityTableState, } from "./row-level-security-boot-check.js";
|
|
33
|
+
export { rowLevelSecurityModeOf } from "./row-level-security-connection.js";
|
|
34
|
+
export { assertNoActiveRowLevelSecurityScope } from "./row-level-security-scope.js";
|
|
34
35
|
export { tableExists } from "./schema-inspection.js";
|
|
35
|
-
export {
|
|
36
|
-
export { buildBaseColumns, buildEntityTable, declareGlobalTenancy, physicalColumnName,
|
|
36
|
+
export { scopeTenantDbToTenant } from "./scope-tenant-db-to-tenant.js";
|
|
37
|
+
export { buildBaseColumns, buildEntityTable, declareGlobalTenancy, physicalColumnName, } from "./table-builder.js";
|
|
37
38
|
export { extractTableInfo } from "./table-info.js";
|
|
38
|
-
export { castTenantRows, createSystemDbView, createTenantDataDestroyDb, createTenantDb,
|
|
39
|
+
export { castTenantRows, createSystemDbView, createTenantDataDestroyDb, createTenantDb, } from "./tenant-db.js";
|
|
40
|
+
export { runInOwnTransaction } from "./tenant-db-scoped-rebind.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FeatureDefinition } from "../engine/types/index.ts";
|
|
2
|
+
export declare function isLiveFrameworkTable(tableName: string): boolean;
|
|
3
|
+
export type KnownTables = {
|
|
4
|
+
readonly has: (tableName: string) => boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare function knownTablesOf(features: readonly FeatureDefinition[]): KnownTables;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { collectTableMetas } from "./collect-table-metas.js";
|
|
2
|
+
import { isRetiredFrameworkTable } from "./retired-framework-tables.js";
|
|
3
|
+
// The prefix only picks which boot-check message a table gets; both groups still throw, and a second
|
|
4
|
+
// framework table list would be one more source to maintain.
|
|
5
|
+
// Event store and pipeline state (kumiko_events, kumiko_projections, ...) are created by framework
|
|
6
|
+
// boot, not by `schema generate`, so no feature declares them.
|
|
7
|
+
const FRAMEWORK_TABLE_PREFIX = "kumiko_";
|
|
8
|
+
export function isLiveFrameworkTable(tableName) {
|
|
9
|
+
return tableName.startsWith(FRAMEWORK_TABLE_PREFIX) && !isRetiredFrameworkTable(tableName);
|
|
10
|
+
}
|
|
11
|
+
// Same source as `kumiko schema generate`: a tenant table that is not listed here has no owner left.
|
|
12
|
+
export function knownTablesOf(features) {
|
|
13
|
+
// Lazy: a healthy boot finds no unprotected table and never asks, so it skips collecting metas.
|
|
14
|
+
let names;
|
|
15
|
+
return {
|
|
16
|
+
has: (tableName) => {
|
|
17
|
+
names ??= new Set(collectTableMetas(features).map((meta) => meta.tableName));
|
|
18
|
+
return names.has(tableName) || isLiveFrameworkTable(tableName);
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
|
|
1
2
|
import type { ListAggregateResult } from "@cosmicdrift/kumiko-types/list-aggregate-types";
|
|
2
|
-
import type { EntityDefinition } from "../engine/types/index.ts";
|
|
3
3
|
import type { EagerLoadEntityResolver, EagerLoadViewer } from "./eagerload.ts";
|
|
4
4
|
import type { EventStoreExecutor } from "./event-store-executor.ts";
|
|
5
5
|
import type { TenantDb } from "./tenant-db.ts";
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
// Automatically converts locatedTimestamp fields in the DB layer.
|
|
2
|
-
//
|
|
3
|
-
// Contract (see also db/money.ts — the same compound-type pattern):
|
|
4
|
-
// API form: { at, tz } | { utc, tz }
|
|
5
|
-
// DB form: <name>Utc TIMESTAMPTZ + <name>Tz TEXT
|
|
6
1
|
// Read form: { at, tz, utc }
|
|
7
2
|
//
|
|
8
3
|
// Default `at` view on read: local to the pickup location (`utc` projected into
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import type { ColumnMeta, EntityTableMeta, IndexMeta } from "./entity-table-meta.ts";
|
|
2
|
+
import { type PrimaryKeyChange } from "./migrate-primary-key.ts";
|
|
3
|
+
import { type RowLevelSecurityChange } from "./migrate-rls-diff.ts";
|
|
4
|
+
import { type RowLevelSecurityMode, type TableRowLevelSecurity } from "./render-rls-ddl.ts";
|
|
2
5
|
import { type RetiredFrameworkTable } from "./retired-framework-tables.ts";
|
|
3
6
|
declare const SNAPSHOT_VERSION: 1;
|
|
4
7
|
export type Snapshot = {
|
|
5
8
|
readonly version: typeof SNAPSHOT_VERSION;
|
|
6
9
|
readonly generatedAt?: string;
|
|
7
10
|
readonly tables: readonly EntityTableMeta[];
|
|
11
|
+
readonly rowLevelSecurity?: Readonly<Record<string, TableRowLevelSecurity>>;
|
|
8
12
|
};
|
|
9
13
|
export type ColumnChange = {
|
|
10
14
|
readonly name: string;
|
|
@@ -48,6 +52,7 @@ export type TableDiff = {
|
|
|
48
52
|
readonly newIndexes: readonly IndexMeta[];
|
|
49
53
|
readonly droppedIndexes: readonly string[];
|
|
50
54
|
readonly changedIndexes: readonly IndexChange[];
|
|
55
|
+
readonly primaryKeyChanged?: PrimaryKeyChange;
|
|
51
56
|
readonly nextMeta: EntityTableMeta;
|
|
52
57
|
};
|
|
53
58
|
export type SchemaDiff = {
|
|
@@ -55,15 +60,24 @@ export type SchemaDiff = {
|
|
|
55
60
|
readonly droppedTables: readonly string[];
|
|
56
61
|
readonly changedTables: readonly TableDiff[];
|
|
57
62
|
};
|
|
58
|
-
export declare function snapshotFromMetas(metas: readonly EntityTableMeta[]
|
|
63
|
+
export declare function snapshotFromMetas(metas: readonly EntityTableMeta[], options?: {
|
|
64
|
+
readonly rowLevelSecurity?: RowLevelSecurityMode;
|
|
65
|
+
}): Snapshot;
|
|
59
66
|
export declare function loadSnapshotJson(path: string): Snapshot | null;
|
|
60
67
|
export declare function writeSnapshotJson(path: string, snapshot: Snapshot): void;
|
|
61
68
|
export declare function diffSnapshots(prev: Snapshot | null, next: Snapshot): SchemaDiff;
|
|
62
69
|
export declare function managedChangeRequiresRecreate(td: TableDiff): boolean;
|
|
70
|
+
export declare function isRecreatedManagedTable(td: TableDiff): boolean;
|
|
71
|
+
export declare function hasNoSchemaChanges(input: {
|
|
72
|
+
readonly diff: SchemaDiff;
|
|
73
|
+
readonly retiredDrops: readonly RetiredFrameworkTable[];
|
|
74
|
+
readonly rowLevelSecurityChanges: readonly RowLevelSecurityChange[];
|
|
75
|
+
}): boolean;
|
|
63
76
|
export declare function renderMigrationSql(diff: SchemaDiff, options: {
|
|
64
77
|
readonly name: string;
|
|
65
78
|
readonly sequenceNumber: number;
|
|
66
79
|
readonly retiredDrops?: readonly RetiredFrameworkTable[];
|
|
80
|
+
readonly rowLevelSecurityChanges?: readonly RowLevelSecurityChange[];
|
|
67
81
|
}): string;
|
|
68
82
|
export type GenerateMigrationInput = {
|
|
69
83
|
readonly metas: readonly EntityTableMeta[];
|
|
@@ -73,6 +87,7 @@ export type GenerateMigrationInput = {
|
|
|
73
87
|
/** Raw SQL of all earlier migrations, in order — lets the generator decide
|
|
74
88
|
* whether a retired framework table still needs its executable drop. */
|
|
75
89
|
readonly priorMigrationsSql?: readonly string[];
|
|
90
|
+
readonly rowLevelSecurity?: RowLevelSecurityMode;
|
|
76
91
|
};
|
|
77
92
|
export type GenerateMigrationOutput = {
|
|
78
93
|
readonly filename: string;
|
|
@@ -80,6 +95,7 @@ export type GenerateMigrationOutput = {
|
|
|
80
95
|
readonly snapshot: Snapshot;
|
|
81
96
|
readonly diff: SchemaDiff;
|
|
82
97
|
readonly retiredDrops: readonly RetiredFrameworkTable[];
|
|
98
|
+
readonly rowLevelSecurityChanges: readonly RowLevelSecurityChange[];
|
|
83
99
|
};
|
|
84
100
|
export declare const MIGRATION_NAME_RE: RegExp;
|
|
85
101
|
export declare function assertValidMigrationName(name: string): void;
|
|
@@ -15,17 +15,23 @@
|
|
|
15
15
|
// never drop automatically.
|
|
16
16
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
17
17
|
import { errorCodeOf, isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
18
|
-
import { compareByCodepoint } from "../utils/
|
|
18
|
+
import { compareByCodepoint } from "../utils/compare.js";
|
|
19
|
+
import { diffPrimaryKey, renderPrimaryKeyChange, } from "./migrate-primary-key.js";
|
|
20
|
+
import { diffRowLevelSecurity, renderRowLevelSecurityChanges, } from "./migrate-rls-diff.js";
|
|
19
21
|
import { renderIndex, renderTableDdl } from "./render-ddl.js";
|
|
22
|
+
import { isTableRowLevelSecurityRecord, rowLevelSecurityByTable, } from "./render-rls-ddl.js";
|
|
20
23
|
import { findRetiredTableDrops } from "./retired-framework-tables.js";
|
|
24
|
+
import { quoteIdent } from "./sql-identifier.js";
|
|
21
25
|
const SNAPSHOT_VERSION = 1;
|
|
22
26
|
function isSnapshot(value) {
|
|
23
27
|
return (isPlainObject(value) &&
|
|
24
28
|
value["version"] === SNAPSHOT_VERSION &&
|
|
25
29
|
(value["generatedAt"] === undefined || typeof value["generatedAt"] === "string") &&
|
|
26
|
-
Array.isArray(value["tables"])
|
|
30
|
+
Array.isArray(value["tables"]) &&
|
|
31
|
+
(value["rowLevelSecurity"] === undefined ||
|
|
32
|
+
isTableRowLevelSecurityRecord(value["rowLevelSecurity"])));
|
|
27
33
|
}
|
|
28
|
-
export function snapshotFromMetas(metas) {
|
|
34
|
+
export function snapshotFromMetas(metas, options = {}) {
|
|
29
35
|
// Stable ordering by tableName so the snapshot.json diff in PRs is
|
|
30
36
|
// meaningful (table-add isn't a noisy re-sort of everything). Codepoint, not
|
|
31
37
|
// localeCompare: the snapshot is serialized to byte-exact JSON and the table
|
|
@@ -36,6 +42,9 @@ export function snapshotFromMetas(metas) {
|
|
|
36
42
|
version: SNAPSHOT_VERSION,
|
|
37
43
|
generatedAt: new Date().toISOString(),
|
|
38
44
|
tables: sorted,
|
|
45
|
+
...(options.rowLevelSecurity === "on" && {
|
|
46
|
+
rowLevelSecurity: rowLevelSecurityByTable(sorted),
|
|
47
|
+
}),
|
|
39
48
|
};
|
|
40
49
|
}
|
|
41
50
|
export function loadSnapshotJson(path) {
|
|
@@ -135,18 +144,20 @@ function compareIndexes(name, prevIndex, nextIndex) {
|
|
|
135
144
|
};
|
|
136
145
|
}
|
|
137
146
|
function hasNoTableChanges(diff) {
|
|
138
|
-
return
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
147
|
+
return (diff.primaryKeyChanged === undefined &&
|
|
148
|
+
[
|
|
149
|
+
diff.newColumns,
|
|
150
|
+
diff.droppedColumns,
|
|
151
|
+
diff.changedColumns,
|
|
152
|
+
diff.newIndexes,
|
|
153
|
+
diff.droppedIndexes,
|
|
154
|
+
diff.changedIndexes,
|
|
155
|
+
].every((list) => list.length === 0));
|
|
146
156
|
}
|
|
147
157
|
function diffOneTable(prev, next) {
|
|
148
158
|
const columns = diffByName(columnsByName(prev), columnsByName(next), compareColumns);
|
|
149
159
|
const indexes = diffByName(indexesByName(prev), indexesByName(next), compareIndexes);
|
|
160
|
+
const primaryKeyChanged = diffPrimaryKey(prev, next);
|
|
150
161
|
const diff = {
|
|
151
162
|
tableName: prev.tableName,
|
|
152
163
|
newColumns: columns.added,
|
|
@@ -155,6 +166,7 @@ function diffOneTable(prev, next) {
|
|
|
155
166
|
newIndexes: indexes.added,
|
|
156
167
|
droppedIndexes: indexes.dropped,
|
|
157
168
|
changedIndexes: indexes.changed,
|
|
169
|
+
...(primaryKeyChanged && { primaryKeyChanged }),
|
|
158
170
|
nextMeta: next,
|
|
159
171
|
};
|
|
160
172
|
return hasNoTableChanges(diff) ? null : diff;
|
|
@@ -225,15 +237,26 @@ function describeRecreateReasons(td) {
|
|
|
225
237
|
if (typeChanged.length > 0) {
|
|
226
238
|
reasons.push(`column type change: ${typeChanged.join(", ")}`);
|
|
227
239
|
}
|
|
240
|
+
if (td.primaryKeyChanged) {
|
|
241
|
+
const { from, to } = td.primaryKeyChanged;
|
|
242
|
+
reasons.push(`primary-key change: ${from.columns.join(", ")} → ${to.columns.join(", ")}`);
|
|
243
|
+
}
|
|
228
244
|
return reasons;
|
|
229
245
|
}
|
|
230
246
|
export function managedChangeRequiresRecreate(td) {
|
|
231
247
|
return describeRecreateReasons(td).length > 0;
|
|
232
248
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
249
|
+
export function isRecreatedManagedTable(td) {
|
|
250
|
+
return td.nextMeta.source === "managed" && managedChangeRequiresRecreate(td);
|
|
251
|
+
}
|
|
252
|
+
export function hasNoSchemaChanges(input) {
|
|
253
|
+
return (input.diff.newTables.length === 0 &&
|
|
254
|
+
input.diff.changedTables.length === 0 &&
|
|
255
|
+
input.diff.droppedTables.length === 0 &&
|
|
256
|
+
input.retiredDrops.length === 0 &&
|
|
257
|
+
input.rowLevelSecurityChanges.length === 0);
|
|
236
258
|
}
|
|
259
|
+
// --- SQL-Render ---------------------------------------------------------
|
|
237
260
|
function renderColumnInline(col) {
|
|
238
261
|
const parts = [quoteIdent(col.name), col.pgType];
|
|
239
262
|
if (col.defaultSql !== undefined)
|
|
@@ -347,7 +370,7 @@ export function renderMigrationSql(diff, options) {
|
|
|
347
370
|
lines.push("-- === Changed tables ===");
|
|
348
371
|
for (const td of diff.changedTables) {
|
|
349
372
|
lines.push(`-- ${td.tableName}`);
|
|
350
|
-
if (
|
|
373
|
+
if (isRecreatedManagedTable(td)) {
|
|
351
374
|
lines.push("-- managed projection — recreated + rebuilt from events (see .rebuild.json)");
|
|
352
375
|
lines.push(`-- WARN: destructive change (${describeRecreateReasons(td).join("; ")}) forces DROP+CREATE + full event replay.`);
|
|
353
376
|
lines.push("-- Consider an Expand/Contract split across two releases to avoid the rebuild — see docs/guides/expand-contract-managed-projections.md.");
|
|
@@ -363,6 +386,7 @@ export function renderMigrationSql(diff, options) {
|
|
|
363
386
|
for (const stmt of renderColumnChange(td.tableName, ch))
|
|
364
387
|
lines.push(stmt);
|
|
365
388
|
}
|
|
389
|
+
lines.push(...renderPrimaryKeyChange(td.tableName, td.primaryKeyChanged));
|
|
366
390
|
for (const idx of td.newIndexes) {
|
|
367
391
|
lines.push(renderIndex(td.tableName, idx));
|
|
368
392
|
}
|
|
@@ -390,6 +414,7 @@ export function renderMigrationSql(diff, options) {
|
|
|
390
414
|
lines.push("");
|
|
391
415
|
}
|
|
392
416
|
}
|
|
417
|
+
lines.push(...renderRowLevelSecurityChanges(options.rowLevelSecurityChanges));
|
|
393
418
|
if (diff.droppedTables.length > 0) {
|
|
394
419
|
lines.push("-- === Dropped tables ===");
|
|
395
420
|
for (const name of diff.droppedTables) {
|
|
@@ -405,10 +430,11 @@ export function renderMigrationSql(diff, options) {
|
|
|
405
430
|
}
|
|
406
431
|
lines.push("");
|
|
407
432
|
}
|
|
408
|
-
if (
|
|
409
|
-
diff
|
|
410
|
-
|
|
411
|
-
|
|
433
|
+
if (hasNoSchemaChanges({
|
|
434
|
+
diff,
|
|
435
|
+
retiredDrops,
|
|
436
|
+
rowLevelSecurityChanges: options.rowLevelSecurityChanges ?? [],
|
|
437
|
+
})) {
|
|
412
438
|
lines.push("-- No schema changes detected.");
|
|
413
439
|
}
|
|
414
440
|
return lines.join("\n");
|
|
@@ -436,13 +462,16 @@ export function assertUniqueTableNames(metas) {
|
|
|
436
462
|
export function generateMigration(input) {
|
|
437
463
|
assertValidMigrationName(input.name);
|
|
438
464
|
assertUniqueTableNames(input.metas);
|
|
439
|
-
const nextSnapshot = snapshotFromMetas(input.metas);
|
|
465
|
+
const nextSnapshot = snapshotFromMetas(input.metas, { rowLevelSecurity: input.rowLevelSecurity });
|
|
440
466
|
const diff = diffSnapshots(input.prevSnapshot, nextSnapshot);
|
|
467
|
+
const recreatedTables = new Set(diff.changedTables.filter(isRecreatedManagedTable).map((td) => td.tableName));
|
|
468
|
+
const rowLevelSecurityChanges = diffRowLevelSecurity(input.prevSnapshot, nextSnapshot, recreatedTables);
|
|
441
469
|
const retiredDrops = findRetiredTableDrops(input.priorMigrationsSql ?? [], nextSnapshot);
|
|
442
470
|
const sqlContent = renderMigrationSql(diff, {
|
|
443
471
|
name: input.name,
|
|
444
472
|
sequenceNumber: input.sequenceNumber,
|
|
445
473
|
retiredDrops,
|
|
474
|
+
rowLevelSecurityChanges,
|
|
446
475
|
});
|
|
447
476
|
const seq = input.sequenceNumber.toString().padStart(4, "0");
|
|
448
477
|
return {
|
|
@@ -451,5 +480,6 @@ export function generateMigration(input) {
|
|
|
451
480
|
snapshot: nextSnapshot,
|
|
452
481
|
diff,
|
|
453
482
|
retiredDrops,
|
|
483
|
+
rowLevelSecurityChanges,
|
|
454
484
|
};
|
|
455
485
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EntityTableMeta } from "./entity-table-meta.ts";
|
|
2
|
+
export type PrimaryKey = {
|
|
3
|
+
readonly columns: readonly string[];
|
|
4
|
+
readonly constraintName: string;
|
|
5
|
+
};
|
|
6
|
+
export type PrimaryKeyChange = {
|
|
7
|
+
readonly from: PrimaryKey;
|
|
8
|
+
readonly to: PrimaryKey;
|
|
9
|
+
};
|
|
10
|
+
export declare function primaryKeyOf(meta: EntityTableMeta): PrimaryKey;
|
|
11
|
+
export declare function diffPrimaryKey(prev: EntityTableMeta, next: EntityTableMeta): PrimaryKeyChange | undefined;
|
|
12
|
+
export declare function renderPrimaryKeyChange(tableName: string, change: PrimaryKeyChange | undefined): readonly string[];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { quoteIdent } from "./sql-identifier.js";
|
|
2
|
+
// Postgres names an implicit PK `<table>_pkey` and, past 63 bytes, shortens the table part, never the suffix.
|
|
3
|
+
const MAX_IDENTIFIER_LENGTH = 63;
|
|
4
|
+
const IMPLICIT_PRIMARY_KEY_SUFFIX = "_pkey";
|
|
5
|
+
// Older snapshots may omit `primaryKey: false` and `compositePrimaryKey`, so only a truthy flag counts.
|
|
6
|
+
export function primaryKeyOf(meta) {
|
|
7
|
+
if (meta.compositePrimaryKey !== undefined) {
|
|
8
|
+
return {
|
|
9
|
+
columns: meta.compositePrimaryKey.columns,
|
|
10
|
+
constraintName: meta.compositePrimaryKey.name,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
columns: meta.columns.filter((col) => col.primaryKey === true).map((col) => col.name),
|
|
15
|
+
constraintName: `${meta.tableName.slice(0, MAX_IDENTIFIER_LENGTH - IMPLICIT_PRIMARY_KEY_SUFFIX.length)}${IMPLICIT_PRIMARY_KEY_SUFFIX}`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function primaryKeysEqual(a, b) {
|
|
19
|
+
return (a.constraintName === b.constraintName &&
|
|
20
|
+
a.columns.length === b.columns.length &&
|
|
21
|
+
a.columns.every((col, i) => col === b.columns[i]));
|
|
22
|
+
}
|
|
23
|
+
export function diffPrimaryKey(prev, next) {
|
|
24
|
+
const from = primaryKeyOf(prev);
|
|
25
|
+
const to = primaryKeyOf(next);
|
|
26
|
+
return primaryKeysEqual(from, to) ? undefined : { from, to };
|
|
27
|
+
}
|
|
28
|
+
// Executable, not commented: the change loses no data, and it fails loudly when existing rows are not unique on the new key.
|
|
29
|
+
export function renderPrimaryKeyChange(tableName, change) {
|
|
30
|
+
if (change === undefined)
|
|
31
|
+
return [];
|
|
32
|
+
const table = quoteIdent(tableName);
|
|
33
|
+
const { from, to } = change;
|
|
34
|
+
const lines = [
|
|
35
|
+
`-- WARN: primary-key change (${from.columns.join(", ")} → ${to.columns.join(", ")}). Existing rows must be unique on the new key.`,
|
|
36
|
+
];
|
|
37
|
+
if (from.columns.length > 0) {
|
|
38
|
+
lines.push(`ALTER TABLE ${table} DROP CONSTRAINT IF EXISTS ${quoteIdent(from.constraintName)};`);
|
|
39
|
+
}
|
|
40
|
+
if (to.columns.length > 0) {
|
|
41
|
+
const columns = to.columns.map(quoteIdent).join(", ");
|
|
42
|
+
lines.push(`ALTER TABLE ${table} ADD CONSTRAINT ${quoteIdent(to.constraintName)} PRIMARY KEY (${columns});`);
|
|
43
|
+
}
|
|
44
|
+
return lines;
|
|
45
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type TableRowLevelSecurity } from "./render-rls-ddl.ts";
|
|
2
|
+
export type RowLevelSecurityChange = {
|
|
3
|
+
readonly kind: "enable";
|
|
4
|
+
readonly tableName: string;
|
|
5
|
+
readonly next: TableRowLevelSecurity;
|
|
6
|
+
readonly previous?: TableRowLevelSecurity;
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: "disable";
|
|
9
|
+
readonly tableName: string;
|
|
10
|
+
readonly previous: TableRowLevelSecurity;
|
|
11
|
+
};
|
|
12
|
+
type RowLevelSecuritySnapshotView = {
|
|
13
|
+
readonly tables: readonly {
|
|
14
|
+
readonly tableName: string;
|
|
15
|
+
}[];
|
|
16
|
+
readonly rowLevelSecurity?: Readonly<Record<string, TableRowLevelSecurity>>;
|
|
17
|
+
};
|
|
18
|
+
export declare function diffRowLevelSecurity(previous: RowLevelSecuritySnapshotView | null, next: RowLevelSecuritySnapshotView, recreatedTables: ReadonlySet<string>): RowLevelSecurityChange[];
|
|
19
|
+
export declare function renderRowLevelSecurityChanges(changes?: readonly RowLevelSecurityChange[]): string[];
|
|
20
|
+
export {};
|