@cosmicdrift/kumiko-samples 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/package.json +1 -1
- package/packages/bundled-features/package.json +16 -2
- package/packages/bundled-features/src/audit/handlers/details.query.ts +1 -1
- package/packages/bundled-features/src/audit/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/bootstrap.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +10 -3
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +10 -3
- package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +6 -2
- package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/seeding.ts +2 -2
- package/packages/bundled-features/src/auth-foundation/feature.ts +43 -34
- package/packages/bundled-features/src/auth-foundation/index.ts +1 -0
- package/packages/bundled-features/src/auth-mfa/db/queries.ts +5 -2
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/status.query.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/mfa-code-verifier.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +1 -1
- package/packages/bundled-features/src/auth-mfa-user-data/index.ts +19 -10
- package/packages/bundled-features/src/billing-foundation/billing-info-query.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/feature.ts +138 -135
- package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/projection.ts +3 -2
- package/packages/bundled-features/src/cap-counter/calendar-cap-usage-reservation.ts +52 -1
- package/packages/bundled-features/src/cap-counter/cap-reservation.ts +203 -15
- package/packages/bundled-features/src/cap-counter/changes.json +13 -0
- package/packages/bundled-features/src/cap-counter/feature.ts +84 -73
- package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +3 -4
- package/packages/bundled-features/src/cap-counter/index.ts +9 -1
- package/packages/bundled-features/src/cap-counter/tables.ts +10 -3
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -2
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +6 -2
- package/packages/bundled-features/src/cap-overview/handlers/tenant-options.query.ts +1 -1
- package/packages/bundled-features/src/channel-email/changes.json +6 -0
- package/packages/bundled-features/src/channel-email/email-channel.ts +12 -2
- package/packages/bundled-features/src/channel-email/feature.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/inbox.query.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/mark-all-read.write.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/tables.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +1 -2
- package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/seeding.ts +8 -4
- package/packages/bundled-features/src/compliance-profiles-ops/index.ts +26 -17
- package/packages/bundled-features/src/config/db/queries/resolver.ts +1 -1
- package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +2 -2
- package/packages/bundled-features/src/config/resolver.ts +1 -1
- package/packages/bundled-features/src/config/write-helpers.ts +1 -1
- package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +9 -7
- package/packages/bundled-features/src/custom-fields/db/queries/field-access.ts +1 -1
- package/packages/bundled-features/src/custom-fields/db/queries/projection.ts +1 -1
- package/packages/bundled-features/src/custom-fields/db/queries/quota.ts +1 -1
- package/packages/bundled-features/src/custom-fields/db/queries/retention.ts +6 -2
- package/packages/bundled-features/src/custom-fields/db/queries/user-data-rights.ts +1 -1
- package/packages/bundled-features/src/custom-fields/feature.ts +11 -14
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +2 -2
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +2 -2
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +2 -2
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +2 -2
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +4 -4
- package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
- package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +16 -10
- package/packages/bundled-features/src/delivery/address-opt-out.ts +5 -2
- package/packages/bundled-features/src/delivery/attempt-log-retention.ts +1 -1
- package/packages/bundled-features/src/delivery/changes.json +12 -0
- package/packages/bundled-features/src/delivery/channel-context.ts +2 -1
- package/packages/bundled-features/src/delivery/db/queries/address-opt-outs.ts +1 -1
- package/packages/bundled-features/src/delivery/db/queries/preferences.ts +1 -1
- package/packages/bundled-features/src/delivery/delivery-service.ts +70 -8
- package/packages/bundled-features/src/delivery/feature.ts +2 -2
- package/packages/bundled-features/src/delivery/handlers/log.query.ts +3 -2
- package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +1 -1
- package/packages/bundled-features/src/delivery/handlers/unsubscribe-address.write.ts +10 -5
- package/packages/bundled-features/src/delivery/index.ts +6 -0
- package/packages/bundled-features/src/delivery/testing.ts +2 -0
- package/packages/bundled-features/src/delivery/types.ts +4 -0
- package/packages/bundled-features/src/delivery/unsubscribe-link.ts +73 -0
- package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +17 -0
- package/packages/bundled-features/src/delivery/unsubscribe.ts +94 -31
- package/packages/bundled-features/src/delivery/upsert-preference.ts +5 -2
- package/packages/bundled-features/src/derivatives-sharp/feature.ts +21 -12
- package/packages/bundled-features/src/derivatives-sharp/index.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +112 -103
- package/packages/bundled-features/src/document-ingest-foundation/forget-extract-with-file-ref.ts +3 -3
- package/packages/bundled-features/src/document-ingest-foundation/index.ts +4 -1
- package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -5
- package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/feature.ts +134 -129
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant-by-file-ref.query.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
- package/packages/bundled-features/src/file-foundation/feature.ts +38 -29
- package/packages/bundled-features/src/file-foundation/index.ts +1 -0
- package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +1 -1
- package/packages/bundled-features/src/file-provider-inmemory/feature.ts +32 -21
- package/packages/bundled-features/src/file-provider-inmemory/index.ts +6 -1
- package/packages/bundled-features/src/file-provider-s3/changes.json +10 -1
- package/packages/bundled-features/src/file-provider-s3/env-feature.ts +62 -0
- package/packages/bundled-features/src/file-provider-s3/feature.ts +107 -73
- package/packages/bundled-features/src/file-provider-s3/index.ts +6 -1
- package/packages/bundled-features/src/file-provider-s3/lib/index.ts +3 -0
- package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/s3-provider.ts +19 -19
- package/packages/bundled-features/src/file-provider-s3-env/index.ts +7 -2
- package/packages/bundled-features/src/files-provider-s3/index.ts +11 -3
- package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +1 -1
- package/packages/bundled-features/src/files-tenant-data/hooks.ts +1 -2
- package/packages/bundled-features/src/folders/feature.ts +8 -3
- package/packages/bundled-features/src/folders-user-data/index.ts +27 -18
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
- package/packages/bundled-features/src/form-draft/db/queries/draft-count.ts +1 -1
- package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +3 -2
- package/packages/bundled-features/src/form-draft/feature.ts +6 -1
- package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +2 -2
- package/packages/bundled-features/src/form-draft/index.ts +1 -1
- package/packages/bundled-features/src/form-draft/lookup.ts +1 -1
- package/packages/bundled-features/src/form-draft-user-data/index.ts +19 -10
- package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +165 -154
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +1 -2
- package/packages/bundled-features/src/inbound-mail-foundation/index.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/oauth-access-token.ts +5 -2
- package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +3 -2
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +1 -1
- package/packages/bundled-features/src/inbound-provider-imap/feature.ts +22 -13
- package/packages/bundled-features/src/inbound-provider-imap/index.ts +6 -1
- package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +20 -12
- package/packages/bundled-features/src/inbound-provider-inmemory/index.ts +1 -0
- package/packages/bundled-features/src/jobs/db/queries/retention.ts +1 -1
- package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/detail.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/list.query.ts +7 -2
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +1 -1
- package/packages/bundled-features/src/jobs/job-run-logger.ts +11 -10
- package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
- package/packages/bundled-features/src/ledger/feature.ts +6 -3
- package/packages/bundled-features/src/mail-foundation/feature.ts +107 -55
- package/packages/bundled-features/src/mail-foundation/index.ts +4 -0
- package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +25 -17
- package/packages/bundled-features/src/mail-transport-inmemory/index.ts +6 -1
- package/packages/bundled-features/src/mail-transport-smtp/feature.ts +91 -79
- package/packages/bundled-features/src/mail-transport-smtp/index.ts +1 -0
- package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +1 -1
- package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +1 -2
- package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +1 -2
- package/packages/bundled-features/src/managed-pages/seeding.ts +8 -4
- package/packages/bundled-features/src/metrics/compute.ts +1 -1
- package/packages/bundled-features/src/metrics/filters.ts +1 -1
- package/packages/bundled-features/src/metrics/validate.ts +1 -1
- package/packages/bundled-features/src/notes-history/feature.ts +6 -3
- package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
- package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/notes-history-user-data/index.ts +27 -18
- package/packages/bundled-features/src/personal-access-tokens/changes.json +6 -0
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +17 -2
- package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/roles.ts +8 -6
- package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -0
- package/packages/bundled-features/src/readiness/feature.ts +25 -16
- package/packages/bundled-features/src/readiness/index.ts +1 -1
- package/packages/bundled-features/src/secrets/db/queries/read.ts +1 -1
- package/packages/bundled-features/src/secrets/feature.ts +8 -3
- package/packages/bundled-features/src/secrets/handlers/rotate.job.ts +2 -2
- package/packages/bundled-features/src/secrets/secrets-context.ts +4 -3
- package/packages/bundled-features/src/sessions/db/queries/cleanup.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/detail.query.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/mine.query.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/sessions/session-callbacks.ts +14 -7
- package/packages/bundled-features/src/sessions/testing.ts +1 -1
- package/packages/bundled-features/src/tags/feature.ts +6 -3
- package/packages/bundled-features/src/template-resolver/api.ts +1 -1
- package/packages/bundled-features/src/template-resolver/changes.json +25 -0
- package/packages/bundled-features/src/template-resolver/compile-document-body.ts +61 -9
- package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +19 -0
- package/packages/bundled-features/src/template-resolver/document-schema.ts +33 -0
- package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +10 -2
- package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +1 -2
- package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -2
- package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +9 -3
- package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +9 -2
- package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +7 -2
- package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +8 -3
- package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +22 -2
- package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/index.ts +4 -0
- package/packages/bundled-features/src/template-resolver/qualified-names.ts +1 -0
- package/packages/bundled-features/src/template-resolver/seeding.ts +57 -10
- package/packages/bundled-features/src/template-resolver/store-template-resource.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-preview.ts +3 -1
- package/packages/bundled-features/src/template-resolver/template-resources.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-system-only.ts +21 -0
- package/packages/bundled-features/src/template-resolver/template-validation.ts +48 -24
- package/packages/bundled-features/src/template-resolver/testing.ts +1 -1
- package/packages/bundled-features/src/template-resolver/web/i18n.ts +2 -0
- package/packages/bundled-features/src/template-resolver-user-data/index.ts +23 -14
- package/packages/bundled-features/src/tenant/handlers/active-tenant-ids.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -2
- package/packages/bundled-features/src/tenant/handlers/cancel-invitation.write.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/invitations.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/me.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/remove-member.write.ts +2 -1
- package/packages/bundled-features/src/tenant/handlers/resolve-user-ids.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/update-member-roles.write.ts +1 -2
- package/packages/bundled-features/src/tenant/invited-membership.ts +2 -2
- package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -2
- package/packages/bundled-features/src/tenant/seeding.ts +12 -12
- package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +1 -2
- package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts +1 -2
- package/packages/bundled-features/src/tenant-lifecycle/lib/revoke-tenant-sessions.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/lifecycle-gate.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +3 -3
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +10 -5
- package/packages/bundled-features/src/tenant-lifecycle/testing.ts +3 -3
- package/packages/bundled-features/src/tenant-settings/feature.ts +34 -29
- package/packages/bundled-features/src/tier-engine/feature.ts +426 -428
- package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +2 -3
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +5 -2
- package/packages/bundled-features/src/user/changes.json +6 -0
- package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +1 -1
- package/packages/bundled-features/src/user/handlers/create.write.ts +1 -2
- package/packages/bundled-features/src/user/handlers/find-for-auth.query.ts +1 -1
- package/packages/bundled-features/src/user/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/user/handlers/update-roles.ts +2 -1
- package/packages/bundled-features/src/user/index.ts +5 -1
- package/packages/bundled-features/src/user/invited-global-roles.ts +2 -2
- package/packages/bundled-features/src/user/principal-status.ts +13 -3
- package/packages/bundled-features/src/user/resolve-display-names.ts +1 -1
- package/packages/bundled-features/src/user/seeding.ts +5 -5
- package/packages/bundled-features/src/user-data-rights/audit-download.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/changes.json +6 -0
- package/packages/bundled-features/src/user-data-rights/db/queries/export-jobs.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +1 -2
- package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/lib/deny-if-target-outside-admin-tenant.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +7 -2
- package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +7 -3
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +11 -5
- package/packages/bundled-features/src/user-data-rights/run-user-export.ts +10 -5
- package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +1 -2
- package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
- package/packages/bundled-features/src/waitlist/lib.ts +5 -2
- package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/feature.ts +58 -47
- package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/index.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/pending-projection.ts +1 -1
- package/samples/apps/admin-console/src/run-config.ts +2 -2
- package/samples/apps/cap-billing-demo/package.json +3 -0
- package/samples/apps/cap-billing-demo/src/feature.ts +2 -2
- package/samples/apps/cap-billing-demo/src/run-config.ts +8 -8
- package/samples/apps/marketing-demo/src/app/seed.ts +1 -1
- package/samples/apps/marketing-demo/src/db/queries/seed-counts.ts +1 -1
- package/samples/apps/showcase/package.json +3 -0
- package/samples/apps/showcase/src/app/seed-items.ts +1 -1
- package/samples/apps/styleguide/src/app/seed.ts +2 -2
- package/samples/apps/styleguide/src/features/ai-settings/seed.ts +2 -2
- package/samples/apps/ui-walkthrough/scripts/emit-e2e-data.ts +1 -1
- package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +1 -1
- package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +2 -2
- package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +2 -0
- package/samples/apps/ui-walkthrough/src/app/seed-vehicles.ts +1 -1
- package/samples/apps/ui-walkthrough/src/app/seed.ts +1 -1
- package/samples/apps/ui-walkthrough/src/app/template-seed-data.ts +12 -0
- package/samples/apps/ui-walkthrough/src/db/queries/row-counts.ts +1 -1
- package/samples/apps/ui-walkthrough/src/db/queries/task-counts.ts +1 -1
- package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +7 -0
- package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +2 -0
- package/samples/apps/use-all-bundled/feature-manifest.json +4 -4
- package/samples/apps/use-all-bundled/package.json +4 -0
- package/samples/apps/use-all-bundled/scripts/check-coverage.ts +2 -2
- package/samples/apps/use-all-bundled/src/app/auth-constants.ts +1 -1
- package/samples/apps/use-all-bundled/src/app/cap-overview-caps.ts +2 -2
- package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +1 -1
- package/samples/apps/use-all-bundled/src/app/seed-documents.ts +1 -1
- package/samples/apps/use-all-bundled/src/app/seed.ts +11 -5
- package/samples/apps/use-all-bundled/src/run-config.ts +55 -56
- package/samples/apps/user-data-rights-demo/README.md +2 -2
- package/samples/apps/user-data-rights-demo/package.json +3 -0
- package/samples/apps/user-data-rights-demo/src/run-config.ts +7 -7
- package/samples/apps/workspaces/package.json +3 -0
- package/samples/recipes/access-control/package.json +3 -0
- package/samples/recipes/anonymous-access/package.json +3 -0
- package/samples/recipes/anonymous-access-multitenant/package.json +3 -0
- package/samples/recipes/apex-landing/package.json +1 -0
- package/samples/recipes/apex-surface-auth/package.json +3 -0
- package/samples/recipes/apex-surface-auth/src/feature.ts +2 -2
- package/samples/recipes/api-worker-split/package.json +3 -0
- package/samples/recipes/api-worker-split/src/feature.ts +1 -2
- package/samples/recipes/auth-claims/package.json +3 -0
- package/samples/recipes/auth-foundation-providers/src/feature.ts +1 -1
- package/samples/recipes/auth-mfa/package.json +3 -0
- package/samples/recipes/basic-entity/package.json +3 -0
- package/samples/recipes/chat-channels/package.json +3 -0
- package/samples/recipes/compliance-profiles-demo/package.json +3 -0
- package/samples/recipes/cross-feature-events/package.json +3 -1
- package/samples/recipes/cross-feature-events/src/feature.ts +1 -1
- package/samples/recipes/crypto-shredding-hr/package.json +3 -0
- package/samples/recipes/currencies-global/package.json +3 -0
- package/samples/recipes/currencies-per-tenant/package.json +3 -0
- package/samples/recipes/custom-fields-basic/package.json +3 -0
- package/samples/recipes/custom-handlers/package.json +3 -0
- package/samples/recipes/dashboard-stats/package.json +3 -0
- package/samples/recipes/delivery-notifications/package.json +3 -0
- package/samples/recipes/e2e-generator/package.json +3 -0
- package/samples/recipes/embedded/package.json +3 -0
- package/samples/recipes/embedded-entity-form/package.json +1 -0
- package/samples/recipes/encrypted-tenant-config/README.md +1 -1
- package/samples/recipes/encrypted-tenant-config/package.json +3 -0
- package/samples/recipes/error-contract/package.json +3 -0
- package/samples/recipes/event-sourcing/package.json +3 -1
- package/samples/recipes/event-sourcing/src/feature.ts +16 -20
- package/samples/recipes/event-sourcing/tsconfig.json +2 -6
- package/samples/recipes/feature-toggles/package.json +3 -0
- package/samples/recipes/field-access/package.json +3 -0
- package/samples/recipes/files-post-processing/package.json +1 -0
- package/samples/recipes/golden-path/README.md +30 -0
- package/samples/recipes/golden-path/package.json +11 -0
- package/samples/recipes/golden-path/src/feature.ts +70 -0
- package/samples/recipes/idempotency/package.json +3 -0
- package/samples/recipes/inbound-mail-triage/package.json +3 -0
- package/samples/recipes/lane-routing/package.json +3 -0
- package/samples/recipes/ledger-banking/package.json +3 -0
- package/samples/recipes/ledger-invoicing/package.json +3 -0
- package/samples/recipes/legal-pages/package.json +3 -0
- package/samples/recipes/lifecycle-hooks/package.json +3 -0
- package/samples/recipes/managed-config/package.json +3 -0
- package/samples/recipes/managed-pages/package.json +3 -0
- package/samples/recipes/notes-history-basic/package.json +3 -0
- package/samples/recipes/ownership/package.json +3 -0
- package/samples/recipes/pdf-audit-export/package.json +1 -0
- package/samples/recipes/pipeline-basics/package.json +3 -0
- package/samples/recipes/public-share-token/package.json +3 -0
- package/samples/recipes/public-share-token/src/feature.ts +1 -1
- package/samples/recipes/rate-limiting/package.json +3 -0
- package/samples/recipes/realtime-sse/package.json +3 -0
- package/samples/recipes/record-detail-layout/package.json +1 -0
- package/samples/recipes/reference-data/package.json +3 -0
- package/samples/recipes/relations/package.json +3 -0
- package/samples/recipes/screens-nav/package.json +3 -0
- package/samples/recipes/search/package.json +3 -0
- package/samples/recipes/secrets-demo/package.json +3 -0
- package/samples/recipes/security-baseline/src/feature.ts +2 -2
- package/samples/recipes/session-revocation/README.md +1 -1
- package/samples/recipes/session-revocation/package.json +3 -0
- package/samples/recipes/session-revocation/src/feature.ts +1 -1
- package/samples/recipes/state-machine/package.json +3 -1
- package/samples/recipes/state-machine/src/entities/invoice.ts +2 -2
- package/samples/recipes/state-machine/src/events.ts +19 -0
- package/samples/recipes/state-machine/src/feature.ts +25 -30
- package/samples/recipes/state-machine/src/handlers/_helpers.ts +13 -14
- package/samples/recipes/state-machine/src/handlers/create.ts +1 -1
- package/samples/recipes/state-machine/src/handlers/transitions.ts +129 -122
- package/samples/recipes/state-machine/src/reducer.ts +1 -1
- package/samples/recipes/state-machine/tsconfig.json +2 -6
- package/samples/recipes/tags-basic/package.json +3 -0
- package/samples/recipes/tenant-isolation/package.json +3 -0
- package/samples/recipes/tenant-settings/package.json +3 -0
- package/samples/recipes/tier-admin/package.json +3 -0
- package/samples/recipes/timezones/package.json +3 -0
- package/samples/recipes/tsconfig.base.json +1 -1
- package/samples/recipes/user-data-rights/package.json +3 -0
- package/samples/recipes/user-data-rights/src/feature.ts +6 -2
- package/samples/recipes/user-profile/package.json +3 -0
- package/samples/recipes/user-profile/src/feature.ts +2 -2
- package/samples/recipes/webhook-step/package.json +3 -0
- package/samples/recipes/wizard-form/package.json +1 -0
- package/samples/recipes/workflow-engine/package.json +3 -0
- package/samples/recipes/workflow-engine/src/db/queries/suspended-runs.ts +5 -2
- package/samples/recipes/writeform-section/package.json +1 -0
- package/packages/bundled-features/src/file-provider-s3-env/feature.ts +0 -58
- /package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/env-helper.ts +0 -0
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
// Default ifExists="skip". The actor is `createSystemUser(SYSTEM_TENANT_ID)`,
|
|
10
10
|
// deliberately not TestUsers (prod seeds are not test utilities).
|
|
11
11
|
|
|
12
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
13
12
|
import {
|
|
14
13
|
createTenantDb,
|
|
15
14
|
type DbConnection,
|
|
16
15
|
deleteMany,
|
|
17
16
|
type EntityTableMeta,
|
|
17
|
+
fetchOne,
|
|
18
18
|
type TenantDb,
|
|
19
19
|
} from "@cosmicdrift/kumiko-framework/db";
|
|
20
20
|
import {
|
|
@@ -28,11 +28,13 @@ import {
|
|
|
28
28
|
getStreamVersion,
|
|
29
29
|
getUnscopedStreamMaxVersionForSeed,
|
|
30
30
|
} from "@cosmicdrift/kumiko-framework/event-store";
|
|
31
|
+
import type { Dispatcher } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
31
32
|
import { runEventStoreSeed, type SeedIfExists } from "@cosmicdrift/kumiko-framework/seeding";
|
|
33
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
32
34
|
import { type ContentFormat, TEXT_BLOCK_KIND, type UpsertKind } from "./constants.js";
|
|
33
35
|
import { executor } from "./handlers/shared.js";
|
|
34
36
|
import { evaluateTemplateWrite } from "./handlers/template-gates.js";
|
|
35
|
-
import { TEMPLATE_RESOLVER_FEATURE } from "./qualified-names.js";
|
|
37
|
+
import { TEMPLATE_RESOLVER_FEATURE, TemplateResolverHandlers } from "./qualified-names.js";
|
|
36
38
|
import { type TemplateResourceRow, templateResourcesTable } from "./table.js";
|
|
37
39
|
import type { TemplateBundle } from "./template-bundle.js";
|
|
38
40
|
import { activeStampChanges, servedStampChanges } from "./template-draft.js";
|
|
@@ -87,7 +89,7 @@ export async function seedSystemTemplate(
|
|
|
87
89
|
): Promise<{ id: string }> {
|
|
88
90
|
const tenantId = SYSTEM_TENANT_ID;
|
|
89
91
|
const by = opts.by ?? createSystemUser(tenantId);
|
|
90
|
-
const tdb = createTenantDb(db, tenantId, "system");
|
|
92
|
+
const tdb = createTenantDb({ db, tenantId, mode: "system" });
|
|
91
93
|
|
|
92
94
|
const label = `seedSystemTemplate ${opts.slug}/${opts.kind}/${opts.locale}`;
|
|
93
95
|
const slug = templateSlugSchema.safeParse(opts.slug);
|
|
@@ -233,20 +235,21 @@ export async function seedSystemTemplate(
|
|
|
233
235
|
export type SeedSystemTemplateBundleOptions = {
|
|
234
236
|
readonly by?: SessionUser;
|
|
235
237
|
readonly ifExists?: SeedIfExists;
|
|
238
|
+
/** Required for bundles with resources (e.g. a `logo`): the files go through the
|
|
239
|
+
* import-bundle-system write, which needs the file provider of the system tenant. */
|
|
240
|
+
readonly dispatcher?: Dispatcher;
|
|
236
241
|
};
|
|
237
242
|
|
|
238
|
-
// Seeds one system row per bundle locale. Bundled resources need a file
|
|
239
|
-
//
|
|
240
|
-
//
|
|
243
|
+
// Seeds one system row per bundle locale. Bundled resources need a file provider and
|
|
244
|
+
// the system tenant's file space, so those bundles are written through the
|
|
245
|
+
// import-bundle-system handler on the seed dispatcher instead of directly.
|
|
241
246
|
export async function seedSystemTemplateBundle(
|
|
242
247
|
db: DbConnection,
|
|
243
248
|
bundle: TemplateBundle,
|
|
244
249
|
opts: SeedSystemTemplateBundleOptions = {},
|
|
245
250
|
): Promise<{ ids: Record<string, string> }> {
|
|
246
251
|
if (Object.keys(bundle.resources).length > 0) {
|
|
247
|
-
|
|
248
|
-
`seedSystemTemplateBundle ${bundle.slug}/${bundle.kind}: bundles with resources cannot be seeded; use the import-bundle-system write`,
|
|
249
|
-
);
|
|
252
|
+
return seedSystemTemplateBundleWithResources(db, bundle, opts);
|
|
250
253
|
}
|
|
251
254
|
const ids: Record<string, string> = {};
|
|
252
255
|
for (const [locale, entry] of Object.entries(bundle.locales)) {
|
|
@@ -266,6 +269,50 @@ export async function seedSystemTemplateBundle(
|
|
|
266
269
|
return { ids };
|
|
267
270
|
}
|
|
268
271
|
|
|
272
|
+
async function seedSystemTemplateBundleWithResources(
|
|
273
|
+
db: DbConnection,
|
|
274
|
+
bundle: TemplateBundle,
|
|
275
|
+
opts: SeedSystemTemplateBundleOptions,
|
|
276
|
+
): Promise<{ ids: Record<string, string> }> {
|
|
277
|
+
const label = `seedSystemTemplateBundle ${bundle.slug}/${bundle.kind}`;
|
|
278
|
+
const { dispatcher } = opts;
|
|
279
|
+
if (!dispatcher) {
|
|
280
|
+
throw new Error(
|
|
281
|
+
`${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`,
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
if ((opts.ifExists ?? "skip") === "skip") {
|
|
285
|
+
const existingIds: Record<string, string> = {};
|
|
286
|
+
for (const locale of Object.keys(bundle.locales)) {
|
|
287
|
+
const row = await fetchOne<TemplateResourceRow>(db, templateResourcesTable, {
|
|
288
|
+
tenantId: SYSTEM_TENANT_ID,
|
|
289
|
+
slug: bundle.slug,
|
|
290
|
+
kind: bundle.kind,
|
|
291
|
+
locale,
|
|
292
|
+
});
|
|
293
|
+
if (row) existingIds[locale] = String(row.id);
|
|
294
|
+
}
|
|
295
|
+
if (Object.keys(existingIds).length === Object.keys(bundle.locales).length) {
|
|
296
|
+
return { ids: existingIds };
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const result = await dispatcher.write(
|
|
300
|
+
TemplateResolverHandlers.importBundleSystem,
|
|
301
|
+
{ bundle },
|
|
302
|
+
opts.by ?? createSystemUser(SYSTEM_TENANT_ID, ["SystemAdmin"]),
|
|
303
|
+
);
|
|
304
|
+
if (!result.isSuccess) {
|
|
305
|
+
throw new Error(`${label} failed: ${result.error.code}: ${result.error.message}`);
|
|
306
|
+
}
|
|
307
|
+
return { ids: importedIds(result.data) };
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function importedIds(data: unknown): Record<string, string> {
|
|
311
|
+
const ids = isPlainObject(data) ? data["ids"] : undefined;
|
|
312
|
+
if (!isPlainObject(ids)) throw new Error("seedSystemTemplateBundle: import returned no ids");
|
|
313
|
+
return Object.fromEntries(Object.entries(ids).map(([locale, id]) => [locale, String(id)]));
|
|
314
|
+
}
|
|
315
|
+
|
|
269
316
|
export function hasNotificationTemplates(registry: Registry): boolean {
|
|
270
317
|
return Array.from(registry.getAllNotifications().values()).some(
|
|
271
318
|
(notification) => notification.template !== undefined,
|
|
@@ -332,7 +379,7 @@ export async function seedTextBlock(
|
|
|
332
379
|
opts: SeedTextBlockOptions,
|
|
333
380
|
): Promise<{ id: string }> {
|
|
334
381
|
const by = opts.by ?? createSystemUser(opts.tenantId);
|
|
335
|
-
const tdb = createTenantDb(db, opts.tenantId, "system");
|
|
382
|
+
const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
|
|
336
383
|
|
|
337
384
|
const existingRow = await fetchOne<TemplateResourceRow>(db, templateResourcesTable, {
|
|
338
385
|
tenantId: opts.tenantId,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/
|
|
1
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import type {
|
|
3
3
|
HandlerContext,
|
|
4
4
|
SessionUser,
|
|
@@ -69,6 +69,8 @@ function sampleScalar(name: string, def: TemplateScalarVariableDef): unknown {
|
|
|
69
69
|
return 0;
|
|
70
70
|
case "date":
|
|
71
71
|
return SAMPLE_DATE;
|
|
72
|
+
case "percent":
|
|
73
|
+
return 0;
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Registry } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
import { isSystemAdmin } from "./template-draft.js";
|
|
3
|
+
|
|
4
|
+
const NOTIFICATION_TEMPLATE_KIND = "mail";
|
|
5
|
+
|
|
6
|
+
// A notification registered with systemOnly keeps its mail template as the system default:
|
|
7
|
+
// tenants neither list nor override it, and overrides stored before the flag are ignored.
|
|
8
|
+
export function isSystemOnlyTemplate(registry: Registry, slug: string, kind: string): boolean {
|
|
9
|
+
return (
|
|
10
|
+
kind === NOTIFICATION_TEMPLATE_KIND &&
|
|
11
|
+
registry.getAllNotifications().get(slug)?.systemOnly === true
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function isSystemOnlyTemplateHiddenFrom(
|
|
16
|
+
user: { readonly roles: readonly string[] },
|
|
17
|
+
registry: Registry,
|
|
18
|
+
row: { readonly slug: string; readonly kind: string },
|
|
19
|
+
): boolean {
|
|
20
|
+
return !isSystemAdmin(user) && isSystemOnlyTemplate(registry, row.slug, row.kind);
|
|
21
|
+
}
|
|
@@ -6,8 +6,12 @@ import type {
|
|
|
6
6
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
7
7
|
import type { Element as ScanElement } from "happy-dom";
|
|
8
8
|
import * as z from "zod";
|
|
9
|
-
import { withParsedDocument } from "./document-sanitizer.js";
|
|
10
|
-
import {
|
|
9
|
+
import { conditionScopeElement, withParsedDocument } from "./document-sanitizer.js";
|
|
10
|
+
import {
|
|
11
|
+
DOCUMENT_CONDITION_ATTRIBUTE,
|
|
12
|
+
isDocumentPlaceholderHref,
|
|
13
|
+
isDocumentReferenceName,
|
|
14
|
+
} from "./document-schema.js";
|
|
11
15
|
import type { TemplateMeta } from "./template-meta.js";
|
|
12
16
|
|
|
13
17
|
export const SYSTEM_PLACEHOLDERS: ReadonlySet<string> = new Set([
|
|
@@ -56,6 +60,7 @@ const scalarVariableSchema = z.discriminatedUnion("type", [
|
|
|
56
60
|
.optional(),
|
|
57
61
|
}),
|
|
58
62
|
z.object({ ...variableCommon, type: z.literal("date"), example: textLikeExample }),
|
|
63
|
+
z.object({ ...variableCommon, type: z.literal("percent"), example: z.number().optional() }),
|
|
59
64
|
]);
|
|
60
65
|
|
|
61
66
|
const variableDefSchema = z.union([
|
|
@@ -154,30 +159,49 @@ const NAME_ATTRIBUTE_BY_TAG: Readonly<Record<string, string>> = {
|
|
|
154
159
|
div: "data-steps",
|
|
155
160
|
};
|
|
156
161
|
|
|
162
|
+
function scanRepeatRows(root: ScanElement, scope: PlaceholderScope): void {
|
|
163
|
+
for (const element of Array.from(root.querySelectorAll("tr[data-each]"))) {
|
|
164
|
+
const listName = element.getAttribute("data-each") ?? "";
|
|
165
|
+
const def = Object.hasOwn(scope.variables, listName) ? scope.variables[listName] : undefined;
|
|
166
|
+
if (def?.type === "list") scope.used.add(listName);
|
|
167
|
+
else scope.unknown.add(listName);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function scanConditions(root: ScanElement, scope: PlaceholderScope): void {
|
|
172
|
+
for (const element of Array.from(root.querySelectorAll(`[${DOCUMENT_CONDITION_ATTRIBUTE}]`))) {
|
|
173
|
+
const itemFields = listItemFields(
|
|
174
|
+
scope.variables,
|
|
175
|
+
enclosingEachName(conditionScopeElement(element)),
|
|
176
|
+
);
|
|
177
|
+
recordName(element.getAttribute(DOCUMENT_CONDITION_ATTRIBUTE) ?? "", itemFields, scope);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function scanReferences(root: ScanElement, scope: PlaceholderScope): void {
|
|
182
|
+
for (const element of Array.from(
|
|
183
|
+
root.querySelectorAll("span[data-variable], div[data-steps], a[href], img[data-resource]"),
|
|
184
|
+
)) {
|
|
185
|
+
const itemFields = listItemFields(scope.variables, enclosingEachName(element));
|
|
186
|
+
const tag = element.tagName.toLowerCase();
|
|
187
|
+
const nameAttribute = NAME_ATTRIBUTE_BY_TAG[tag];
|
|
188
|
+
if (nameAttribute !== undefined) {
|
|
189
|
+
recordName(element.getAttribute(nameAttribute) ?? "", itemFields, scope);
|
|
190
|
+
} else if (tag === "a") {
|
|
191
|
+
const href = element.getAttribute("href") ?? "";
|
|
192
|
+
if (isDocumentPlaceholderHref(href)) recordName(href.slice(2, -2), itemFields, scope);
|
|
193
|
+
} else {
|
|
194
|
+
const key = element.getAttribute("data-resource") ?? "";
|
|
195
|
+
if (!scope.resourceKeys.has(key)) scope.unknownResources.add(key);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
157
200
|
function scanBodyPlaceholders(body: string, scope: PlaceholderScope): void {
|
|
158
201
|
withParsedDocument(body, (root) => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (def?.type === "list") scope.used.add(listName);
|
|
163
|
-
else scope.unknown.add(listName);
|
|
164
|
-
}
|
|
165
|
-
for (const element of Array.from(
|
|
166
|
-
root.querySelectorAll("span[data-variable], div[data-steps], a[href], img[data-resource]"),
|
|
167
|
-
)) {
|
|
168
|
-
const itemFields = listItemFields(scope.variables, enclosingEachName(element));
|
|
169
|
-
const tag = element.tagName.toLowerCase();
|
|
170
|
-
const nameAttribute = NAME_ATTRIBUTE_BY_TAG[tag];
|
|
171
|
-
if (nameAttribute !== undefined) {
|
|
172
|
-
recordName(element.getAttribute(nameAttribute) ?? "", itemFields, scope);
|
|
173
|
-
} else if (tag === "a") {
|
|
174
|
-
const href = element.getAttribute("href") ?? "";
|
|
175
|
-
if (isDocumentPlaceholderHref(href)) recordName(href.slice(2, -2), itemFields, scope);
|
|
176
|
-
} else {
|
|
177
|
-
const key = element.getAttribute("data-resource") ?? "";
|
|
178
|
-
if (!scope.resourceKeys.has(key)) scope.unknownResources.add(key);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
202
|
+
scanRepeatRows(root, scope);
|
|
203
|
+
scanConditions(root, scope);
|
|
204
|
+
scanReferences(root, scope);
|
|
181
205
|
});
|
|
182
206
|
}
|
|
183
207
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// No bun:test here — callers register cases with their own test runner.
|
|
4
4
|
|
|
5
5
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
6
|
-
import { seedRow } from "@cosmicdrift/kumiko-
|
|
6
|
+
import { seedRow } from "@cosmicdrift/kumiko-testing/helpers";
|
|
7
7
|
import type { ResolveRequest, TemplateResource } from "./api.js";
|
|
8
8
|
import { TemplateNotFoundError } from "./api.js";
|
|
9
9
|
import {
|
|
@@ -96,6 +96,8 @@ export const defaultTranslations: TranslationsByLocale = {
|
|
|
96
96
|
"“{detail}” templates are written through their own editor, not through a collection.",
|
|
97
97
|
"templateResolver.errors.noSystemTemplate": "There is no active system template to reset to.",
|
|
98
98
|
"templateResolver.errors.noDraft": "There is no draft to discard.",
|
|
99
|
+
"templateResolver.errors.systemOnlyTemplate":
|
|
100
|
+
"Only the platform maintains this template; it cannot be overridden per tenant.",
|
|
99
101
|
"templateResolver.errors.template.invalidMeta": "The template settings are invalid.",
|
|
100
102
|
"templateResolver.errors.template.meta.subject.required": "The subject is missing.",
|
|
101
103
|
"templateResolver.errors.template.meta.subject.invalid":
|
|
@@ -8,18 +8,27 @@
|
|
|
8
8
|
import { defineFeature, EXT_USER_DATA } from "@cosmicdrift/kumiko-framework/engine";
|
|
9
9
|
import { userContentDeleteHook, userContentExportHook } from "./hooks.js";
|
|
10
10
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
"
|
|
11
|
+
export function createTemplateResolverUserDataFeature() {
|
|
12
|
+
return defineFeature(
|
|
13
|
+
"template-resolver-user-data",
|
|
14
|
+
(r) => {
|
|
15
|
+
r.describe(
|
|
16
|
+
"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`.",
|
|
17
|
+
);
|
|
18
|
+
// user-data-rights is the hard dependency (EXT_USER_DATA host).
|
|
19
|
+
// template-resolver is optional for the same reason as in
|
|
20
|
+
// notes-history-user-data: a toggleable mount would otherwise trip the
|
|
21
|
+
// "effectively disabled" boot warning even though the entity is there.
|
|
22
|
+
r.requires({ features: ["user-data-rights"] });
|
|
23
|
+
r.optionalRequires("template-resolver");
|
|
24
|
+
r.useExtension(EXT_USER_DATA, "user-content-entry", {
|
|
25
|
+
export: userContentExportHook,
|
|
26
|
+
delete: userContentDeleteHook,
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
{ dedupeOptions: {} },
|
|
14
30
|
);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
r.requires({ features: ["user-data-rights"] });
|
|
20
|
-
r.optionalRequires("template-resolver");
|
|
21
|
-
r.useExtension(EXT_USER_DATA, "user-content-entry", {
|
|
22
|
-
export: userContentExportHook,
|
|
23
|
-
delete: userContentDeleteHook,
|
|
24
|
-
});
|
|
25
|
-
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** @deprecated Use createTemplateResolverUserDataFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
34
|
+
export const templateResolverUserDataFeature = createTemplateResolverUserDataFeature();
|
|
@@ -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 {
|
|
4
3
|
defineWriteHandler,
|
|
5
4
|
type SessionUser,
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// invitation = no-op + 200. Cancelling a non-existent invitation
|
|
11
11
|
// = invitation_not_found.
|
|
12
12
|
|
|
13
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/
|
|
13
|
+
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
14
14
|
import { access, defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
15
15
|
import { InternalError, NotFoundError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
16
16
|
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, 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,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, type DbRow } from "@cosmicdrift/kumiko-framework/db";
|
|
1
|
+
import { createEventStoreExecutor, type DbRow, fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
3
2
|
import {
|
|
4
3
|
access,
|
|
5
4
|
assignableAppRolesOf,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
1
|
import {
|
|
3
2
|
createEventStoreExecutor,
|
|
4
3
|
createTenantDb,
|
|
5
4
|
type DbRunner,
|
|
5
|
+
fetchOne,
|
|
6
6
|
type TenantDb,
|
|
7
7
|
} from "@cosmicdrift/kumiko-framework/db";
|
|
8
8
|
import { createSystemUser, type TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
@@ -87,7 +87,7 @@ export async function grantInvitedMembershipRole(db: DbRunner, options: InvitedM
|
|
|
87
87
|
const updateResult = await membershipExecutor.update(
|
|
88
88
|
{ id: existing.id, version: existing.version, changes: { roles: JSON.stringify(roles) } },
|
|
89
89
|
createSystemUser(options.tenantId),
|
|
90
|
-
createTenantDb(db, options.tenantId, "system"),
|
|
90
|
+
createTenantDb({ db, tenantId: options.tenantId, mode: "system" }),
|
|
91
91
|
);
|
|
92
92
|
if (!updateResult.isSuccess) return updateResult;
|
|
93
93
|
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";
|
|
@@ -28,11 +28,11 @@
|
|
|
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
30
|
|
|
31
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
32
31
|
import {
|
|
33
32
|
createEventStoreExecutor,
|
|
34
33
|
createTenantDb,
|
|
35
34
|
type DbRunner,
|
|
35
|
+
fetchOne,
|
|
36
36
|
} from "@cosmicdrift/kumiko-framework/db";
|
|
37
37
|
import {
|
|
38
38
|
type AppContext,
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
createDeferringNotify,
|
|
49
49
|
createLifecycleHooks,
|
|
50
50
|
} from "@cosmicdrift/kumiko-framework/pipeline";
|
|
51
|
-
import { TestUsers } from "@cosmicdrift/kumiko-framework/
|
|
51
|
+
import { TestUsers } from "@cosmicdrift/kumiko-framework/seeding";
|
|
52
52
|
import { assertAssignableMembershipRoles } from "./membership-roles.js";
|
|
53
53
|
import { tenantMembershipEntity, tenantMembershipsTable } from "./membership-table.js";
|
|
54
54
|
import { tenantEntity, tenantTable } from "./schema/tenant.js";
|
|
@@ -159,14 +159,14 @@ function scopeSeedHookContext(
|
|
|
159
159
|
// afterCommit-phase hook would be dropped: that phase must notify inline.
|
|
160
160
|
notifyTiming: "deferUntilCommit" | "inline",
|
|
161
161
|
): AppContext {
|
|
162
|
-
const db = createTenantDb(
|
|
163
|
-
runner,
|
|
164
|
-
targetTenantId,
|
|
165
|
-
"system",
|
|
166
|
-
context.tracer,
|
|
167
|
-
context.meter,
|
|
168
|
-
context.signal,
|
|
169
|
-
);
|
|
162
|
+
const db = createTenantDb({
|
|
163
|
+
db: runner,
|
|
164
|
+
tenantId: targetTenantId,
|
|
165
|
+
mode: "system",
|
|
166
|
+
tracer: context.tracer,
|
|
167
|
+
meter: context.meter,
|
|
168
|
+
signal: context.signal,
|
|
169
|
+
});
|
|
170
170
|
|
|
171
171
|
// HandlerContext carries `user`; AppContext only `systemUser`. Prefer the
|
|
172
172
|
// live handler user when present so notify/hasFeature keep a real SessionUser.
|
|
@@ -260,7 +260,7 @@ export async function seedTenant(
|
|
|
260
260
|
// tenant-scoped ist, braucht der Wrap-Layer für die runtime-API zu
|
|
261
261
|
// existieren. by.tenantId reicht — keine Override-Semantik wie bei
|
|
262
262
|
// seedTenantMembership nötig.
|
|
263
|
-
const tdb = createTenantDb(db, by.tenantId, "system");
|
|
263
|
+
const tdb = createTenantDb({ db, tenantId: by.tenantId, mode: "system" });
|
|
264
264
|
|
|
265
265
|
const existing = await fetchOne(db, tenantTable, { id: options.id });
|
|
266
266
|
if (existing) return { id: options.id };
|
|
@@ -323,7 +323,7 @@ export async function seedTenantMembership(
|
|
|
323
323
|
const by = options.by ?? createSystemUser(options.tenantId);
|
|
324
324
|
// System-scoped TenantDb: payload.tenantId may differ from an explicit
|
|
325
325
|
// `by` override; stream tenant still follows `by` via streamTenantFor.
|
|
326
|
-
const tdb = createTenantDb(db, options.tenantId, "system");
|
|
326
|
+
const tdb = createTenantDb({ db, tenantId: options.tenantId, mode: "system" });
|
|
327
327
|
|
|
328
328
|
// Idempotency: duplicate seeds are common across beforeEach-resets where
|
|
329
329
|
// only certain tables get truncated. A plain executor.create would trip
|
|
@@ -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";
|
package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts
CHANGED
|
@@ -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,5 +1,5 @@
|
|
|
1
|
-
import { updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
1
|
import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import { updateMany } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
5
5
|
import { userSessionTable } from "../../sessions/index.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
1
|
import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
import { tenantTable } from "../tenant/index.js";
|
|
5
5
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="temporal-polyfill/global" preserve="true" />
|
|
2
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
3
2
|
import type { DbRunner, TenantDb, WhereObject } from "@cosmicdrift/kumiko-framework/db";
|
|
4
3
|
import {
|
|
5
4
|
createEventStoreExecutor,
|
|
6
5
|
createTenantDb,
|
|
6
|
+
selectMany,
|
|
7
7
|
WritePurposes,
|
|
8
8
|
} from "@cosmicdrift/kumiko-framework/db";
|
|
9
9
|
import {
|
|
@@ -173,7 +173,7 @@ async function appendTenantStageEventIdempotent(
|
|
|
173
173
|
|
|
174
174
|
async function markTenantDestroyFailed(db: DbRunner, tenantId: TenantId): Promise<void> {
|
|
175
175
|
const user = createSystemUser(tenantId);
|
|
176
|
-
const scopedDb = createTenantDb(db, tenantId, "system");
|
|
176
|
+
const scopedDb = createTenantDb({ db, tenantId, mode: "system" });
|
|
177
177
|
await tenantCrud.update(
|
|
178
178
|
{
|
|
179
179
|
id: tenantId,
|
|
@@ -431,7 +431,7 @@ export async function runTenantDestructionSweep(args: {
|
|
|
431
431
|
const events = await loadAggregate(args.db, tenantId, tenantId);
|
|
432
432
|
const version = lastEventVersion(events);
|
|
433
433
|
const user = createSystemUser(tenantId);
|
|
434
|
-
const scopedDb = createTenantDb(args.db, tenantId, "system");
|
|
434
|
+
const scopedDb = createTenantDb({ db: args.db, tenantId, mode: "system" });
|
|
435
435
|
// Version-guarded (no skipOptimisticLock): a concurrent cancel-destruction
|
|
436
436
|
// between the `due` select above and this write also appends to the same
|
|
437
437
|
// tenant stream, so an unguarded overwrite here would silently revert the
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
1
|
import {
|
|
3
2
|
configuredPiiSubjectKms,
|
|
4
3
|
type SubjectId,
|
|
@@ -8,6 +7,7 @@ import {
|
|
|
8
7
|
createEventStoreExecutor,
|
|
9
8
|
createTenantDb,
|
|
10
9
|
type DbRunner,
|
|
10
|
+
selectMany,
|
|
11
11
|
WritePurposes,
|
|
12
12
|
} from "@cosmicdrift/kumiko-framework/db";
|
|
13
13
|
import {
|
|
@@ -143,9 +143,14 @@ async function runTenantDataHooks(ctx: DestructionStageCtx): Promise<StageRunOut
|
|
|
143
143
|
log: ctx.escapeHatchAuditLog ?? createFallbackLogger("tenant-lifecycle"),
|
|
144
144
|
});
|
|
145
145
|
const hookCtx: TenantDataHookCtx = {
|
|
146
|
-
db: createTenantDb(
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
db: createTenantDb({
|
|
147
|
+
db: ctx.db,
|
|
148
|
+
tenantId: ctx.tenantId,
|
|
149
|
+
mode: "tenant",
|
|
150
|
+
grants: {
|
|
151
|
+
unsafeRaw: reason !== undefined ? { reason } : undefined,
|
|
152
|
+
report,
|
|
153
|
+
},
|
|
149
154
|
}),
|
|
150
155
|
registry: ctx.registry,
|
|
151
156
|
tenantId: ctx.tenantId,
|
|
@@ -202,7 +207,7 @@ async function purgeTenantCache(ctx: DestructionStageCtx): Promise<StageRunOutco
|
|
|
202
207
|
async function tombstoneTenantRow(ctx: DestructionStageCtx): Promise<StageRunOutcome> {
|
|
203
208
|
const now = getTemporal().Now.instant();
|
|
204
209
|
const user = createSystemUser(ctx.tenantId);
|
|
205
|
-
const db = createTenantDb(ctx.db, ctx.tenantId, "system");
|
|
210
|
+
const db = createTenantDb({ db: ctx.db, tenantId: ctx.tenantId, mode: "system" });
|
|
206
211
|
// Per-row forget() through the executor, not a bulk deleteMany: memberships
|
|
207
212
|
// are an ES-managed projection (add/remove/update-roles all go through
|
|
208
213
|
// tenantMembershipCrud), so a store table write here is eventless — a future
|