@cosmicdrift/kumiko-bundled-features 0.362.0 → 0.364.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/admin-shell/feature.d.ts +3 -0
- package/dist/admin-shell/feature.js +6 -1
- package/dist/agent-tools/agent-manifest.js +2 -1
- package/dist/agent-tools/filter-ops.d.ts +1 -1
- package/dist/agent-tools/filter-ops.js +1 -3
- package/dist/agent-tools/tool-dispatch.js +2 -1
- package/dist/audit/handlers/list.query.js +9 -5
- package/dist/auth-email-password/bootstrap.d.ts +8 -5
- package/dist/auth-email-password/bootstrap.js +12 -4
- package/dist/auth-email-password/email-rate-limits.d.ts +4 -0
- package/dist/auth-email-password/email-rate-limits.js +13 -0
- package/dist/auth-email-password/email-templates.d.ts +4 -26
- package/dist/auth-email-password/email-templates.js +9 -101
- package/dist/auth-email-password/feature.js +24 -6
- package/dist/auth-email-password/handlers/change-password.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/change-password.write.js +6 -2
- package/dist/auth-email-password/handlers/confirm-account-unlock.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/invite-accept.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
- package/dist/auth-email-password/handlers/invite-create.write.js +4 -4
- package/dist/auth-email-password/handlers/invite-signup-complete.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/logout.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/logout.write.js +6 -2
- package/dist/auth-email-password/handlers/request-account-unlock.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/request-account-unlock.write.js +2 -4
- package/dist/auth-email-password/handlers/request-email-verification.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/request-email-verification.write.js +2 -4
- package/dist/auth-email-password/handlers/request-password-reset.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/request-password-reset.write.js +2 -4
- package/dist/auth-email-password/handlers/reset-password.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/signup-confirm.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/signup-confirm.write.js +3 -4
- package/dist/auth-email-password/handlers/signup-request.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/signup-request.write.js +2 -1
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/token-request-handler.d.ts +2 -3
- package/dist/auth-email-password/handlers/token-request-handler.js +2 -2
- package/dist/auth-email-password/handlers/verify-email.write.d.ts +1 -1
- package/dist/auth-email-password/index.d.ts +2 -2
- package/dist/auth-email-password/index.js +1 -1
- package/dist/auth-email-password/magic-link-mail.d.ts +3 -2
- package/dist/auth-email-password/magic-link-mail.js +19 -14
- package/dist/auth-email-password/mail-notifications.d.ts +32 -0
- package/dist/auth-email-password/mail-notifications.js +116 -0
- package/dist/auth-email-password/signup-activation.d.ts +1 -1
- package/dist/auth-email-password/signup-activation.js +2 -3
- package/dist/auth-email-password/web/auth-gate.js +16 -4
- package/dist/auth-foundation/types.js +2 -8
- package/dist/auth-mfa/feature.js +4 -4
- package/dist/auth-mfa/handlers/disable.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/enable-confirm.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/enable-start-preauth.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/enable-start.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/regenerate-recovery.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/verify.write.d.ts +1 -1
- package/dist/auth-mfa/hmac-token-codec.js +4 -4
- package/dist/auth-mfa/mfa-challenge-token.js +3 -3
- package/dist/auth-mfa/mfa-preauth-setup-token.js +3 -3
- package/dist/auth-mfa/mfa-setup-token.js +8 -8
- package/dist/billing-foundation/constants.d.ts +3 -3
- package/dist/billing-foundation/constants.js +5 -4
- package/dist/billing-foundation/consumer-protection/confirmation-mail.d.ts +32 -14
- package/dist/billing-foundation/consumer-protection/confirmation-mail.js +74 -32
- package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +3 -0
- package/dist/billing-foundation/consumer-protection/consent-gate.js +21 -2
- package/dist/billing-foundation/consumer-protection/issue-confirmation.js +3 -3
- package/dist/billing-foundation/consumer-protection/mail-notifications.d.ts +8 -0
- package/dist/billing-foundation/consumer-protection/mail-notifications.js +95 -0
- package/dist/billing-foundation/consumer-protection/register-consent.js +2 -0
- package/dist/billing-foundation/consumer-protection/register-termination.js +11 -1
- package/dist/billing-foundation/consumer-protection/termination-mail.d.ts +25 -13
- package/dist/billing-foundation/consumer-protection/termination-mail.js +11 -23
- package/dist/billing-foundation/consumer-protection/termination-notify.js +2 -2
- package/dist/billing-foundation/consumer-protection/termination-pages.js +1 -3
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +6 -0
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +34 -0
- package/dist/billing-foundation/consumer-protection/termination-record.d.ts +2 -0
- package/dist/billing-foundation/consumer-protection/termination-record.js +7 -1
- package/dist/billing-foundation/consumer-protection/termination-request.js +31 -21
- package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
- package/dist/billing-foundation/consumer-protection/termination-texts.js +6 -0
- package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +10 -0
- package/dist/billing-foundation/consumer-protection/withdrawal-period.js +26 -0
- package/dist/billing-foundation/handlers/create-checkout-session.write.js +11 -5
- package/dist/billing-foundation/handlers/process-event.write.js +12 -8
- package/dist/billing-foundation/handlers/process-payment-event.write.js +1 -1
- package/dist/billing-foundation/i18n.js +3 -0
- package/dist/billing-foundation/subscription-tier-sync.d.ts +7 -1
- package/dist/billing-foundation/subscription-tier-sync.js +16 -9
- package/dist/billing-foundation/types.d.ts +7 -2
- package/dist/cap-counter/calendar-cap-usage-reservation.js +2 -0
- package/dist/cap-counter/enforce-cap.d.ts +18 -1
- package/dist/cap-counter/enforce-cap.js +49 -6
- package/dist/cap-counter/index.d.ts +1 -1
- package/dist/cap-counter/index.js +1 -1
- package/dist/cap-counter/with-cap-enforcement.d.ts +2 -0
- package/dist/cap-overview/handlers/tenant-caps-list.query.js +2 -1
- package/dist/cap-overview/web/cap-usage-cell.js +5 -4
- package/dist/channel-email/email-channel.d.ts +2 -2
- package/dist/channel-email/email-channel.js +101 -26
- package/dist/channel-email/feature.js +3 -3
- package/dist/channel-email/index.d.ts +1 -1
- package/dist/channel-email/index.js +1 -1
- package/dist/channel-email/pii-guard.js +10 -0
- package/dist/channel-email/smtp-transport.js +13 -0
- package/dist/channel-email/types.d.ts +8 -0
- package/dist/channel-in-app/handlers/mark-all-read.write.d.ts +1 -1
- package/dist/channel-in-app/handlers/mark-read.write.d.ts +1 -1
- package/dist/compliance-profiles/handlers/set-profile.write.d.ts +1 -1
- package/dist/config/handlers/reset.write.d.ts +1 -1
- package/dist/config/handlers/set.write.d.ts +1 -1
- package/dist/config/handlers/set.write.js +3 -4
- package/dist/config/resolver.d.ts +1 -0
- package/dist/config/resolver.js +11 -14
- package/dist/config/write-helpers.d.ts +2 -0
- package/dist/config/write-helpers.js +19 -0
- package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +1 -1
- package/dist/crypto-shredding/handlers/forget-subject.write.js +29 -19
- package/dist/custom-fields/handlers/update-tenant-field.write.js +0 -1
- package/dist/custom-fields/lib/value-schema.js +10 -11
- package/dist/custom-fields/wire-user-data-rights.js +7 -6
- package/dist/data-retention/index.d.ts +1 -0
- package/dist/data-retention/index.js +1 -0
- package/dist/data-retention/run-retention-cleanup.js +6 -6
- package/dist/delivery/attachment-ref.d.ts +41 -0
- package/dist/delivery/attachment-ref.js +78 -0
- package/dist/delivery/channel-context.d.ts +8 -4
- package/dist/delivery/channel-context.js +94 -2
- package/dist/delivery/constants.d.ts +1 -0
- package/dist/delivery/constants.js +1 -0
- package/dist/delivery/delivery-service.d.ts +4 -1
- package/dist/delivery/delivery-service.js +38 -32
- package/dist/delivery/feature.js +1 -1
- package/dist/delivery/handlers/resubscribe-address.write.d.ts +1 -1
- package/dist/delivery/handlers/resubscribe-user.write.d.ts +1 -1
- package/dist/delivery/handlers/set-preference.write.d.ts +1 -1
- package/dist/delivery/handlers/unsubscribe-address.write.d.ts +1 -1
- package/dist/delivery/handlers/unsubscribe-user.write.d.ts +1 -1
- package/dist/delivery/index.d.ts +5 -2
- package/dist/delivery/index.js +4 -1
- package/dist/delivery/jobs.js +66 -14
- package/dist/delivery/notify-factory.js +4 -1
- package/dist/delivery/testing.d.ts +4 -1
- package/dist/delivery/types.d.ts +26 -14
- package/dist/delivery/unsubscribe.js +4 -1
- package/dist/derivatives-sharp/render.js +1 -18
- package/dist/document-ingest-foundation/pages.js +4 -4
- package/dist/feature-toggles/handlers/set.write.d.ts +1 -1
- package/dist/feature-toggles/toggle-sync-signal.js +4 -4
- package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
- package/dist/file-foundation/index.d.ts +1 -0
- package/dist/file-foundation/index.js +1 -0
- package/dist/file-foundation/read-file-ref-content.d.ts +27 -0
- package/dist/file-foundation/read-file-ref-content.js +51 -0
- package/dist/files-tenant-data/hooks.js +4 -0
- package/dist/folders/web/folder-manager.js +3 -2
- package/dist/form-draft/db/queries/cleanup.js +4 -4
- package/dist/form-draft/db/queries/draft-count.js +2 -2
- package/dist/form-draft/db/queries/owned-file-refs.js +2 -2
- package/dist/form-draft/handlers/discard.write.d.ts +1 -1
- package/dist/form-draft/handlers/save.write.d.ts +1 -1
- package/dist/form-draft/release-file-refs.js +3 -2
- package/dist/inbound-mail-foundation/handlers/connect-account.write.js +1 -1
- package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +6 -6
- package/dist/inbound-mail-foundation/handlers/scope-visibility.d.ts +1 -1
- package/dist/inbound-mail-foundation/oauth-access-token.js +8 -3
- package/dist/inbound-mail-foundation/oauth-state.js +7 -7
- package/dist/inbound-mail-foundation/types.js +4 -4
- package/dist/inbound-mail-foundation/watch-supervisor.js +24 -13
- package/dist/inbound-provider-imap/imap-client.js +4 -3
- package/dist/jobs/db/queries/stale-run-sweep.d.ts +1 -1
- package/dist/jobs/db/queries/stale-run-sweep.js +12 -5
- package/dist/jobs/feature.js +5 -3
- package/dist/jobs/handlers/list.query.js +3 -1
- package/dist/jobs/handlers/retry.write.d.ts +1 -1
- package/dist/jobs/handlers/stale-run-sweep.job.d.ts +1 -1
- package/dist/jobs/handlers/stale-run-sweep.job.js +2 -2
- package/dist/jobs/handlers/trigger.write.d.ts +1 -1
- package/dist/jobs/job-run-logger.js +32 -10
- package/dist/jobs/tenant-job-run-table.js +3 -2
- package/dist/ledger/entity.js +3 -1
- package/dist/ledger/recurring.js +1 -3
- package/dist/managed-pages/branding.d.ts +2 -0
- package/dist/managed-pages/branding.js +24 -2
- package/dist/managed-pages/feature.js +1 -0
- package/dist/managed-pages/handlers/set.write.d.ts +1 -1
- package/dist/managed-pages/i18n.js +1 -0
- package/dist/managed-pages/screens/branding-screen.js +8 -1
- package/dist/page-render/branding.d.ts +1 -0
- package/dist/page-render/branding.js +1 -0
- package/dist/page-render/markdown.js +1 -1
- package/dist/personal-access-tokens/feature.js +1 -1
- package/dist/personal-access-tokens/handlers/create.write.d.ts +1 -1
- package/dist/personal-access-tokens/handlers/list.query.js +2 -1
- package/dist/personal-access-tokens/handlers/revoke.write.d.ts +1 -1
- package/dist/personal-access-tokens/revoke-for-user.js +2 -1
- package/dist/renderer-foundation/api.d.ts +13 -13
- package/dist/renderer-foundation/api.js +1 -1
- package/dist/renderer-foundation/constants.js +2 -4
- package/dist/renderer-foundation/feature.js +7 -7
- package/dist/renderer-foundation/index.d.ts +2 -1
- package/dist/renderer-foundation/index.js +1 -0
- package/dist/renderer-foundation/types.d.ts +94 -32
- package/dist/renderer-pdf/feature.js +7 -1
- package/dist/renderer-pdf/render-table-pdf.d.ts +27 -33
- package/dist/renderer-pdf/render-table-pdf.js +95 -34
- package/dist/secrets/feature.js +4 -3
- package/dist/secrets/handlers/delete.write.d.ts +1 -1
- package/dist/secrets/handlers/set.write.d.ts +1 -1
- package/dist/secrets/secrets-context.js +15 -3
- package/dist/sessions/db/queries/cleanup.js +2 -2
- package/dist/sessions/feature.js +1 -1
- package/dist/sessions/handlers/list.query.js +2 -1
- package/dist/sessions/handlers/revoke-all-for-user.write.d.ts +1 -1
- package/dist/sessions/handlers/revoke-all-others.write.d.ts +1 -1
- package/dist/sessions/handlers/revoke.write.d.ts +1 -1
- package/dist/shared/attachment-file-name.d.ts +3 -0
- package/dist/shared/attachment-file-name.js +35 -0
- package/dist/shared/chunked-entity-migration.d.ts +1 -0
- package/dist/shared/chunked-entity-migration.js +1 -1
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +3 -0
- package/dist/shared/is-tenant-db.js +1 -1
- package/dist/shared/mail-template-body.d.ts +7 -0
- package/dist/shared/mail-template-body.js +27 -0
- package/dist/shared/sharp-input-limits.d.ts +6 -0
- package/dist/shared/sharp-input-limits.js +22 -0
- package/dist/shared/signup-handover.js +2 -2
- package/dist/subscription-stripe/plugin-methods.js +18 -8
- package/dist/subscription-stripe/verify-webhook.d.ts +1 -1
- package/dist/tags/handlers/assign-tag.write.js +3 -1
- package/dist/tags/web/tag-chip.js +2 -0
- package/dist/template-resolver/api.d.ts +30 -2
- package/dist/template-resolver/api.js +42 -6
- package/dist/template-resolver/compile-document-body.d.ts +12 -0
- package/dist/template-resolver/compile-document-body.js +205 -0
- package/dist/template-resolver/constants.d.ts +13 -4
- package/dist/template-resolver/constants.js +32 -10
- package/dist/template-resolver/document-sanitizer.d.ts +32 -0
- package/dist/template-resolver/document-sanitizer.js +201 -0
- package/dist/template-resolver/document-schema.d.ts +21 -0
- package/dist/template-resolver/document-schema.js +316 -0
- package/dist/template-resolver/feature.d.ts +20 -0
- package/dist/template-resolver/feature.js +53 -6
- package/dist/template-resolver/handlers/bundle-import.d.ts +20 -0
- package/dist/template-resolver/handlers/bundle-import.js +147 -0
- package/dist/template-resolver/handlers/collection-set.write.d.ts +1 -1
- package/dist/template-resolver/handlers/collection-set.write.js +25 -2
- package/dist/template-resolver/handlers/copy-locale.write.d.ts +19 -0
- package/dist/template-resolver/handlers/copy-locale.write.js +134 -0
- package/dist/template-resolver/handlers/diff-to-system.query.d.ts +22 -0
- package/dist/template-resolver/handlers/diff-to-system.query.js +30 -0
- package/dist/template-resolver/handlers/discard-draft.write.d.ts +13 -0
- package/dist/template-resolver/handlers/discard-draft.write.js +37 -0
- package/dist/template-resolver/handlers/export-bundle.query.d.ts +35 -0
- package/dist/template-resolver/handlers/export-bundle.query.js +118 -0
- package/dist/template-resolver/handlers/find-by-id.query.d.ts +2 -0
- package/dist/template-resolver/handlers/find-by-id.query.js +9 -6
- package/dist/template-resolver/handlers/import-bundle-system.write.d.ts +39 -0
- package/dist/template-resolver/handlers/import-bundle-system.write.js +36 -0
- package/dist/template-resolver/handlers/import-bundle.write.d.ts +40 -0
- package/dist/template-resolver/handlers/import-bundle.write.js +19 -0
- package/dist/template-resolver/handlers/layout-source.query.d.ts +31 -0
- package/dist/template-resolver/handlers/layout-source.query.js +87 -0
- package/dist/template-resolver/handlers/list.query.d.ts +4 -1
- package/dist/template-resolver/handlers/list.query.js +9 -8
- package/dist/template-resolver/handlers/override-diff.d.ts +20 -0
- package/dist/template-resolver/handlers/override-diff.js +41 -0
- package/dist/template-resolver/handlers/overview.query.d.ts +65 -0
- package/dist/template-resolver/handlers/overview.query.js +205 -0
- package/dist/template-resolver/handlers/preview.query.d.ts +12 -0
- package/dist/template-resolver/handlers/preview.query.js +24 -0
- package/dist/template-resolver/handlers/reset-to-system.write.d.ts +8 -0
- package/dist/template-resolver/handlers/reset-to-system.write.js +50 -0
- package/dist/template-resolver/handlers/resource-link-pdf.write.d.ts +8 -0
- package/dist/template-resolver/handlers/resource-link-pdf.write.js +32 -0
- package/dist/template-resolver/handlers/resource-remove.write.d.ts +9 -0
- package/dist/template-resolver/handlers/resource-remove.write.js +44 -0
- package/dist/template-resolver/handlers/resource-shared.d.ts +9 -0
- package/dist/template-resolver/handlers/resource-shared.js +14 -0
- package/dist/template-resolver/handlers/resource-upload.write.d.ts +13 -0
- package/dist/template-resolver/handlers/resource-upload.write.js +98 -0
- package/dist/template-resolver/handlers/send-test.write.d.ts +13 -0
- package/dist/template-resolver/handlers/send-test.write.js +108 -0
- package/dist/template-resolver/handlers/set.write.d.ts +5 -2
- package/dist/template-resolver/handlers/set.write.js +25 -3
- package/dist/template-resolver/handlers/shared.d.ts +9 -5
- package/dist/template-resolver/handlers/shared.js +6 -2
- package/dist/template-resolver/handlers/template-gates.d.ts +36 -0
- package/dist/template-resolver/handlers/template-gates.js +142 -0
- package/dist/template-resolver/handlers/template-write.d.ts +45 -0
- package/dist/template-resolver/handlers/template-write.js +141 -0
- package/dist/template-resolver/handlers/tenant-overrides.query.d.ts +49 -0
- package/dist/template-resolver/handlers/tenant-overrides.query.js +112 -0
- package/dist/template-resolver/handlers/toggle-status.write.d.ts +27 -2
- package/dist/template-resolver/handlers/toggle-status.write.js +47 -15
- package/dist/template-resolver/handlers/upsert-system.write.d.ts +5 -8
- package/dist/template-resolver/handlers/upsert-system.write.js +14 -59
- package/dist/template-resolver/handlers/upsert-tenant.write.d.ts +5 -8
- package/dist/template-resolver/handlers/upsert-tenant.write.js +11 -62
- package/dist/template-resolver/handlers/usage.query.d.ts +17 -0
- package/dist/template-resolver/handlers/usage.query.js +24 -0
- package/dist/template-resolver/handlers/validate.query.d.ts +74 -0
- package/dist/template-resolver/handlers/validate.query.js +80 -0
- package/dist/template-resolver/index.d.ts +19 -1
- package/dist/template-resolver/index.js +17 -1
- package/dist/template-resolver/layout-appearance.d.ts +10 -0
- package/dist/template-resolver/layout-appearance.js +26 -0
- package/dist/template-resolver/layout-regions.d.ts +23 -0
- package/dist/template-resolver/layout-regions.js +125 -0
- package/dist/template-resolver/linked-resources.d.ts +17 -0
- package/dist/template-resolver/linked-resources.js +75 -0
- package/dist/template-resolver/pdf-constants.d.ts +7 -0
- package/dist/template-resolver/pdf-constants.js +8 -0
- package/dist/template-resolver/preview-display-html.d.ts +7 -0
- package/dist/template-resolver/preview-display-html.js +27 -0
- package/dist/template-resolver/print-document.d.ts +1 -0
- package/dist/template-resolver/print-document.js +55 -0
- package/dist/template-resolver/qualified-names.d.ts +34 -0
- package/dist/template-resolver/qualified-names.js +34 -0
- package/dist/template-resolver/record-mapping.d.ts +2 -0
- package/dist/template-resolver/record-mapping.js +21 -0
- package/dist/template-resolver/resource-image.d.ts +15 -0
- package/dist/template-resolver/resource-image.js +34 -0
- package/dist/template-resolver/seeding.d.ts +14 -1
- package/dist/template-resolver/seeding.js +125 -18
- package/dist/template-resolver/store-template-resource.d.ts +64 -0
- package/dist/template-resolver/store-template-resource.js +264 -0
- package/dist/template-resolver/table.d.ts +150 -8
- package/dist/template-resolver/table.js +20 -2
- package/dist/template-resolver/template-bundle.d.ts +36 -0
- package/dist/template-resolver/template-bundle.js +60 -0
- package/dist/template-resolver/template-diff.d.ts +7 -0
- package/dist/template-resolver/template-diff.js +68 -0
- package/dist/template-resolver/template-draft.d.ts +51 -0
- package/dist/template-resolver/template-draft.js +72 -0
- package/dist/template-resolver/template-meta.d.ts +85 -0
- package/dist/template-resolver/template-meta.js +145 -0
- package/dist/template-resolver/template-preview.d.ts +103 -0
- package/dist/template-resolver/template-preview.js +418 -0
- package/dist/template-resolver/template-resources.d.ts +19 -0
- package/dist/template-resolver/template-resources.js +73 -0
- package/dist/template-resolver/template-usage.d.ts +16 -0
- package/dist/template-resolver/template-usage.js +35 -0
- package/dist/template-resolver/template-validation.d.ts +22 -0
- package/dist/template-resolver/template-validation.js +173 -0
- package/dist/template-resolver/testing.js +5 -5
- package/dist/template-resolver/user-content-table.d.ts +14 -8
- package/dist/template-resolver/web/client-plugin.d.ts +1 -0
- package/dist/template-resolver/web/client-plugin.js +12 -7
- package/dist/template-resolver/web/document-editor-extensions.d.ts +18 -0
- package/dist/template-resolver/web/document-editor-extensions.js +145 -0
- package/dist/template-resolver/web/document-editor.d.ts +4 -0
- package/dist/template-resolver/web/document-editor.js +17 -0
- package/dist/template-resolver/web/document-tiptap-editor.d.ts +3 -0
- package/dist/template-resolver/web/document-tiptap-editor.js +492 -0
- package/dist/template-resolver/web/document-toolbar-blocks.d.ts +41 -0
- package/dist/template-resolver/web/document-toolbar-blocks.js +19 -0
- package/dist/template-resolver/web/editor-handle.d.ts +3 -0
- package/dist/template-resolver/web/editor-handle.js +24 -0
- package/dist/template-resolver/web/i18n.js +91 -0
- package/dist/template-resolver/web/index.d.ts +5 -0
- package/dist/template-resolver/web/index.js +5 -0
- package/dist/template-resolver/web/placeholder-line-editor-lazy.d.ts +4 -0
- package/dist/template-resolver/web/placeholder-line-editor-lazy.js +16 -0
- package/dist/template-resolver/web/placeholder-line-editor.d.ts +17 -0
- package/dist/template-resolver/web/placeholder-line-editor.js +94 -0
- package/dist/template-resolver/web/placeholder-text.d.ts +4 -0
- package/dist/template-resolver/web/placeholder-text.js +34 -0
- package/dist/template-resolver/web/use-stable-by-key.d.ts +1 -0
- package/dist/template-resolver/web/use-stable-by-key.js +13 -0
- package/dist/tenant/handlers/add-member.write.d.ts +1 -1
- package/dist/tenant/handlers/cancel-invitation.write.d.ts +1 -1
- package/dist/tenant/handlers/create.write.d.ts +1 -1
- package/dist/tenant/handlers/remove-member.write.d.ts +1 -1
- package/dist/tenant/handlers/team-list.query.js +3 -2
- package/dist/tenant/handlers/toggle-enabled.write.d.ts +2 -2
- package/dist/tenant/handlers/update-member-roles.write.d.ts +1 -1
- package/dist/tenant/handlers/update.write.d.ts +1 -1
- package/dist/tenant/seeding.js +31 -6
- package/dist/tenant-handover/handlers/claim.write.d.ts +1 -1
- package/dist/tenant-lifecycle/handlers/cancel-destruction.write.d.ts +2 -2
- package/dist/tenant-lifecycle/handlers/cancel-destruction.write.js +2 -1
- package/dist/tenant-lifecycle/handlers/request-destruction.write.d.ts +1 -1
- package/dist/tier-engine/feature.js +9 -3
- package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +1 -1
- package/dist/user/db/queries/stream-tenant-backfill.js +4 -4
- package/dist/user/handlers/create.write.d.ts +1 -1
- package/dist/user/handlers/detail.query.js +2 -1
- package/dist/user/handlers/update.write.d.ts +1 -1
- package/dist/user/resolve-display-names.js +5 -9
- package/dist/user/seeding.js +20 -1
- package/dist/user-data-rights/db/queries/forget-cleanup.d.ts +2 -2
- package/dist/user-data-rights/email-templates.d.ts +1 -29
- package/dist/user-data-rights/email-templates.js +5 -106
- package/dist/user-data-rights/feature.js +53 -35
- package/dist/user-data-rights/handlers/cancel-deletion.write.d.ts +2 -2
- package/dist/user-data-rights/handlers/cancel-deletion.write.js +2 -1
- package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/lift-restriction.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/request-deletion.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/request-deletion.write.js +5 -7
- package/dist/user-data-rights/handlers/request-export.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/restrict-account.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/run-forget-cleanup.write.d.ts +1 -1
- package/dist/user-data-rights/lib/default-mailers.d.ts +15 -7
- package/dist/user-data-rights/lib/default-mailers.js +100 -48
- package/dist/user-data-rights/lib/update-user-lifecycle.js +1 -1
- package/dist/user-data-rights/mail-notifications.d.ts +13 -0
- package/dist/user-data-rights/mail-notifications.js +118 -0
- package/dist/user-data-rights/web/privacy-center-screen.js +2 -1
- package/dist/user-profile/handlers/change-email.write.d.ts +1 -1
- package/dist/user-profile/web/profile-screen.js +2 -1
- package/dist/waitlist/feature.js +10 -0
- package/dist/waitlist/handlers/invite.write.d.ts +1 -1
- package/dist/waitlist/handlers/reject.write.d.ts +1 -1
- package/dist/waitlist/handlers/submit.write.d.ts +1 -1
- package/dist/waitlist/handlers/submit.write.js +3 -4
- package/dist/waitlist/mail.d.ts +19 -6
- package/dist/waitlist/mail.js +50 -14
- package/dist/waitlist/options.js +1 -1
- package/dist/workflow-runner/event-trigger.js +2 -2
- package/dist/workflow-runner/handlers/resume-run.write.js +7 -2
- package/package.json +37 -17
- package/src/admin-shell/changes.json +6 -0
- package/src/audit/changes.json +6 -0
- package/src/auth-email-password/changes.json +51 -0
- package/src/billing-foundation/changes.json +43 -0
- package/src/cap-counter/changes.json +6 -0
- package/src/channel-email/changes.json +19 -0
- package/src/config/changes.json +6 -0
- package/src/crypto-shredding/changes.json +6 -0
- package/src/custom-fields/changes.json +6 -0
- package/src/data-retention/changes.json +6 -0
- package/src/delivery/changes.json +66 -0
- package/src/file-foundation/changes.json +6 -0
- package/src/files-tenant-data/changes.json +6 -0
- package/src/inbound-mail-foundation/changes.json +6 -0
- package/src/jobs/changes.json +19 -0
- package/src/ledger/changes.json +7 -0
- package/src/managed-pages/changes.json +6 -0
- package/src/renderer-foundation/changes.json +39 -0
- package/src/renderer-pdf/changes.json +12 -0
- package/src/secrets/changes.json +6 -0
- package/src/shared/changes.json +6 -0
- package/src/subscription-stripe/changes.json +6 -0
- package/src/template-resolver/changes.json +186 -0
- package/src/tier-engine/changes.json +6 -0
- package/src/user/changes.json +6 -0
- package/src/user-data-rights/changes.json +13 -0
- package/src/user-profile/changes.json +1 -1
- package/src/waitlist/changes.json +7 -0
- package/src/workflow-runner/changes.json +6 -0
- package/dist/renderer-simple/feature.d.ts +0 -10
- package/dist/renderer-simple/feature.js +0 -42
- package/dist/renderer-simple/index.d.ts +0 -3
- package/dist/renderer-simple/index.js +0 -2
- package/dist/renderer-simple/mail-blocks.d.ts +0 -21
- package/dist/renderer-simple/mail-blocks.js +0 -107
- package/dist/renderer-simple/resolve-variables.d.ts +0 -7
- package/dist/renderer-simple/resolve-variables.js +0 -47
- package/dist/renderer-simple/simple-renderer.d.ts +0 -24
- package/dist/renderer-simple/simple-renderer.js +0 -200
- package/src/renderer-simple/changes.json +0 -27
|
@@ -6,12 +6,103 @@
|
|
|
6
6
|
// Keys follow `template-resolver.editor.<slug>`.
|
|
7
7
|
export const defaultTranslations = {
|
|
8
8
|
en: {
|
|
9
|
+
"template-resolver.documentEditor.button": "Button",
|
|
10
|
+
"template-resolver.documentEditor.buttonDefaultText": "Confirm",
|
|
11
|
+
"template-resolver.documentEditor.buttonTarget": "Button target",
|
|
12
|
+
"template-resolver.documentEditor.buttonText": "Button text",
|
|
13
|
+
"template-resolver.documentEditor.cancel": "Cancel",
|
|
14
|
+
"template-resolver.documentEditor.divider": "Divider",
|
|
15
|
+
"template-resolver.documentEditor.heading3": "Heading 3",
|
|
16
|
+
"template-resolver.documentEditor.image": "Image",
|
|
17
|
+
"template-resolver.documentEditor.imageBlock": "Image · inline",
|
|
18
|
+
"template-resolver.documentEditor.imageAlt": "Alt text (optional)",
|
|
19
|
+
"template-resolver.documentEditor.insert": "Insert",
|
|
20
|
+
"template-resolver.documentEditor.insertPlaceholder": "Placeholder",
|
|
21
|
+
"template-resolver.documentEditor.invalidImageAlt": "The alt text must not contain < or >.",
|
|
22
|
+
"template-resolver.documentEditor.invalidLink": "This link target is not allowed. Use https, http, mailto, tel or a placeholder.",
|
|
23
|
+
"template-resolver.documentEditor.invalidResourceKey": "This resource key is not valid.",
|
|
24
|
+
"template-resolver.documentEditor.link": "Link",
|
|
25
|
+
"template-resolver.documentEditor.linkHref": "Link target",
|
|
26
|
+
"template-resolver.documentEditor.linkHrefPlaceholder": "https://",
|
|
27
|
+
"template-resolver.documentEditor.noVariables": "No matching variables are available here.",
|
|
28
|
+
"template-resolver.documentEditor.pageBreak": "Page break",
|
|
29
|
+
"template-resolver.documentEditor.align": "Align",
|
|
30
|
+
"template-resolver.documentEditor.alignLeft": "Left",
|
|
31
|
+
"template-resolver.documentEditor.alignCenter": "Centered",
|
|
32
|
+
"template-resolver.documentEditor.alignRight": "Right",
|
|
33
|
+
"template-resolver.documentEditor.alignJustify": "Justified",
|
|
34
|
+
"template-resolver.documentEditor.repeatBarList": "Repeat · {list}",
|
|
35
|
+
"template-resolver.documentEditor.repeatHeader": "Repeat header row",
|
|
36
|
+
"template-resolver.documentEditor.paragraph": "Paragraph",
|
|
37
|
+
"template-resolver.documentEditor.paragraphStyle": "Paragraph style",
|
|
38
|
+
"template-resolver.documentEditor.placeholder": "Write your text…",
|
|
39
|
+
"template-resolver.documentEditor.removeLink": "Remove link",
|
|
40
|
+
"template-resolver.documentEditor.repeat": "Repeat",
|
|
41
|
+
"template-resolver.documentEditor.repeatList": "List to repeat",
|
|
42
|
+
"template-resolver.documentEditor.resourceKey": "Resource key",
|
|
43
|
+
"template-resolver.documentEditor.table": "Table",
|
|
9
44
|
"template-resolver.editor.titleLabel": "Title",
|
|
10
45
|
"template-resolver.editor.contentLabel": "Content",
|
|
11
46
|
"template-resolver.editor.save": "Save",
|
|
12
47
|
"template-resolver.editor.saving": "Saving…",
|
|
13
48
|
"template-resolver.editor.created": "Created.",
|
|
14
49
|
"template-resolver.editor.saved": "Saved.",
|
|
50
|
+
"templateResolver.errors.document.buttonHrefNotPlaceholder": "The button target “{detail}” must be a placeholder.",
|
|
51
|
+
"templateResolver.errors.document.disallowedLinkHref": "Link target “{detail}” is not allowed; use https, http, mailto, tel or a placeholder.",
|
|
52
|
+
"templateResolver.errors.document.documentRequiresHtmlFormat": "This template kind requires the html format, got “{detail}”.",
|
|
53
|
+
"templateResolver.errors.document.layoutRequiresMjmlFormat": "Mail layouts require the mjml format, got “{detail}”.",
|
|
54
|
+
"templateResolver.errors.document.layoutInvalidStructure": "The layout may only contain the header, content, signature and footer regions: {detail}.",
|
|
55
|
+
"templateResolver.errors.document.layoutMissingContentSlot": "The layout needs its content slot: {detail}.",
|
|
56
|
+
"templateResolver.errors.document.layoutSourceSystemOnly": "Only system layouts may use {detail} source; use the structured html layout.",
|
|
57
|
+
"templateResolver.errors.template.targetExists": "A template for locale “{detail}” already exists; overwrite it explicitly to replace it.",
|
|
58
|
+
"templateResolver.warnings.resourceNotUploaded": "Image not uploaded: {detail}",
|
|
59
|
+
"templateResolver.checks.resourcesResolved": "All images are available",
|
|
60
|
+
"templateResolver.checks.textPresent": "A plain-text version is present",
|
|
61
|
+
"templateResolver.checks.sizeUnderCap": "The mail is within the 10 MiB size limit",
|
|
62
|
+
"templateResolver.checks.requiredPlaceholders": "All required placeholders are used",
|
|
63
|
+
"templateResolver.errors.preview.renderFailed": "The preview could not be rendered.",
|
|
64
|
+
"templateResolver.errors.testMail.noChannel": "No email channel is set up, so no test mail can be sent.",
|
|
65
|
+
"templateResolver.errors.testMail.noAddress": "Your account has no email address to send the test mail to.",
|
|
66
|
+
"templateResolver.errors.testMail.failed": "The test mail could not be sent.",
|
|
67
|
+
"templateResolver.errors.resource.tooLarge": "The image is too large.",
|
|
68
|
+
"templateResolver.errors.resource.unsupportedImage": "This file is not a supported image. Use PNG, JPEG, WebP or GIF.",
|
|
69
|
+
"templateResolver.errors.template.systemResourcesNeedSystemTenant": "Resource files of system templates can only be imported or exported by a user of the system tenant.",
|
|
70
|
+
"templateResolver.errors.template.bundleLocalesDiffer": "The locales of this template differ in content format or variables, so they cannot be exported as one bundle.",
|
|
71
|
+
"templateResolver.errors.collection.kindNotAllowed": "“{detail}” templates are written through their own editor, not through a collection.",
|
|
72
|
+
"templateResolver.errors.noSystemTemplate": "There is no active system template to reset to.",
|
|
73
|
+
"templateResolver.errors.noDraft": "There is no draft to discard.",
|
|
74
|
+
"templateResolver.errors.template.invalidMeta": "The template settings are invalid.",
|
|
75
|
+
"templateResolver.errors.template.meta.subject.required": "The subject is missing.",
|
|
76
|
+
"templateResolver.errors.template.meta.subject.invalid": "The subject is invalid (at most 200 characters, no line breaks).",
|
|
77
|
+
"templateResolver.errors.template.meta.previewText.required": "The preview text is missing.",
|
|
78
|
+
"templateResolver.errors.template.meta.previewText.invalid": "The preview text is invalid (at most 200 characters, no line breaks).",
|
|
79
|
+
"templateResolver.errors.template.meta.senderName.required": "The sender name is missing.",
|
|
80
|
+
"templateResolver.errors.template.meta.senderName.invalid": "The sender name is invalid (at most 80 characters, no line breaks).",
|
|
81
|
+
"templateResolver.errors.template.meta.replyTo.required": "The reply-to address is missing.",
|
|
82
|
+
"templateResolver.errors.template.meta.replyTo.invalid": "The reply-to address is not a valid email address.",
|
|
83
|
+
"templateResolver.errors.template.meta.layoutSlug.required": "The layout is missing.",
|
|
84
|
+
"templateResolver.errors.template.meta.layoutSlug.invalid": "The chosen layout is invalid.",
|
|
85
|
+
"templateResolver.errors.template.meta.fileName.required": "The file name is missing.",
|
|
86
|
+
"templateResolver.errors.template.meta.fileName.invalid": "The file name is invalid: no slashes, quotes, semicolons or two dots in a row.",
|
|
87
|
+
"templateResolver.errors.template.unknownPlaceholders": "Unknown placeholders: {detail}",
|
|
88
|
+
"templateResolver.errors.template.missingRequiredPlaceholders": "Required placeholders are not used: {detail}",
|
|
89
|
+
"templateResolver.errors.document.embeddedContent": "<{detail}> elements are not allowed in template bodies.",
|
|
90
|
+
"templateResolver.errors.document.unsafeAttributeValue": "The attribute value “{detail}” must not contain < or >.",
|
|
91
|
+
"templateResolver.errors.document.eventHandlerAttribute": "Inline event handler “{detail}” is not allowed.",
|
|
92
|
+
"templateResolver.errors.document.externalImageSource": "Images must reference an uploaded resource; image source “{detail}” is not allowed.",
|
|
93
|
+
"templateResolver.errors.document.imageWithoutResource": "Images must reference an uploaded resource.",
|
|
94
|
+
"templateResolver.errors.document.invalidReferenceName": "“{detail}” is not a valid name.",
|
|
95
|
+
"templateResolver.errors.document.scriptElement": "<script> elements are not allowed in template bodies.",
|
|
96
|
+
"templateResolver.errors.attachment.unsupportedType": "Attachments must be a PDF, PNG or JPEG file.",
|
|
97
|
+
"templateResolver.errors.attachment.limit": "A template can have at most {max} attachments.",
|
|
98
|
+
"templateResolver.errors.attachment.invalid": "The attachment needs a template, a key and a valid file name.",
|
|
99
|
+
"templateResolver.errors.attachment.pdfTemplateMissing": "There is no PDF template “{slug}” for this tenant or the system.",
|
|
100
|
+
"template-resolver.documentEditor.htmlSource": "HTML source",
|
|
101
|
+
"template-resolver.documentEditor.removeBlock": "Remove block",
|
|
102
|
+
"template-resolver.documentEditor.list": "List",
|
|
103
|
+
"template-resolver.documentEditor.more": "More",
|
|
104
|
+
"template-resolver.documentEditor.showHtml": "HTML",
|
|
105
|
+
"template-resolver.documentEditor.underline": "Underline",
|
|
15
106
|
"template-resolver.editor.saveFailed": "Save failed.",
|
|
16
107
|
"template-resolver.editor.networkError": "Network error while saving.",
|
|
17
108
|
"template-resolver.editor.loading": "Loading current version…",
|
|
@@ -1 +1,6 @@
|
|
|
1
|
+
export { PDF_DEFAULT_MARGIN_MM, PDF_FOOTER_MARGIN_MM, PDF_HEADER_MARGIN_MM, PDF_ORIENTATIONS, PDF_PAGE_FORMATS, } from "../pdf-constants.js";
|
|
2
|
+
export { TemplateResolverErrors, TemplateResolverHandlers, TemplateResolverQueries, } from "../qualified-names.js";
|
|
1
3
|
export { textBlocksClient } from "./client-plugin.js";
|
|
4
|
+
export { DocumentContentEditor } from "./document-editor.js";
|
|
5
|
+
export { type DocumentEditorChrome, type DocumentEditorHandle, type DocumentEditorProps, type DocumentResourcePreview, type DocumentToolbarBlock, MAIL_DOCUMENT_BLOCKS, PDF_DOCUMENT_BLOCKS, } from "./document-toolbar-blocks.js";
|
|
6
|
+
export { PlaceholderLineEditor, type PlaceholderLineEditorProps, } from "./placeholder-line-editor-lazy.js";
|
|
@@ -4,4 +4,9 @@
|
|
|
4
4
|
// — the server side (defineFeature) lives in
|
|
5
5
|
// `@cosmicdrift/kumiko-bundled-features/template-resolver` and has no React or
|
|
6
6
|
// DOM deps.
|
|
7
|
+
export { PDF_DEFAULT_MARGIN_MM, PDF_FOOTER_MARGIN_MM, PDF_HEADER_MARGIN_MM, PDF_ORIENTATIONS, PDF_PAGE_FORMATS, } from "../pdf-constants.js";
|
|
8
|
+
export { TemplateResolverErrors, TemplateResolverHandlers, TemplateResolverQueries, } from "../qualified-names.js";
|
|
7
9
|
export { textBlocksClient } from "./client-plugin.js";
|
|
10
|
+
export { DocumentContentEditor } from "./document-editor.js";
|
|
11
|
+
export { MAIL_DOCUMENT_BLOCKS, PDF_DOCUMENT_BLOCKS, } from "./document-toolbar-blocks.js";
|
|
12
|
+
export { PlaceholderLineEditor, } from "./placeholder-line-editor-lazy.js";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { PlaceholderLineEditorProps } from "./placeholder-line-editor.js";
|
|
3
|
+
export type { PlaceholderLineEditorProps } from "./placeholder-line-editor.js";
|
|
4
|
+
export declare function PlaceholderLineEditor(props: PlaceholderLineEditorProps): ReactNode;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @runtime client
|
|
3
|
+
//
|
|
4
|
+
// Lazy boundary for the placeholder line editor: tiptap loads with the chunk,
|
|
5
|
+
// the fallback is a plain text input holding the same `{{name}}` text.
|
|
6
|
+
// Never import placeholder-line-editor statically here.
|
|
7
|
+
import { usePrimitives } from "@cosmicdrift/kumiko-renderer";
|
|
8
|
+
import { lazy, Suspense } from "react";
|
|
9
|
+
const LazyPlaceholderLineEditor = lazy(() => import("./placeholder-line-editor.js"));
|
|
10
|
+
function PlainLineFallback({ id, value, onChange, readOnly = false, "aria-label": ariaLabel, }) {
|
|
11
|
+
const { Field, Input } = usePrimitives();
|
|
12
|
+
return (_jsx(Field, { id: id, label: ariaLabel, hideLabel: true, children: _jsx(Input, { kind: "text", id: id, name: id, value: value, onChange: onChange, disabled: readOnly }) }));
|
|
13
|
+
}
|
|
14
|
+
export function PlaceholderLineEditor(props) {
|
|
15
|
+
return (_jsx(Suspense, { fallback: _jsx(PlainLineFallback, { ...props }), children: _jsx(LazyPlaceholderLineEditor, { ...props }) }));
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { DocumentEditorHandle } from "./document-toolbar-blocks.js";
|
|
3
|
+
export type PlaceholderLineEditorProps = {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
/** Plain text with `{{name}}` placeholders. */
|
|
6
|
+
readonly value: string;
|
|
7
|
+
readonly onChange: (value: string) => void;
|
|
8
|
+
readonly variableLabels?: Readonly<Record<string, string>>;
|
|
9
|
+
/** Placeholders shown as system chips (a different tint). */
|
|
10
|
+
readonly systemVariables?: readonly string[];
|
|
11
|
+
readonly readOnly?: boolean;
|
|
12
|
+
/** Drops the input frame so the line sits flat inside a label/value row. */
|
|
13
|
+
readonly flat?: boolean;
|
|
14
|
+
readonly onEditorReady?: (handle: DocumentEditorHandle) => void;
|
|
15
|
+
readonly "aria-label": string;
|
|
16
|
+
};
|
|
17
|
+
export default function PlaceholderLineEditor({ id, value, onChange, variableLabels, systemVariables, readOnly, flat, onEditorReady, "aria-label": ariaLabel, }: PlaceholderLineEditorProps): ReactNode;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @runtime client
|
|
3
|
+
//
|
|
4
|
+
// Single-line editor for plain-text fields that carry {{placeholders}}
|
|
5
|
+
// (subject, preheader). The stored value stays plain text; placeholders show
|
|
6
|
+
// as chips while editing. Lives in the same lazy chunk as the document editor.
|
|
7
|
+
import { cn } from "@cosmicdrift/kumiko-renderer-web";
|
|
8
|
+
import { Extension, Node } from "@tiptap/core";
|
|
9
|
+
import { UndoRedo } from "@tiptap/extensions";
|
|
10
|
+
import { EditorContent, useEditor } from "@tiptap/react";
|
|
11
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
12
|
+
import { useMemo, useState } from "react";
|
|
13
|
+
import { DocumentVariable } from "../document-schema.js";
|
|
14
|
+
import { createVariableView } from "./document-editor-extensions.js";
|
|
15
|
+
import { createEditorHandle } from "./editor-handle.js";
|
|
16
|
+
import { contentToLine, lineToContent, singleLine } from "./placeholder-text.js";
|
|
17
|
+
import { useStableByKey } from "./use-stable-by-key.js";
|
|
18
|
+
const LineDocument = Node.create({ name: "doc", topNode: true, content: "paragraph" });
|
|
19
|
+
// One line only: Enter must not split the paragraph.
|
|
20
|
+
const BlockLineBreaks = Extension.create({
|
|
21
|
+
name: "blockLineBreaks",
|
|
22
|
+
addKeyboardShortcuts() {
|
|
23
|
+
return { Enter: () => true, "Shift-Enter": () => true, "Mod-Enter": () => true };
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
const NO_LABELS = {};
|
|
27
|
+
const NO_NAMES = [];
|
|
28
|
+
function LineEditorBody({ id, initialValue, onChange, variableLabels, systemVariables, readOnly, flat, onEditorReady, ariaLabel, }) {
|
|
29
|
+
const extensions = useMemo(() => [
|
|
30
|
+
LineDocument,
|
|
31
|
+
StarterKit.configure({
|
|
32
|
+
document: false,
|
|
33
|
+
blockquote: false,
|
|
34
|
+
bold: false,
|
|
35
|
+
bulletList: false,
|
|
36
|
+
code: false,
|
|
37
|
+
codeBlock: false,
|
|
38
|
+
dropcursor: false,
|
|
39
|
+
gapcursor: false,
|
|
40
|
+
hardBreak: false,
|
|
41
|
+
heading: false,
|
|
42
|
+
horizontalRule: false,
|
|
43
|
+
italic: false,
|
|
44
|
+
link: false,
|
|
45
|
+
listItem: false,
|
|
46
|
+
listKeymap: false,
|
|
47
|
+
orderedList: false,
|
|
48
|
+
strike: false,
|
|
49
|
+
trailingNode: false,
|
|
50
|
+
underline: false,
|
|
51
|
+
undoRedo: false,
|
|
52
|
+
}),
|
|
53
|
+
DocumentVariable.extend({
|
|
54
|
+
addNodeView: () => createVariableView(variableLabels, systemVariables, flat),
|
|
55
|
+
}),
|
|
56
|
+
UndoRedo,
|
|
57
|
+
BlockLineBreaks,
|
|
58
|
+
], [variableLabels, systemVariables, flat]);
|
|
59
|
+
const editor = useEditor({
|
|
60
|
+
extensions,
|
|
61
|
+
content: {
|
|
62
|
+
type: "doc",
|
|
63
|
+
content: [{ type: "paragraph", content: lineToContent(initialValue) }],
|
|
64
|
+
},
|
|
65
|
+
editable: !readOnly,
|
|
66
|
+
immediatelyRender: false,
|
|
67
|
+
editorProps: {
|
|
68
|
+
attributes: { id, role: "textbox", "aria-label": ariaLabel, "aria-multiline": "false" },
|
|
69
|
+
transformPastedText: singleLine,
|
|
70
|
+
// Rich pastes would bring several paragraphs; only their text is kept.
|
|
71
|
+
transformPastedHTML: (html) => singleLine(html.replace(/<[^>]*>/g, " ")),
|
|
72
|
+
},
|
|
73
|
+
onCreate: ({ editor: created }) => onEditorReady?.(createEditorHandle(created)),
|
|
74
|
+
onUpdate: ({ editor: e }) => onChange(contentToLine(e.getJSON().content?.[0]?.content)),
|
|
75
|
+
});
|
|
76
|
+
return (_jsx(EditorContent, { editor: editor, className: cn("flex items-center bg-transparent text-base md:text-sm", flat ? "min-h-10" : "min-h-9 rounded-md border border-input px-3", "[&_.ProseMirror]:w-full [&_.ProseMirror]:whitespace-nowrap [&_.ProseMirror]:outline-none", "[&_p]:m-0", readOnly && "opacity-60") }));
|
|
77
|
+
}
|
|
78
|
+
export default function PlaceholderLineEditor({ id, value, onChange, variableLabels = NO_LABELS, systemVariables = NO_NAMES, readOnly = false, flat = false, onEditorReady, "aria-label": ariaLabel, }) {
|
|
79
|
+
const stableLabels = useStableByKey(variableLabels, JSON.stringify(variableLabels));
|
|
80
|
+
const stableSystem = useStableByKey(systemVariables, systemVariables.join("\n"));
|
|
81
|
+
// The text is the source of truth. Typing reports it through onChange and
|
|
82
|
+
// keeps `emitted` equal to `value`; any other value (async load, reset)
|
|
83
|
+
// remounts the editor body on the new text.
|
|
84
|
+
const [emitted, setEmitted] = useState(value);
|
|
85
|
+
const [epoch, setEpoch] = useState(0);
|
|
86
|
+
if (value !== emitted) {
|
|
87
|
+
setEmitted(value);
|
|
88
|
+
setEpoch((current) => current + 1);
|
|
89
|
+
}
|
|
90
|
+
return (_jsx(LineEditorBody, { id: id, initialValue: value, onChange: (next) => {
|
|
91
|
+
setEmitted(next);
|
|
92
|
+
onChange(next);
|
|
93
|
+
}, variableLabels: stableLabels, systemVariables: stableSystem, readOnly: readOnly, flat: flat, onEditorReady: onEditorReady, ariaLabel: ariaLabel }, `${epoch}-${readOnly}-${JSON.stringify(stableLabels)}`));
|
|
94
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isDocumentReferenceName } from "../document-schema.js";
|
|
2
|
+
const PLACEHOLDER_TOKEN = /\{\{([^{}]*)\}\}/g;
|
|
3
|
+
// Names the schema refuses stay plain text, so a typo never becomes a chip
|
|
4
|
+
// that the server would reject.
|
|
5
|
+
export function lineToContent(text) {
|
|
6
|
+
const content = [];
|
|
7
|
+
let cursor = 0;
|
|
8
|
+
const pushText = (value) => {
|
|
9
|
+
if (value !== "")
|
|
10
|
+
content.push({ type: "text", text: value });
|
|
11
|
+
};
|
|
12
|
+
for (const match of text.matchAll(PLACEHOLDER_TOKEN)) {
|
|
13
|
+
const name = match[1] ?? "";
|
|
14
|
+
if (!isDocumentReferenceName(name))
|
|
15
|
+
continue;
|
|
16
|
+
pushText(text.slice(cursor, match.index));
|
|
17
|
+
content.push({ type: "variable", attrs: { name } });
|
|
18
|
+
cursor = match.index + match[0].length;
|
|
19
|
+
}
|
|
20
|
+
pushText(text.slice(cursor));
|
|
21
|
+
return content;
|
|
22
|
+
}
|
|
23
|
+
export function contentToLine(nodes) {
|
|
24
|
+
return (nodes ?? [])
|
|
25
|
+
.map((node) => {
|
|
26
|
+
if (node.type === "variable")
|
|
27
|
+
return `{{${String(node.attrs?.["name"])}}}`;
|
|
28
|
+
return node.type === "text" ? (node.text ?? "") : "";
|
|
29
|
+
})
|
|
30
|
+
.join("");
|
|
31
|
+
}
|
|
32
|
+
export function singleLine(text) {
|
|
33
|
+
return text.replace(/\s*[\r\n]+\s*/g, " ");
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useStableByKey<T>(value: T, key: string): T;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @runtime client
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
// Callers often pass fresh object literals every render; this keeps the first
|
|
4
|
+
// value for as long as the content key is unchanged, so memoized extension
|
|
5
|
+
// lists (and the editor built from them) are not rebuilt on every render.
|
|
6
|
+
export function useStableByKey(value, key) {
|
|
7
|
+
const [stored, setStored] = useState({ key, value });
|
|
8
|
+
if (stored.key !== key) {
|
|
9
|
+
setStored({ key, value });
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
return stored.value;
|
|
13
|
+
}
|
|
@@ -3,4 +3,4 @@ export declare const addMemberWrite: import("@cosmicdrift/kumiko-types/define-ha
|
|
|
3
3
|
userId: z.ZodString;
|
|
4
4
|
tenantId: z.ZodString;
|
|
5
5
|
roles: z.ZodArray<z.ZodString>;
|
|
6
|
-
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
6
|
+
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -4,4 +4,4 @@ export declare const cancelInvitationWrite: import("@cosmicdrift/kumiko-types/de
|
|
|
4
4
|
}, z.core.$strip>, {
|
|
5
5
|
id: string;
|
|
6
6
|
alreadyDone: boolean;
|
|
7
|
-
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
7
|
+
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -3,4 +3,4 @@ export declare const createWrite: import("@cosmicdrift/kumiko-types/define-handl
|
|
|
3
3
|
id: z.ZodOptional<z.ZodUUID>;
|
|
4
4
|
key: z.ZodString;
|
|
5
5
|
name: z.ZodString;
|
|
6
|
-
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
6
|
+
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -5,4 +5,4 @@ export declare const removeMemberWrite: import("@cosmicdrift/kumiko-types/define
|
|
|
5
5
|
}, z.core.$strip>, {
|
|
6
6
|
userId: string;
|
|
7
7
|
tenantId: string;
|
|
8
|
-
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
8
|
+
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -3,6 +3,7 @@ import { access, definePagedQueryHandler, MAX_LIST_LIMIT, } from "@cosmicdrift/k
|
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
5
5
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
6
|
+
import { errorCodeOf, isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
6
7
|
import * as z from "zod";
|
|
7
8
|
import { userSessionTable } from "../../sessions/index.js";
|
|
8
9
|
import { decryptStoredPii, mapWithConcurrency } from "../../shared/index.js";
|
|
@@ -15,7 +16,7 @@ const KMS_POOL_CONCURRENCY = 4;
|
|
|
15
16
|
// the wire already names a TeamRow field directly.
|
|
16
17
|
const SORT_FIELDS = ["email", "status", "createdAt", "lastSeenAt"];
|
|
17
18
|
function isSortField(value) {
|
|
18
|
-
return SORT_FIELDS
|
|
19
|
+
return isOneOf(SORT_FIELDS, value);
|
|
19
20
|
}
|
|
20
21
|
// Nulls (no session yet, invitation rows) sort last regardless of
|
|
21
22
|
// direction — "unknown" reads as "least recent", not as a magic minimum
|
|
@@ -109,7 +110,7 @@ export const teamListQuery = definePagedQueryHandler({
|
|
|
109
110
|
// ponytail: lean sample apps (admin-console) mount auth without
|
|
110
111
|
// sessions — store_user_sessions never gets pushed. Integration tests
|
|
111
112
|
// may seed the table without mounting the feature; prod mounts both.
|
|
112
|
-
if (err
|
|
113
|
+
if (errorCodeOf(err) !== "42P01")
|
|
113
114
|
throw err;
|
|
114
115
|
}
|
|
115
116
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
2
|
export declare const enableWrite: import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"disable" | "enable", z.ZodObject<{
|
|
3
3
|
id: z.ZodUUID;
|
|
4
|
-
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
4
|
+
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
5
5
|
export declare const disableWrite: import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"disable" | "enable", z.ZodObject<{
|
|
6
6
|
id: z.ZodUUID;
|
|
7
|
-
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
7
|
+
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -7,4 +7,4 @@ export declare const updateMemberRolesWrite: import("@cosmicdrift/kumiko-types/d
|
|
|
7
7
|
userId: string;
|
|
8
8
|
roles: readonly string[];
|
|
9
9
|
tenantId: string;
|
|
10
|
-
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
10
|
+
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -5,4 +5,4 @@ export declare const updateWrite: import("@cosmicdrift/kumiko-types/define-handl
|
|
|
5
5
|
changes: z.ZodObject<{
|
|
6
6
|
name: z.ZodOptional<z.ZodString>;
|
|
7
7
|
}, z.core.$strip>;
|
|
8
|
-
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
8
|
+
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
package/dist/tenant/seeding.js
CHANGED
|
@@ -31,7 +31,7 @@ import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
|
31
31
|
import { createEventStoreExecutor, createTenantDb, } from "@cosmicdrift/kumiko-framework/db";
|
|
32
32
|
import { createSystemUser, HookPhases, } from "@cosmicdrift/kumiko-framework/engine";
|
|
33
33
|
import { getUnscopedAggregateStreamMaxVersion } from "@cosmicdrift/kumiko-framework/event-store";
|
|
34
|
-
import { createLifecycleHooks } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
34
|
+
import { createDeferringNotify, createLifecycleHooks, } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
35
35
|
import { TestUsers } from "@cosmicdrift/kumiko-framework/stack";
|
|
36
36
|
import { assertAssignableMembershipRoles } from "./membership-roles.js";
|
|
37
37
|
import { tenantMembershipEntity, tenantMembershipsTable } from "./membership-table.js";
|
|
@@ -62,9 +62,31 @@ const executor = createEventStoreExecutor(tenantMembershipsTable, tenantMembersh
|
|
|
62
62
|
// dispatcher's sink and flush post-commit. Without a sink (fixture / plain
|
|
63
63
|
// Connection) they still fire immediately — there is no outer TX to wait for.
|
|
64
64
|
//
|
|
65
|
+
function buildSeedHookNotify(context, scopedUser, targetTenantId, notifyTiming) {
|
|
66
|
+
const notifyFactory = context._notifyFactory;
|
|
67
|
+
if (!notifyFactory)
|
|
68
|
+
return context.notify;
|
|
69
|
+
if (notifyTiming === "inline")
|
|
70
|
+
return notifyFactory(scopedUser, targetTenantId);
|
|
71
|
+
// Still inside the caller's write tx: delivery DB work must not wait for an app-pool slot.
|
|
72
|
+
const notifyInsideTransaction = (context._notifyInTransactionFactory ?? notifyFactory)(scopedUser, targetTenantId);
|
|
73
|
+
const scheduleAfterCommit = context.scheduleAfterCommit;
|
|
74
|
+
if (!scheduleAfterCommit)
|
|
75
|
+
return notifyInsideTransaction;
|
|
76
|
+
return createDeferringNotify({
|
|
77
|
+
registry: context.registry,
|
|
78
|
+
tenantId: targetTenantId,
|
|
79
|
+
notifyAfterCommit: notifyFactory(scopedUser, targetTenantId),
|
|
80
|
+
notifyNow: notifyInsideTransaction,
|
|
81
|
+
scheduleAfterCommit,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
65
84
|
// `runner` comes from the caller, which already holds a declared DbRunner —
|
|
66
85
|
// a TenantDb exposes no runner back out to feature code.
|
|
67
|
-
function scopeSeedHookContext(context, targetTenantId, runner
|
|
86
|
+
function scopeSeedHookContext(context, targetTenantId, runner,
|
|
87
|
+
// The afterCommit sink is snapshotted when it flushes, so a hook scheduled from inside an
|
|
88
|
+
// afterCommit-phase hook would be dropped: that phase must notify inline.
|
|
89
|
+
notifyTiming) {
|
|
68
90
|
const db = createTenantDb(runner, targetTenantId, "system", context.tracer, context.meter, context.signal);
|
|
69
91
|
// HandlerContext carries `user`; AppContext only `systemUser`. Prefer the
|
|
70
92
|
// live handler user when present so notify/hasFeature keep a real SessionUser.
|
|
@@ -73,8 +95,8 @@ function scopeSeedHookContext(context, targetTenantId, runner) {
|
|
|
73
95
|
const scopedUser = baseUser
|
|
74
96
|
? { ...baseUser, tenantId: targetTenantId }
|
|
75
97
|
: undefined;
|
|
76
|
-
const notify =
|
|
77
|
-
? context
|
|
98
|
+
const notify = scopedUser
|
|
99
|
+
? buildSeedHookNotify(context, scopedUser, targetTenantId, notifyTiming)
|
|
78
100
|
: context.notify;
|
|
79
101
|
const features = context.effectiveFeatures;
|
|
80
102
|
const hasFeature = features
|
|
@@ -109,9 +131,12 @@ target) {
|
|
|
109
131
|
const lifecycle = createLifecycleHooks(hooks.registry);
|
|
110
132
|
const scopedContext = target === undefined
|
|
111
133
|
? hooks.context
|
|
112
|
-
: scopeSeedHookContext(hooks.context, target.tenantId, target.db);
|
|
134
|
+
: scopeSeedHookContext(hooks.context, target.tenantId, target.db, "deferUntilCommit");
|
|
135
|
+
const afterCommitContext = target === undefined
|
|
136
|
+
? hooks.context
|
|
137
|
+
: scopeSeedHookContext(hooks.context, target.tenantId, target.db, "inline");
|
|
113
138
|
await lifecycle.runPostSave(pseudoType, entityData, scopedContext, HookPhases.inTransaction);
|
|
114
|
-
const runAfterCommit = () => lifecycle.runPostSave(pseudoType, entityData,
|
|
139
|
+
const runAfterCommit = () => lifecycle.runPostSave(pseudoType, entityData, afterCommitContext, HookPhases.afterCommit);
|
|
115
140
|
if (scopedContext.scheduleAfterCommit) {
|
|
116
141
|
scopedContext.scheduleAfterCommit(runAfterCommit);
|
|
117
142
|
}
|
|
@@ -11,4 +11,4 @@ export declare function createClaimTenantHandoverHandler(opts?: ClaimTenantHando
|
|
|
11
11
|
sourceTenantId: string;
|
|
12
12
|
destinationTenantId: string;
|
|
13
13
|
movedEntities: Readonly<Record<string, number>>;
|
|
14
|
-
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
14
|
+
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -2,5 +2,5 @@ import * as z from "zod";
|
|
|
2
2
|
export declare const cancelDestructionWrite: import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"cancel-destruction", z.ZodObject<{}, z.core.$strip>, {
|
|
3
3
|
tenantId: string;
|
|
4
4
|
status: "active";
|
|
5
|
-
gracePeriodEnd:
|
|
6
|
-
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
5
|
+
gracePeriodEnd: null;
|
|
6
|
+
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -52,12 +52,13 @@ export const cancelDestructionWrite = defineWriteHandler({
|
|
|
52
52
|
type: DESTRUCTION_CANCELLED_EVENT_QN,
|
|
53
53
|
payload: { cancelledBy: event.user.id },
|
|
54
54
|
});
|
|
55
|
+
const gracePeriodEnd = null;
|
|
55
56
|
return {
|
|
56
57
|
isSuccess: true,
|
|
57
58
|
data: {
|
|
58
59
|
tenantId,
|
|
59
60
|
status: "active",
|
|
60
|
-
gracePeriodEnd
|
|
61
|
+
gracePeriodEnd,
|
|
61
62
|
},
|
|
62
63
|
};
|
|
63
64
|
},
|
|
@@ -3,4 +3,4 @@ export declare const requestDestructionWrite: import("@cosmicdrift/kumiko-types/
|
|
|
3
3
|
tenantId: string;
|
|
4
4
|
status: "destroyRequested";
|
|
5
5
|
gracePeriodEnd: string;
|
|
6
|
-
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
6
|
+
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -239,7 +239,8 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
239
239
|
};
|
|
240
240
|
const publishAssignmentChange = (tenantId) => {
|
|
241
241
|
const message = { tenantId };
|
|
242
|
-
|
|
242
|
+
// The writer already updated its own cache; only other pods need to re-read.
|
|
243
|
+
busHolder.bus?.publish(CACHE_SYNC_TOPICS.tierAssignment, message, { remoteOnly: true });
|
|
243
244
|
};
|
|
244
245
|
// Trial: zeit-abgeleitet aus tenant.inserted_at (≈ Signup), live am
|
|
245
246
|
// Feature-Gate geprüft — NICHT im Resolver-Cache. Der Resolver ist
|
|
@@ -404,12 +405,17 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
404
405
|
}
|
|
405
406
|
const isNewerThanSnapshot = (tenantId) => (latestTicket.get(tenantId) ?? 0) > startedAtTicket;
|
|
406
407
|
for (const tenantId of [...cache.keys()]) {
|
|
407
|
-
if (!loaded.has(tenantId) && !isNewerThanSnapshot(tenantId))
|
|
408
|
+
if (!loaded.has(tenantId) && !isNewerThanSnapshot(tenantId)) {
|
|
408
409
|
cache.delete(tenantId);
|
|
410
|
+
latestTicket.set(tenantId, startedAtTicket);
|
|
411
|
+
}
|
|
409
412
|
}
|
|
410
413
|
for (const [tenantId, features] of loaded) {
|
|
411
|
-
if (!isNewerThanSnapshot(tenantId))
|
|
414
|
+
if (!isNewerThanSnapshot(tenantId)) {
|
|
412
415
|
cache.set(tenantId, features);
|
|
416
|
+
// Makes a single reload that started before this snapshot discard its older result.
|
|
417
|
+
latestTicket.set(tenantId, startedAtTicket);
|
|
418
|
+
}
|
|
413
419
|
}
|
|
414
420
|
};
|
|
415
421
|
busHolder.bus = deps.cacheSync;
|
|
@@ -19,4 +19,4 @@ export declare function createSetTenantTierWrite(opts?: SetTenantTierOptions): i
|
|
|
19
19
|
tenantId: string;
|
|
20
20
|
tier: string;
|
|
21
21
|
isNew: boolean;
|
|
22
|
-
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
22
|
+
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
import { asRawClient, transaction, unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
27
27
|
import { SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
|
|
28
28
|
export async function backfillUserStreamTenants(db) {
|
|
29
|
-
const candidates =
|
|
30
|
-
WHERE "aggregate_type" = 'user' AND "tenant_id" <> $1::uuid`, [SYSTEM_TENANT_ID])
|
|
29
|
+
const candidates = await unsafeReadRetrying(db, `SELECT DISTINCT "aggregate_id" FROM "kumiko_events"
|
|
30
|
+
WHERE "aggregate_type" = 'user' AND "tenant_id" <> $1::uuid`, [SYSTEM_TENANT_ID]);
|
|
31
31
|
let aggregatesMigrated = 0;
|
|
32
32
|
let eventsMigrated = 0;
|
|
33
33
|
const failed = [];
|
|
@@ -50,10 +50,10 @@ async function migrateAggregate(db, aggregateId) {
|
|
|
50
50
|
const raw = asRawClient(tx);
|
|
51
51
|
// Global id order = commit-adjacent replay order; merges a split stream
|
|
52
52
|
// (legacy tenant + SYSTEM) into one consistent version sequence.
|
|
53
|
-
const events =
|
|
53
|
+
const events = await raw.unsafe(`SELECT "id" FROM "kumiko_events"
|
|
54
54
|
WHERE "aggregate_type" = 'user' AND "aggregate_id" = $1::uuid
|
|
55
55
|
ORDER BY "id" ASC
|
|
56
|
-
FOR UPDATE`, [aggregateId])
|
|
56
|
+
FOR UPDATE`, [aggregateId]);
|
|
57
57
|
// Phase 1: negative interim versions — real versions are always >= 1, so
|
|
58
58
|
// nothing can collide with events_aggregate_version_uq mid-migration.
|
|
59
59
|
for (const [i, ev] of events.entries()) {
|
|
@@ -6,4 +6,4 @@ export declare const createWrite: import("@cosmicdrift/kumiko-types/define-handl
|
|
|
6
6
|
locale: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
7
7
|
timezone: z.ZodOptional<z.ZodString>;
|
|
8
8
|
roles: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>>;
|
|
9
|
-
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
9
|
+
}, z.core.$strip>, import("@cosmicdrift/kumiko-types/hooks").SaveContext, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { access, defineEntityDetailHandler, } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
3
|
import { userEntity } from "../schema/user.js";
|
|
3
4
|
import { attachTenantLabels, dbForList } from "./list.query.js";
|
|
4
5
|
// Only SystemAdmins can read arbitrary users. Tenant-level "Admin" does NOT
|
|
@@ -14,7 +15,7 @@ export const detailQuery = {
|
|
|
14
15
|
...baseDetail,
|
|
15
16
|
handler: async (query, ctx) => {
|
|
16
17
|
const result = await baseDetail.handler?.(query, ctx);
|
|
17
|
-
if (result
|
|
18
|
+
if (!isPlainObject(result))
|
|
18
19
|
return result;
|
|
19
20
|
if (!ctx.registry.features.has("tenant"))
|
|
20
21
|
return result;
|
|
@@ -12,4 +12,4 @@ export declare const updateWrite: import("@cosmicdrift/kumiko-types/define-handl
|
|
|
12
12
|
emailVerified: z.ZodOptional<z.ZodBoolean>;
|
|
13
13
|
roles: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>>;
|
|
14
14
|
}, z.core.$strip>;
|
|
15
|
-
}, z.core.$strip>, unknown, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
15
|
+
}, z.core.$strip>, unknown, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|