@cosmicdrift/kumiko-bundled-features 0.366.0 → 0.368.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/handlers/details.query.js +1 -1
- package/dist/audit/handlers/list.query.js +1 -1
- package/dist/audit/run-escape-hatch-retention.js +1 -1
- package/dist/auth-email-password/bootstrap.js +1 -1
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +6 -3
- package/dist/auth-email-password/handlers/invite-accept.write.js +6 -3
- package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
- package/dist/auth-email-password/handlers/invite-signup-complete.write.js +6 -3
- package/dist/auth-email-password/handlers/signup-confirm.write.js +1 -1
- package/dist/auth-email-password/seeding.js +2 -2
- package/dist/auth-foundation/feature.d.ts +4 -0
- package/dist/auth-foundation/feature.js +37 -33
- package/dist/auth-foundation/index.d.ts +1 -1
- package/dist/auth-foundation/index.js +1 -1
- package/dist/auth-mfa/db/queries.js +1 -2
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/reencrypt.job.js +2 -3
- package/dist/auth-mfa/handlers/status.query.js +1 -1
- package/dist/auth-mfa/handlers/verify.write.js +1 -1
- package/dist/auth-mfa/mfa-code-verifier.js +1 -1
- package/dist/auth-mfa/mfa-status-checker.js +1 -1
- package/dist/auth-mfa-user-data/index.d.ts +4 -0
- package/dist/auth-mfa-user-data/index.js +13 -9
- package/dist/billing-foundation/billing-info-query.js +1 -1
- package/dist/billing-foundation/feature.d.ts +1 -0
- package/dist/billing-foundation/feature.js +5 -6
- package/dist/billing-foundation/handlers/create-portal-session.write.js +1 -1
- package/dist/billing-foundation/projection.js +1 -2
- package/dist/cap-counter/calendar-cap-usage-reservation.d.ts +7 -0
- package/dist/cap-counter/calendar-cap-usage-reservation.js +28 -2
- package/dist/cap-counter/cap-reservation.d.ts +16 -0
- package/dist/cap-counter/cap-reservation.js +144 -14
- package/dist/cap-counter/feature.d.ts +4 -0
- package/dist/cap-counter/feature.js +74 -68
- package/dist/cap-counter/handlers/increment-rolling.write.js +3 -4
- package/dist/cap-counter/index.d.ts +3 -2
- package/dist/cap-counter/index.js +3 -2
- package/dist/cap-counter/tables.js +10 -3
- package/dist/cap-overview/handlers/caps-usage.query.js +1 -2
- package/dist/cap-overview/handlers/tenant-caps-list.query.js +1 -2
- package/dist/cap-overview/handlers/tenant-options.query.js +1 -1
- package/dist/channel-email/email-channel.d.ts +5 -1
- package/dist/channel-email/email-channel.js +8 -2
- package/dist/channel-email/feature.js +1 -1
- package/dist/channel-in-app/handlers/inbox.query.js +1 -1
- package/dist/channel-in-app/handlers/mark-all-read.write.js +1 -1
- package/dist/channel-in-app/handlers/mark-read.write.js +1 -1
- package/dist/channel-in-app/handlers/unread-count.query.js +1 -1
- package/dist/channel-in-app/tables.js +1 -2
- package/dist/compliance-profiles/handlers/for-tenant.query.js +1 -1
- package/dist/compliance-profiles/handlers/needs-profile.query.js +1 -1
- package/dist/compliance-profiles/handlers/set-profile.write.js +1 -2
- package/dist/compliance-profiles/resolve-for-tenant.js +1 -1
- package/dist/compliance-profiles/seeding.js +3 -5
- package/dist/compliance-profiles-ops/index.d.ts +8 -0
- package/dist/compliance-profiles-ops/index.js +19 -15
- package/dist/config/db/queries/resolver.js +1 -1
- package/dist/config/handlers/reencrypt.job.js +2 -2
- package/dist/config/resolver.js +1 -1
- package/dist/config/write-helpers.js +1 -1
- package/dist/crypto-shredding/handlers/forget-subject.write.js +6 -3
- package/dist/custom-fields/db/queries/field-access.js +1 -1
- package/dist/custom-fields/db/queries/projection.js +1 -1
- package/dist/custom-fields/db/queries/quota.js +1 -1
- package/dist/custom-fields/db/queries/retention.js +1 -2
- package/dist/custom-fields/db/queries/user-data-rights.js +1 -1
- package/dist/custom-fields/feature.d.ts +20 -2
- package/dist/custom-fields/feature.js +9 -13
- package/dist/custom-fields/handlers/clear-custom-field.write.js +2 -2
- package/dist/custom-fields/handlers/delete-system-field.write.js +2 -2
- package/dist/custom-fields/handlers/delete-tenant-field.write.js +2 -2
- package/dist/custom-fields/handlers/set-custom-field.write.js +2 -2
- package/dist/custom-fields/wire-for-entity.js +4 -4
- package/dist/data-retention/resolve-for-tenant.js +1 -1
- package/dist/data-retention/run-retention-cleanup.js +17 -13
- package/dist/delivery/address-opt-out.js +1 -2
- package/dist/delivery/attempt-log-retention.js +1 -1
- package/dist/delivery/channel-context.js +2 -1
- package/dist/delivery/db/queries/address-opt-outs.js +1 -1
- package/dist/delivery/db/queries/preferences.js +1 -1
- package/dist/delivery/delivery-service.d.ts +2 -0
- package/dist/delivery/delivery-service.js +46 -11
- package/dist/delivery/feature.js +2 -2
- package/dist/delivery/handlers/log.query.js +2 -3
- package/dist/delivery/handlers/preferences.query.js +1 -1
- package/dist/delivery/handlers/unsubscribe-address.write.d.ts +6 -0
- package/dist/delivery/handlers/unsubscribe-address.write.js +8 -5
- package/dist/delivery/index.d.ts +3 -0
- package/dist/delivery/index.js +2 -0
- package/dist/delivery/testing.d.ts +2 -0
- package/dist/delivery/types.d.ts +2 -1
- package/dist/delivery/unsubscribe-link.d.ts +25 -0
- package/dist/delivery/unsubscribe-link.js +40 -0
- package/dist/delivery/unsubscribe-page-strings.d.ts +11 -0
- package/dist/delivery/unsubscribe-page-strings.js +15 -0
- package/dist/delivery/unsubscribe.d.ts +3 -0
- package/dist/delivery/unsubscribe.js +65 -29
- package/dist/delivery/upsert-preference.js +1 -2
- package/dist/derivatives-sharp/feature.d.ts +4 -0
- package/dist/derivatives-sharp/feature.js +15 -11
- package/dist/derivatives-sharp/index.d.ts +1 -1
- package/dist/derivatives-sharp/index.js +1 -1
- package/dist/document-ingest-foundation/feature.d.ts +7 -0
- package/dist/document-ingest-foundation/feature.js +94 -90
- package/dist/document-ingest-foundation/forget-extract-with-file-ref.js +3 -3
- package/dist/document-ingest-foundation/index.d.ts +1 -1
- package/dist/document-ingest-foundation/index.js +1 -1
- package/dist/feature-toggles/global-feature-state-table.js +1 -2
- package/dist/feature-toggles/handlers/set.write.js +3 -5
- package/dist/feature-toggles/toggle-runtime.js +1 -1
- package/dist/file-derivatives/feature.d.ts +1 -0
- package/dist/file-derivatives/feature.js +2 -1
- package/dist/file-derivatives/handlers/public-variant-by-file-ref.query.js +1 -1
- package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
- package/dist/file-foundation/feature.d.ts +6 -0
- package/dist/file-foundation/feature.js +29 -25
- package/dist/file-foundation/index.d.ts +1 -1
- package/dist/file-foundation/index.js +1 -1
- package/dist/file-foundation/read-file-ref-content.js +1 -1
- package/dist/file-provider-inmemory/feature.d.ts +4 -0
- package/dist/file-provider-inmemory/feature.js +24 -20
- package/dist/file-provider-inmemory/index.d.ts +1 -1
- package/dist/file-provider-inmemory/index.js +1 -1
- package/dist/file-provider-s3/env-feature.d.ts +3 -0
- package/dist/file-provider-s3/env-feature.js +46 -0
- package/dist/file-provider-s3/feature.d.ts +26 -0
- package/dist/file-provider-s3/feature.js +84 -72
- package/dist/file-provider-s3/index.d.ts +1 -1
- package/dist/file-provider-s3/index.js +1 -1
- package/dist/file-provider-s3/lib/index.d.ts +3 -0
- package/dist/file-provider-s3/lib/index.js +2 -0
- package/dist/{files-provider-s3 → file-provider-s3/lib}/s3-provider.js +19 -19
- package/dist/file-provider-s3-env/index.d.ts +8 -1
- package/dist/file-provider-s3-env/index.js +7 -2
- package/dist/files-provider-s3/index.d.ts +5 -3
- package/dist/files-provider-s3/index.js +5 -2
- package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +1 -1
- package/dist/files-tenant-data/hooks.js +1 -2
- package/dist/folders/feature.d.ts +6 -2
- package/dist/folders/feature.js +4 -2
- package/dist/folders-user-data/index.d.ts +4 -0
- package/dist/folders-user-data/index.js +21 -17
- package/dist/form-draft/db/queries/cleanup.js +1 -1
- package/dist/form-draft/db/queries/draft-count.js +1 -1
- package/dist/form-draft/db/queries/owned-file-refs.js +1 -2
- package/dist/form-draft/feature.d.ts +4 -0
- package/dist/form-draft/feature.js +5 -1
- package/dist/form-draft/handlers/cleanup.job.js +2 -2
- package/dist/form-draft/index.d.ts +1 -1
- package/dist/form-draft/index.js +1 -1
- package/dist/form-draft/lookup.js +1 -1
- package/dist/form-draft-user-data/index.d.ts +4 -0
- package/dist/form-draft-user-data/index.js +13 -9
- package/dist/inbound-mail-foundation/feature.d.ts +4 -0
- package/dist/inbound-mail-foundation/feature.js +151 -147
- package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +1 -2
- package/dist/inbound-mail-foundation/index.d.ts +1 -1
- package/dist/inbound-mail-foundation/index.js +1 -1
- package/dist/inbound-mail-foundation/oauth-access-token.js +1 -2
- package/dist/inbound-mail-foundation/projection.js +1 -2
- package/dist/inbound-mail-foundation/watch-supervisor.js +1 -1
- package/dist/inbound-provider-imap/feature.d.ts +4 -0
- package/dist/inbound-provider-imap/feature.js +16 -12
- package/dist/inbound-provider-imap/index.d.ts +1 -1
- package/dist/inbound-provider-imap/index.js +1 -1
- package/dist/inbound-provider-inmemory/feature.d.ts +4 -0
- package/dist/inbound-provider-inmemory/feature.js +14 -10
- package/dist/inbound-provider-inmemory/index.d.ts +1 -1
- package/dist/inbound-provider-inmemory/index.js +1 -1
- package/dist/jobs/db/queries/retention.js +1 -1
- package/dist/jobs/db/queries/stale-run-sweep.js +1 -1
- package/dist/jobs/handlers/detail.query.js +1 -1
- package/dist/jobs/handlers/list.query.js +1 -2
- package/dist/jobs/handlers/retry.write.js +1 -1
- package/dist/jobs/handlers/tenant-failures.query.js +1 -1
- package/dist/jobs/handlers/tenant-runs.query.js +1 -1
- package/dist/jobs/job-run-logger.js +1 -2
- package/dist/jobs/tenant-job-failure-table.js +1 -2
- package/dist/jobs/tenant-job-run-table.js +1 -2
- package/dist/ledger/feature.d.ts +6 -2
- package/dist/ledger/feature.js +4 -2
- package/dist/mail-foundation/feature.d.ts +23 -1
- package/dist/mail-foundation/feature.js +76 -49
- package/dist/mail-foundation/index.d.ts +1 -1
- package/dist/mail-foundation/index.js +1 -1
- package/dist/mail-transport-inmemory/feature.d.ts +4 -0
- package/dist/mail-transport-inmemory/feature.js +20 -16
- package/dist/mail-transport-inmemory/index.d.ts +1 -1
- package/dist/mail-transport-inmemory/index.js +1 -1
- package/dist/mail-transport-smtp/feature.d.ts +16 -0
- package/dist/mail-transport-smtp/feature.js +85 -79
- package/dist/mail-transport-smtp/index.d.ts +1 -1
- package/dist/mail-transport-smtp/index.js +1 -1
- package/dist/managed-pages/handlers/by-slug.query.js +1 -1
- package/dist/managed-pages/handlers/by-tenant-published.query.js +1 -2
- package/dist/managed-pages/handlers/set.write.js +1 -2
- package/dist/managed-pages/seeding.js +3 -5
- package/dist/metrics/compute.d.ts +1 -1
- package/dist/metrics/filters.d.ts +1 -1
- package/dist/metrics/filters.js +1 -1
- package/dist/metrics/validate.js +1 -1
- package/dist/notes-history/feature.d.ts +7 -2
- package/dist/notes-history/feature.js +4 -2
- package/dist/notes-history/handlers/add-note.write.js +1 -1
- package/dist/notes-history-user-data/hooks.js +1 -1
- package/dist/notes-history-user-data/index.d.ts +4 -0
- package/dist/notes-history-user-data/index.js +21 -17
- package/dist/personal-access-tokens/feature.d.ts +4 -1
- package/dist/personal-access-tokens/feature.js +10 -2
- package/dist/personal-access-tokens/handlers/create.write.js +1 -1
- package/dist/personal-access-tokens/handlers/list.query.js +2 -2
- package/dist/personal-access-tokens/handlers/revoke.write.js +1 -1
- package/dist/personal-access-tokens/resolver.js +1 -1
- package/dist/personal-access-tokens/revoke-for-user.js +1 -1
- package/dist/personal-access-tokens/roles.js +3 -5
- package/dist/personal-access-tokens/screens.js +2 -0
- package/dist/readiness/feature.d.ts +8 -0
- package/dist/readiness/feature.js +18 -14
- package/dist/readiness/index.d.ts +1 -1
- package/dist/readiness/index.js +1 -1
- package/dist/secrets/db/queries/read.js +1 -1
- package/dist/secrets/feature.d.ts +3 -0
- package/dist/secrets/feature.js +3 -2
- package/dist/secrets/handlers/rotate.job.js +2 -3
- package/dist/secrets/secrets-context.js +3 -4
- package/dist/sessions/db/queries/cleanup.js +1 -1
- package/dist/sessions/handlers/detail.query.js +1 -1
- package/dist/sessions/handlers/list.query.js +2 -2
- package/dist/sessions/handlers/mine.query.js +1 -1
- package/dist/sessions/handlers/revoke-all-for-user.write.js +1 -1
- package/dist/sessions/handlers/revoke-all-others.write.js +1 -1
- package/dist/sessions/handlers/revoke.write.js +1 -1
- package/dist/sessions/session-callbacks.js +4 -6
- package/dist/sessions/testing.d.ts +1 -1
- package/dist/tags/feature.d.ts +6 -2
- package/dist/tags/feature.js +4 -2
- package/dist/template-resolver/api.js +1 -1
- package/dist/template-resolver/compile-document-body.js +47 -11
- package/dist/template-resolver/document-sanitizer.d.ts +2 -0
- package/dist/template-resolver/document-sanitizer.js +16 -1
- package/dist/template-resolver/document-schema.d.ts +2 -0
- package/dist/template-resolver/document-schema.js +31 -0
- package/dist/template-resolver/handlers/bundle-import.js +4 -3
- package/dist/template-resolver/handlers/by-slug.query.js +1 -1
- package/dist/template-resolver/handlers/by-tenant.query.js +1 -2
- package/dist/template-resolver/handlers/collection-item.query.js +1 -1
- package/dist/template-resolver/handlers/collection-list.query.js +1 -2
- package/dist/template-resolver/handlers/collection-set.write.js +1 -1
- package/dist/template-resolver/handlers/copy-locale.write.js +4 -3
- package/dist/template-resolver/handlers/diff-to-system.query.js +1 -1
- package/dist/template-resolver/handlers/export-bundle.query.js +1 -1
- package/dist/template-resolver/handlers/find-by-id.query.js +6 -2
- package/dist/template-resolver/handlers/layout-source.query.js +1 -1
- package/dist/template-resolver/handlers/list.query.js +4 -2
- package/dist/template-resolver/handlers/overview.query.js +5 -3
- package/dist/template-resolver/handlers/reset-to-system.write.js +1 -1
- package/dist/template-resolver/handlers/resource-remove.write.js +1 -1
- package/dist/template-resolver/handlers/set.write.js +1 -1
- package/dist/template-resolver/handlers/template-write.d.ts +2 -1
- package/dist/template-resolver/handlers/template-write.js +13 -2
- package/dist/template-resolver/handlers/tenant-overrides.query.js +1 -1
- package/dist/template-resolver/handlers/toggle-status.write.js +1 -1
- package/dist/template-resolver/handlers/usage.query.js +1 -1
- package/dist/template-resolver/handlers/validate.query.js +1 -1
- package/dist/template-resolver/index.d.ts +3 -2
- package/dist/template-resolver/index.js +3 -2
- package/dist/template-resolver/qualified-names.d.ts +1 -0
- package/dist/template-resolver/qualified-names.js +1 -0
- package/dist/template-resolver/seeding.d.ts +4 -0
- package/dist/template-resolver/seeding.js +43 -9
- package/dist/template-resolver/store-template-resource.js +1 -1
- package/dist/template-resolver/template-preview.js +3 -1
- package/dist/template-resolver/template-resources.js +1 -1
- package/dist/template-resolver/template-system-only.d.ts +8 -0
- package/dist/template-resolver/template-system-only.js +11 -0
- package/dist/template-resolver/template-validation.js +42 -28
- package/dist/template-resolver/testing.js +1 -1
- package/dist/template-resolver/web/i18n.js +1 -0
- package/dist/template-resolver-user-data/index.d.ts +4 -0
- package/dist/template-resolver-user-data/index.js +17 -13
- package/dist/tenant/handlers/active-tenant-ids.query.js +1 -1
- package/dist/tenant/handlers/add-member.write.js +1 -2
- package/dist/tenant/handlers/cancel-invitation.write.js +1 -1
- package/dist/tenant/handlers/invitations.query.js +1 -1
- package/dist/tenant/handlers/me.query.js +1 -1
- package/dist/tenant/handlers/member-directory.query.js +1 -1
- package/dist/tenant/handlers/members.query.js +1 -1
- package/dist/tenant/handlers/memberships.query.js +1 -1
- package/dist/tenant/handlers/remove-member.write.js +1 -2
- package/dist/tenant/handlers/resolve-user-ids.query.js +1 -1
- package/dist/tenant/handlers/team-list.query.js +1 -1
- package/dist/tenant/handlers/tenant-directory.query.js +1 -1
- package/dist/tenant/handlers/update-member-roles.write.js +1 -2
- package/dist/tenant/invited-membership.js +2 -3
- package/dist/tenant/last-tenant-admin.js +1 -2
- package/dist/tenant/seeding.js +12 -6
- package/dist/tenant-lifecycle/handlers/cancel-destruction.write.js +1 -2
- package/dist/tenant-lifecycle/handlers/request-destruction.write.js +1 -2
- package/dist/tenant-lifecycle/lib/revoke-tenant-sessions.js +1 -1
- package/dist/tenant-lifecycle/lifecycle-gate.js +1 -1
- package/dist/tenant-lifecycle/run-tenant-destroy.js +3 -5
- package/dist/tenant-lifecycle/stages.js +10 -6
- package/dist/tenant-lifecycle/testing.d.ts +1 -1
- package/dist/tenant-lifecycle/testing.js +2 -2
- package/dist/tenant-settings/feature.d.ts +1 -0
- package/dist/tenant-settings/feature.js +2 -1
- package/dist/tier-engine/feature.d.ts +1 -8
- package/dist/tier-engine/feature.js +71 -78
- package/dist/tier-engine/handlers/get-tenant-tier.query.js +2 -3
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +1 -2
- package/dist/user/db/queries/stream-tenant-backfill.js +1 -1
- package/dist/user/handlers/create.write.js +1 -2
- package/dist/user/handlers/find-for-auth.query.js +1 -1
- package/dist/user/handlers/list.query.js +1 -1
- package/dist/user/handlers/update-roles.js +1 -2
- package/dist/user/index.d.ts +1 -1
- package/dist/user/index.js +1 -1
- package/dist/user/invited-global-roles.js +2 -3
- package/dist/user/principal-status.d.ts +4 -0
- package/dist/user/principal-status.js +9 -3
- package/dist/user/resolve-display-names.js +1 -1
- package/dist/user/seeding.js +5 -6
- package/dist/user-data-rights/audit-download.js +2 -2
- package/dist/user-data-rights/db/queries/export-jobs.js +1 -1
- package/dist/user-data-rights/db/queries/forget-cleanup.js +1 -1
- package/dist/user-data-rights/handlers/download-by-job.query.js +1 -1
- package/dist/user-data-rights/handlers/download-by-token.query.js +1 -1
- package/dist/user-data-rights/handlers/export-status.query.js +1 -1
- package/dist/user-data-rights/handlers/list-download-attempts.query.js +1 -1
- package/dist/user-data-rights/handlers/my-audit-log.query.js +1 -1
- package/dist/user-data-rights/handlers/request-export.write.js +1 -2
- package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +3 -3
- package/dist/user-data-rights/lib/deny-if-target-outside-admin-tenant.d.ts +1 -1
- package/dist/user-data-rights/lib/deny-if-target-outside-admin-tenant.js +1 -1
- package/dist/user-data-rights/lib/update-user-lifecycle.d.ts +1 -0
- package/dist/user-data-rights/lib/update-user-lifecycle.js +3 -3
- package/dist/user-data-rights/run-export-jobs.js +2 -3
- package/dist/user-data-rights/run-forget-cleanup.js +9 -5
- package/dist/user-data-rights/run-user-export.js +9 -5
- package/dist/waitlist/handlers/invite.write.js +1 -2
- package/dist/waitlist/handlers/reject.write.js +1 -1
- package/dist/waitlist/lib.js +1 -2
- package/dist/workflow-runner/event-subscriber.js +1 -1
- package/dist/workflow-runner/feature.d.ts +4 -0
- package/dist/workflow-runner/feature.js +44 -40
- package/dist/workflow-runner/handlers/resume-run.write.js +1 -1
- package/dist/workflow-runner/index.d.ts +1 -1
- package/dist/workflow-runner/index.js +1 -1
- package/dist/workflow-runner/pending-projection.js +1 -1
- package/package.json +28 -11
- package/src/cap-counter/changes.json +13 -0
- package/src/channel-email/changes.json +6 -0
- package/src/crypto-shredding/changes.json +6 -0
- package/src/delivery/changes.json +12 -0
- package/src/file-provider-s3/changes.json +10 -1
- package/src/personal-access-tokens/changes.json +6 -0
- package/src/template-resolver/changes.json +25 -0
- package/src/user/changes.json +6 -0
- package/src/user-data-rights/changes.json +6 -0
- package/dist/file-provider-s3-env/feature.d.ts +0 -3
- package/dist/file-provider-s3-env/feature.js +0 -46
- /package/dist/{files-provider-s3 → file-provider-s3/lib}/env-helper.d.ts +0 -0
- /package/dist/{files-provider-s3 → file-provider-s3/lib}/env-helper.js +0 -0
- /package/dist/{files-provider-s3 → file-provider-s3/lib}/s3-provider.d.ts +0 -0
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
//
|
|
9
9
|
// Default ifExists="skip". The actor is `createSystemUser(SYSTEM_TENANT_ID)`,
|
|
10
10
|
// deliberately not TestUsers (prod seeds are not test utilities).
|
|
11
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
12
|
-
import { createTenantDb, deleteMany, } from "@cosmicdrift/kumiko-framework/db";
|
|
11
|
+
import { createTenantDb, deleteMany, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
|
|
13
12
|
import { createSystemUser, SYSTEM_TENANT_ID, } from "@cosmicdrift/kumiko-framework/engine";
|
|
14
13
|
import { getStreamVersion, getUnscopedStreamMaxVersionForSeed, } from "@cosmicdrift/kumiko-framework/event-store";
|
|
15
14
|
import { runEventStoreSeed } from "@cosmicdrift/kumiko-framework/seeding";
|
|
15
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
16
16
|
import { TEXT_BLOCK_KIND } from "./constants.js";
|
|
17
17
|
import { executor } from "./handlers/shared.js";
|
|
18
18
|
import { evaluateTemplateWrite } from "./handlers/template-gates.js";
|
|
19
|
-
import { TEMPLATE_RESOLVER_FEATURE } from "./qualified-names.js";
|
|
19
|
+
import { TEMPLATE_RESOLVER_FEATURE, TemplateResolverHandlers } from "./qualified-names.js";
|
|
20
20
|
import { templateResourcesTable } from "./table.js";
|
|
21
21
|
import { activeStampChanges, servedStampChanges } from "./template-draft.js";
|
|
22
22
|
import { templateSlugSchema } from "./template-meta.js";
|
|
@@ -43,7 +43,7 @@ async function resolveExistingForEventStoreSeed(db, tdb, existingRow, tenantId)
|
|
|
43
43
|
export async function seedSystemTemplate(db, opts) {
|
|
44
44
|
const tenantId = SYSTEM_TENANT_ID;
|
|
45
45
|
const by = opts.by ?? createSystemUser(tenantId);
|
|
46
|
-
const tdb = createTenantDb(db, tenantId, "system");
|
|
46
|
+
const tdb = createTenantDb({ db, tenantId, mode: "system" });
|
|
47
47
|
const label = `seedSystemTemplate ${opts.slug}/${opts.kind}/${opts.locale}`;
|
|
48
48
|
const slug = templateSlugSchema.safeParse(opts.slug);
|
|
49
49
|
if (!slug.success)
|
|
@@ -154,12 +154,12 @@ export async function seedSystemTemplate(db, opts) {
|
|
|
154
154
|
update: (row) => applyUpdate(row, existingRow),
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
|
-
// Seeds one system row per bundle locale. Bundled resources need a file
|
|
158
|
-
//
|
|
159
|
-
//
|
|
157
|
+
// Seeds one system row per bundle locale. Bundled resources need a file provider and
|
|
158
|
+
// the system tenant's file space, so those bundles are written through the
|
|
159
|
+
// import-bundle-system handler on the seed dispatcher instead of directly.
|
|
160
160
|
export async function seedSystemTemplateBundle(db, bundle, opts = {}) {
|
|
161
161
|
if (Object.keys(bundle.resources).length > 0) {
|
|
162
|
-
|
|
162
|
+
return seedSystemTemplateBundleWithResources(db, bundle, opts);
|
|
163
163
|
}
|
|
164
164
|
const ids = {};
|
|
165
165
|
for (const [locale, entry] of Object.entries(bundle.locales)) {
|
|
@@ -178,6 +178,40 @@ export async function seedSystemTemplateBundle(db, bundle, opts = {}) {
|
|
|
178
178
|
}
|
|
179
179
|
return { ids };
|
|
180
180
|
}
|
|
181
|
+
async function seedSystemTemplateBundleWithResources(db, bundle, opts) {
|
|
182
|
+
const label = `seedSystemTemplateBundle ${bundle.slug}/${bundle.kind}`;
|
|
183
|
+
const { dispatcher } = opts;
|
|
184
|
+
if (!dispatcher) {
|
|
185
|
+
throw new Error(`${label}: bundles with resources need a file provider; pass opts.dispatcher (the dispatcher of the seed deps) so the files are stored through the import-bundle-system write`);
|
|
186
|
+
}
|
|
187
|
+
if ((opts.ifExists ?? "skip") === "skip") {
|
|
188
|
+
const existingIds = {};
|
|
189
|
+
for (const locale of Object.keys(bundle.locales)) {
|
|
190
|
+
const row = await fetchOne(db, templateResourcesTable, {
|
|
191
|
+
tenantId: SYSTEM_TENANT_ID,
|
|
192
|
+
slug: bundle.slug,
|
|
193
|
+
kind: bundle.kind,
|
|
194
|
+
locale,
|
|
195
|
+
});
|
|
196
|
+
if (row)
|
|
197
|
+
existingIds[locale] = String(row.id);
|
|
198
|
+
}
|
|
199
|
+
if (Object.keys(existingIds).length === Object.keys(bundle.locales).length) {
|
|
200
|
+
return { ids: existingIds };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const result = await dispatcher.write(TemplateResolverHandlers.importBundleSystem, { bundle }, opts.by ?? createSystemUser(SYSTEM_TENANT_ID, ["SystemAdmin"]));
|
|
204
|
+
if (!result.isSuccess) {
|
|
205
|
+
throw new Error(`${label} failed: ${result.error.code}: ${result.error.message}`);
|
|
206
|
+
}
|
|
207
|
+
return { ids: importedIds(result.data) };
|
|
208
|
+
}
|
|
209
|
+
function importedIds(data) {
|
|
210
|
+
const ids = isPlainObject(data) ? data["ids"] : undefined;
|
|
211
|
+
if (!isPlainObject(ids))
|
|
212
|
+
throw new Error("seedSystemTemplateBundle: import returned no ids");
|
|
213
|
+
return Object.fromEntries(Object.entries(ids).map(([locale, id]) => [locale, String(id)]));
|
|
214
|
+
}
|
|
181
215
|
export function hasNotificationTemplates(registry) {
|
|
182
216
|
return Array.from(registry.getAllNotifications().values()).some((notification) => notification.template !== undefined);
|
|
183
217
|
}
|
|
@@ -215,7 +249,7 @@ export async function seedNotificationTemplates(db, registry) {
|
|
|
215
249
|
// without the access check. Default ifExists="skip".
|
|
216
250
|
export async function seedTextBlock(db, opts) {
|
|
217
251
|
const by = opts.by ?? createSystemUser(opts.tenantId);
|
|
218
|
-
const tdb = createTenantDb(db, opts.tenantId, "system");
|
|
252
|
+
const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
|
|
219
253
|
const existingRow = await fetchOne(db, templateResourcesTable, {
|
|
220
254
|
tenantId: opts.tenantId,
|
|
221
255
|
slug: opts.slug,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { NotFoundError, UnprocessableError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
3
3
|
import { createFileRefFromUploadedBytes, uploadFileBytesBeforeTransaction, } from "@cosmicdrift/kumiko-framework/files";
|
|
4
4
|
import { fileContextForTenant } from "../file-foundation/index.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { NotFoundError, UnprocessableError, ValidationError, } from "@cosmicdrift/kumiko-framework/errors";
|
|
3
3
|
import { fileRefsTable } from "@cosmicdrift/kumiko-framework/files";
|
|
4
4
|
import { escapeHtml } from "@cosmicdrift/kumiko-headless";
|
|
@@ -33,6 +33,8 @@ function sampleScalar(name, def) {
|
|
|
33
33
|
return 0;
|
|
34
34
|
case "date":
|
|
35
35
|
return SAMPLE_DATE;
|
|
36
|
+
case "percent":
|
|
37
|
+
return 0;
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
function sampleRow(item, given = {}) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { NotFoundError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
3
3
|
import { fileRefsTable } from "@cosmicdrift/kumiko-framework/files";
|
|
4
4
|
import { requireForTenant } from "../shared/index.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Registry } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
export declare function isSystemOnlyTemplate(registry: Registry, slug: string, kind: string): boolean;
|
|
3
|
+
export declare function isSystemOnlyTemplateHiddenFrom(user: {
|
|
4
|
+
readonly roles: readonly string[];
|
|
5
|
+
}, registry: Registry, row: {
|
|
6
|
+
readonly slug: string;
|
|
7
|
+
readonly kind: string;
|
|
8
|
+
}): boolean;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { isSystemAdmin } from "./template-draft.js";
|
|
2
|
+
const NOTIFICATION_TEMPLATE_KIND = "mail";
|
|
3
|
+
// A notification registered with systemOnly keeps its mail template as the system default:
|
|
4
|
+
// tenants neither list nor override it, and overrides stored before the flag are ignored.
|
|
5
|
+
export function isSystemOnlyTemplate(registry, slug, kind) {
|
|
6
|
+
return (kind === NOTIFICATION_TEMPLATE_KIND &&
|
|
7
|
+
registry.getAllNotifications().get(slug)?.systemOnly === true);
|
|
8
|
+
}
|
|
9
|
+
export function isSystemOnlyTemplateHiddenFrom(user, registry, row) {
|
|
10
|
+
return !isSystemAdmin(user) && isSystemOnlyTemplate(registry, row.slug, row.kind);
|
|
11
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
-
import { withParsedDocument } from "./document-sanitizer.js";
|
|
3
|
-
import { isDocumentPlaceholderHref, isDocumentReferenceName } from "./document-schema.js";
|
|
2
|
+
import { conditionScopeElement, withParsedDocument } from "./document-sanitizer.js";
|
|
3
|
+
import { DOCUMENT_CONDITION_ATTRIBUTE, isDocumentPlaceholderHref, isDocumentReferenceName, } from "./document-schema.js";
|
|
4
4
|
export const SYSTEM_PLACEHOLDERS = new Set([
|
|
5
5
|
"tenantName",
|
|
6
6
|
"signature",
|
|
@@ -34,6 +34,7 @@ const scalarVariableSchema = z.discriminatedUnion("type", [
|
|
|
34
34
|
.optional(),
|
|
35
35
|
}),
|
|
36
36
|
z.object({ ...variableCommon, type: z.literal("date"), example: textLikeExample }),
|
|
37
|
+
z.object({ ...variableCommon, type: z.literal("percent"), example: z.number().optional() }),
|
|
37
38
|
]);
|
|
38
39
|
const variableDefSchema = z.union([
|
|
39
40
|
scalarVariableSchema,
|
|
@@ -99,34 +100,47 @@ const NAME_ATTRIBUTE_BY_TAG = {
|
|
|
99
100
|
span: "data-variable",
|
|
100
101
|
div: "data-steps",
|
|
101
102
|
};
|
|
102
|
-
function
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
function scanRepeatRows(root, scope) {
|
|
104
|
+
for (const element of Array.from(root.querySelectorAll("tr[data-each]"))) {
|
|
105
|
+
const listName = element.getAttribute("data-each") ?? "";
|
|
106
|
+
const def = Object.hasOwn(scope.variables, listName) ? scope.variables[listName] : undefined;
|
|
107
|
+
if (def?.type === "list")
|
|
108
|
+
scope.used.add(listName);
|
|
109
|
+
else
|
|
110
|
+
scope.unknown.add(listName);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function scanConditions(root, scope) {
|
|
114
|
+
for (const element of Array.from(root.querySelectorAll(`[${DOCUMENT_CONDITION_ATTRIBUTE}]`))) {
|
|
115
|
+
const itemFields = listItemFields(scope.variables, enclosingEachName(conditionScopeElement(element)));
|
|
116
|
+
recordName(element.getAttribute(DOCUMENT_CONDITION_ATTRIBUTE) ?? "", itemFields, scope);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function scanReferences(root, scope) {
|
|
120
|
+
for (const element of Array.from(root.querySelectorAll("span[data-variable], div[data-steps], a[href], img[data-resource]"))) {
|
|
121
|
+
const itemFields = listItemFields(scope.variables, enclosingEachName(element));
|
|
122
|
+
const tag = element.tagName.toLowerCase();
|
|
123
|
+
const nameAttribute = NAME_ATTRIBUTE_BY_TAG[tag];
|
|
124
|
+
if (nameAttribute !== undefined) {
|
|
125
|
+
recordName(element.getAttribute(nameAttribute) ?? "", itemFields, scope);
|
|
126
|
+
}
|
|
127
|
+
else if (tag === "a") {
|
|
128
|
+
const href = element.getAttribute("href") ?? "";
|
|
129
|
+
if (isDocumentPlaceholderHref(href))
|
|
130
|
+
recordName(href.slice(2, -2), itemFields, scope);
|
|
111
131
|
}
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (nameAttribute !== undefined) {
|
|
117
|
-
recordName(element.getAttribute(nameAttribute) ?? "", itemFields, scope);
|
|
118
|
-
}
|
|
119
|
-
else if (tag === "a") {
|
|
120
|
-
const href = element.getAttribute("href") ?? "";
|
|
121
|
-
if (isDocumentPlaceholderHref(href))
|
|
122
|
-
recordName(href.slice(2, -2), itemFields, scope);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
const key = element.getAttribute("data-resource") ?? "";
|
|
126
|
-
if (!scope.resourceKeys.has(key))
|
|
127
|
-
scope.unknownResources.add(key);
|
|
128
|
-
}
|
|
132
|
+
else {
|
|
133
|
+
const key = element.getAttribute("data-resource") ?? "";
|
|
134
|
+
if (!scope.resourceKeys.has(key))
|
|
135
|
+
scope.unknownResources.add(key);
|
|
129
136
|
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function scanBodyPlaceholders(body, scope) {
|
|
140
|
+
withParsedDocument(body, (root) => {
|
|
141
|
+
scanRepeatRows(root, scope);
|
|
142
|
+
scanConditions(root, scope);
|
|
143
|
+
scanReferences(root, scope);
|
|
130
144
|
});
|
|
131
145
|
}
|
|
132
146
|
const HANDLEBARS_EXPRESSION = /\{\{([^{}]*)\}\}/g;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Test-only helpers for template-resolver consumers. Import via
|
|
2
2
|
// `@cosmicdrift/kumiko-bundled-features/template-resolver/testing`.
|
|
3
3
|
// No bun:test here — callers register cases with their own test runner.
|
|
4
|
-
import { seedRow } from "@cosmicdrift/kumiko-
|
|
4
|
+
import { seedRow } from "@cosmicdrift/kumiko-testing/helpers";
|
|
5
5
|
import { TemplateNotFoundError } from "./api.js";
|
|
6
6
|
import { FALLBACK_LOCALE, SYSTEM_TENANT_ID, } from "./constants.js";
|
|
7
7
|
import { templateResourcesTable } from "./table.js";
|
|
@@ -76,6 +76,7 @@ export const defaultTranslations = {
|
|
|
76
76
|
"templateResolver.errors.collection.kindNotAllowed": "“{detail}” templates are written through their own editor, not through a collection.",
|
|
77
77
|
"templateResolver.errors.noSystemTemplate": "There is no active system template to reset to.",
|
|
78
78
|
"templateResolver.errors.noDraft": "There is no draft to discard.",
|
|
79
|
+
"templateResolver.errors.systemOnlyTemplate": "Only the platform maintains this template; it cannot be overridden per tenant.",
|
|
79
80
|
"templateResolver.errors.template.invalidMeta": "The template settings are invalid.",
|
|
80
81
|
"templateResolver.errors.template.meta.subject.required": "The subject is missing.",
|
|
81
82
|
"templateResolver.errors.template.meta.subject.invalid": "The subject is invalid (at most 200 characters, no line breaks).",
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export declare function createTemplateResolverUserDataFeature(): import("@cosmicdrift/kumiko-types/feature").FeatureDefinition & {
|
|
2
|
+
readonly exports: void;
|
|
3
|
+
};
|
|
4
|
+
/** @deprecated Use createTemplateResolverUserDataFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
1
5
|
export declare const templateResolverUserDataFeature: import("@cosmicdrift/kumiko-types/feature").FeatureDefinition & {
|
|
2
6
|
readonly exports: void;
|
|
3
7
|
};
|
|
@@ -6,16 +6,20 @@
|
|
|
6
6
|
// notes-history-user-data.
|
|
7
7
|
import { defineFeature, EXT_USER_DATA } from "@cosmicdrift/kumiko-framework/engine";
|
|
8
8
|
import { userContentDeleteHook, userContentExportHook } from "./hooks.js";
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
9
|
+
export function createTemplateResolverUserDataFeature() {
|
|
10
|
+
return defineFeature("template-resolver-user-data", (r) => {
|
|
11
|
+
r.describe("GDPR (Art. 20 export / Art. 17 erasure) coverage for the `template-resolver` feature's `user-content-entry` entity — the per-user half of the content store (mail signatures, personal reply snippets). Mounts the EXT_USER_DATA export hook so a user's own entries land in the export bundle; the delete hook is a deliberate no-op because `content` is annotated `userOwned`, so erasure runs via crypto-shredding (destroying the owner's subject key) rather than a physical delete, which would not survive an event replay. Mount this whenever `createTemplateResolverFeature` declares a collection with `ownership: \"user\"` — the boot guard otherwise refuses the entity. Requires `user-data-rights`, optionalRequires `template-resolver`.");
|
|
12
|
+
// user-data-rights is the hard dependency (EXT_USER_DATA host).
|
|
13
|
+
// template-resolver is optional for the same reason as in
|
|
14
|
+
// notes-history-user-data: a toggleable mount would otherwise trip the
|
|
15
|
+
// "effectively disabled" boot warning even though the entity is there.
|
|
16
|
+
r.requires({ features: ["user-data-rights"] });
|
|
17
|
+
r.optionalRequires("template-resolver");
|
|
18
|
+
r.useExtension(EXT_USER_DATA, "user-content-entry", {
|
|
19
|
+
export: userContentExportHook,
|
|
20
|
+
delete: userContentDeleteHook,
|
|
21
|
+
});
|
|
22
|
+
}, { dedupeOptions: {} });
|
|
23
|
+
}
|
|
24
|
+
/** @deprecated Use createTemplateResolverUserDataFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
25
|
+
export const templateResolverUserDataFeature = createTemplateResolverUserDataFeature();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { defineQueryHandler, SYSTEM_ROLE, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
2
|
-
import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
|
|
1
|
+
import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
3
2
|
import { defineWriteHandler, SYSTEM_ROLE, SYSTEM_USER_ID, } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
3
|
import { AccessDeniedError, ConflictError, InternalError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
5
4
|
import * as z from "zod";
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// Idempotent: cancelling an already-cancelled / accepted / expired
|
|
10
10
|
// invitation = no-op + 200. Cancelling a non-existent invitation
|
|
11
11
|
// = invitation_not_found.
|
|
12
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
12
|
+
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
13
13
|
import { access, defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
14
14
|
import { InternalError, NotFoundError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
15
15
|
import * as z from "zod";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { access, defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { access, definePagedQueryHandler, MAX_LIST_LIMIT, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { access, defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { defineQueryHandler, SYSTEM_ROLE } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/
|
|
2
|
-
import { createEventStoreExecutor, } from "@cosmicdrift/kumiko-framework/db";
|
|
1
|
+
import { createEventStoreExecutor, fetchOne, selectMany, } from "@cosmicdrift/kumiko-framework/db";
|
|
3
2
|
import { createSystemUser, defineWriteHandler, parseTenantId, withResponseData, } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
3
|
import { InternalError, NotFoundError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
5
4
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { defineQueryHandler, SYSTEM_ROLE } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { access, definePagedQueryHandler, MAX_LIST_LIMIT, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { access, definePagedQueryHandler, MAX_LIST_LIMIT, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
2
|
-
import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
|
|
1
|
+
import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
3
2
|
import { access, assignableAppRolesOf, createSystemUser, defineWriteHandler, findForbiddenRoleAssignment, mayOverrideTenant, mergeAssignedRoles, parseTenantId, SYSTEM_ROLE, withResponseData, } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
3
|
import { InternalError, NotFoundError, ValidationError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
5
4
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
2
|
-
import { createEventStoreExecutor, createTenantDb, } from "@cosmicdrift/kumiko-framework/db";
|
|
1
|
+
import { createEventStoreExecutor, createTenantDb, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
|
|
3
2
|
import { createSystemUser } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
3
|
import { ConflictError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
5
4
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
@@ -44,7 +43,7 @@ export async function grantInvitedMembershipRole(db, options) {
|
|
|
44
43
|
if (currentRoles.includes(options.role))
|
|
45
44
|
return grantedMembership(true, currentRoles);
|
|
46
45
|
const roles = [...currentRoles, options.role];
|
|
47
|
-
const updateResult = await membershipExecutor.update({ id: existing.id, version: existing.version, changes: { roles: JSON.stringify(roles) } }, createSystemUser(options.tenantId), createTenantDb(db, options.tenantId, "system"));
|
|
46
|
+
const updateResult = await membershipExecutor.update({ id: existing.id, version: existing.version, changes: { roles: JSON.stringify(roles) } }, createSystemUser(options.tenantId), createTenantDb({ db, tenantId: options.tenantId, mode: "system" }));
|
|
48
47
|
if (!updateResult.isSuccess)
|
|
49
48
|
return updateResult;
|
|
50
49
|
return grantedMembership(true, roles);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
2
|
-
import { acquireNamespacedAdvisoryLock } from "@cosmicdrift/kumiko-framework/db";
|
|
1
|
+
import { acquireNamespacedAdvisoryLock, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
3
2
|
import { ConflictError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
3
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
5
4
|
import { TenantErrors } from "./constants.js";
|
package/dist/tenant/seeding.js
CHANGED
|
@@ -27,12 +27,11 @@
|
|
|
27
27
|
// Idempotent (add-only): calling twice for the same (userId, tenantId) is
|
|
28
28
|
// a no-op on the second call. Memberships have no update-semantic — to
|
|
29
29
|
// change roles, write a new event via the regular handler path.
|
|
30
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
31
|
-
import { createEventStoreExecutor, createTenantDb, } from "@cosmicdrift/kumiko-framework/db";
|
|
30
|
+
import { createEventStoreExecutor, createTenantDb, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
|
|
32
31
|
import { createSystemUser, HookPhases, } from "@cosmicdrift/kumiko-framework/engine";
|
|
33
32
|
import { getUnscopedAggregateStreamMaxVersion } from "@cosmicdrift/kumiko-framework/event-store";
|
|
34
33
|
import { createDeferringNotify, createLifecycleHooks, } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
35
|
-
import { TestUsers } from "@cosmicdrift/kumiko-framework/
|
|
34
|
+
import { TestUsers } from "@cosmicdrift/kumiko-framework/seeding";
|
|
36
35
|
import { assertAssignableMembershipRoles } from "./membership-roles.js";
|
|
37
36
|
import { tenantMembershipEntity, tenantMembershipsTable } from "./membership-table.js";
|
|
38
37
|
import { tenantEntity, tenantTable } from "./schema/tenant.js";
|
|
@@ -87,7 +86,14 @@ function scopeSeedHookContext(context, targetTenantId, runner,
|
|
|
87
86
|
// The afterCommit sink is snapshotted when it flushes, so a hook scheduled from inside an
|
|
88
87
|
// afterCommit-phase hook would be dropped: that phase must notify inline.
|
|
89
88
|
notifyTiming) {
|
|
90
|
-
const db = createTenantDb(
|
|
89
|
+
const db = createTenantDb({
|
|
90
|
+
db: runner,
|
|
91
|
+
tenantId: targetTenantId,
|
|
92
|
+
mode: "system",
|
|
93
|
+
tracer: context.tracer,
|
|
94
|
+
meter: context.meter,
|
|
95
|
+
signal: context.signal,
|
|
96
|
+
});
|
|
91
97
|
// HandlerContext carries `user`; AppContext only `systemUser`. Prefer the
|
|
92
98
|
// live handler user when present so notify/hasFeature keep a real SessionUser.
|
|
93
99
|
const handlerUser = context.user;
|
|
@@ -160,7 +166,7 @@ export async function seedTenant(db, options, hooks) {
|
|
|
160
166
|
// tenant-scoped ist, braucht der Wrap-Layer für die runtime-API zu
|
|
161
167
|
// existieren. by.tenantId reicht — keine Override-Semantik wie bei
|
|
162
168
|
// seedTenantMembership nötig.
|
|
163
|
-
const tdb = createTenantDb(db, by.tenantId, "system");
|
|
169
|
+
const tdb = createTenantDb({ db, tenantId: by.tenantId, mode: "system" });
|
|
164
170
|
const existing = await fetchOne(db, tenantTable, { id: options.id });
|
|
165
171
|
if (existing)
|
|
166
172
|
return { id: options.id };
|
|
@@ -211,7 +217,7 @@ hooks) {
|
|
|
211
217
|
const by = options.by ?? createSystemUser(options.tenantId);
|
|
212
218
|
// System-scoped TenantDb: payload.tenantId may differ from an explicit
|
|
213
219
|
// `by` override; stream tenant still follows `by` via streamTenantFor.
|
|
214
|
-
const tdb = createTenantDb(db, options.tenantId, "system");
|
|
220
|
+
const tdb = createTenantDb({ db, tenantId: options.tenantId, mode: "system" });
|
|
215
221
|
// Idempotency: duplicate seeds are common across beforeEach-resets where
|
|
216
222
|
// only certain tables get truncated. A plain executor.create would trip
|
|
217
223
|
// the (user_id, tenant_id) unique index; the fixture call-site would then
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
2
|
-
import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
|
|
1
|
+
import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
3
2
|
import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
3
|
import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
5
4
|
import * as z from "zod";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
1
|
import { addDurationSpec } from "@cosmicdrift/kumiko-framework/compliance";
|
|
3
|
-
import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
4
3
|
import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
5
4
|
import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
6
5
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { updateMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { updateMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
3
3
|
import { userSessionTable } from "../../sessions/index.js";
|
|
4
4
|
/** Revoke all live sessions scoped to a tenant (destruction-request gate). */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { tenantTable } from "../tenant/index.js";
|
|
3
3
|
// Every authenticated + anonymous request consults this (via auth-middleware's
|
|
4
4
|
// resolveTenantLifecycleStatus) — a per-request DB round-trip otherwise.
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
3
|
-
import { createEventStoreExecutor, createTenantDb, WritePurposes, } from "@cosmicdrift/kumiko-framework/db";
|
|
1
|
+
import { createEventStoreExecutor, createTenantDb, selectMany, WritePurposes, } from "@cosmicdrift/kumiko-framework/db";
|
|
4
2
|
import { createSystemUser, } from "@cosmicdrift/kumiko-framework/engine";
|
|
5
3
|
import { append, loadAggregate, VersionConflictError, } from "@cosmicdrift/kumiko-framework/event-store";
|
|
6
4
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
@@ -91,7 +89,7 @@ async function appendTenantStageEventIdempotent(db, tenantId, type, payload, exp
|
|
|
91
89
|
}
|
|
92
90
|
async function markTenantDestroyFailed(db, tenantId) {
|
|
93
91
|
const user = createSystemUser(tenantId);
|
|
94
|
-
const scopedDb = createTenantDb(db, tenantId, "system");
|
|
92
|
+
const scopedDb = createTenantDb({ db, tenantId, mode: "system" });
|
|
95
93
|
await tenantCrud.update({
|
|
96
94
|
id: tenantId,
|
|
97
95
|
changes: { status: "destroyFailed" },
|
|
@@ -234,7 +232,7 @@ export async function runTenantDestructionSweep(args) {
|
|
|
234
232
|
const events = await loadAggregate(args.db, tenantId, tenantId);
|
|
235
233
|
const version = lastEventVersion(events);
|
|
236
234
|
const user = createSystemUser(tenantId);
|
|
237
|
-
const scopedDb = createTenantDb(args.db, tenantId, "system");
|
|
235
|
+
const scopedDb = createTenantDb({ db: args.db, tenantId, mode: "system" });
|
|
238
236
|
// Version-guarded (no skipOptimisticLock): a concurrent cancel-destruction
|
|
239
237
|
// between the `due` select above and this write also appends to the same
|
|
240
238
|
// tenant stream, so an unguarded overwrite here would silently revert the
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
1
|
import { configuredPiiSubjectKms, subjectIdToKey, } from "@cosmicdrift/kumiko-framework/crypto";
|
|
3
|
-
import { createEventStoreExecutor, createTenantDb, WritePurposes, } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import { createEventStoreExecutor, createTenantDb, selectMany, WritePurposes, } from "@cosmicdrift/kumiko-framework/db";
|
|
4
3
|
import { createSystemUser, EXT_EXTERNAL_RESOURCE, EXT_INFRA_RESOURCE, EXT_SEARCH_ADAPTER, EXT_STORAGE_PROVIDER, EXT_TENANT_DATA, extensionUsageEscapeHatchReason, isTenantDataExtensionHooks, isTenantResourceExtensionHooks, } from "@cosmicdrift/kumiko-framework/engine";
|
|
5
4
|
import { createFallbackLogger } from "@cosmicdrift/kumiko-framework/logging";
|
|
6
5
|
import { createEscapeHatchReporter, UNATTRIBUTED_ACTOR, } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
@@ -56,9 +55,14 @@ async function runTenantDataHooks(ctx) {
|
|
|
56
55
|
log: ctx.escapeHatchAuditLog ?? createFallbackLogger("tenant-lifecycle"),
|
|
57
56
|
});
|
|
58
57
|
const hookCtx = {
|
|
59
|
-
db: createTenantDb(
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
db: createTenantDb({
|
|
59
|
+
db: ctx.db,
|
|
60
|
+
tenantId: ctx.tenantId,
|
|
61
|
+
mode: "tenant",
|
|
62
|
+
grants: {
|
|
63
|
+
unsafeRaw: reason !== undefined ? { reason } : undefined,
|
|
64
|
+
report,
|
|
65
|
+
},
|
|
62
66
|
}),
|
|
63
67
|
registry: ctx.registry,
|
|
64
68
|
tenantId: ctx.tenantId,
|
|
@@ -106,7 +110,7 @@ async function purgeTenantCache(ctx) {
|
|
|
106
110
|
async function tombstoneTenantRow(ctx) {
|
|
107
111
|
const now = getTemporal().Now.instant();
|
|
108
112
|
const user = createSystemUser(ctx.tenantId);
|
|
109
|
-
const db = createTenantDb(ctx.db, ctx.tenantId, "system");
|
|
113
|
+
const db = createTenantDb({ db: ctx.db, tenantId: ctx.tenantId, mode: "system" });
|
|
110
114
|
// Per-row forget() through the executor, not a bulk deleteMany: memberships
|
|
111
115
|
// are an ES-managed projection (add/remove/update-roles all go through
|
|
112
116
|
// tenantMembershipCrud), so a store table write here is eventless — a future
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import type { SearchAdapter } from "@cosmicdrift/kumiko-framework/search";
|
|
4
|
-
import type { TestStack } from "@cosmicdrift/kumiko-
|
|
4
|
+
import type { TestStack } from "@cosmicdrift/kumiko-testing/stack";
|
|
5
5
|
import { runTenantDestructionSweep } from "./run-tenant-destroy.js";
|
|
6
6
|
export declare function seedDestroyingTenant(db: DbConnection, tenantId: TenantId): Promise<void>;
|
|
7
7
|
export declare function driveDestructionToCompletion(stack: TestStack, db: DbConnection, tenantId: TenantId, searchAdapter?: SearchAdapter): Promise<string>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { append, loadAggregate } from "@cosmicdrift/kumiko-framework/event-store";
|
|
3
|
-
import { updateRows } from "@cosmicdrift/kumiko-framework/testing";
|
|
4
3
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
4
|
+
import { updateRows } from "@cosmicdrift/kumiko-testing/helpers";
|
|
5
5
|
import { tenantTable } from "../tenant/index.js";
|
|
6
6
|
import { TENANT_AGGREGATE_TYPE, TENANT_DESTRUCTION_STARTED_EVENT_QN } from "./constants.js";
|
|
7
7
|
import { runTenantDestructionSweep } from "./run-tenant-destroy.js";
|
|
@@ -2,4 +2,5 @@ import { type FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
2
2
|
import { type TenantSettingsKeyOptions } from "./config.js";
|
|
3
3
|
export type TenantSettingsFeatureOptions = TenantSettingsKeyOptions;
|
|
4
4
|
export declare function createTenantSettingsFeature(opts?: TenantSettingsFeatureOptions): FeatureDefinition;
|
|
5
|
+
/** @deprecated Use createTenantSettingsFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
5
6
|
export declare const tenantSettingsFeature: FeatureDefinition;
|