@cosmicdrift/kumiko-samples 0.377.0 → 0.379.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 +18 -17
- package/packages/bundled-features/src/account-security/feature.ts +2 -2
- package/packages/bundled-features/src/account-security/index.ts +8 -8
- package/packages/bundled-features/src/account-security/{constants.ts → web/constants.ts} +0 -2
- package/packages/bundled-features/src/account-security/{i18n.ts → web/i18n.ts} +0 -1
- package/packages/bundled-features/src/admin-shell/feature.ts +10 -9
- package/packages/bundled-features/src/admin-shell/index.ts +8 -8
- package/packages/bundled-features/src/admin-shell/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/admin-shell/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/admin-shell/web/default-translations.ts +10 -0
- package/packages/bundled-features/src/admin-shell/web/i18n.ts +51 -9
- package/packages/bundled-features/src/admin-shell/web/index.ts +0 -1
- package/packages/bundled-features/src/audit/changes.json +7 -0
- package/packages/bundled-features/src/audit/feature.ts +72 -64
- package/packages/bundled-features/src/audit/handlers/audit-events.ts +153 -0
- package/packages/bundled-features/src/audit/handlers/audit-system-db.ts +13 -0
- package/packages/bundled-features/src/audit/handlers/details-all-tenants.query.ts +26 -0
- package/packages/bundled-features/src/audit/handlers/details.query.ts +11 -39
- package/packages/bundled-features/src/audit/handlers/list-all-tenants.query.ts +47 -0
- package/packages/bundled-features/src/audit/handlers/list.query.ts +16 -123
- package/packages/bundled-features/src/audit/handlers/resolve-audit-tenant.ts +21 -7
- package/packages/bundled-features/src/audit/index.ts +1 -1
- package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +4 -4
- package/packages/bundled-features/src/audit/screens.ts +82 -0
- package/packages/bundled-features/src/audit/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/audit/{constants.ts → web/constants.ts} +11 -1
- package/packages/bundled-features/src/audit/web/default-translations.ts +7 -0
- package/packages/bundled-features/src/audit/web/i18n.ts +33 -7
- package/packages/bundled-features/src/audit/web/index.ts +0 -2
- package/packages/bundled-features/src/auth-email-password/bootstrap.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/changes.json +6 -0
- package/packages/bundled-features/src/auth-email-password/errors.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/feature.ts +2 -2
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-account-unlock.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +3 -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/login.write.ts +38 -4
- package/packages/bundled-features/src/auth-email-password/handlers/request-account-unlock.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/request-email-verification.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/request-password-reset.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/reset-password.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/verify-email.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/index.ts +6 -1
- package/packages/bundled-features/src/auth-email-password/mail-notifications.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/signup-activation.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-form-logic.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-redirect.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/client-actions.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +1 -2
- package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/{constants.ts → web/constants.ts} +3 -6
- package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/{i18n.ts → web/i18n.ts} +3 -4
- package/packages/bundled-features/src/auth-email-password/web/index.ts +1 -2
- package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +2 -3
- package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/{mail-i18n.ts → web/mail-i18n.ts} +0 -1
- package/packages/bundled-features/src/auth-email-password/web/request-account-unlock-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/session-bootstrap-error.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/session.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +2 -3
- package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/tenant-menu-items.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
- package/packages/bundled-features/src/auth-mfa/errors.ts +2 -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/enable-start.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/index.ts +8 -8
- package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/screens.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +0 -1
- package/packages/bundled-features/src/auth-mfa/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/auth-mfa/web/i18n.ts +0 -1
- package/packages/bundled-features/src/auth-mfa/web/index.ts +0 -1
- package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +0 -1
- package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +1 -2
- package/packages/bundled-features/src/auth-mfa/web/mfa-recovery-codes-reveal.tsx +0 -1
- package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +1 -2
- package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +21 -23
- package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +0 -1
- package/packages/bundled-features/src/billing-foundation/changes.json +18 -0
- package/packages/bundled-features/src/billing-foundation/checkout-core.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-text.ts +2 -2
- package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +11 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +11 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/register-consent.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/register-termination.ts +12 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +12 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-mail.ts +6 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-notify.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-pages.ts +167 -28
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +102 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +43 -12
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +202 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +70 -0
- package/packages/bundled-features/src/billing-foundation/events.ts +20 -2
- package/packages/bundled-features/src/billing-foundation/feature.ts +5 -5
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +82 -9
- package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/index.ts +27 -27
- package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +7 -7
- package/packages/bundled-features/src/billing-foundation/screens.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/types.ts +17 -3
- package/packages/bundled-features/src/billing-foundation/validate-options.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/web/billing-contact-plan.tsx +1 -3
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +5 -7
- package/packages/bundled-features/src/billing-foundation/web/cancel-contract-dialog.tsx +1 -3
- package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +1 -3
- package/packages/bundled-features/src/billing-foundation/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/billing-foundation/{constants.ts → web/constants.ts} +37 -31
- package/packages/bundled-features/src/billing-foundation/{consumer-protection → web/consumer-protection}/consent-locale.ts +0 -1
- package/packages/bundled-features/src/billing-foundation/{contact-card.ts → web/contact-card.ts} +0 -2
- package/packages/bundled-features/src/billing-foundation/web/index.ts +14 -15
- package/packages/bundled-features/src/billing-foundation/web/localized-params.ts +0 -2
- package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +5 -2
- package/packages/bundled-features/src/cap-counter/changes.json +12 -0
- package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +9 -0
- package/packages/bundled-features/src/cap-overview/feature.ts +1 -1
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -1
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +2 -2
- package/packages/bundled-features/src/cap-overview/index.ts +9 -9
- package/packages/bundled-features/src/cap-overview/screens.ts +2 -2
- package/packages/bundled-features/src/cap-overview/web/cap-cards-panel.tsx +1 -2
- package/packages/bundled-features/src/cap-overview/web/cap-usage-bar.tsx +1 -2
- package/packages/bundled-features/src/cap-overview/web/cap-usage-cell.tsx +0 -2
- package/packages/bundled-features/src/cap-overview/web/client-plugin.tsx +3 -4
- package/packages/bundled-features/src/cap-overview/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/cap-overview/web/index.ts +0 -1
- package/packages/bundled-features/src/cap-overview/{usage-math.ts → web/usage-math.ts} +1 -2
- package/packages/bundled-features/src/compliance-profiles/feature.ts +5 -5
- package/packages/bundled-features/src/compliance-profiles/index.ts +6 -6
- package/packages/bundled-features/src/compliance-profiles/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/compliance-profiles/web/compliance-profile-catalog.tsx +1 -2
- package/packages/bundled-features/src/compliance-profiles/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/compliance-profiles/web/i18n.ts +0 -1
- package/packages/bundled-features/src/compliance-profiles/web/index.ts +0 -1
- package/packages/bundled-features/src/config/index.ts +6 -6
- package/packages/bundled-features/src/config/web/client-plugin.ts +1 -2
- package/packages/bundled-features/src/config/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/config/web/i18n.ts +1 -1
- package/packages/bundled-features/src/config/web/index.ts +1 -3
- package/packages/bundled-features/src/config/write-helpers.ts +1 -1
- package/packages/bundled-features/src/custom-fields/feature.ts +8 -8
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +4 -4
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/index.ts +8 -8
- package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +1 -1
- package/packages/bundled-features/src/custom-fields/schemas.ts +1 -1
- package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/custom-fields/{constants.ts → web/constants.ts} +18 -19
- package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +1 -2
- package/packages/bundled-features/src/custom-fields/web/i18n.ts +0 -1
- package/packages/bundled-features/src/custom-fields/web/index.ts +2 -3
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +1 -2
- package/packages/bundled-features/src/delivery/address-opt-out.ts +1 -1
- package/packages/bundled-features/src/delivery/attempt-log-retention.ts +24 -8
- package/packages/bundled-features/src/delivery/changes.json +6 -0
- package/packages/bundled-features/src/delivery/constants.ts +2 -2
- package/packages/bundled-features/src/delivery/i18n.ts +1 -1
- package/packages/bundled-features/src/delivery/unsubscribe-page.ts +1 -1
- package/packages/bundled-features/src/delivery/web/client-plugin.tsx +6 -7
- package/packages/bundled-features/src/delivery/web/delivery-channel-cell.tsx +0 -1
- package/packages/bundled-features/src/delivery/web/delivery-error-cell.tsx +0 -1
- package/packages/bundled-features/src/delivery/web/delivery-status-cell.tsx +1 -2
- package/packages/bundled-features/src/delivery/web/delivery-time-cell.tsx +0 -1
- package/packages/bundled-features/src/delivery/web/delivery-type-cell.tsx +0 -1
- package/packages/bundled-features/src/delivery/web/index.ts +0 -1
- package/packages/bundled-features/src/delivery/{public-names.ts → web/public-names.ts} +0 -1
- package/packages/bundled-features/src/document-ingest-foundation/changes.json +6 -0
- package/packages/bundled-features/src/document-ingest-foundation/events.ts +4 -0
- package/packages/bundled-features/src/document-ingest-foundation/executor.ts +2 -1
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +18 -4
- package/packages/bundled-features/src/document-ingest-foundation/index.ts +1 -0
- package/packages/bundled-features/src/feature-toggles/feature.ts +7 -7
- package/packages/bundled-features/src/feature-toggles/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -3
- package/packages/bundled-features/src/feature-toggles/index.ts +6 -6
- package/packages/bundled-features/src/feature-toggles/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/feature-toggles/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/feature-toggles/web/i18n.ts +0 -1
- package/packages/bundled-features/src/feature-toggles/web/index.ts +0 -1
- package/packages/bundled-features/src/files/changes.json +7 -0
- package/packages/bundled-features/src/folders/feature.ts +1 -1
- package/packages/bundled-features/src/folders/handlers/clear-folder.write.ts +1 -1
- package/packages/bundled-features/src/folders/handlers/delete-folder.write.ts +1 -1
- package/packages/bundled-features/src/folders/handlers/set-folder.write.ts +1 -1
- package/packages/bundled-features/src/folders/index.ts +8 -8
- package/packages/bundled-features/src/folders/web/client-plugin.tsx +1 -3
- package/packages/bundled-features/src/folders/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/folders/web/folder-manager.tsx +1 -2
- package/packages/bundled-features/src/folders/web/folder-section.tsx +1 -2
- package/packages/bundled-features/src/folders/web/i18n.ts +0 -1
- package/packages/bundled-features/src/folders/web/index.ts +1 -2
- package/packages/bundled-features/src/folders/web/tree.ts +0 -1
- package/packages/bundled-features/src/form-draft/changes.json +7 -0
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +25 -11
- package/packages/bundled-features/src/form-draft/decrypt-draft.ts +24 -0
- package/packages/bundled-features/src/form-draft/entity.ts +6 -9
- package/packages/bundled-features/src/form-draft/feature.ts +1 -1
- package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +26 -5
- package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
- package/packages/bundled-features/src/form-draft/handlers/get.query.ts +6 -7
- package/packages/bundled-features/src/form-draft/handlers/list.query.ts +13 -7
- package/packages/bundled-features/src/form-draft/handlers/save.write.ts +5 -5
- package/packages/bundled-features/src/form-draft/index.ts +8 -8
- package/packages/bundled-features/src/form-draft/lookup.ts +10 -4
- package/packages/bundled-features/src/form-draft/schemas.ts +1 -1
- package/packages/bundled-features/src/form-draft/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/form-draft-user-data/hooks.ts +2 -2
- package/packages/bundled-features/src/inbound-mail-foundation/changes.json +6 -0
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +11 -4
- package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +10 -10
- package/packages/bundled-features/src/jobs/feature.ts +7 -7
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/trigger.write.ts +1 -1
- package/packages/bundled-features/src/jobs/index.ts +1 -1
- package/packages/bundled-features/src/jobs/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/jobs/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/jobs/web/default-translations.ts +7 -0
- package/packages/bundled-features/src/jobs/web/i18n.ts +53 -7
- package/packages/bundled-features/src/jobs/web/index.ts +0 -1
- package/packages/bundled-features/src/ledger/changes.json +7 -0
- package/packages/bundled-features/src/ledger/entity.ts +1 -1
- package/packages/bundled-features/src/ledger/feature.ts +1 -1
- package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +2 -10
- package/packages/bundled-features/src/ledger/handlers/create-transaction.write.ts +1 -1
- package/packages/bundled-features/src/ledger/handlers/reports.query.ts +1 -1
- package/packages/bundled-features/src/ledger/handlers/reverse-transaction.write.ts +1 -1
- package/packages/bundled-features/src/ledger/index.ts +13 -13
- package/packages/bundled-features/src/ledger/recurring.ts +1 -1
- package/packages/bundled-features/src/ledger/reports.ts +1 -1
- package/packages/bundled-features/src/ledger/schemas.ts +1 -1
- package/packages/bundled-features/src/ledger/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/ledger/web/index.ts +11 -12
- package/packages/bundled-features/src/legal-pages/README.md +1 -1
- package/packages/bundled-features/src/legal-pages/feature.ts +5 -5
- package/packages/bundled-features/src/legal-pages/index.ts +11 -11
- package/packages/bundled-features/src/legal-pages/lib/boot-check.ts +1 -1
- package/packages/bundled-features/src/legal-pages/lib/validate-routes.ts +1 -1
- package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +1 -2
- package/packages/bundled-features/src/legal-pages/{constants.ts → web/constants.ts} +6 -8
- package/packages/bundled-features/src/legal-pages/web/index.ts +0 -1
- package/packages/bundled-features/src/mail-foundation/changes.json +6 -0
- package/packages/bundled-features/src/mail-foundation/i18n.ts +3 -2
- package/packages/bundled-features/src/mail-transport-smtp/i18n.ts +1 -1
- package/packages/bundled-features/src/managed-pages/feature.ts +1 -1
- package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/managed-pages/web/default-translations.ts +17 -0
- package/packages/bundled-features/src/managed-pages/web/i18n.ts +59 -16
- package/packages/bundled-features/src/managed-pages/web/index.ts +1 -2
- package/packages/bundled-features/src/metrics/compute.ts +1 -1
- package/packages/bundled-features/src/metrics/feature.ts +6 -6
- package/packages/bundled-features/src/metrics/index.ts +8 -8
- package/packages/bundled-features/src/metrics/types.ts +1 -1
- package/packages/bundled-features/src/metrics/validate.ts +1 -1
- package/packages/bundled-features/src/metrics/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/metrics/window.ts +1 -1
- package/packages/bundled-features/src/notes-history/feature.ts +1 -1
- package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
- package/packages/bundled-features/src/notes-history/index.ts +8 -8
- package/packages/bundled-features/src/notes-history/web/client-plugin.tsx +1 -3
- package/packages/bundled-features/src/notes-history/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/notes-history/web/i18n.ts +0 -1
- package/packages/bundled-features/src/notes-history/web/index.ts +2 -3
- package/packages/bundled-features/src/notes-history/web/notes-section.tsx +2 -3
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +12 -10
- package/packages/bundled-features/src/personal-access-tokens/handlers/available-scopes.query.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/hash.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/i18n.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/index.ts +5 -5
- package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/schema/api-token.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/personal-access-tokens/{scopes.ts → web/scopes.ts} +0 -1
- package/packages/bundled-features/src/presets/changes.json +7 -0
- package/packages/bundled-features/src/presets/index.ts +0 -1
- package/packages/bundled-features/src/presets/security-baseline.ts +1 -1
- package/packages/bundled-features/src/renderer-foundation/types.ts +1 -1
- package/packages/bundled-features/src/secrets/feature.ts +1 -1
- package/packages/bundled-features/src/secrets/handlers/delete.write.ts +1 -1
- package/packages/bundled-features/src/secrets/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/secrets/handlers/set.write.ts +1 -1
- package/packages/bundled-features/src/secrets/i18n.ts +1 -1
- package/packages/bundled-features/src/secrets/index.ts +8 -8
- package/packages/bundled-features/src/secrets/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/secrets/write-gate.ts +1 -1
- package/packages/bundled-features/src/sessions/feature.ts +7 -4
- package/packages/bundled-features/src/sessions/{i18n.ts → web/i18n.ts} +0 -1
- package/packages/bundled-features/src/shared/index.ts +6 -1
- package/packages/bundled-features/src/shared/purge-files-reaching-subject.ts +10 -2
- package/packages/bundled-features/src/shared/web/translate-or-raw.ts +0 -1
- package/packages/bundled-features/src/subscription-stripe/feature.ts +2 -0
- package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +19 -0
- package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +1 -0
- package/packages/bundled-features/src/tags/changes.json +6 -0
- package/packages/bundled-features/src/tags/feature.ts +1 -1
- package/packages/bundled-features/src/tags/handlers/assign-tag.write.ts +11 -7
- package/packages/bundled-features/src/tags/handlers/create-tag.write.ts +1 -1
- package/packages/bundled-features/src/tags/handlers/delete-tag.write.ts +4 -1
- package/packages/bundled-features/src/tags/handlers/remove-tag.write.ts +1 -1
- package/packages/bundled-features/src/tags/handlers/update-tag.write.ts +1 -1
- package/packages/bundled-features/src/tags/index.ts +12 -12
- package/packages/bundled-features/src/tags/screens.ts +1 -1
- package/packages/bundled-features/src/tags/web/client-plugin.tsx +1 -3
- package/packages/bundled-features/src/tags/{constants.ts → web/constants.ts} +4 -1
- package/packages/bundled-features/src/tags/web/entity-tags.tsx +1 -2
- package/packages/bundled-features/src/tags/web/i18n.ts +2 -2
- package/packages/bundled-features/src/tags/web/index.ts +2 -3
- package/packages/bundled-features/src/tags/web/tag-chip.tsx +0 -1
- package/packages/bundled-features/src/tags/web/tag-filter.tsx +1 -2
- package/packages/bundled-features/src/tags/web/tag-manager.tsx +5 -4
- package/packages/bundled-features/src/tags/web/tag-picker.tsx +0 -1
- package/packages/bundled-features/src/tags/web/tag-section.tsx +1 -2
- package/packages/bundled-features/src/tags/web/tags-cell.tsx +1 -2
- package/packages/bundled-features/src/template-resolver/README.md +1 -1
- package/packages/bundled-features/src/template-resolver/api.ts +75 -28
- package/packages/bundled-features/src/template-resolver/changes.json +63 -0
- package/packages/bundled-features/src/template-resolver/compile-document-body.ts +62 -4
- package/packages/bundled-features/src/template-resolver/compile-steps-block.ts +2 -2
- package/packages/bundled-features/src/template-resolver/document-ops.ts +5 -5
- package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +39 -4
- package/packages/bundled-features/src/template-resolver/feature.ts +88 -38
- package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +6 -1
- package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +6 -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 -1
- package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +20 -7
- package/packages/bundled-features/src/template-resolver/handlers/collection-shared.ts +0 -6
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +69 -60
- package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +7 -1
- package/packages/bundled-features/src/template-resolver/handlers/discard-draft.write.ts +37 -14
- package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +8 -2
- package/packages/bundled-features/src/template-resolver/handlers/document-blocks.query.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +5 -2
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +4 -2
- package/packages/bundled-features/src/template-resolver/handlers/import-bundle.write.ts +37 -28
- package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +10 -5
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +5 -2
- package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +132 -70
- package/packages/bundled-features/src/template-resolver/handlers/patch-draft.write.ts +106 -97
- package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +62 -49
- package/packages/bundled-features/src/template-resolver/handlers/resource-link-pdf.write.ts +44 -29
- package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +52 -36
- package/packages/bundled-features/src/template-resolver/handlers/resource-shared.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/resource-upload.write.ts +127 -107
- package/packages/bundled-features/src/template-resolver/handlers/send-test-shared.ts +38 -0
- package/packages/bundled-features/src/template-resolver/handlers/send-test-status.query.ts +31 -0
- package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +106 -112
- package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +111 -104
- package/packages/bundled-features/src/template-resolver/handlers/shared.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/template-gates.ts +6 -6
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +56 -28
- package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +38 -29
- package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +8 -2
- package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +4 -2
- package/packages/bundled-features/src/template-resolver/i18n.ts +25 -0
- package/packages/bundled-features/src/template-resolver/index.ts +68 -60
- package/packages/bundled-features/src/template-resolver/layout-appearance.ts +1 -1
- package/packages/bundled-features/src/template-resolver/layout-regions.ts +1 -1
- package/packages/bundled-features/src/template-resolver/seeding.ts +16 -7
- package/packages/bundled-features/src/template-resolver/store-template-resource.ts +2 -2
- package/packages/bundled-features/src/template-resolver/table.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-bundle.ts +2 -2
- package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +82 -0
- package/packages/bundled-features/src/template-resolver/template-draft.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-edit-policy.ts +91 -0
- package/packages/bundled-features/src/template-resolver/template-meta.ts +2 -2
- package/packages/bundled-features/src/template-resolver/template-preview.ts +22 -12
- package/packages/bundled-features/src/template-resolver/template-usage.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-validation.ts +33 -12
- package/packages/bundled-features/src/template-resolver/testing.ts +2 -2
- package/packages/bundled-features/src/template-resolver/user-content-table.ts +1 -1
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +4 -5
- package/packages/bundled-features/src/template-resolver/{constants.ts → web/constants.ts} +10 -10
- package/packages/bundled-features/src/template-resolver/{document-blocks.ts → web/document-blocks.ts} +3 -2
- package/packages/bundled-features/src/template-resolver/web/document-editor-extensions.ts +31 -3
- package/packages/bundled-features/src/template-resolver/web/document-editor.tsx +0 -1
- package/packages/bundled-features/src/template-resolver/web/document-images.ts +28 -0
- package/packages/bundled-features/src/template-resolver/{document-schema.ts → web/document-schema.ts} +5 -1
- package/packages/bundled-features/src/template-resolver/{document-steps.ts → web/document-steps.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-editor.tsx +48 -11
- package/packages/bundled-features/src/template-resolver/web/document-toolbar-blocks.ts +4 -3
- package/packages/bundled-features/src/template-resolver/web/editor-handle.ts +1 -2
- package/packages/bundled-features/src/template-resolver/web/i18n.ts +8 -1
- package/packages/bundled-features/src/template-resolver/web/index.ts +13 -14
- package/packages/bundled-features/src/template-resolver/{mail-constants.ts → web/mail-constants.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/{pdf-constants.ts → web/pdf-constants.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor-lazy.tsx +0 -1
- package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor.tsx +5 -4
- package/packages/bundled-features/src/template-resolver/{placeholder-text.ts → web/placeholder-text.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/{qualified-names.ts → web/qualified-names.ts} +2 -1
- package/packages/bundled-features/src/template-resolver/web/use-stable-by-key.ts +0 -1
- package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -1
- package/packages/bundled-features/src/tenant/index.ts +7 -7
- package/packages/bundled-features/src/tenant/invitation-table.ts +1 -1
- package/packages/bundled-features/src/tenant/invited-membership.ts +1 -1
- package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -1
- package/packages/bundled-features/src/tenant/member-role-options.ts +1 -1
- package/packages/bundled-features/src/tenant/screens.ts +2 -2
- package/packages/bundled-features/src/tenant/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/tenant/{constants.ts → web/constants.ts} +3 -6
- package/packages/bundled-features/src/tenant/web/index.ts +0 -1
- package/packages/bundled-features/src/tenant/web/member-roles-cell.tsx +0 -1
- package/packages/bundled-features/src/tenant/web/member-status-cell.tsx +0 -1
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +2 -2
- package/packages/bundled-features/src/tier-engine/entity.ts +1 -1
- package/packages/bundled-features/src/tier-engine/feature.ts +7 -7
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +1 -1
- package/packages/bundled-features/src/tier-engine/index.ts +8 -8
- package/packages/bundled-features/src/tier-engine/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/tier-engine/{constants.ts → web/constants.ts} +2 -3
- package/packages/bundled-features/src/tier-engine/{i18n.ts → web/i18n.ts} +0 -1
- package/packages/bundled-features/src/tier-engine/web/index.ts +0 -1
- package/packages/bundled-features/src/user/handlers/create.write.ts +1 -1
- package/packages/bundled-features/src/user/handlers/update-roles.ts +1 -1
- package/packages/bundled-features/src/user/handlers/update.write.ts +1 -1
- package/packages/bundled-features/src/user/index.ts +1 -1
- package/packages/bundled-features/src/user/invited-global-roles.ts +1 -1
- package/packages/bundled-features/src/user/schema/user.ts +1 -1
- package/packages/bundled-features/src/user/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/user-data-rights/changes.json +14 -0
- package/packages/bundled-features/src/user-data-rights/env.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/feature.ts +9 -9
- package/packages/bundled-features/src/user-data-rights/index.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/lib/resolve-tenant-model.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/mail-notifications.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +0 -1
- package/packages/bundled-features/src/user-data-rights/{constants.ts → web/constants.ts} +11 -12
- package/packages/bundled-features/src/user-data-rights/web/default-translations.ts +91 -0
- package/packages/bundled-features/src/user-data-rights/web/i18n.ts +41 -91
- package/packages/bundled-features/src/user-data-rights/web/index.ts +1 -2
- package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +1 -2
- package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +0 -1
- package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +0 -1
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +10 -1
- package/packages/bundled-features/src/user-profile/feature.ts +2 -2
- package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +1 -1
- package/packages/bundled-features/src/user-profile/index.ts +3 -2
- package/packages/bundled-features/src/user-profile/web/client-plugin.ts +2 -3
- package/packages/bundled-features/src/user-profile/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/user-profile/{i18n.ts → web/i18n.ts} +0 -1
- package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +2 -3
- package/packages/bundled-features/src/waitlist/changes.json +6 -0
- package/packages/bundled-features/src/waitlist/entity.ts +1 -1
- package/packages/bundled-features/src/waitlist/feature.ts +5 -5
- package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +3 -3
- package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +5 -1
- package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
- package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +3 -3
- package/packages/bundled-features/src/waitlist/import.ts +1 -1
- package/packages/bundled-features/src/waitlist/index.ts +11 -11
- package/packages/bundled-features/src/waitlist/legacy-migrate.ts +1 -1
- package/packages/bundled-features/src/waitlist/link-on-signup.ts +1 -1
- package/packages/bundled-features/src/waitlist/mail.ts +7 -6
- package/packages/bundled-features/src/waitlist/payloads.ts +1 -1
- package/packages/bundled-features/src/waitlist/screens.ts +1 -1
- package/packages/bundled-features/src/waitlist/{constants.ts → web/constants.ts} +0 -1
- package/samples/apps/styleguide/src/features/content/web.tsx +0 -1
- package/samples/apps/ui-walkthrough/src/app/client.tsx +2 -0
- package/samples/apps/ui-walkthrough/src/app/help-action.tsx +37 -0
- package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +17 -1
- package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +13 -0
- package/samples/apps/ui-walkthrough/src/app/server.ts +2 -1
- package/samples/apps/ui-walkthrough/src/app/shell.tsx +6 -0
- package/samples/apps/ui-walkthrough/src/app/template-seed-data.ts +20 -0
- package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +35 -7
- package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +6 -0
- package/samples/apps/ui-walkthrough/src/features/rental/entities.ts +27 -0
- package/samples/apps/ui-walkthrough/src/features/rental/feature.ts +120 -2
- package/samples/apps/ui-walkthrough/src/features/rental/i18n.ts +94 -0
- package/samples/apps/ui-walkthrough/src/features/rental/invoice-receive.ts +19 -0
- package/samples/apps/ui-walkthrough/src/features/rental/lease-support.ts +32 -1
- package/samples/apps/ui-walkthrough/src/features/rental/qualified-names.ts +5 -0
- package/samples/apps/ui-walkthrough/src/features/rental/receipts-upload.ts +70 -0
- package/samples/apps/ui-walkthrough/src/features/rental/screens.ts +156 -0
- package/samples/apps/ui-walkthrough/src/features/subscription-plans/feature.ts +103 -0
- package/samples/apps/ui-walkthrough/src/features/subscription-plans/i18n.ts +36 -0
- package/samples/apps/ui-walkthrough/src/features/subscription-plans/index.ts +2 -0
- package/samples/apps/ui-walkthrough/src/features/subscription-plans/seed.ts +21 -0
- package/samples/apps/ui-walkthrough/src/features/tasks/i18n.ts +8 -0
- package/samples/apps/ui-walkthrough/src/run-config.ts +43 -3
- package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +1 -1
- package/samples/apps/use-all-bundled/feature-manifest.json +5 -5
- package/samples/apps/use-all-bundled/scripts/check-coverage.ts +1 -1
- package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +3 -1
- package/samples/recipes/compose-stacks/README.md +1 -2
- package/samples/recipes/delivery-notifications/README.md +1 -1
- package/samples/recipes/embedded/README.md +8 -0
- package/samples/recipes/embedded/src/feature.ts +8 -0
- package/samples/recipes/embedded/src/handlers/invoice-receive.write.ts +37 -0
- package/samples/recipes/embedded/src/screens/invoice-receive.screen.ts +56 -0
- package/samples/recipes/legal-pages/README.md +2 -2
- package/samples/recipes/legal-pages/src/feature.ts +1 -1
- package/samples/recipes/reference-data/src/feature.ts +3 -7
- package/packages/bundled-features/src/admin-shell/i18n.ts +0 -54
- package/packages/bundled-features/src/audit/i18n.ts +0 -25
- package/packages/bundled-features/src/auth-mfa/web/qrcode-browser.d.ts +0 -11
- package/packages/bundled-features/src/jobs/i18n.ts +0 -55
- package/packages/bundled-features/src/managed-pages/i18n.ts +0 -63
- package/packages/bundled-features/src/presets/dsgvo-self-service.ts +0 -35
- package/packages/bundled-features/src/user-data-rights/i18n.ts +0 -44
|
@@ -3,44 +3,51 @@ import {
|
|
|
3
3
|
createSystemConfig,
|
|
4
4
|
defineFeature,
|
|
5
5
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
6
|
-
import { isCollectionRefusedKind } from "./constants.ts";
|
|
7
6
|
import { bySlugQuery } from "./handlers/by-slug.query.ts";
|
|
8
7
|
import { byTenantQuery } from "./handlers/by-tenant.query.ts";
|
|
9
8
|
import { makeCollectionItemQuery } from "./handlers/collection-item.query.ts";
|
|
10
9
|
import { makeCollectionListQuery } from "./handlers/collection-list.query.ts";
|
|
11
10
|
import { makeCollectionSetWrite } from "./handlers/collection-set.write.ts";
|
|
12
|
-
import {
|
|
11
|
+
import { makeCopyLocaleWrite } from "./handlers/copy-locale.write.ts";
|
|
13
12
|
import { diffToSystemQuery } from "./handlers/diff-to-system.query.ts";
|
|
14
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
makeDiscardDraftSystemWrite,
|
|
15
|
+
makeDiscardDraftWrite,
|
|
16
|
+
} from "./handlers/discard-draft.write.ts";
|
|
15
17
|
import { documentBlocksQuery } from "./handlers/document-blocks.query.ts";
|
|
16
18
|
import { exportBundleQuery } from "./handlers/export-bundle.query.ts";
|
|
17
19
|
import { findByIdQuery } from "./handlers/find-by-id.query.ts";
|
|
18
|
-
import {
|
|
20
|
+
import { makeImportBundleWrite } from "./handlers/import-bundle.write.ts";
|
|
19
21
|
import { importBundleSystemWrite } from "./handlers/import-bundle-system.write.ts";
|
|
20
22
|
import { layoutSourceQuery } from "./handlers/layout-source.query.ts";
|
|
21
23
|
import { listQuery } from "./handlers/list.query.ts";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
+
import { makeOverviewQuery } from "./handlers/overview.query.ts";
|
|
25
|
+
import { makePatchDraftWrite } from "./handlers/patch-draft.write.ts";
|
|
24
26
|
import { previewQuery } from "./handlers/preview.query.ts";
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
27
|
+
import { makeResetToSystemWrite } from "./handlers/reset-to-system.write.ts";
|
|
28
|
+
import { makeResourceLinkPdfWrite } from "./handlers/resource-link-pdf.write.ts";
|
|
29
|
+
import { makeResourceRemoveWrite } from "./handlers/resource-remove.write.ts";
|
|
30
|
+
import { makeResourceUploadWrite } from "./handlers/resource-upload.write.ts";
|
|
31
|
+
import { makeSendTestWrite } from "./handlers/send-test.write.ts";
|
|
32
|
+
import { sendTestStatusQuery } from "./handlers/send-test-status.query.ts";
|
|
33
|
+
import { makeSetWrite } from "./handlers/set.write.ts";
|
|
31
34
|
import { tenantOverridesQuery } from "./handlers/tenant-overrides.query.ts";
|
|
32
35
|
import {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
makeArchiveSystemWrite,
|
|
37
|
+
makeArchiveWrite,
|
|
38
|
+
makePublishSystemWrite,
|
|
39
|
+
makePublishWrite,
|
|
37
40
|
} from "./handlers/toggle-status.write.ts";
|
|
38
41
|
import { upsertSystemWrite } from "./handlers/upsert-system.write.ts";
|
|
39
|
-
import {
|
|
42
|
+
import { makeUpsertTenantWrite } from "./handlers/upsert-tenant.write.ts";
|
|
40
43
|
import { usageQuery } from "./handlers/usage.query.ts";
|
|
41
44
|
import { validateQuery } from "./handlers/validate.query.ts";
|
|
45
|
+
import { TEMPLATE_RESOLVER_I18N } from "./i18n.ts";
|
|
42
46
|
import { templateResourceEntity } from "./table.ts";
|
|
47
|
+
import type { TemplateDeliveryPolicy } from "./template-delivery-policy.ts";
|
|
48
|
+
import type { TenantEditableTemplate } from "./template-edit-policy.ts";
|
|
43
49
|
import { userContentEntryEntity } from "./user-content-table.ts";
|
|
50
|
+
import { DEFAULT_COLLECTION_ACCESS, isCollectionRefusedKind } from "./web/constants.ts";
|
|
44
51
|
|
|
45
52
|
// template-resolver — structured template storage with tenant-override
|
|
46
53
|
// hierarchy, locale fallback and resource linking via file-foundation.
|
|
@@ -61,6 +68,13 @@ export type TemplateResolverOptions = {
|
|
|
61
68
|
* access rule, so the dispatcher enforces the separation instead of a
|
|
62
69
|
* branch in a shared handler. */
|
|
63
70
|
readonly collections?: readonly ContentCollectionDefinition[];
|
|
71
|
+
/** Templates a TenantAdmin may edit for the own tenant (override, draft, publish, archive,
|
|
72
|
+
* reset, copy-locale, import, resources). Without an entry only a SystemAdmin edits.
|
|
73
|
+
* A tenant-edited mail goes out under the platform's name, so the app opts in per
|
|
74
|
+
* template instead of the framework guessing which ones a tenant may reword.
|
|
75
|
+
* `access` is required: the host decides its role vocabulary here, like for
|
|
76
|
+
* `collections`. SystemAdmin always passes. */
|
|
77
|
+
readonly tenantEditable?: readonly TenantEditableTemplate[];
|
|
64
78
|
};
|
|
65
79
|
|
|
66
80
|
function assertCollectionKindsAllowed(collections: readonly ContentCollectionDefinition[]): void {
|
|
@@ -73,20 +87,51 @@ function assertCollectionKindsAllowed(collections: readonly ContentCollectionDef
|
|
|
73
87
|
}
|
|
74
88
|
}
|
|
75
89
|
|
|
90
|
+
function assertTenantEditableValid(entries: readonly TenantEditableTemplate[]): void {
|
|
91
|
+
const seen = new Set<string>();
|
|
92
|
+
for (const entry of entries) {
|
|
93
|
+
const key = `${entry.kind}/${entry.slug}`;
|
|
94
|
+
if (seen.has(key)) {
|
|
95
|
+
throw new Error(`template-resolver: tenantEditable lists "${key}" twice`);
|
|
96
|
+
}
|
|
97
|
+
seen.add(key);
|
|
98
|
+
if (entry.slug.trim() === "") {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`template-resolver: tenantEditable entry of kind "${entry.kind}" has an empty slug`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
if (entry.access.roles.length === 0) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
`template-resolver: tenantEditable entry "${entry.kind}/${entry.slug}" has no roles in access`,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
76
111
|
export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}) {
|
|
77
112
|
const collections = opts.collections ?? [];
|
|
78
113
|
assertCollectionKindsAllowed(collections);
|
|
114
|
+
const tenantEditable = opts.tenantEditable ?? [];
|
|
115
|
+
assertTenantEditableValid(tenantEditable);
|
|
116
|
+
const policy = { tenantEditable };
|
|
117
|
+
const deliveryPolicy: TemplateDeliveryPolicy = {
|
|
118
|
+
tenantEditable: tenantEditable.map(({ kind, slug }) => ({ kind, slug })),
|
|
119
|
+
collectionKinds: collections
|
|
120
|
+
.filter((c) => c.ownership !== "user" && c.access !== undefined)
|
|
121
|
+
.map((c) => c.kind),
|
|
122
|
+
};
|
|
79
123
|
const hasUserOwned = collections.some((c) => c.ownership === "user");
|
|
80
124
|
return defineFeature("template-resolver", (r) => {
|
|
81
125
|
r.describe(
|
|
82
126
|
[
|
|
83
127
|
"Every piece of editable text lives here, in one entity: mail bodies, notification texts, PDF document templates, AI prompts and plain text blocks. What a record is used for is the `kind` (`notification`, `mail`, `mail-layout`, `document-pdf`, `pdf-layout`, `ai-prompt`, `text-block`, `snippet`, `image-snapshot`).",
|
|
84
128
|
"Reading is one call — `ctx.templateResolver.resolveTemplate({ tenantId, slug, kind, locale })`. It walks four levels: tenant+locale, system+locale, tenant+fallback-locale, system+fallback-locale. A tenant overrides a system default by simply having its own record; no application code changes. Writing programmatically goes through the `upsertSystem`, `upsertTenant`, `publish` and `archive` write handlers; a SystemAdmin retires or restores a system default with `publishSystem` and `archiveSystem`, and a tenant drops its override with `resetToSystem`. Saving a draft over an active template keeps the active version served and stores the edit beside it (column `draft`); `publish` makes it the served version, `discardDraft` / `discardDraftSystem` throws it away.",
|
|
129
|
+
'Editing templates is for SystemAdmin only. A TenantAdmin edits only the templates the app unlocks at the mount site, `createTemplateResolverFeature({ tenantEditable: [{ kind: "mail", slug: "status-update", access: { roles: ["TenantAdmin"] } }] })`, and every write handler enforces that on the server (override, draft, publish, archive, reset, copy-locale, import, resources, `set`). Each entry carries the `access` roles allowed to edit it, because a bundled feature cannot know the host\'s roles. The same list decides delivery: a tenant override is served (mail, PDF, layouts, text blocks) only while its template is listed in tenantEditable; otherwise the system version is served. A locked override stays stored, a SystemAdmin sees it in the overview marked as not delivered, and listing the template makes it effective again. Tenant rows of a collection mounted with `access` are always served. A collection mounted without `access` is SystemAdmin only.',
|
|
85
130
|
"Text an editor should be able to change belongs in a collection, declared at mount: `createTemplateResolverFeature({ collections: [{ id, kind, access: { roles }, nav }] })`. It appears in the navigation, and `access` is part of the mount because a bundled feature cannot know the host's roles. Each collection gets its own `<id>-list` / `<id>-item` / `<id>-set` handlers, so the dispatcher enforces the separation.",
|
|
86
131
|
"How a collection is edited follows from `contentFormat`: `plain` gives a text area, `rich` a small WYSIWYG (bold, italic, headings, lists, links), `markdown` a text area that stores markdown text (same insertable chips as `plain`). All three offer the collection's `variableSchema` as insertable chips and a preview rendered with sample data — an editor sees what `{{firstName}}` becomes without sending a mail. An app can register its own editor for a format; the last `clientFeature` that registers a format wins (a conflict logs a warning).",
|
|
87
132
|
'A collection is tenant-wide by default. With `ownership: "user"` every user keeps their own entries — mail signatures being the obvious case. Those rows live in the separate `user-content-entry` entity and count as user data, so mounting one also requires the `template-resolver-user-data` feature and a migration on the app side.',
|
|
88
133
|
"`validate` dry-runs the write pipeline for a draft (sanitizer, layout rules, placeholders) and reports what the template uses and misses. `export-bundle` / `import-bundle` (and `import-bundle-system`) move one template with all locales and resource files between tenants or environments; `copy-locale` starts a translation from an existing locale. Layouts are structured: a mail or PDF layout is `data-header` / `data-content` / `data-signature` / `data-footer` regions, and mjml layout source is system-only.",
|
|
89
|
-
"`preview` renders a draft (or the stored template) with sample values taken from the `example` of each declared variable, through the same gates and the same mail renderer as a real send, and returns subject, html, `displayHtml` (the html with cid images as data URIs for an editor), text, attachments (inline images and files) and `checks` (images resolved, plain text present, size under 10 MiB, required placeholders used); nothing is saved or sent. `send-test` mails that rendering to the calling user's own address only, subject prefixed with `[TEST]`, at most 10 per user and hour; it needs `delivery`, `channel-email` and `renderer-mail-html` to be mounted.",
|
|
134
|
+
"`preview` renders a draft (or the stored template) with sample values taken from the `example` of each declared variable, through the same gates and the same mail renderer as a real send, and returns subject, html, `displayHtml` (the html with cid images as data URIs for an editor), text, attachments (inline images and files) and `checks` (images resolved, plain text present, size under 10 MiB, required placeholders used); nothing is saved or sent. `send-test` mails that rendering to the calling user's own address only, subject prefixed with `[TEST]`, at most 10 per user and hour; it needs `delivery`, `channel-email` and `renderer-mail-html` to be mounted. `send-test-status` tells an editor beforehand whether that send can work for the caller (`canSend`, else `reason` `no_channel` or `no_address`), never returning the address.",
|
|
90
135
|
'Images used by a template (`<img data-resource="logo">`) are uploaded with `resourceUpload`, which re-encodes them, stores a file and links it under the key; `resourceRemove` unlinks it. `linkedResources` is written only through these two handlers. With `purpose: "attachment"` and a `fileName`, `resourceUpload` stores a PDF, PNG or JPEG as a file attachment of a mail template (original bytes, at most 10) that the mail renderer attaches after the inline images. `resourceLinkPdf` instead links a `document-pdf` template under a key: every mail sent from the template then carries that PDF, rendered at send time with the mail\'s own variables and locale, under a file name pattern such as `invoice-{{number}}.pdf`; files and linked PDFs share the limit of 10.',
|
|
91
136
|
"Replaces the former `text-content` feature; its blocks now live here as kind `text-block`.",
|
|
92
137
|
].join("\n\n"),
|
|
@@ -101,6 +146,7 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
101
146
|
resourceMaxBytes: createSystemConfig("number", { default: 2_097_152, bounds: { min: 1 } }),
|
|
102
147
|
},
|
|
103
148
|
});
|
|
149
|
+
r.translations({ keys: TEMPLATE_RESOLVER_I18N });
|
|
104
150
|
r.entity({ name: "template-resource", ...templateResourceEntity });
|
|
105
151
|
// Only when the app actually mounts a user-owned collection: the entity's
|
|
106
152
|
// `content` is `userOwned`, which makes it subject data — the boot guard
|
|
@@ -110,23 +156,23 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
110
156
|
|
|
111
157
|
const handlers = {
|
|
112
158
|
upsertSystem: r.writeHandler(upsertSystemWrite),
|
|
113
|
-
upsertTenant: r.writeHandler(
|
|
114
|
-
publish: r.writeHandler(
|
|
115
|
-
archive: r.writeHandler(
|
|
116
|
-
publishSystem: r.writeHandler(
|
|
117
|
-
archiveSystem: r.writeHandler(
|
|
118
|
-
discardDraft: r.writeHandler(
|
|
119
|
-
discardDraftSystem: r.writeHandler(
|
|
120
|
-
resetToSystem: r.writeHandler(
|
|
121
|
-
set: r.writeHandler(
|
|
122
|
-
importBundle: r.writeHandler(
|
|
159
|
+
upsertTenant: r.writeHandler(makeUpsertTenantWrite(policy)),
|
|
160
|
+
publish: r.writeHandler(makePublishWrite(policy)),
|
|
161
|
+
archive: r.writeHandler(makeArchiveWrite(policy)),
|
|
162
|
+
publishSystem: r.writeHandler(makePublishSystemWrite(policy)),
|
|
163
|
+
archiveSystem: r.writeHandler(makeArchiveSystemWrite(policy)),
|
|
164
|
+
discardDraft: r.writeHandler(makeDiscardDraftWrite(policy)),
|
|
165
|
+
discardDraftSystem: r.writeHandler(makeDiscardDraftSystemWrite(policy)),
|
|
166
|
+
resetToSystem: r.writeHandler(makeResetToSystemWrite(policy)),
|
|
167
|
+
set: r.writeHandler(makeSetWrite(policy)),
|
|
168
|
+
importBundle: r.writeHandler(makeImportBundleWrite(policy)),
|
|
123
169
|
importBundleSystem: r.writeHandler(importBundleSystemWrite),
|
|
124
|
-
copyLocale: r.writeHandler(
|
|
125
|
-
resourceUpload: r.writeHandler(
|
|
126
|
-
resourceRemove: r.writeHandler(
|
|
127
|
-
resourceLinkPdf: r.writeHandler(
|
|
128
|
-
sendTest: r.writeHandler(
|
|
129
|
-
patchDraft: r.writeHandler(
|
|
170
|
+
copyLocale: r.writeHandler(makeCopyLocaleWrite(policy)),
|
|
171
|
+
resourceUpload: r.writeHandler(makeResourceUploadWrite(policy)),
|
|
172
|
+
resourceRemove: r.writeHandler(makeResourceRemoveWrite(policy)),
|
|
173
|
+
resourceLinkPdf: r.writeHandler(makeResourceLinkPdfWrite(policy)),
|
|
174
|
+
sendTest: r.writeHandler(makeSendTestWrite(policy)),
|
|
175
|
+
patchDraft: r.writeHandler(makePatchDraftWrite(policy)),
|
|
130
176
|
};
|
|
131
177
|
|
|
132
178
|
const queries = {
|
|
@@ -135,7 +181,7 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
135
181
|
bySlug: r.queryHandler(bySlugQuery),
|
|
136
182
|
byTenant: r.queryHandler(byTenantQuery),
|
|
137
183
|
usage: r.queryHandler(usageQuery),
|
|
138
|
-
overview: r.queryHandler(
|
|
184
|
+
overview: r.queryHandler(makeOverviewQuery(policy)),
|
|
139
185
|
layoutSource: r.queryHandler(layoutSourceQuery),
|
|
140
186
|
tenantOverrides: r.queryHandler(tenantOverridesQuery),
|
|
141
187
|
diffToSystem: r.queryHandler(diffToSystemQuery),
|
|
@@ -143,13 +189,17 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
143
189
|
preview: r.queryHandler(previewQuery),
|
|
144
190
|
documentBlocks: r.queryHandler(documentBlocksQuery),
|
|
145
191
|
exportBundle: r.queryHandler(exportBundleQuery),
|
|
192
|
+
sendTestStatus: r.queryHandler(sendTestStatusQuery),
|
|
146
193
|
};
|
|
147
194
|
|
|
148
195
|
for (const collection of collections) {
|
|
149
|
-
r.contentCollection(
|
|
196
|
+
r.contentCollection({
|
|
197
|
+
...collection,
|
|
198
|
+
access: collection.access ?? DEFAULT_COLLECTION_ACCESS,
|
|
199
|
+
});
|
|
150
200
|
r.queryHandler(makeCollectionListQuery(collection));
|
|
151
201
|
r.queryHandler(makeCollectionItemQuery(collection));
|
|
152
|
-
r.writeHandler(makeCollectionSetWrite(collection));
|
|
202
|
+
r.writeHandler(makeCollectionSetWrite(collection, policy));
|
|
153
203
|
}
|
|
154
204
|
|
|
155
205
|
// Visual-tree actions for the text-block content tree. The handle is
|
|
@@ -163,6 +213,6 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
163
213
|
create: { args: { folder: emptyString } },
|
|
164
214
|
});
|
|
165
215
|
|
|
166
|
-
return { handlers, queries, treeHandle };
|
|
216
|
+
return { handlers, queries, treeHandle, deliveryPolicy };
|
|
167
217
|
});
|
|
168
218
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import * as z from "zod";
|
|
4
|
-
import {
|
|
4
|
+
import { isRowDeliveredTo } from "../api.ts";
|
|
5
5
|
import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
|
|
6
|
+
import { deliveryPolicyOf } from "../template-delivery-policy.ts";
|
|
7
|
+
import { TEXT_BLOCK_KIND } from "../web/constants.ts";
|
|
6
8
|
|
|
7
9
|
// Public read of a single text-block by (tenantId, slug, locale). Anonymous
|
|
8
10
|
// must be listed explicitly — `openToAll` alone is auth-only (regression
|
|
@@ -39,6 +41,9 @@ export const bySlugQuery = defineQueryHandler({
|
|
|
39
41
|
});
|
|
40
42
|
|
|
41
43
|
if (!row) return null;
|
|
44
|
+
if (!(await isRowDeliveredTo(ctx.db, deliveryPolicyOf(ctx.registry), query.user, row))) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
42
47
|
return {
|
|
43
48
|
slug: row.slug,
|
|
44
49
|
locale: row.locale,
|
|
@@ -2,8 +2,10 @@ import { castTenantRows, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
|
2
2
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
4
4
|
import * as z from "zod";
|
|
5
|
-
import {
|
|
5
|
+
import { filterDeliveredTo } from "../api.ts";
|
|
6
6
|
import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
|
|
7
|
+
import { deliveryPolicyOf } from "../template-delivery-policy.ts";
|
|
8
|
+
import { TEXT_BLOCK_KIND } from "../web/constants.ts";
|
|
7
9
|
|
|
8
10
|
// All text-blocks of one tenant — feeds the public content tree sidebar.
|
|
9
11
|
// Anonymous is listed explicitly so no-JWT visitors get the sidebar on public
|
|
@@ -39,8 +41,10 @@ export const byTenantQuery = defineQueryHandler({
|
|
|
39
41
|
const rows = castTenantRows<TemplateResourceRow>(
|
|
40
42
|
await selectMany(ctx.db, templateResourcesTable, { tenantId, kind: TEXT_BLOCK_KIND }),
|
|
41
43
|
);
|
|
44
|
+
const policy = deliveryPolicyOf(ctx.registry);
|
|
45
|
+
const served = await filterDeliveredTo(ctx.db, policy, query.user, rows);
|
|
42
46
|
return {
|
|
43
|
-
blocks:
|
|
47
|
+
blocks: served.map((row) => ({
|
|
44
48
|
slug: row.slug,
|
|
45
49
|
locale: row.locale,
|
|
46
50
|
title: row.title,
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
defineQueryHandler,
|
|
5
5
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
6
6
|
import * as z from "zod";
|
|
7
|
+
import { DEFAULT_COLLECTION_ACCESS } from "../web/constants.ts";
|
|
7
8
|
import {
|
|
8
9
|
type CollectionEntryRow,
|
|
9
10
|
collectionStore,
|
|
10
|
-
DEFAULT_COLLECTION_ACCESS,
|
|
11
11
|
toCollectionEntry,
|
|
12
12
|
} from "./collection-shared.ts";
|
|
13
13
|
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
defineQueryHandler,
|
|
5
5
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
6
6
|
import * as z from "zod";
|
|
7
|
+
import { DEFAULT_COLLECTION_ACCESS } from "../web/constants.ts";
|
|
7
8
|
import {
|
|
8
9
|
type CollectionEntryRow,
|
|
9
10
|
collectionStore,
|
|
10
|
-
DEFAULT_COLLECTION_ACCESS,
|
|
11
11
|
toCollectionEntry,
|
|
12
12
|
} from "./collection-shared.ts";
|
|
13
13
|
|
|
@@ -7,13 +7,11 @@ import {
|
|
|
7
7
|
import { ValidationError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
8
8
|
import * as z from "zod";
|
|
9
9
|
import { requireForTenant } from "../../shared/index.ts";
|
|
10
|
-
import {
|
|
10
|
+
import { systemTemplateExists } from "../api.ts";
|
|
11
11
|
import { documentViolationsToFieldIssues, sanitizeTemplateBody } from "../document-sanitizer.ts";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
DEFAULT_COLLECTION_ACCESS,
|
|
16
|
-
} from "./collection-shared.ts";
|
|
12
|
+
import { refuseTemplateEdit, type TemplateEditPolicy } from "../template-edit-policy.ts";
|
|
13
|
+
import { DEFAULT_COLLECTION_ACCESS, isCollectionRefusedKind } from "../web/constants.ts";
|
|
14
|
+
import { type CollectionEntryRow, collectionStore } from "./collection-shared.ts";
|
|
17
15
|
import { contentFormatSchema, folderSchema, localeSchema, slugSchema } from "./shared.ts";
|
|
18
16
|
|
|
19
17
|
// Upsert inside one collection. Mirrors set.write for text-blocks, but the
|
|
@@ -23,7 +21,10 @@ import { contentFormatSchema, folderSchema, localeSchema, slugSchema } from "./s
|
|
|
23
21
|
//
|
|
24
22
|
// Like set.write this publishes on save (status active, empty variableSchema)
|
|
25
23
|
// — the draft stage lives on upsertTenant + publish.
|
|
26
|
-
export function makeCollectionSetWrite(
|
|
24
|
+
export function makeCollectionSetWrite(
|
|
25
|
+
collection: ContentCollectionDefinition,
|
|
26
|
+
editPolicy: TemplateEditPolicy,
|
|
27
|
+
) {
|
|
27
28
|
const store = collectionStore(collection);
|
|
28
29
|
return defineWriteHandler({
|
|
29
30
|
name: `${collection.id}-set`,
|
|
@@ -79,6 +80,18 @@ export function makeCollectionSetWrite(collection: ContentCollectionDefinition)
|
|
|
79
80
|
);
|
|
80
81
|
}
|
|
81
82
|
|
|
83
|
+
// The collection's access must not open a system template that the app did not unlock.
|
|
84
|
+
if (
|
|
85
|
+
collection.ownership !== "user" &&
|
|
86
|
+
(await systemTemplateExists(db, collection.kind, event.payload.slug))
|
|
87
|
+
) {
|
|
88
|
+
const refused = refuseTemplateEdit(editPolicy, event.user, {
|
|
89
|
+
slug: event.payload.slug,
|
|
90
|
+
kind: collection.kind,
|
|
91
|
+
});
|
|
92
|
+
if (refused) return refused;
|
|
93
|
+
}
|
|
94
|
+
|
|
82
95
|
const existing = await fetchOne<CollectionEntryRow>(db, store.table, {
|
|
83
96
|
tenantId,
|
|
84
97
|
slug: event.payload.slug,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { EventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
import type {
|
|
4
|
-
AccessRule,
|
|
5
4
|
ContentCollectionDefinition,
|
|
6
5
|
SessionUser,
|
|
7
6
|
TenantId,
|
|
@@ -11,11 +10,6 @@ import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
|
11
10
|
import { templateResourceEntity, templateResourcesTable } from "../table.ts";
|
|
12
11
|
import { userContentEntriesTable, userContentEntryEntity } from "../user-content-table.ts";
|
|
13
12
|
|
|
14
|
-
// Applies when an app mounts a collection without saying who may reach it.
|
|
15
|
-
// Deliberately narrow: a collection whose access nobody decided should be
|
|
16
|
-
// invisible to normal users rather than open by default.
|
|
17
|
-
export const DEFAULT_COLLECTION_ACCESS: AccessRule = { roles: ["TenantAdmin", "SystemAdmin"] };
|
|
18
|
-
|
|
19
13
|
const templateExecutor = createEventStoreExecutor(templateResourcesTable, templateResourceEntity, {
|
|
20
14
|
entityName: "template-resource",
|
|
21
15
|
});
|
|
@@ -16,17 +16,22 @@ import {
|
|
|
16
16
|
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
17
17
|
import * as z from "zod";
|
|
18
18
|
import { requireForTenant } from "../../shared/index.ts";
|
|
19
|
-
import { CONTENT_FORMATS, type ContentFormat } from "../constants.ts";
|
|
20
19
|
import { type LinkedResourceEntry, parseLinkedResourceEntries } from "../linked-resources.ts";
|
|
21
|
-
import { TemplateResolverErrors } from "../qualified-names.ts";
|
|
22
20
|
import {
|
|
23
21
|
createLinkedResourceCopies,
|
|
24
22
|
prepareLinkedResourceCopiesBeforeTransaction,
|
|
25
23
|
} from "../store-template-resource.ts";
|
|
26
24
|
import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
|
|
27
25
|
import { toWorkingRow, type WorkingRow } from "../template-draft.ts";
|
|
26
|
+
import {
|
|
27
|
+
refuseTemplateEdit,
|
|
28
|
+
type TemplateEditPolicy,
|
|
29
|
+
templateEditAccess,
|
|
30
|
+
} from "../template-edit-policy.ts";
|
|
28
31
|
import { attachTemplateResources } from "../template-resources.ts";
|
|
29
32
|
import { resolveTemplateVariables } from "../template-validation.ts";
|
|
33
|
+
import { CONTENT_FORMATS, type ContentFormat } from "../web/constants.ts";
|
|
34
|
+
import { TemplateResolverErrors } from "../web/qualified-names.ts";
|
|
30
35
|
import { targetExistsIssue } from "./bundle-import.ts";
|
|
31
36
|
import { kindSchema, localeSchema, templateSlugSchema } from "./shared.ts";
|
|
32
37
|
import { parseStoredJson, storedRecord } from "./template-gates.ts";
|
|
@@ -97,6 +102,7 @@ type CopyRequest = {
|
|
|
97
102
|
// Runs before the upload (reject early, store nothing) and again in the transaction on the fresh rows.
|
|
98
103
|
async function checkCopyRequest(
|
|
99
104
|
ctx: WriteCtx,
|
|
105
|
+
policy: TemplateEditPolicy,
|
|
100
106
|
event: {
|
|
101
107
|
readonly user: SessionUser;
|
|
102
108
|
readonly payload: z.infer<typeof copyLocaleSchema>;
|
|
@@ -113,6 +119,7 @@ async function checkCopyRequest(
|
|
|
113
119
|
}
|
|
114
120
|
const tenantId = scope === "system" ? SYSTEM_TENANT_ID : event.user.tenantId;
|
|
115
121
|
const refused =
|
|
122
|
+
(scope === "tenant" ? refuseTemplateEdit(policy, event.user, { slug, kind }) : null) ??
|
|
116
123
|
refuseTenantScopeUnderSystemTenant(scope, tenantId) ??
|
|
117
124
|
refuseSystemOnlyTenantOverride(ctx.registry, scope, slug, kind);
|
|
118
125
|
if (refused !== null) return refused;
|
|
@@ -155,62 +162,64 @@ async function checkCopyRequest(
|
|
|
155
162
|
};
|
|
156
163
|
}
|
|
157
164
|
|
|
158
|
-
export
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
165
|
+
export function makeCopyLocaleWrite(policy: TemplateEditPolicy) {
|
|
166
|
+
return defineWriteHandler({
|
|
167
|
+
name: "copy-locale",
|
|
168
|
+
schema: copyLocaleSchema,
|
|
169
|
+
access: templateEditAccess(policy.tenantEditable),
|
|
170
|
+
description:
|
|
171
|
+
"Copies the text of one locale of a template into another locale as a draft override of the caller's tenant, taking the tenant's own row or else the system default as the source; use it as the starting point for a translation. It refuses an existing target unless overwrite is set. With scope system (SystemAdmin only) both source and target are system-default rows and the target lands as a system draft; any other caller gets a 403. A TenantAdmin may copy only templates the app lists in tenantEditable, otherwise SystemAdmin only.",
|
|
172
|
+
beforeTransaction: async (event, ctx) => {
|
|
173
|
+
const request = await checkCopyRequest(ctx, policy, event);
|
|
174
|
+
if (!request.isSuccess) return request;
|
|
175
|
+
if (!request.data.sourceIsForeign) return { isSuccess: true, data: [] };
|
|
176
|
+
return prepareLinkedResourceCopiesBeforeTransaction({
|
|
177
|
+
ctx,
|
|
178
|
+
user: event.user,
|
|
179
|
+
tenantId: request.data.tenantId,
|
|
180
|
+
resources: request.data.sourceResources,
|
|
181
|
+
});
|
|
182
|
+
},
|
|
183
|
+
handler: async (event, ctx) => {
|
|
184
|
+
const { slug, kind, toLocale } = event.payload;
|
|
185
|
+
const request = await checkCopyRequest(ctx, policy, event);
|
|
186
|
+
if (!request.isSuccess) return request;
|
|
187
|
+
const { scope, tenantId, source, contentFormat, sourceResources, sourceIsForeign } =
|
|
188
|
+
request.data;
|
|
181
189
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
});
|
|
190
|
+
const variableSchema = storedRecord(source.variableSchema);
|
|
191
|
+
const written = await writeTemplateRow({
|
|
192
|
+
ctx,
|
|
193
|
+
user: event.user,
|
|
194
|
+
tenantId,
|
|
195
|
+
scope,
|
|
196
|
+
status: "draft",
|
|
197
|
+
variables: resolveTemplateVariables(ctx.registry, slug, variableSchema),
|
|
198
|
+
payload: {
|
|
199
|
+
slug,
|
|
200
|
+
kind,
|
|
201
|
+
locale: toLocale,
|
|
202
|
+
content: source.content,
|
|
203
|
+
contentFormat,
|
|
204
|
+
variableSchema,
|
|
205
|
+
meta: parseStoredJson(source.meta),
|
|
206
|
+
title: source.title,
|
|
207
|
+
folder: source.folder,
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
if (!written.isSuccess) return written;
|
|
211
|
+
const resources = sourceIsForeign
|
|
212
|
+
? await createLinkedResourceCopies({ ctx, user: event.user, tenantId }, event.prepared)
|
|
213
|
+
: { isSuccess: true as const, data: sourceResources };
|
|
214
|
+
if (!resources.isSuccess) return resources;
|
|
215
|
+
const attached = await attachTemplateResources(ctx, {
|
|
216
|
+
user: event.user,
|
|
217
|
+
tenantId,
|
|
218
|
+
templateId: written.data.id,
|
|
219
|
+
resources: resources.data,
|
|
220
|
+
});
|
|
221
|
+
if (!attached.isSuccess) return attached;
|
|
222
|
+
return written;
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
}
|
|
@@ -3,6 +3,7 @@ import { defineQueryHandler, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framew
|
|
|
3
3
|
import { NotFoundError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
|
|
6
|
+
import { deliveryPolicyOf, isRowServedTo } from "../template-delivery-policy.ts";
|
|
6
7
|
import { isHiddenSystemDraft } from "../template-draft.ts";
|
|
7
8
|
import { buildOverrideDiff } from "./override-diff.ts";
|
|
8
9
|
|
|
@@ -16,7 +17,12 @@ export const diffToSystemQuery = defineQueryHandler({
|
|
|
16
17
|
const tenantRow = await fetchOne<TemplateResourceRow>(ctx.db, templateResourcesTable, {
|
|
17
18
|
id: query.payload.id,
|
|
18
19
|
});
|
|
19
|
-
if (
|
|
20
|
+
if (
|
|
21
|
+
!tenantRow ||
|
|
22
|
+
tenantRow.tenantId !== query.user.tenantId ||
|
|
23
|
+
tenantRow.scope !== "tenant" ||
|
|
24
|
+
!isRowServedTo(deliveryPolicyOf(ctx.registry), query.user, tenantRow)
|
|
25
|
+
) {
|
|
20
26
|
throw new NotFoundError("template-resource", query.payload.id);
|
|
21
27
|
}
|
|
22
28
|
const systemRow = await fetchOne<TemplateResourceRow>(ctx.db, templateResourcesTable, {
|
|
@@ -1,20 +1,37 @@
|
|
|
1
1
|
import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import { NotFoundError, ValidationError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
3
3
|
import * as z from "zod";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
refuseMissingTemplate,
|
|
6
|
+
refuseTemplateEdit,
|
|
7
|
+
type TemplateEditPolicy,
|
|
8
|
+
} from "../template-edit-policy.ts";
|
|
9
|
+
import { TemplateResolverErrors } from "../web/qualified-names.ts";
|
|
5
10
|
import { executor } from "./shared.ts";
|
|
6
11
|
import { loadTargetRow, type StatusTarget, writeAccessFor } from "./toggle-status.write.ts";
|
|
7
12
|
|
|
8
|
-
function createDiscardDraftHandler(
|
|
13
|
+
function createDiscardDraftHandler(
|
|
14
|
+
policy: TemplateEditPolicy,
|
|
15
|
+
name: string,
|
|
16
|
+
target: StatusTarget,
|
|
17
|
+
description: string,
|
|
18
|
+
) {
|
|
9
19
|
return defineWriteHandler({
|
|
10
20
|
name,
|
|
11
21
|
schema: z.object({ id: z.string().min(1) }),
|
|
12
|
-
access: writeAccessFor(target),
|
|
22
|
+
access: writeAccessFor(target, policy),
|
|
13
23
|
...(target === "system" ? { agent: { risk: "high" as const } } : {}),
|
|
14
24
|
description,
|
|
15
25
|
handler: async (event, ctx) => {
|
|
16
26
|
const { db, scoped, row } = await loadTargetRow(ctx, target, event.user, event.payload.id);
|
|
17
|
-
if (!row)
|
|
27
|
+
if (!row) {
|
|
28
|
+
const refused = target === "own" ? refuseMissingTemplate(policy, event.user) : null;
|
|
29
|
+
return refused ?? writeFailure(new NotFoundError("template-resource", event.payload.id));
|
|
30
|
+
}
|
|
31
|
+
if (target === "own") {
|
|
32
|
+
const refused = refuseTemplateEdit(policy, event.user, row);
|
|
33
|
+
if (refused !== null) return refused;
|
|
34
|
+
}
|
|
18
35
|
if (row.draft === null) {
|
|
19
36
|
return writeFailure(
|
|
20
37
|
new ValidationError({
|
|
@@ -40,13 +57,19 @@ function createDiscardDraftHandler(name: string, target: StatusTarget, descripti
|
|
|
40
57
|
});
|
|
41
58
|
}
|
|
42
59
|
|
|
43
|
-
export
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
export function makeDiscardDraftWrite(policy: TemplateEditPolicy) {
|
|
61
|
+
return createDiscardDraftHandler(
|
|
62
|
+
policy,
|
|
63
|
+
"discard-draft",
|
|
64
|
+
"own",
|
|
65
|
+
"Throws away the open draft of one template resource of the caller's tenant so the editor shows the active version again; the served version is untouched. Refused with no_draft when there is no draft. Outside the templates the app lists in tenantEditable only a SystemAdmin may use it.",
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
export function makeDiscardDraftSystemWrite(policy: TemplateEditPolicy) {
|
|
69
|
+
return createDiscardDraftHandler(
|
|
70
|
+
policy,
|
|
71
|
+
"discard-draft-system",
|
|
72
|
+
"system",
|
|
73
|
+
"Throws away the open draft of one system-default template; the served version stays. SystemAdmin only, refused with no_draft when there is no draft.",
|
|
74
|
+
);
|
|
75
|
+
}
|