@cosmicdrift/kumiko-samples 0.378.0 → 0.380.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-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 +0 -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/global-feature-state-table.ts +14 -13
- 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/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/job-run-table.ts +4 -3
- 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/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 +3 -3
- 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/schema/user-session.ts +2 -3
- 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 +43 -0
- package/packages/bundled-features/src/template-resolver/compile-document-body.ts +1 -1
- 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 +4 -4
- package/packages/bundled-features/src/template-resolver/feature.ts +13 -4
- 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 +19 -2
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +2 -2
- 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 +1 -1
- 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/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 +68 -10
- package/packages/bundled-features/src/template-resolver/handlers/patch-draft.write.ts +1 -1
- 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 +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +1 -1
- 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/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 +60 -59
- 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 +2 -2
- package/packages/bundled-features/src/template-resolver/template-meta.ts +2 -2
- package/packages/bundled-features/src/template-resolver/template-preview.ts +14 -10
- package/packages/bundled-features/src/template-resolver/template-usage.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-validation.ts +2 -2
- 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} +7 -10
- package/packages/bundled-features/src/template-resolver/{document-blocks.ts → web/document-blocks.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/web/document-editor-extensions.ts +2 -3
- package/packages/bundled-features/src/template-resolver/web/document-editor.tsx +0 -1
- package/packages/bundled-features/src/template-resolver/{document-images.ts → web/document-images.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/{document-schema.ts → web/document-schema.ts} +0 -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 +6 -7
- package/packages/bundled-features/src/template-resolver/web/document-toolbar-blocks.ts +2 -3
- package/packages/bundled-features/src/template-resolver/web/editor-handle.ts +1 -2
- package/packages/bundled-features/src/template-resolver/web/i18n.ts +2 -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} +0 -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/seed-rental.ts +17 -1
- package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +11 -0
- package/samples/apps/ui-walkthrough/src/app/server.ts +2 -1
- 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 +61 -7
- package/samples/apps/ui-walkthrough/src/features/rental/i18n.ts +48 -24
- package/samples/apps/ui-walkthrough/src/features/rental/invoice-receive.ts +0 -1
- package/samples/apps/ui-walkthrough/src/features/rental/lease-support.ts +17 -1
- package/samples/apps/ui-walkthrough/src/features/rental/qualified-names.ts +3 -0
- package/samples/apps/ui-walkthrough/src/features/rental/receipts-upload.ts +70 -0
- package/samples/apps/ui-walkthrough/src/features/rental/screens.ts +90 -13
- package/samples/apps/ui-walkthrough/src/features/rental/web/index.ts +0 -2
- 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/run-config.ts +11 -0
- package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +1 -1
- package/samples/apps/use-all-bundled/feature-manifest.json +4 -4
- 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/embedded/README.md +5 -5
- package/samples/recipes/embedded/src/handlers/invoice-receive.write.ts +0 -1
- package/samples/recipes/embedded/src/screens/invoice-receive.screen.ts +9 -12
- 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
- package/samples/apps/ui-walkthrough/src/features/rental/web/upload-standard-layout.tsx +0 -61
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// TagFilter — a drop-in tag filter for ANY entityList toolbar. Register it as
|
|
3
2
|
// the list's header slot (`screen.slots.header`); the renderer passes it the
|
|
4
3
|
// list's screenId, and picking tags resolves the matching row ids and narrows
|
|
@@ -20,7 +19,7 @@ import {
|
|
|
20
19
|
useTranslation,
|
|
21
20
|
} from "@cosmicdrift/kumiko-renderer";
|
|
22
21
|
import { type ReactNode, useState } from "react";
|
|
23
|
-
import { TagsQueries } from "
|
|
22
|
+
import { TagsQueries } from "./constants.ts";
|
|
24
23
|
import { TagChip } from "./tag-chip.tsx";
|
|
25
24
|
import { TagPicker } from "./tag-picker.tsx";
|
|
26
25
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// TagManager — the shared tag-catalog UI, GitLab-labels style. Built ONCE,
|
|
3
2
|
// mounted twice:
|
|
4
3
|
// - standalone: <TagManager /> → the Tags admin screen
|
|
@@ -16,8 +15,9 @@ import {
|
|
|
16
15
|
useQuery,
|
|
17
16
|
useTranslation,
|
|
18
17
|
} from "@cosmicdrift/kumiko-renderer";
|
|
18
|
+
import { pluralKey } from "@cosmicdrift/kumiko-renderer/headless";
|
|
19
19
|
import { type ReactNode, useState } from "react";
|
|
20
|
-
import { TagsHandlers, TagsQueries } from "
|
|
20
|
+
import { TagsHandlers, TagsQueries } from "./constants.ts";
|
|
21
21
|
import { TagChip } from "./tag-chip.tsx";
|
|
22
22
|
|
|
23
23
|
type TagRow = {
|
|
@@ -139,6 +139,7 @@ export function TagManager({
|
|
|
139
139
|
const usage = new Map<string, number>();
|
|
140
140
|
for (const a of assignments.data?.rows ?? []) usage.set(a.tagId, (usage.get(a.tagId) ?? 0) + 1);
|
|
141
141
|
|
|
142
|
+
const deletingUsage = usage.get(deleting?.id ?? "") ?? 0;
|
|
142
143
|
const selecting = selection !== undefined;
|
|
143
144
|
const allTags = catalog.data?.rows ?? [];
|
|
144
145
|
const tags = selecting
|
|
@@ -378,8 +379,8 @@ export function TagManager({
|
|
|
378
379
|
if (!open) setDeleting(null);
|
|
379
380
|
}}
|
|
380
381
|
title={t("tags.manage.deleteConfirmTitle", { name: deleting?.name ?? "" })}
|
|
381
|
-
description={t("tags.manage.deleteConfirmDesc", {
|
|
382
|
-
count:
|
|
382
|
+
description={t(pluralKey("tags.manage.deleteConfirmDesc", deletingUsage), {
|
|
383
|
+
count: deletingUsage,
|
|
383
384
|
})}
|
|
384
385
|
confirmLabel={t("tags.manage.delete")}
|
|
385
386
|
variant="danger"
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// TagSection — drop-in tag editor for ANY entity, GitLab-labels style. Shows the
|
|
3
2
|
// entity's tags as colored chips plus an "Edit tags" button that opens the
|
|
4
3
|
// shared TagPicker modal (pick + manage). Applying the picker diffs the
|
|
@@ -19,7 +18,7 @@ import {
|
|
|
19
18
|
useTranslation,
|
|
20
19
|
} from "@cosmicdrift/kumiko-renderer";
|
|
21
20
|
import { type ReactNode, useState } from "react";
|
|
22
|
-
import { TagsHandlers, TagsQueries } from "
|
|
21
|
+
import { TagsHandlers, TagsQueries } from "./constants.ts";
|
|
23
22
|
import { TagChip } from "./tag-chip.tsx";
|
|
24
23
|
import { TagPicker } from "./tag-picker.tsx";
|
|
25
24
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// TagsCell — a reusable columnRenderer that shows an entity's tags as colored
|
|
3
2
|
// chips inline in a list row. Drop it into ANY entityList by declaring a labeled
|
|
4
3
|
// virtual column (no host-schema change), after mounting tagsClient():
|
|
@@ -17,7 +16,7 @@
|
|
|
17
16
|
|
|
18
17
|
import { type ColumnRendererProps, useQuery } from "@cosmicdrift/kumiko-renderer";
|
|
19
18
|
import type { ReactNode } from "react";
|
|
20
|
-
import { TagsQueries } from "
|
|
19
|
+
import { TagsQueries } from "./constants.ts";
|
|
21
20
|
import { TagChip } from "./tag-chip.tsx";
|
|
22
21
|
|
|
23
22
|
type TagRow = { readonly id: string; readonly name: string; readonly color?: string | null };
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
|
|
6
6
|
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
7
|
-
import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
7
|
+
import type { Registry, SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
8
8
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
9
9
|
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
10
10
|
import type { FileAttachmentRef } from "../renderer-foundation/index.ts";
|
|
11
|
-
import type { ContentFormat, TemplateKind } from "./constants.ts";
|
|
12
|
-
import { FALLBACK_LOCALE, SYSTEM_TENANT_ID } from "./constants.ts";
|
|
13
11
|
import {
|
|
14
12
|
fileAttachmentsOf,
|
|
15
13
|
imageLinksOf,
|
|
@@ -18,8 +16,16 @@ import {
|
|
|
18
16
|
type TemplatePdfAttachmentLink,
|
|
19
17
|
} from "./linked-resources.ts";
|
|
20
18
|
import { type TemplateResourceRow, templateResourcesTable } from "./table.ts";
|
|
21
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
deliveryPolicyOf,
|
|
21
|
+
isRowServed,
|
|
22
|
+
isServedByCollectionOnly,
|
|
23
|
+
type TemplateDeliveryPolicy,
|
|
24
|
+
} from "./template-delivery-policy.ts";
|
|
25
|
+
import { activeVersionOf, isSystemAdmin, servedVersionOf } from "./template-draft.ts";
|
|
22
26
|
import { parseTemplateMeta, type TemplateMeta } from "./template-meta.ts";
|
|
27
|
+
import type { ContentFormat, TemplateKind } from "./web/constants.ts";
|
|
28
|
+
import { FALLBACK_LOCALE, SYSTEM_TENANT_ID } from "./web/constants.ts";
|
|
23
29
|
|
|
24
30
|
// Public TemplateResource: what consumers see. Hides DB-internal columns
|
|
25
31
|
// (insertedById, internal id-type) but keeps the fields needed for rendering.
|
|
@@ -68,15 +74,11 @@ export type ResolveLayoutRequest = {
|
|
|
68
74
|
|
|
69
75
|
export type TemplateResolverApi = {
|
|
70
76
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* `resolveTemplate` nutzen.
|
|
77
|
+
* Raw lookup by (tenantId, slug, kind, locale): no locale fallback, no override
|
|
78
|
+
* hierarchy. Render paths must use `resolveTemplate`. `scope: "system"` forces
|
|
79
|
+
* SYSTEM_TENANT_ID and ignores the passed tenantId.
|
|
75
80
|
*
|
|
76
|
-
*
|
|
77
|
-
* den übergebenen tenantId). Default = Lookup gegen den übergebenen
|
|
78
|
-
* tenantId direkt (Caller wählt entweder Tenant oder System per
|
|
79
|
-
* tenantId).
|
|
81
|
+
* Tenant rows of a template that is not tenantEditable are not returned.
|
|
80
82
|
*/
|
|
81
83
|
readonly findExact: (args: {
|
|
82
84
|
readonly tenantId: TenantId;
|
|
@@ -87,18 +89,10 @@ export type TemplateResolverApi = {
|
|
|
87
89
|
}) => Promise<TemplateResource | null>;
|
|
88
90
|
|
|
89
91
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* 4. system + FALLBACK_LOCALE
|
|
95
|
-
* Resource-Substitution wird hier NICHT ausgeführt — das macht der
|
|
96
|
-
* Caller (renderer-foundation-Plugin) je nach kind-passendem Modus
|
|
97
|
-
* (inline-base64 vs. signed-url). API liefert TemplateResource pur.
|
|
98
|
-
*
|
|
99
|
-
* **Caller-Invariante:** `tenantId` MUSS vom Server kommen (typisch
|
|
100
|
-
* `ctx.user.tenantId`). Niemals direkt aus User-Input — sonst kann
|
|
101
|
-
* User cross-tenant Templates abfragen (Tenant-Isolation gebrochen).
|
|
92
|
+
* Four-step fallback: tenant+locale, system+locale, tenant+FALLBACK_LOCALE,
|
|
93
|
+
* system+FALLBACK_LOCALE (see template-resolver.md).
|
|
94
|
+
* Tenant rows count only for templates unlocked for tenants (tenantEditable,
|
|
95
|
+
* or a collection with access); locked overrides are skipped but stay stored.
|
|
102
96
|
*/
|
|
103
97
|
readonly resolveTemplate: (args: ResolveRequest) => Promise<TemplateResource>;
|
|
104
98
|
|
|
@@ -114,12 +108,18 @@ export type TemplateResolverApi = {
|
|
|
114
108
|
readonly resolveLayout: (args: ResolveLayoutRequest) => Promise<TemplateResource>;
|
|
115
109
|
};
|
|
116
110
|
|
|
117
|
-
export function createTemplateResolverApi(
|
|
111
|
+
export function createTemplateResolverApi(
|
|
112
|
+
db: DbRunner | TenantDb,
|
|
113
|
+
registry: Registry,
|
|
114
|
+
): TemplateResolverApi {
|
|
115
|
+
const deliveryPolicy = deliveryPolicyOf(registry);
|
|
116
|
+
// A collection entry must not shadow a system template of the same slug that the app did not unlock.
|
|
117
|
+
const isServed = (row: TemplateResourceRow) => isRowDelivered(db, deliveryPolicy, row);
|
|
118
118
|
return {
|
|
119
119
|
findExact: async ({ tenantId, slug, kind, locale, scope }) => {
|
|
120
120
|
const effectiveTenantId = scope === "system" ? SYSTEM_TENANT_ID : tenantId;
|
|
121
121
|
const row = await fetchTemplate(db, effectiveTenantId, slug, kind, locale);
|
|
122
|
-
return row ? toPublic(row) : null;
|
|
122
|
+
return row && (await isServed(row)) ? toPublic(row) : null;
|
|
123
123
|
},
|
|
124
124
|
|
|
125
125
|
resolveTemplate: async ({ tenantId, slug, kind, locale }) => {
|
|
@@ -135,14 +135,16 @@ export function createTemplateResolverApi(db: DbRunner | TenantDb): TemplateReso
|
|
|
135
135
|
: []),
|
|
136
136
|
];
|
|
137
137
|
for (const c of candidates) {
|
|
138
|
+
if (!isRowServed(deliveryPolicy, { tenantId: c.tid, kind, slug })) continue;
|
|
138
139
|
const row = await fetchTemplate(db, c.tid, slug, kind, c.loc);
|
|
139
|
-
if (row && row.status === "active") return toPublic(row);
|
|
140
|
+
if (row && row.status === "active" && (await isServed(row))) return toPublic(row);
|
|
140
141
|
}
|
|
141
142
|
throw new TemplateNotFoundError({ slug, kind, locale });
|
|
142
143
|
},
|
|
143
144
|
|
|
144
145
|
resolveLayout: async ({ tenantId, slug, kind, locale }) => {
|
|
145
146
|
for (const tid of [tenantId, SYSTEM_TENANT_ID]) {
|
|
147
|
+
if (!isRowServed(deliveryPolicy, { tenantId: tid, kind, slug })) continue;
|
|
146
148
|
const rows = await selectMany<TemplateResourceRow>(db, templateResourcesTable, {
|
|
147
149
|
tenantId: tid,
|
|
148
150
|
slug,
|
|
@@ -156,6 +158,51 @@ export function createTemplateResolverApi(db: DbRunner | TenantDb): TemplateReso
|
|
|
156
158
|
};
|
|
157
159
|
}
|
|
158
160
|
|
|
161
|
+
// The one delivery rule for a stored row: unlocked, and a collection entry never shadows a system
|
|
162
|
+
// template of the same slug that the app did not unlock.
|
|
163
|
+
export async function isRowDelivered(
|
|
164
|
+
db: DbRunner | TenantDb,
|
|
165
|
+
policy: TemplateDeliveryPolicy,
|
|
166
|
+
row: TemplateResourceRow,
|
|
167
|
+
): Promise<boolean> {
|
|
168
|
+
if (!isRowServed(policy, row)) return false;
|
|
169
|
+
if (row.tenantId === SYSTEM_TENANT_ID || !isServedByCollectionOnly(policy, row)) return true;
|
|
170
|
+
return !(await systemTemplateExists(db, row.kind, row.slug));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export async function isRowDeliveredTo(
|
|
174
|
+
db: DbRunner | TenantDb,
|
|
175
|
+
policy: TemplateDeliveryPolicy,
|
|
176
|
+
user: { readonly roles: readonly string[] },
|
|
177
|
+
row: TemplateResourceRow,
|
|
178
|
+
): Promise<boolean> {
|
|
179
|
+
return isSystemAdmin(user) || (await isRowDelivered(db, policy, row));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export async function filterDeliveredTo(
|
|
183
|
+
db: DbRunner | TenantDb,
|
|
184
|
+
policy: TemplateDeliveryPolicy,
|
|
185
|
+
user: { readonly roles: readonly string[] },
|
|
186
|
+
rows: readonly TemplateResourceRow[],
|
|
187
|
+
): Promise<TemplateResourceRow[]> {
|
|
188
|
+
const flags = await Promise.all(rows.map((row) => isRowDeliveredTo(db, policy, user, row)));
|
|
189
|
+
return rows.filter((_, index) => flags[index]);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export async function systemTemplateExists(
|
|
193
|
+
db: DbRunner | TenantDb,
|
|
194
|
+
kind: string,
|
|
195
|
+
slug: string,
|
|
196
|
+
): Promise<boolean> {
|
|
197
|
+
const rows = await selectMany(
|
|
198
|
+
db,
|
|
199
|
+
templateResourcesTable,
|
|
200
|
+
{ tenantId: SYSTEM_TENANT_ID, slug, kind },
|
|
201
|
+
{ limit: 1 },
|
|
202
|
+
);
|
|
203
|
+
return rows.length > 0;
|
|
204
|
+
}
|
|
205
|
+
|
|
159
206
|
function pickActiveLayoutRow(
|
|
160
207
|
rows: readonly TemplateResourceRow[],
|
|
161
208
|
locale: string,
|
|
@@ -268,7 +315,7 @@ export function requireTemplateResolver(
|
|
|
268
315
|
throw new InternalError({
|
|
269
316
|
message:
|
|
270
317
|
`[${callerName}] ctx.templateResolver missing — App-Bootstrap muss ` +
|
|
271
|
-
`extraContext: { templateResolver: createTemplateResolverApi(db) } setzen ` +
|
|
318
|
+
`extraContext: { templateResolver: createTemplateResolverApi(db, registry) } setzen ` +
|
|
272
319
|
`(siehe template-resolver/README.md).`,
|
|
273
320
|
});
|
|
274
321
|
}
|
|
@@ -1,4 +1,47 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.379.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "Titles for the template-resolver write handlers",
|
|
6
|
+
"detail": "Every agent-callable template-resolver write handler now has a title in de, en, es, fr and it, so the AI assistant names actions such as \"Edit template draft\" instead of \"template-resolver:write:patch-draft\". The handlers of mounted content collections (`<id>-set`) stay untitled because their names depend on the app. The empty-field hint of the placeholder line editor now ends in an ellipsis inside the field instead of running past it."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"version": "0.379.0",
|
|
10
|
+
"type": "breaking",
|
|
11
|
+
"title": "Overrides of locked templates are no longer served",
|
|
12
|
+
"detail": "A tenant override of a mail, PDF or layout template is delivered (mail send, PDF render, linked PDFs, layouts, previews, export bundles, document blocks, overview, text blocks) only while the template is listed in tenantEditable. A locked override stays stored and has no effect; listing the template makes it effective again, nothing is deleted. A SystemAdmin sees locked overrides in the overview (`lockedOverride`, `lockedOverrideI18nKey`) and can reset or archive them with the existing handlers; the template-resolver queries do not show them to a TenantAdmin; the audit log keeps the history. Tenant rows of a collection mounted with `access` are served, except for a slug that has a system template outside tenantEditable: that system template wins, and the collection `-set` handler refuses such a slug for a non-SystemAdmin. createTemplateResolverApi(db) became createTemplateResolverApi(db, registry) because the delivery policy is read from the mounted feature; without the mounted feature no tenant override is served.",
|
|
13
|
+
"migration": "Overrides of templates that are not tenantEditable are no longer served; enable the template via tenantEditable to keep using them. Pass the registry as second argument to createTemplateResolverApi (ctx.registry in handlers, stack.registry in tests). Tenant rows without a system counterpart (for example text blocks seeded directly into a tenant) are hidden as well unless listed in tenantEditable."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"version": "0.379.0",
|
|
17
|
+
"type": "improvement",
|
|
18
|
+
"title": "Overview label for locked template overrides",
|
|
19
|
+
"detail": "Adds templateResolver.overview.lockedOverride."
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"version": "0.379.0",
|
|
23
|
+
"type": "improvement",
|
|
24
|
+
"title": "Mail rendering follows the template delivery policy",
|
|
25
|
+
"detail": "Resolves templates through createTemplateResolverApi(db, registry); overrides of locked templates fall back to the system version."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"version": "0.379.0",
|
|
29
|
+
"type": "improvement",
|
|
30
|
+
"title": "PDF rendering follows the template delivery policy",
|
|
31
|
+
"detail": "Resolves templates through createTemplateResolverApi(db, registry); overrides of locked templates fall back to the system version."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"version": "0.379.0",
|
|
35
|
+
"type": "improvement",
|
|
36
|
+
"title": "Samples follow the createTemplateResolverApi(db, registry) signature",
|
|
37
|
+
"detail": "Recipes and sample apps build the template resolver API with the registry as second argument."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"version": "0.379.0",
|
|
41
|
+
"type": "improvement",
|
|
42
|
+
"title": "seedSystemTemplate accepts titleI18nKey",
|
|
43
|
+
"detail": "A seeded template can store an i18n key as its title (titleI18nKey, exclusive with title). The overview returns the key; the document-designer overview, mail editor and PDF link modal translate it and fall back to the raw text. Templates without a key behave as before; no migration."
|
|
44
|
+
},
|
|
2
45
|
{
|
|
3
46
|
"version": "0.378.0",
|
|
4
47
|
"type": "improvement",
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
isDocumentPlaceholderHref,
|
|
12
12
|
isDocumentReferenceName,
|
|
13
13
|
isDocumentResourceKey,
|
|
14
|
-
} from "./document-schema.ts";
|
|
14
|
+
} from "./web/document-schema.ts";
|
|
15
15
|
|
|
16
16
|
// Private-use characters mark where a Handlebars expression goes. Author text
|
|
17
17
|
// is scrubbed of them first and every `{`/`}` is entity-encoded before the
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Element as ScanElement } from "happy-dom";
|
|
2
|
-
import { isDocumentReferenceName } from "./document-schema.ts";
|
|
3
|
-
import { readDocumentSteps } from "./document-steps.ts";
|
|
4
2
|
import { isHexColor } from "./layout-appearance.ts";
|
|
3
|
+
import { isDocumentReferenceName } from "./web/document-schema.ts";
|
|
4
|
+
import { readDocumentSteps } from "./web/document-steps.ts";
|
|
5
5
|
|
|
6
6
|
export const DEFAULT_STEPS_COLOR = "#1f5468";
|
|
7
7
|
const TODO_BAR_COLOR = "#ECEDEA";
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { FieldIssue } from "@cosmicdrift/kumiko-framework/errors";
|
|
2
2
|
import { getSchema, type JSONContent } from "@tiptap/core";
|
|
3
3
|
import * as z from "zod";
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
4
|
+
import { toVariableDef } from "./template-validation.ts";
|
|
5
|
+
import type { DocumentHtmlKind } from "./web/constants.ts";
|
|
6
|
+
import { documentBlocksForKind } from "./web/document-blocks.ts";
|
|
6
7
|
import {
|
|
7
8
|
DOCUMENT_TEXT_ALIGNMENTS,
|
|
8
9
|
documentExtensions,
|
|
9
10
|
isDocumentPlaceholderHref,
|
|
10
11
|
isDocumentReferenceName,
|
|
11
12
|
isDocumentResourceKey,
|
|
12
|
-
} from "./document-schema.ts";
|
|
13
|
-
import { contentToLine, lineToContent, singleLine } from "./placeholder-text.ts";
|
|
14
|
-
import { toVariableDef } from "./template-validation.ts";
|
|
13
|
+
} from "./web/document-schema.ts";
|
|
14
|
+
import { contentToLine, lineToContent, singleLine } from "./web/placeholder-text.ts";
|
|
15
15
|
|
|
16
16
|
export const MAX_DOCUMENT_OPS = 50;
|
|
17
17
|
|
|
@@ -5,8 +5,8 @@ import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
|
5
5
|
import type { JSONContent } from "@tiptap/core";
|
|
6
6
|
import { generateHTML, generateJSON } from "@tiptap/html/server";
|
|
7
7
|
import { type Element as ScanElement, Window } from "happy-dom";
|
|
8
|
-
import type { ContentFormat } from "./constants.ts";
|
|
9
|
-
import { DOCUMENT_HTML_KINDS } from "./constants.ts";
|
|
8
|
+
import type { ContentFormat } from "./web/constants.ts";
|
|
9
|
+
import { DOCUMENT_HTML_KINDS } from "./web/constants.ts";
|
|
10
10
|
import {
|
|
11
11
|
DOCUMENT_CONDITION_ATTRIBUTE,
|
|
12
12
|
documentExtensions,
|
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
isDocumentPlaceholderHref,
|
|
15
15
|
isDocumentReferenceName,
|
|
16
16
|
isDocumentResourceKey,
|
|
17
|
-
} from "./document-schema.ts";
|
|
18
|
-
import { isDocumentStepKey } from "./document-steps.ts";
|
|
17
|
+
} from "./web/document-schema.ts";
|
|
18
|
+
import { isDocumentStepKey } from "./web/document-steps.ts";
|
|
19
19
|
|
|
20
20
|
export type DocumentViolationCode =
|
|
21
21
|
| "script_element"
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
createSystemConfig,
|
|
4
4
|
defineFeature,
|
|
5
5
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
6
|
-
import { DEFAULT_COLLECTION_ACCESS, 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";
|
|
@@ -43,9 +42,12 @@ import { upsertSystemWrite } from "./handlers/upsert-system.write.ts";
|
|
|
43
42
|
import { makeUpsertTenantWrite } from "./handlers/upsert-tenant.write.ts";
|
|
44
43
|
import { usageQuery } from "./handlers/usage.query.ts";
|
|
45
44
|
import { validateQuery } from "./handlers/validate.query.ts";
|
|
45
|
+
import { TEMPLATE_RESOLVER_I18N } from "./i18n.ts";
|
|
46
46
|
import { templateResourceEntity } from "./table.ts";
|
|
47
|
+
import type { TemplateDeliveryPolicy } from "./template-delivery-policy.ts";
|
|
47
48
|
import type { TenantEditableTemplate } from "./template-edit-policy.ts";
|
|
48
49
|
import { userContentEntryEntity } from "./user-content-table.ts";
|
|
50
|
+
import { DEFAULT_COLLECTION_ACCESS, isCollectionRefusedKind } from "./web/constants.ts";
|
|
49
51
|
|
|
50
52
|
// template-resolver — structured template storage with tenant-override
|
|
51
53
|
// hierarchy, locale fallback and resource linking via file-foundation.
|
|
@@ -112,13 +114,19 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
112
114
|
const tenantEditable = opts.tenantEditable ?? [];
|
|
113
115
|
assertTenantEditableValid(tenantEditable);
|
|
114
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
|
+
};
|
|
115
123
|
const hasUserOwned = collections.some((c) => c.ownership === "user");
|
|
116
124
|
return defineFeature("template-resolver", (r) => {
|
|
117
125
|
r.describe(
|
|
118
126
|
[
|
|
119
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`).",
|
|
120
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.",
|
|
121
|
-
'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.
|
|
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.',
|
|
122
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.",
|
|
123
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).",
|
|
124
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.',
|
|
@@ -138,6 +146,7 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
138
146
|
resourceMaxBytes: createSystemConfig("number", { default: 2_097_152, bounds: { min: 1 } }),
|
|
139
147
|
},
|
|
140
148
|
});
|
|
149
|
+
r.translations({ keys: TEMPLATE_RESOLVER_I18N });
|
|
141
150
|
r.entity({ name: "template-resource", ...templateResourceEntity });
|
|
142
151
|
// Only when the app actually mounts a user-owned collection: the entity's
|
|
143
152
|
// `content` is `userOwned`, which makes it subject data — the boot guard
|
|
@@ -190,7 +199,7 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
190
199
|
});
|
|
191
200
|
r.queryHandler(makeCollectionListQuery(collection));
|
|
192
201
|
r.queryHandler(makeCollectionItemQuery(collection));
|
|
193
|
-
r.writeHandler(makeCollectionSetWrite(collection));
|
|
202
|
+
r.writeHandler(makeCollectionSetWrite(collection, policy));
|
|
194
203
|
}
|
|
195
204
|
|
|
196
205
|
// Visual-tree actions for the text-block content tree. The handle is
|
|
@@ -204,6 +213,6 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
204
213
|
create: { args: { folder: emptyString } },
|
|
205
214
|
});
|
|
206
215
|
|
|
207
|
-
return { handlers, queries, treeHandle };
|
|
216
|
+
return { handlers, queries, treeHandle, deliveryPolicy };
|
|
208
217
|
});
|
|
209
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,7 +4,7 @@ import {
|
|
|
4
4
|
defineQueryHandler,
|
|
5
5
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
6
6
|
import * as z from "zod";
|
|
7
|
-
import { DEFAULT_COLLECTION_ACCESS } from "../constants.ts";
|
|
7
|
+
import { DEFAULT_COLLECTION_ACCESS } from "../web/constants.ts";
|
|
8
8
|
import {
|
|
9
9
|
type CollectionEntryRow,
|
|
10
10
|
collectionStore,
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
defineQueryHandler,
|
|
5
5
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
6
6
|
import * as z from "zod";
|
|
7
|
-
import { DEFAULT_COLLECTION_ACCESS } from "../constants.ts";
|
|
7
|
+
import { DEFAULT_COLLECTION_ACCESS } from "../web/constants.ts";
|
|
8
8
|
import {
|
|
9
9
|
type CollectionEntryRow,
|
|
10
10
|
collectionStore,
|
|
@@ -7,8 +7,10 @@ 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 { refuseTemplateEdit, type TemplateEditPolicy } from "../template-edit-policy.ts";
|
|
13
|
+
import { DEFAULT_COLLECTION_ACCESS, isCollectionRefusedKind } from "../web/constants.ts";
|
|
12
14
|
import { type CollectionEntryRow, collectionStore } from "./collection-shared.ts";
|
|
13
15
|
import { contentFormatSchema, folderSchema, localeSchema, slugSchema } from "./shared.ts";
|
|
14
16
|
|
|
@@ -19,7 +21,10 @@ import { contentFormatSchema, folderSchema, localeSchema, slugSchema } from "./s
|
|
|
19
21
|
//
|
|
20
22
|
// Like set.write this publishes on save (status active, empty variableSchema)
|
|
21
23
|
// — the draft stage lives on upsertTenant + publish.
|
|
22
|
-
export function makeCollectionSetWrite(
|
|
24
|
+
export function makeCollectionSetWrite(
|
|
25
|
+
collection: ContentCollectionDefinition,
|
|
26
|
+
editPolicy: TemplateEditPolicy,
|
|
27
|
+
) {
|
|
23
28
|
const store = collectionStore(collection);
|
|
24
29
|
return defineWriteHandler({
|
|
25
30
|
name: `${collection.id}-set`,
|
|
@@ -75,6 +80,18 @@ export function makeCollectionSetWrite(collection: ContentCollectionDefinition)
|
|
|
75
80
|
);
|
|
76
81
|
}
|
|
77
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
|
+
|
|
78
95
|
const existing = await fetchOne<CollectionEntryRow>(db, store.table, {
|
|
79
96
|
tenantId,
|
|
80
97
|
slug: event.payload.slug,
|
|
@@ -16,9 +16,7 @@ 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,
|
|
@@ -32,6 +30,8 @@ import {
|
|
|
32
30
|
} from "../template-edit-policy.ts";
|
|
33
31
|
import { attachTemplateResources } from "../template-resources.ts";
|
|
34
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";
|
|
35
35
|
import { targetExistsIssue } from "./bundle-import.ts";
|
|
36
36
|
import { kindSchema, localeSchema, templateSlugSchema } from "./shared.ts";
|
|
37
37
|
import { parseStoredJson, storedRecord } from "./template-gates.ts";
|
|
@@ -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,12 +1,12 @@
|
|
|
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 { TemplateResolverErrors } from "../qualified-names.ts";
|
|
5
4
|
import {
|
|
6
5
|
refuseMissingTemplate,
|
|
7
6
|
refuseTemplateEdit,
|
|
8
7
|
type TemplateEditPolicy,
|
|
9
8
|
} from "../template-edit-policy.ts";
|
|
9
|
+
import { TemplateResolverErrors } from "../web/qualified-names.ts";
|
|
10
10
|
import { executor } from "./shared.ts";
|
|
11
11
|
import { loadTargetRow, type StatusTarget, writeAccessFor } from "./toggle-status.write.ts";
|
|
12
12
|
|