@cosmicdrift/kumiko-bundled-features 0.378.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/dist/account-security/feature.js +2 -2
- package/dist/account-security/index.d.ts +2 -2
- package/dist/account-security/index.js +2 -2
- package/dist/account-security/{constants.js → web/constants.js} +0 -1
- package/dist/account-security/{i18n.js → web/i18n.js} +0 -1
- package/dist/admin-shell/feature.js +4 -3
- package/dist/admin-shell/index.d.ts +2 -2
- package/dist/admin-shell/index.js +2 -2
- package/dist/admin-shell/web/client-plugin.js +2 -3
- package/dist/admin-shell/{constants.js → web/constants.js} +0 -1
- package/dist/admin-shell/web/default-translations.d.ts +2 -0
- package/dist/admin-shell/web/default-translations.js +4 -0
- package/dist/admin-shell/web/i18n.d.ts +5 -2
- package/dist/admin-shell/web/i18n.js +50 -5
- package/dist/admin-shell/web/index.js +0 -1
- package/dist/audit/feature.js +58 -59
- package/dist/audit/handlers/audit-events.d.ts +102 -0
- package/dist/audit/handlers/audit-events.js +112 -0
- package/dist/audit/handlers/audit-system-db.d.ts +1 -0
- package/dist/audit/handlers/audit-system-db.js +9 -0
- package/dist/audit/handlers/details-all-tenants.query.d.ts +15 -0
- package/dist/audit/handlers/details-all-tenants.query.js +20 -0
- package/dist/audit/handlers/details.query.d.ts +2 -1
- package/dist/audit/handlers/details.query.js +8 -24
- package/dist/audit/handlers/list-all-tenants.query.d.ts +41 -0
- package/dist/audit/handlers/list-all-tenants.query.js +32 -0
- package/dist/audit/handlers/list.query.d.ts +2 -1
- package/dist/audit/handlers/list.query.js +9 -99
- package/dist/audit/handlers/resolve-audit-tenant.d.ts +3 -1
- package/dist/audit/handlers/resolve-audit-tenant.js +21 -7
- package/dist/audit/index.d.ts +1 -1
- package/dist/audit/index.js +1 -1
- package/dist/audit/run-escape-hatch-retention.js +1 -1
- package/dist/audit/screens.d.ts +65 -0
- package/dist/audit/screens.js +73 -0
- package/dist/audit/web/client-plugin.js +2 -3
- package/dist/audit/{constants.d.ts → web/constants.d.ts} +8 -0
- package/dist/audit/{constants.js → web/constants.js} +8 -1
- package/dist/audit/web/default-translations.d.ts +2 -0
- package/dist/audit/web/default-translations.js +3 -0
- package/dist/audit/web/i18n.d.ts +5 -2
- package/dist/audit/web/i18n.js +31 -4
- package/dist/audit/web/index.js +0 -1
- package/dist/auth-email-password/bootstrap.d.ts +1 -1
- package/dist/auth-email-password/bootstrap.js +4 -4
- package/dist/auth-email-password/errors.js +1 -1
- package/dist/auth-email-password/feature.js +2 -2
- package/dist/auth-email-password/handlers/confirm-account-unlock.write.js +1 -1
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
- package/dist/auth-email-password/handlers/invite-create.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/invite-create.write.js +3 -3
- package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
- package/dist/auth-email-password/handlers/login.write.d.ts +1 -0
- package/dist/auth-email-password/handlers/login.write.js +26 -1
- package/dist/auth-email-password/handlers/request-account-unlock.write.js +1 -1
- package/dist/auth-email-password/handlers/request-email-verification.write.js +1 -1
- package/dist/auth-email-password/handlers/request-password-reset.write.js +1 -1
- package/dist/auth-email-password/handlers/reset-password.write.js +1 -1
- package/dist/auth-email-password/handlers/verify-email.write.js +1 -1
- package/dist/auth-email-password/index.d.ts +1 -1
- package/dist/auth-email-password/index.js +1 -1
- package/dist/auth-email-password/mail-notifications.js +1 -1
- package/dist/auth-email-password/signup-activation.js +1 -1
- package/dist/auth-email-password/web/auth-client.js +0 -1
- package/dist/auth-email-password/web/auth-form-logic.js +0 -1
- package/dist/auth-email-password/web/auth-form-primitives.js +0 -1
- package/dist/auth-email-password/web/auth-gate.js +0 -1
- package/dist/auth-email-password/web/auth-redirect.js +0 -1
- package/dist/auth-email-password/web/client-actions.js +0 -1
- package/dist/auth-email-password/web/client-plugin.js +1 -2
- package/dist/auth-email-password/web/confirm-account-unlock-screen.js +0 -1
- package/dist/auth-email-password/{constants.js → web/constants.js} +3 -6
- package/dist/auth-email-password/web/default-topbar-actions.js +0 -1
- package/dist/auth-email-password/web/forgot-password-screen.js +0 -1
- package/dist/auth-email-password/{i18n.js → web/i18n.js} +3 -4
- package/dist/auth-email-password/web/index.d.ts +1 -1
- package/dist/auth-email-password/web/index.js +1 -2
- package/dist/auth-email-password/web/invite-accept-screen.d.ts +2 -2
- package/dist/auth-email-password/web/invite-accept-screen.js +0 -1
- package/dist/auth-email-password/web/login-screen.js +0 -1
- package/dist/auth-email-password/{mail-i18n.js → web/mail-i18n.js} +0 -1
- package/dist/auth-email-password/web/request-account-unlock-screen.js +0 -1
- package/dist/auth-email-password/web/reset-password-screen.js +0 -1
- package/dist/auth-email-password/web/session-bootstrap-error.js +0 -1
- package/dist/auth-email-password/web/session.js +0 -1
- package/dist/auth-email-password/web/signup-complete-screen.d.ts +2 -2
- package/dist/auth-email-password/web/signup-complete-screen.js +0 -1
- package/dist/auth-email-password/web/signup-screen.js +0 -1
- package/dist/auth-email-password/web/tenant-menu-items.js +0 -1
- package/dist/auth-email-password/web/tenant-switcher.js +0 -1
- package/dist/auth-email-password/web/use-shell-user.js +0 -1
- package/dist/auth-email-password/web/user-menu.js +0 -1
- package/dist/auth-email-password/web/verify-email-screen.js +0 -1
- package/dist/auth-mfa/errors.d.ts +1 -1
- package/dist/auth-mfa/errors.js +2 -2
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/enable-start.write.js +1 -1
- package/dist/auth-mfa/handlers/verify.write.js +1 -1
- package/dist/auth-mfa/index.d.ts +1 -1
- package/dist/auth-mfa/index.js +1 -1
- package/dist/auth-mfa/mfa-status-checker.js +1 -1
- package/dist/auth-mfa/screens.js +1 -1
- package/dist/auth-mfa/web/client-plugin.js +0 -1
- package/dist/auth-mfa/{constants.js → web/constants.js} +0 -1
- package/dist/auth-mfa/web/i18n.js +0 -1
- package/dist/auth-mfa/web/index.js +0 -1
- package/dist/auth-mfa/web/mfa-client.js +0 -1
- package/dist/auth-mfa/web/mfa-disable-dialog.js +1 -2
- package/dist/auth-mfa/web/mfa-recovery-codes-reveal.js +0 -1
- package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +1 -2
- package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +11 -18
- package/dist/auth-mfa/web/mfa-verify-screen.js +0 -1
- package/dist/billing-foundation/checkout-core.js +1 -1
- package/dist/billing-foundation/consumer-protection/consent-text.d.ts +2 -2
- package/dist/billing-foundation/consumer-protection/consent-text.js +1 -1
- package/dist/billing-foundation/consumer-protection/issue-confirmation.js +7 -3
- package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
- package/dist/billing-foundation/consumer-protection/register-consent.js +1 -1
- package/dist/billing-foundation/consumer-protection/register-termination.js +8 -2
- package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +1 -0
- package/dist/billing-foundation/consumer-protection/stored-user-email.js +8 -0
- package/dist/billing-foundation/consumer-protection/termination-mail.d.ts +5 -1
- package/dist/billing-foundation/consumer-protection/termination-mail.js +3 -1
- package/dist/billing-foundation/consumer-protection/termination-notify.js +1 -1
- package/dist/billing-foundation/consumer-protection/termination-pages.js +109 -15
- package/dist/billing-foundation/consumer-protection/termination-record.d.ts +8 -1
- package/dist/billing-foundation/consumer-protection/termination-record.js +76 -3
- package/dist/billing-foundation/consumer-protection/termination-request.js +33 -6
- package/dist/billing-foundation/consumer-protection/termination-revoke.d.ts +28 -0
- package/dist/billing-foundation/consumer-protection/termination-revoke.js +149 -0
- package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +17 -1
- package/dist/billing-foundation/consumer-protection/termination-texts.js +39 -0
- package/dist/billing-foundation/events.d.ts +9 -0
- package/dist/billing-foundation/events.js +14 -2
- package/dist/billing-foundation/feature.js +1 -1
- package/dist/billing-foundation/handlers/process-event.write.d.ts +5 -1
- package/dist/billing-foundation/handlers/process-event.write.js +57 -3
- package/dist/billing-foundation/handlers/switch-plan.write.js +1 -1
- package/dist/billing-foundation/handlers/sync-subscription.write.js +1 -1
- package/dist/billing-foundation/index.d.ts +2 -2
- package/dist/billing-foundation/index.js +2 -2
- package/dist/billing-foundation/plan-catalog.js +1 -1
- package/dist/billing-foundation/screens.js +1 -1
- package/dist/billing-foundation/subscription-tier-sync.js +1 -1
- package/dist/billing-foundation/types.d.ts +14 -2
- package/dist/billing-foundation/types.js +1 -1
- package/dist/billing-foundation/validate-options.js +3 -3
- package/dist/billing-foundation/web/billing-contact-plan.js +1 -2
- package/dist/billing-foundation/web/billing-plans-panel.js +1 -2
- package/dist/billing-foundation/web/cancel-contract-dialog.js +1 -2
- package/dist/billing-foundation/web/checkout-consent-dialog.js +1 -2
- package/dist/billing-foundation/web/client-plugin.js +1 -1
- package/dist/billing-foundation/{constants.d.ts → web/constants.d.ts} +21 -14
- package/dist/billing-foundation/{constants.js → web/constants.js} +35 -31
- package/dist/billing-foundation/{consumer-protection → web/consumer-protection}/consent-locale.js +0 -1
- package/dist/billing-foundation/{contact-card.js → web/contact-card.js} +0 -1
- package/dist/billing-foundation/web/index.d.ts +2 -2
- package/dist/billing-foundation/web/index.js +2 -3
- package/dist/billing-foundation/web/localized-params.js +0 -1
- package/dist/billing-foundation/webhook-handler.js +4 -1
- package/dist/cap-overview/feature.js +1 -1
- package/dist/cap-overview/handlers/caps-usage.query.js +1 -1
- package/dist/cap-overview/handlers/tenant-caps-list.query.js +2 -2
- package/dist/cap-overview/index.d.ts +2 -2
- package/dist/cap-overview/index.js +2 -2
- package/dist/cap-overview/screens.js +1 -1
- package/dist/cap-overview/web/cap-cards-panel.js +1 -1
- package/dist/cap-overview/web/cap-usage-bar.js +1 -2
- package/dist/cap-overview/web/client-plugin.js +1 -1
- package/dist/cap-overview/{constants.js → web/constants.js} +0 -1
- package/dist/cap-overview/web/index.js +0 -1
- package/dist/cap-overview/{usage-math.d.ts → web/usage-math.d.ts} +1 -1
- package/dist/compliance-profiles/feature.js +1 -1
- package/dist/compliance-profiles/index.d.ts +1 -1
- package/dist/compliance-profiles/index.js +1 -1
- package/dist/compliance-profiles/web/client-plugin.js +1 -2
- package/dist/compliance-profiles/web/compliance-profile-catalog.js +1 -2
- package/dist/compliance-profiles/{constants.js → web/constants.js} +0 -1
- package/dist/compliance-profiles/web/index.js +0 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/web/client-plugin.d.ts +1 -1
- package/dist/config/web/client-plugin.js +1 -2
- package/dist/config/{constants.js → web/constants.js} +0 -1
- package/dist/config/web/i18n.js +0 -1
- package/dist/config/web/index.d.ts +1 -1
- package/dist/config/web/index.js +1 -2
- package/dist/config/write-helpers.js +1 -1
- package/dist/custom-fields/feature.js +1 -1
- package/dist/custom-fields/handlers/clear-custom-field.write.js +1 -1
- package/dist/custom-fields/handlers/define-tenant-field.write.js +1 -1
- package/dist/custom-fields/handlers/delete-system-field.write.js +1 -1
- package/dist/custom-fields/handlers/delete-tenant-field.write.js +1 -1
- package/dist/custom-fields/handlers/set-custom-field.write.js +1 -1
- package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
- package/dist/custom-fields/index.d.ts +1 -1
- package/dist/custom-fields/index.js +1 -1
- package/dist/custom-fields/lib/value-schema.js +1 -1
- package/dist/custom-fields/schemas.js +1 -1
- package/dist/custom-fields/web/client-plugin.js +1 -2
- package/dist/custom-fields/{constants.js → web/constants.js} +18 -19
- package/dist/custom-fields/web/custom-fields-form-section.js +1 -2
- package/dist/custom-fields/web/i18n.js +0 -1
- package/dist/custom-fields/web/index.d.ts +1 -1
- package/dist/custom-fields/web/index.js +1 -2
- package/dist/custom-fields/wire-for-entity.js +1 -1
- package/dist/delivery/address-opt-out.js +1 -1
- package/dist/delivery/attempt-log-retention.js +21 -3
- package/dist/delivery/constants.d.ts +1 -1
- package/dist/delivery/constants.js +2 -2
- package/dist/delivery/i18n.js +1 -1
- package/dist/delivery/unsubscribe-page.js +1 -1
- package/dist/delivery/web/client-plugin.js +1 -1
- package/dist/delivery/web/delivery-channel-cell.js +0 -1
- package/dist/delivery/web/delivery-error-cell.js +0 -1
- package/dist/delivery/web/delivery-status-cell.js +1 -2
- package/dist/delivery/web/delivery-time-cell.js +0 -1
- package/dist/delivery/web/delivery-type-cell.js +0 -1
- package/dist/delivery/web/index.js +0 -1
- package/dist/delivery/{public-names.js → web/public-names.js} +0 -1
- package/dist/document-ingest-foundation/events.d.ts +1 -0
- package/dist/document-ingest-foundation/events.js +3 -0
- package/dist/document-ingest-foundation/executor.js +2 -1
- package/dist/document-ingest-foundation/feature.js +16 -5
- package/dist/document-ingest-foundation/index.d.ts +1 -1
- package/dist/document-ingest-foundation/index.js +1 -1
- package/dist/feature-toggles/feature.d.ts +1 -1
- package/dist/feature-toggles/feature.js +2 -2
- package/dist/feature-toggles/handlers/list.query.js +1 -1
- package/dist/feature-toggles/handlers/registered.query.js +1 -1
- package/dist/feature-toggles/handlers/set.write.js +1 -1
- package/dist/feature-toggles/index.d.ts +1 -1
- package/dist/feature-toggles/index.js +1 -1
- package/dist/feature-toggles/web/client-plugin.js +1 -2
- package/dist/feature-toggles/{constants.js → web/constants.js} +0 -1
- package/dist/feature-toggles/web/index.js +0 -1
- package/dist/folders/feature.js +1 -1
- package/dist/folders/handlers/clear-folder.write.js +1 -1
- package/dist/folders/handlers/delete-folder.write.js +1 -1
- package/dist/folders/handlers/set-folder.write.js +1 -1
- package/dist/folders/index.d.ts +1 -1
- package/dist/folders/index.js +1 -1
- package/dist/folders/web/client-plugin.js +1 -2
- package/dist/folders/{constants.js → web/constants.js} +0 -1
- package/dist/folders/web/folder-manager.js +1 -2
- package/dist/folders/web/folder-section.js +1 -2
- package/dist/folders/web/i18n.js +0 -1
- package/dist/folders/web/index.d.ts +1 -1
- package/dist/folders/web/index.js +1 -2
- package/dist/folders/web/tree.js +0 -1
- package/dist/form-draft/db/queries/cleanup.d.ts +3 -2
- package/dist/form-draft/db/queries/cleanup.js +18 -9
- package/dist/form-draft/decrypt-draft.d.ts +2 -0
- package/dist/form-draft/decrypt-draft.js +19 -0
- package/dist/form-draft/entity.js +6 -9
- package/dist/form-draft/feature.js +1 -1
- package/dist/form-draft/handlers/cleanup.job.d.ts +1 -0
- package/dist/form-draft/handlers/cleanup.job.js +17 -4
- package/dist/form-draft/handlers/discard.write.js +1 -1
- package/dist/form-draft/handlers/get.query.js +6 -7
- package/dist/form-draft/handlers/list.query.js +11 -7
- package/dist/form-draft/handlers/save.write.js +1 -1
- package/dist/form-draft/index.d.ts +1 -1
- package/dist/form-draft/index.js +1 -1
- package/dist/form-draft/lookup.d.ts +2 -2
- package/dist/form-draft/lookup.js +7 -2
- package/dist/form-draft/schemas.js +1 -1
- package/dist/form-draft/{constants.js → web/constants.js} +0 -1
- package/dist/form-draft-user-data/hooks.js +2 -2
- package/dist/inbound-mail-foundation/retention-sweep.js +7 -5
- package/dist/jobs/feature.js +2 -2
- package/dist/jobs/handlers/retry.write.js +1 -1
- package/dist/jobs/handlers/trigger.write.js +1 -1
- package/dist/jobs/index.d.ts +1 -1
- package/dist/jobs/index.js +1 -1
- package/dist/jobs/web/client-plugin.js +2 -3
- package/dist/jobs/{constants.js → web/constants.js} +0 -1
- package/dist/jobs/web/default-translations.d.ts +2 -0
- package/dist/jobs/web/default-translations.js +3 -0
- package/dist/jobs/web/i18n.d.ts +5 -2
- package/dist/jobs/web/i18n.js +51 -4
- package/dist/jobs/web/index.js +0 -1
- package/dist/ledger/entity.d.ts +1 -1
- package/dist/ledger/entity.js +1 -1
- package/dist/ledger/feature.js +1 -1
- package/dist/ledger/handlers/confirm-schedule-period.write.js +2 -5
- package/dist/ledger/handlers/create-transaction.write.js +1 -1
- package/dist/ledger/handlers/reports.query.js +1 -1
- package/dist/ledger/handlers/reverse-transaction.write.js +1 -1
- package/dist/ledger/index.d.ts +1 -1
- package/dist/ledger/index.js +1 -1
- package/dist/ledger/recurring.d.ts +1 -1
- package/dist/ledger/reports.d.ts +1 -1
- package/dist/ledger/schemas.js +1 -1
- package/dist/ledger/{constants.js → web/constants.js} +0 -1
- package/dist/ledger/web/index.d.ts +1 -1
- package/dist/ledger/web/index.js +1 -2
- package/dist/legal-pages/feature.d.ts +1 -1
- package/dist/legal-pages/feature.js +1 -1
- package/dist/legal-pages/index.d.ts +1 -1
- package/dist/legal-pages/index.js +1 -1
- package/dist/legal-pages/lib/boot-check.d.ts +1 -1
- package/dist/legal-pages/lib/boot-check.js +1 -1
- package/dist/legal-pages/lib/validate-routes.d.ts +1 -1
- package/dist/legal-pages/web/client-plugin.js +1 -2
- package/dist/legal-pages/{constants.js → web/constants.js} +6 -8
- package/dist/legal-pages/web/index.js +0 -1
- package/dist/managed-pages/feature.js +1 -1
- package/dist/managed-pages/web/client-plugin.js +1 -2
- package/dist/managed-pages/web/default-translations.d.ts +2 -0
- package/dist/managed-pages/web/default-translations.js +11 -0
- package/dist/managed-pages/web/i18n.d.ts +5 -2
- package/dist/managed-pages/web/i18n.js +53 -12
- package/dist/managed-pages/web/index.d.ts +1 -1
- package/dist/managed-pages/web/index.js +1 -2
- package/dist/metrics/compute.d.ts +1 -1
- package/dist/metrics/compute.js +1 -1
- package/dist/metrics/feature.js +1 -1
- package/dist/metrics/index.d.ts +1 -1
- package/dist/metrics/index.js +1 -1
- package/dist/metrics/types.d.ts +1 -1
- package/dist/metrics/validate.js +1 -1
- package/dist/metrics/{constants.js → web/constants.js} +0 -1
- package/dist/metrics/window.d.ts +1 -1
- package/dist/notes-history/feature.js +1 -1
- package/dist/notes-history/handlers/add-note.write.js +1 -1
- package/dist/notes-history/index.d.ts +1 -1
- package/dist/notes-history/index.js +1 -1
- package/dist/notes-history/web/client-plugin.js +1 -2
- package/dist/notes-history/{constants.js → web/constants.js} +0 -1
- package/dist/notes-history/web/i18n.js +0 -1
- package/dist/notes-history/web/index.d.ts +1 -1
- package/dist/notes-history/web/index.js +1 -2
- package/dist/notes-history/web/notes-section.js +2 -3
- package/dist/personal-access-tokens/feature.d.ts +2 -2
- package/dist/personal-access-tokens/feature.js +6 -4
- package/dist/personal-access-tokens/handlers/available-scopes.query.d.ts +1 -1
- package/dist/personal-access-tokens/handlers/create.write.js +1 -1
- package/dist/personal-access-tokens/handlers/revoke.write.js +1 -1
- package/dist/personal-access-tokens/hash.js +1 -1
- package/dist/personal-access-tokens/i18n.d.ts +1 -1
- package/dist/personal-access-tokens/i18n.js +1 -1
- package/dist/personal-access-tokens/index.d.ts +5 -5
- package/dist/personal-access-tokens/index.js +3 -3
- package/dist/personal-access-tokens/resolver.d.ts +1 -1
- package/dist/personal-access-tokens/resolver.js +1 -1
- package/dist/personal-access-tokens/schema/api-token.js +1 -1
- package/dist/personal-access-tokens/screens.d.ts +1 -1
- package/dist/personal-access-tokens/screens.js +1 -1
- package/dist/personal-access-tokens/{constants.js → web/constants.js} +0 -1
- package/dist/presets/index.d.ts +0 -1
- package/dist/presets/index.js +0 -1
- package/dist/presets/security-baseline.d.ts +1 -1
- package/dist/presets/security-baseline.js +1 -1
- package/dist/secrets/feature.js +1 -1
- package/dist/secrets/handlers/delete.write.js +1 -1
- package/dist/secrets/handlers/list.query.js +1 -1
- package/dist/secrets/handlers/set.write.js +1 -1
- package/dist/secrets/i18n.js +1 -1
- package/dist/secrets/index.d.ts +1 -1
- package/dist/secrets/index.js +1 -1
- package/dist/secrets/{constants.js → web/constants.js} +0 -1
- package/dist/secrets/write-gate.js +1 -1
- package/dist/sessions/feature.js +7 -4
- package/dist/sessions/{i18n.js → web/i18n.js} +0 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/purge-files-reaching-subject.js +7 -3
- package/dist/subscription-stripe/feature.js +2 -1
- package/dist/subscription-stripe/plugin-methods.d.ts +3 -0
- package/dist/subscription-stripe/plugin-methods.js +14 -0
- package/dist/subscription-stripe/verify-webhook.js +1 -0
- package/dist/tags/feature.js +1 -1
- package/dist/tags/handlers/assign-tag.write.js +11 -7
- package/dist/tags/handlers/create-tag.write.js +1 -1
- package/dist/tags/handlers/delete-tag.write.js +4 -1
- package/dist/tags/handlers/remove-tag.write.js +1 -1
- package/dist/tags/handlers/update-tag.write.js +1 -1
- package/dist/tags/index.d.ts +1 -1
- package/dist/tags/index.js +1 -1
- package/dist/tags/screens.js +1 -1
- package/dist/tags/web/client-plugin.js +1 -2
- package/dist/tags/{constants.d.ts → web/constants.d.ts} +1 -0
- package/dist/tags/{constants.js → web/constants.js} +3 -1
- package/dist/tags/web/entity-tags.js +1 -2
- package/dist/tags/web/i18n.js +2 -2
- package/dist/tags/web/index.d.ts +1 -1
- package/dist/tags/web/index.js +1 -2
- package/dist/tags/web/tag-filter.js +1 -2
- package/dist/tags/web/tag-manager.js +5 -4
- package/dist/tags/web/tag-picker.js +0 -1
- package/dist/tags/web/tag-section.js +1 -2
- package/dist/tags/web/tags-cell.js +1 -2
- package/dist/template-resolver/api.d.ts +21 -23
- package/dist/template-resolver/api.js +34 -6
- package/dist/template-resolver/compile-document-body.js +1 -1
- package/dist/template-resolver/compile-steps-block.js +2 -2
- package/dist/template-resolver/document-ops.d.ts +1 -1
- package/dist/template-resolver/document-ops.js +3 -3
- package/dist/template-resolver/document-sanitizer.d.ts +1 -1
- package/dist/template-resolver/document-sanitizer.js +3 -3
- package/dist/template-resolver/feature.d.ts +2 -0
- package/dist/template-resolver/feature.js +12 -4
- package/dist/template-resolver/handlers/by-slug.query.js +6 -1
- package/dist/template-resolver/handlers/by-tenant.query.js +6 -2
- package/dist/template-resolver/handlers/collection-item.query.js +1 -1
- package/dist/template-resolver/handlers/collection-list.query.js +1 -1
- package/dist/template-resolver/handlers/collection-set.write.d.ts +2 -1
- package/dist/template-resolver/handlers/collection-set.write.js +14 -2
- package/dist/template-resolver/handlers/copy-locale.write.js +2 -2
- package/dist/template-resolver/handlers/diff-to-system.query.js +5 -1
- package/dist/template-resolver/handlers/discard-draft.write.js +1 -1
- package/dist/template-resolver/handlers/document-base.d.ts +1 -1
- package/dist/template-resolver/handlers/document-base.js +6 -1
- package/dist/template-resolver/handlers/document-blocks.query.d.ts +1 -1
- package/dist/template-resolver/handlers/document-blocks.query.js +2 -2
- package/dist/template-resolver/handlers/export-bundle.query.js +5 -2
- package/dist/template-resolver/handlers/find-by-id.query.js +4 -2
- package/dist/template-resolver/handlers/layout-source.query.js +5 -5
- package/dist/template-resolver/handlers/list.query.js +5 -2
- package/dist/template-resolver/handlers/overview.query.d.ts +10 -2
- package/dist/template-resolver/handlers/overview.query.js +44 -12
- package/dist/template-resolver/handlers/patch-draft.write.js +1 -1
- package/dist/template-resolver/handlers/resource-shared.js +1 -1
- package/dist/template-resolver/handlers/resource-upload.write.js +1 -1
- package/dist/template-resolver/handlers/send-test.write.js +2 -2
- package/dist/template-resolver/handlers/set.write.js +1 -1
- package/dist/template-resolver/handlers/shared.js +1 -1
- package/dist/template-resolver/handlers/template-gates.d.ts +1 -1
- package/dist/template-resolver/handlers/template-gates.js +1 -1
- package/dist/template-resolver/handlers/template-write.d.ts +1 -1
- package/dist/template-resolver/handlers/template-write.js +1 -1
- package/dist/template-resolver/handlers/usage.query.js +3 -2
- package/dist/template-resolver/handlers/validate.query.d.ts +1 -1
- package/dist/template-resolver/handlers/validate.query.js +3 -1
- package/dist/template-resolver/i18n.d.ts +3 -0
- package/dist/template-resolver/i18n.js +24 -0
- package/dist/template-resolver/index.d.ts +4 -3
- package/dist/template-resolver/index.js +3 -3
- package/dist/template-resolver/layout-appearance.js +1 -1
- package/dist/template-resolver/layout-regions.d.ts +1 -1
- package/dist/template-resolver/seeding.d.ts +4 -1
- package/dist/template-resolver/seeding.js +13 -7
- package/dist/template-resolver/store-template-resource.js +2 -2
- package/dist/template-resolver/table.js +1 -1
- package/dist/template-resolver/template-bundle.js +2 -2
- package/dist/template-resolver/template-delivery-policy.d.ts +22 -0
- package/dist/template-resolver/template-delivery-policy.js +40 -0
- package/dist/template-resolver/template-draft.d.ts +1 -1
- package/dist/template-resolver/template-draft.js +1 -1
- package/dist/template-resolver/template-edit-policy.d.ts +1 -1
- package/dist/template-resolver/template-edit-policy.js +1 -1
- package/dist/template-resolver/template-meta.d.ts +2 -2
- package/dist/template-resolver/template-meta.js +2 -2
- package/dist/template-resolver/template-preview.d.ts +1 -1
- package/dist/template-resolver/template-preview.js +8 -4
- package/dist/template-resolver/template-usage.d.ts +1 -1
- package/dist/template-resolver/template-usage.js +1 -1
- package/dist/template-resolver/template-validation.js +1 -1
- package/dist/template-resolver/testing.js +1 -1
- package/dist/template-resolver/user-content-table.js +1 -1
- package/dist/template-resolver/web/client-plugin.js +1 -2
- package/dist/template-resolver/{constants.d.ts → web/constants.d.ts} +1 -1
- package/dist/template-resolver/{constants.js → web/constants.js} +7 -10
- package/dist/template-resolver/web/document-editor-extensions.js +2 -2
- package/dist/template-resolver/web/document-editor.js +0 -1
- package/dist/template-resolver/{document-images.js → web/document-images.js} +0 -1
- package/dist/template-resolver/{document-schema.js → web/document-schema.js} +0 -1
- package/dist/template-resolver/{document-steps.js → web/document-steps.js} +0 -1
- package/dist/template-resolver/web/document-tiptap-editor.js +2 -3
- package/dist/template-resolver/web/document-toolbar-blocks.d.ts +2 -2
- package/dist/template-resolver/web/document-toolbar-blocks.js +1 -1
- package/dist/template-resolver/web/editor-handle.js +1 -1
- package/dist/template-resolver/web/i18n.js +1 -1
- package/dist/template-resolver/web/index.d.ts +3 -3
- package/dist/template-resolver/web/index.js +3 -4
- package/dist/template-resolver/{mail-constants.js → web/mail-constants.js} +0 -1
- package/dist/template-resolver/{pdf-constants.js → web/pdf-constants.js} +0 -1
- package/dist/template-resolver/web/placeholder-line-editor-lazy.js +0 -1
- package/dist/template-resolver/web/placeholder-line-editor.js +6 -4
- package/dist/template-resolver/{qualified-names.js → web/qualified-names.js} +0 -1
- package/dist/template-resolver/web/use-stable-by-key.js +0 -1
- package/dist/tenant/handlers/add-member.write.js +1 -1
- package/dist/tenant/index.d.ts +1 -1
- package/dist/tenant/index.js +1 -1
- package/dist/tenant/invitation-table.js +1 -1
- package/dist/tenant/invited-membership.js +1 -1
- package/dist/tenant/last-tenant-admin.js +1 -1
- package/dist/tenant/member-role-options.js +1 -1
- package/dist/tenant/screens.js +1 -1
- package/dist/tenant/web/client-plugin.js +1 -2
- package/dist/tenant/{constants.js → web/constants.js} +3 -6
- package/dist/tenant/web/index.js +0 -1
- package/dist/tenant/web/member-roles-cell.js +0 -1
- package/dist/tenant/web/member-status-cell.js +0 -1
- package/dist/tenant-lifecycle/stages.js +2 -3
- package/dist/tier-engine/entity.d.ts +1 -1
- package/dist/tier-engine/entity.js +1 -1
- package/dist/tier-engine/feature.js +2 -2
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +1 -1
- package/dist/tier-engine/index.d.ts +1 -1
- package/dist/tier-engine/index.js +1 -1
- package/dist/tier-engine/web/client-plugin.js +2 -3
- package/dist/tier-engine/{constants.js → web/constants.js} +2 -3
- package/dist/tier-engine/{i18n.js → web/i18n.js} +0 -1
- package/dist/tier-engine/web/index.js +0 -1
- package/dist/user/handlers/create.write.js +1 -1
- package/dist/user/handlers/update-roles.js +1 -1
- package/dist/user/handlers/update.write.js +1 -1
- package/dist/user/index.d.ts +1 -1
- package/dist/user/index.js +1 -1
- package/dist/user/invited-global-roles.d.ts +1 -1
- package/dist/user/invited-global-roles.js +1 -1
- package/dist/user/schema/user.js +1 -1
- package/dist/user/{constants.js → web/constants.js} +0 -1
- package/dist/user-data-rights/env.js +1 -1
- package/dist/user-data-rights/feature.js +3 -3
- package/dist/user-data-rights/index.d.ts +1 -1
- package/dist/user-data-rights/index.js +1 -1
- package/dist/user-data-rights/lib/resolve-tenant-model.js +1 -1
- package/dist/user-data-rights/mail-notifications.js +1 -1
- package/dist/user-data-rights/web/client-plugin.js +2 -3
- package/dist/user-data-rights/web/confirm-deletion-screen.js +0 -1
- package/dist/user-data-rights/{constants.js → web/constants.js} +11 -12
- package/dist/user-data-rights/web/default-translations.d.ts +2 -0
- package/dist/user-data-rights/web/default-translations.js +59 -0
- package/dist/user-data-rights/web/i18n.d.ts +5 -2
- package/dist/user-data-rights/web/i18n.js +37 -59
- package/dist/user-data-rights/web/index.d.ts +1 -1
- package/dist/user-data-rights/web/index.js +1 -2
- package/dist/user-data-rights/web/privacy-center-screen.js +1 -2
- package/dist/user-data-rights/web/request-deletion-screen.js +0 -1
- package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +6 -1
- package/dist/user-profile/feature.js +1 -1
- package/dist/user-profile/handlers/change-email.write.js +1 -1
- package/dist/user-profile/index.d.ts +1 -1
- package/dist/user-profile/index.js +1 -1
- package/dist/user-profile/web/client-plugin.js +2 -3
- package/dist/user-profile/{constants.js → web/constants.js} +0 -1
- package/dist/user-profile/{i18n.js → web/i18n.js} +0 -1
- package/dist/user-profile/web/profile-screen.js +2 -3
- package/dist/waitlist/entity.js +1 -1
- package/dist/waitlist/feature.js +1 -1
- package/dist/waitlist/handlers/export-purge.write.js +1 -1
- package/dist/waitlist/handlers/invite.write.js +1 -1
- package/dist/waitlist/handlers/reject.write.js +1 -1
- package/dist/waitlist/handlers/submit.write.js +4 -3
- package/dist/waitlist/import.d.ts +1 -1
- package/dist/waitlist/index.d.ts +1 -1
- package/dist/waitlist/index.js +1 -1
- package/dist/waitlist/legacy-migrate.js +1 -1
- package/dist/waitlist/link-on-signup.js +1 -1
- package/dist/waitlist/mail.d.ts +0 -1
- package/dist/waitlist/mail.js +6 -4
- package/dist/waitlist/payloads.js +1 -1
- package/dist/waitlist/screens.js +1 -1
- package/dist/waitlist/{constants.js → web/constants.js} +0 -1
- package/kumiko-es-tables.json +102 -0
- package/package.json +30 -29
- package/src/audit/changes.json +7 -0
- package/src/auth-email-password/changes.json +6 -0
- package/src/auth-mfa/changes.json +6 -0
- package/src/billing-foundation/changes.json +18 -0
- package/src/delivery/changes.json +6 -0
- package/src/document-ingest-foundation/changes.json +6 -0
- package/src/files/changes.json +7 -0
- package/src/form-draft/changes.json +7 -0
- package/src/ledger/changes.json +7 -0
- package/src/presets/changes.json +7 -0
- package/src/tags/changes.json +6 -0
- package/src/template-resolver/changes.json +43 -0
- package/src/user-data-rights/changes.json +14 -0
- package/src/waitlist/changes.json +6 -0
- package/dist/admin-shell/i18n.d.ts +0 -5
- package/dist/admin-shell/i18n.js +0 -51
- package/dist/audit/i18n.d.ts +0 -5
- package/dist/audit/i18n.js +0 -22
- package/dist/jobs/i18n.d.ts +0 -5
- package/dist/jobs/i18n.js +0 -52
- package/dist/managed-pages/i18n.d.ts +0 -5
- package/dist/managed-pages/i18n.js +0 -55
- package/dist/presets/dsgvo-self-service.d.ts +0 -10
- package/dist/presets/dsgvo-self-service.js +0 -24
- package/dist/user-data-rights/i18n.d.ts +0 -5
- package/dist/user-data-rights/i18n.js +0 -39
- /package/dist/account-security/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/account-security/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/admin-shell/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/auth-email-password/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/auth-email-password/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/auth-email-password/{mail-i18n.d.ts → web/mail-i18n.d.ts} +0 -0
- /package/dist/auth-mfa/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/billing-foundation/{consumer-protection → web/consumer-protection}/consent-locale.d.ts +0 -0
- /package/dist/billing-foundation/{contact-card.d.ts → web/contact-card.d.ts} +0 -0
- /package/dist/cap-overview/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/cap-overview/{usage-math.js → web/usage-math.js} +0 -0
- /package/dist/compliance-profiles/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/config/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/custom-fields/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/delivery/{public-names.d.ts → web/public-names.d.ts} +0 -0
- /package/dist/feature-toggles/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/folders/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/form-draft/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/jobs/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/ledger/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/legal-pages/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/metrics/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/notes-history/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/personal-access-tokens/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/personal-access-tokens/{scopes.d.ts → web/scopes.d.ts} +0 -0
- /package/dist/personal-access-tokens/{scopes.js → web/scopes.js} +0 -0
- /package/dist/secrets/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/sessions/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/template-resolver/{document-blocks.d.ts → web/document-blocks.d.ts} +0 -0
- /package/dist/template-resolver/{document-blocks.js → web/document-blocks.js} +0 -0
- /package/dist/template-resolver/{document-images.d.ts → web/document-images.d.ts} +0 -0
- /package/dist/template-resolver/{document-schema.d.ts → web/document-schema.d.ts} +0 -0
- /package/dist/template-resolver/{document-steps.d.ts → web/document-steps.d.ts} +0 -0
- /package/dist/template-resolver/{mail-constants.d.ts → web/mail-constants.d.ts} +0 -0
- /package/dist/template-resolver/{pdf-constants.d.ts → web/pdf-constants.d.ts} +0 -0
- /package/dist/template-resolver/{placeholder-text.d.ts → web/placeholder-text.d.ts} +0 -0
- /package/dist/template-resolver/{placeholder-text.js → web/placeholder-text.js} +0 -0
- /package/dist/template-resolver/{qualified-names.d.ts → web/qualified-names.d.ts} +0 -0
- /package/dist/tenant/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/tier-engine/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/tier-engine/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/user/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/user-data-rights/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/user-profile/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/user-profile/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/waitlist/{constants.d.ts → web/constants.d.ts} +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// @runtime client
|
|
3
2
|
// TagManager — the shared tag-catalog UI, GitLab-labels style. Built ONCE,
|
|
4
3
|
// mounted twice:
|
|
5
4
|
// - standalone: <TagManager /> → the Tags admin screen
|
|
@@ -11,8 +10,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
11
10
|
// per-tenant catalog. Selection is buffered by the caller (TagPicker) and only
|
|
12
11
|
// applied on confirm — managing labels and picking them are separate concerns.
|
|
13
12
|
import { useDispatcher, usePrimitives, useQuery, useTranslation, } from "@cosmicdrift/kumiko-renderer";
|
|
13
|
+
import { pluralKey } from "@cosmicdrift/kumiko-renderer/headless";
|
|
14
14
|
import { useState } from "react";
|
|
15
|
-
import { TagsHandlers, TagsQueries } from "
|
|
15
|
+
import { TagsHandlers, TagsQueries } from "./constants.js";
|
|
16
16
|
import { TagChip } from "./tag-chip.js";
|
|
17
17
|
// A small fixed palette so labels stay visually distinct without a color-wheel
|
|
18
18
|
// dependency; the hex field below still accepts any custom value.
|
|
@@ -66,6 +66,7 @@ export function TagManager({ entityType, selection, }) {
|
|
|
66
66
|
const usage = new Map();
|
|
67
67
|
for (const a of assignments.data?.rows ?? [])
|
|
68
68
|
usage.set(a.tagId, (usage.get(a.tagId) ?? 0) + 1);
|
|
69
|
+
const deletingUsage = usage.get(deleting?.id ?? "") ?? 0;
|
|
69
70
|
const selecting = selection !== undefined;
|
|
70
71
|
const allTags = catalog.data?.rows ?? [];
|
|
71
72
|
const tags = selecting
|
|
@@ -162,7 +163,7 @@ export function TagManager({ entityType, selection, }) {
|
|
|
162
163
|
return (_jsxs("div", { "data-testid": "tag-manager", className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-3", children: [_jsx(Field, { id: "tag-manager-new-name", label: t("tags.manage.newLabel"), children: _jsx(Input, { kind: "text", id: "tag-manager-new-name", name: "newTagName", value: newName, onChange: setNewName, placeholder: t("tags.manage.namePlaceholder") }) }), _jsx(ColorPicker, { value: newColor, onChange: setNewColor, idPrefix: "tag-manager-new-color" }), !selecting && (_jsx(Field, { id: "tag-manager-new-scope", label: t("tags.manage.scopeLabel"), children: _jsx(Input, { kind: "text", id: "tag-manager-new-scope", name: "newTagScope", value: newScope, onChange: setNewScope, placeholder: t("tags.manage.scopePlaceholder") }) })), _jsx("div", { children: _jsx(Button, { variant: "primary", disabled: busy || newName.trim() === "", onClick: () => createTag(), testId: "tag-manager-create", children: busy ? t("tags.section.working") : t("tags.manage.create") }) })] }), tags.length === 0 ? (_jsx(Banner, { variant: "info", testId: "tag-manager-empty", children: _jsx(Text, { children: t("tags.section.empty") }) })) : (_jsx("div", { className: "flex flex-col gap-1", children: tags.map((tag) => editingId === tag.id ? (_jsxs("div", { "data-testid": `tag-manager-edit-${tag.id}`, className: "flex flex-col gap-2 rounded-md border p-3", children: [_jsx(Input, { kind: "text", id: `tag-edit-name-${tag.id}`, name: "editName", value: editName, onChange: setEditName }), _jsx(ColorPicker, { value: editColor, onChange: setEditColor, idPrefix: `tag-edit-color-${tag.id}` }), _jsx(Input, { kind: "text", id: `tag-edit-scope-${tag.id}`, name: "editScope", value: editScope, onChange: setEditScope, placeholder: t("tags.manage.scopePlaceholder") }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "primary", disabled: busy || editName.trim() === "", onClick: () => saveEdit(tag), testId: `tag-manager-save-${tag.id}`, children: t("tags.manage.save") }), _jsx(Button, { variant: "secondary", disabled: busy, onClick: () => setEditingId(null), children: t("tags.manage.cancel") })] })] }, tag.id)) : (_jsxs("div", { "data-testid": `tag-manager-row-${tag.id}`, className: "flex items-center gap-2 rounded-md px-2 py-1 hover:bg-muted", children: [selecting && (_jsx(Button, { variant: selection?.value.includes(tag.id) ? "primary" : "secondary", onClick: () => toggle(tag.id), testId: `tag-manager-toggle-${tag.id}`, children: selection?.value.includes(tag.id) ? "✓" : "+" })), _jsx(TagChip, { name: tag.name, color: tag.color }), !selecting && (tag.scope ?? "") !== "" && (_jsx(Text, { variant: "small", children: `@${tag.scope}` })), _jsx(Text, { variant: "small", children: t("tags.manage.usage", { count: usage.get(tag.id) ?? 0 }) }), _jsxs("div", { className: "ml-auto flex gap-1", children: [_jsx(Button, { variant: "secondary", disabled: busy, onClick: () => startEdit(tag), testId: `tag-manager-edit-btn-${tag.id}`, children: t("tags.manage.edit") }), _jsx(Button, { variant: "danger", disabled: busy, onClick: () => setDeleting(tag), testId: `tag-manager-delete-btn-${tag.id}`, children: t("tags.manage.delete") })] })] }, tag.id))) })), errorKey !== null && (_jsx(Banner, { variant: "error", testId: "tag-manager-action-error", children: _jsx(Text, { children: t(errorKey) }) })), _jsx(Dialog, { open: deleting !== null, onOpenChange: (open) => {
|
|
163
164
|
if (!open)
|
|
164
165
|
setDeleting(null);
|
|
165
|
-
}, title: t("tags.manage.deleteConfirmTitle", { name: deleting?.name ?? "" }), description: t("tags.manage.deleteConfirmDesc", {
|
|
166
|
-
count:
|
|
166
|
+
}, title: t("tags.manage.deleteConfirmTitle", { name: deleting?.name ?? "" }), description: t(pluralKey("tags.manage.deleteConfirmDesc", deletingUsage), {
|
|
167
|
+
count: deletingUsage,
|
|
167
168
|
}), confirmLabel: t("tags.manage.delete"), variant: "danger", onConfirm: confirmDelete, testId: "tag-manager-delete-dialog" })] }));
|
|
168
169
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
// @runtime client
|
|
3
2
|
// TagPicker — the shared "manage + pick labels" modal. Wraps TagManager in
|
|
4
3
|
// select-mode inside a Dialog: the user can create/recolor/delete labels (those
|
|
5
4
|
// hit the catalog immediately) and toggle which ones apply (buffered). On
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// @runtime client
|
|
3
2
|
// TagSection — drop-in tag editor for ANY entity, GitLab-labels style. Shows the
|
|
4
3
|
// entity's tags as colored chips plus an "Edit tags" button that opens the
|
|
5
4
|
// shared TagPicker modal (pick + manage). Applying the picker diffs the
|
|
@@ -14,7 +13,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
14
13
|
// (RenderEdit passes { entityName, entityId }).
|
|
15
14
|
import { useDispatcher, usePrimitives, useQuery, useTranslation, } from "@cosmicdrift/kumiko-renderer";
|
|
16
15
|
import { useState } from "react";
|
|
17
|
-
import { TagsHandlers, TagsQueries } from "
|
|
16
|
+
import { TagsHandlers, TagsQueries } from "./constants.js";
|
|
18
17
|
import { TagChip } from "./tag-chip.js";
|
|
19
18
|
import { TagPicker } from "./tag-picker.js";
|
|
20
19
|
// What changed between the entity's current tags and the picker's new selection.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
// @runtime client
|
|
3
2
|
// TagsCell — a reusable columnRenderer that shows an entity's tags as colored
|
|
4
3
|
// chips inline in a list row. Drop it into ANY entityList by declaring a labeled
|
|
5
4
|
// virtual column (no host-schema change), after mounting tagsClient():
|
|
@@ -16,7 +15,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
16
15
|
// calls, so the whole column shares two queries, not two-per-row. For huge
|
|
17
16
|
// assignment sets add a server-side entitiesByTag query + join filter.
|
|
18
17
|
import { useQuery } from "@cosmicdrift/kumiko-renderer";
|
|
19
|
-
import { TagsQueries } from "
|
|
18
|
+
import { TagsQueries } from "./constants.js";
|
|
20
19
|
import { TagChip } from "./tag-chip.js";
|
|
21
20
|
export function TagsCell({ row }) {
|
|
22
21
|
const entityId = String(row["id"] ?? "");
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
-
import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
import type { Registry, SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
4
4
|
import type { FileAttachmentRef } from "../renderer-foundation/index.ts";
|
|
5
|
-
import type { ContentFormat, TemplateKind } from "./constants.ts";
|
|
6
5
|
import { type TemplatePdfAttachmentLink } from "./linked-resources.ts";
|
|
6
|
+
import { type TemplateResourceRow } from "./table.ts";
|
|
7
|
+
import { type TemplateDeliveryPolicy } from "./template-delivery-policy.ts";
|
|
7
8
|
import { type TemplateMeta } from "./template-meta.ts";
|
|
9
|
+
import type { ContentFormat, TemplateKind } from "./web/constants.ts";
|
|
8
10
|
export type TemplateResource = {
|
|
9
11
|
readonly id: string;
|
|
10
12
|
readonly version: number;
|
|
@@ -46,15 +48,11 @@ export type ResolveLayoutRequest = {
|
|
|
46
48
|
};
|
|
47
49
|
export type TemplateResolverApi = {
|
|
48
50
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* `resolveTemplate` nutzen.
|
|
51
|
+
* Raw lookup by (tenantId, slug, kind, locale): no locale fallback, no override
|
|
52
|
+
* hierarchy. Render paths must use `resolveTemplate`. `scope: "system"` forces
|
|
53
|
+
* SYSTEM_TENANT_ID and ignores the passed tenantId.
|
|
53
54
|
*
|
|
54
|
-
*
|
|
55
|
-
* den übergebenen tenantId). Default = Lookup gegen den übergebenen
|
|
56
|
-
* tenantId direkt (Caller wählt entweder Tenant oder System per
|
|
57
|
-
* tenantId).
|
|
55
|
+
* Tenant rows of a template that is not tenantEditable are not returned.
|
|
58
56
|
*/
|
|
59
57
|
readonly findExact: (args: {
|
|
60
58
|
readonly tenantId: TenantId;
|
|
@@ -64,18 +62,10 @@ export type TemplateResolverApi = {
|
|
|
64
62
|
readonly scope?: "system";
|
|
65
63
|
}) => Promise<TemplateResource | null>;
|
|
66
64
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* 4. system + FALLBACK_LOCALE
|
|
72
|
-
* Resource-Substitution wird hier NICHT ausgeführt — das macht der
|
|
73
|
-
* Caller (renderer-foundation-Plugin) je nach kind-passendem Modus
|
|
74
|
-
* (inline-base64 vs. signed-url). API liefert TemplateResource pur.
|
|
75
|
-
*
|
|
76
|
-
* **Caller-Invariante:** `tenantId` MUSS vom Server kommen (typisch
|
|
77
|
-
* `ctx.user.tenantId`). Niemals direkt aus User-Input — sonst kann
|
|
78
|
-
* User cross-tenant Templates abfragen (Tenant-Isolation gebrochen).
|
|
65
|
+
* Four-step fallback: tenant+locale, system+locale, tenant+FALLBACK_LOCALE,
|
|
66
|
+
* system+FALLBACK_LOCALE (see template-resolver.md).
|
|
67
|
+
* Tenant rows count only for templates unlocked for tenants (tenantEditable,
|
|
68
|
+
* or a collection with access); locked overrides are skipped but stay stored.
|
|
79
69
|
*/
|
|
80
70
|
readonly resolveTemplate: (args: ResolveRequest) => Promise<TemplateResource>;
|
|
81
71
|
/**
|
|
@@ -89,7 +79,15 @@ export type TemplateResolverApi = {
|
|
|
89
79
|
*/
|
|
90
80
|
readonly resolveLayout: (args: ResolveLayoutRequest) => Promise<TemplateResource>;
|
|
91
81
|
};
|
|
92
|
-
export declare function createTemplateResolverApi(db: DbRunner | TenantDb): TemplateResolverApi;
|
|
82
|
+
export declare function createTemplateResolverApi(db: DbRunner | TenantDb, registry: Registry): TemplateResolverApi;
|
|
83
|
+
export declare function isRowDelivered(db: DbRunner | TenantDb, policy: TemplateDeliveryPolicy, row: TemplateResourceRow): Promise<boolean>;
|
|
84
|
+
export declare function isRowDeliveredTo(db: DbRunner | TenantDb, policy: TemplateDeliveryPolicy, user: {
|
|
85
|
+
readonly roles: readonly string[];
|
|
86
|
+
}, row: TemplateResourceRow): Promise<boolean>;
|
|
87
|
+
export declare function filterDeliveredTo(db: DbRunner | TenantDb, policy: TemplateDeliveryPolicy, user: {
|
|
88
|
+
readonly roles: readonly string[];
|
|
89
|
+
}, rows: readonly TemplateResourceRow[]): Promise<TemplateResourceRow[]>;
|
|
90
|
+
export declare function systemTemplateExists(db: DbRunner | TenantDb, kind: string, slug: string): Promise<boolean>;
|
|
93
91
|
export declare class TemplateNotFoundError extends Error {
|
|
94
92
|
readonly query: {
|
|
95
93
|
slug: string;
|
|
@@ -3,17 +3,21 @@
|
|
|
3
3
|
// ctx.templateResolver at runtime.
|
|
4
4
|
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
5
5
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
6
|
-
import { FALLBACK_LOCALE, SYSTEM_TENANT_ID } from "./constants.js";
|
|
7
6
|
import { fileAttachmentsOf, imageLinksOf, parseLinkedResourceEntries, pdfAttachmentLinksOf, } from "./linked-resources.js";
|
|
8
7
|
import { templateResourcesTable } from "./table.js";
|
|
9
|
-
import {
|
|
8
|
+
import { deliveryPolicyOf, isRowServed, isServedByCollectionOnly, } from "./template-delivery-policy.js";
|
|
9
|
+
import { activeVersionOf, isSystemAdmin, servedVersionOf } from "./template-draft.js";
|
|
10
10
|
import { parseTemplateMeta } from "./template-meta.js";
|
|
11
|
-
|
|
11
|
+
import { FALLBACK_LOCALE, SYSTEM_TENANT_ID } from "./web/constants.js";
|
|
12
|
+
export function createTemplateResolverApi(db, registry) {
|
|
13
|
+
const deliveryPolicy = deliveryPolicyOf(registry);
|
|
14
|
+
// A collection entry must not shadow a system template of the same slug that the app did not unlock.
|
|
15
|
+
const isServed = (row) => isRowDelivered(db, deliveryPolicy, row);
|
|
12
16
|
return {
|
|
13
17
|
findExact: async ({ tenantId, slug, kind, locale, scope }) => {
|
|
14
18
|
const effectiveTenantId = scope === "system" ? SYSTEM_TENANT_ID : tenantId;
|
|
15
19
|
const row = await fetchTemplate(db, effectiveTenantId, slug, kind, locale);
|
|
16
|
-
return row ? toPublic(row) : null;
|
|
20
|
+
return row && (await isServed(row)) ? toPublic(row) : null;
|
|
17
21
|
},
|
|
18
22
|
resolveTemplate: async ({ tenantId, slug, kind, locale }) => {
|
|
19
23
|
// Fallback-Chain — finde erste passende Variante
|
|
@@ -28,14 +32,18 @@ export function createTemplateResolverApi(db) {
|
|
|
28
32
|
: []),
|
|
29
33
|
];
|
|
30
34
|
for (const c of candidates) {
|
|
35
|
+
if (!isRowServed(deliveryPolicy, { tenantId: c.tid, kind, slug }))
|
|
36
|
+
continue;
|
|
31
37
|
const row = await fetchTemplate(db, c.tid, slug, kind, c.loc);
|
|
32
|
-
if (row && row.status === "active")
|
|
38
|
+
if (row && row.status === "active" && (await isServed(row)))
|
|
33
39
|
return toPublic(row);
|
|
34
40
|
}
|
|
35
41
|
throw new TemplateNotFoundError({ slug, kind, locale });
|
|
36
42
|
},
|
|
37
43
|
resolveLayout: async ({ tenantId, slug, kind, locale }) => {
|
|
38
44
|
for (const tid of [tenantId, SYSTEM_TENANT_ID]) {
|
|
45
|
+
if (!isRowServed(deliveryPolicy, { tenantId: tid, kind, slug }))
|
|
46
|
+
continue;
|
|
39
47
|
const rows = await selectMany(db, templateResourcesTable, {
|
|
40
48
|
tenantId: tid,
|
|
41
49
|
slug,
|
|
@@ -49,6 +57,26 @@ export function createTemplateResolverApi(db) {
|
|
|
49
57
|
},
|
|
50
58
|
};
|
|
51
59
|
}
|
|
60
|
+
// The one delivery rule for a stored row: unlocked, and a collection entry never shadows a system
|
|
61
|
+
// template of the same slug that the app did not unlock.
|
|
62
|
+
export async function isRowDelivered(db, policy, row) {
|
|
63
|
+
if (!isRowServed(policy, row))
|
|
64
|
+
return false;
|
|
65
|
+
if (row.tenantId === SYSTEM_TENANT_ID || !isServedByCollectionOnly(policy, row))
|
|
66
|
+
return true;
|
|
67
|
+
return !(await systemTemplateExists(db, row.kind, row.slug));
|
|
68
|
+
}
|
|
69
|
+
export async function isRowDeliveredTo(db, policy, user, row) {
|
|
70
|
+
return isSystemAdmin(user) || (await isRowDelivered(db, policy, row));
|
|
71
|
+
}
|
|
72
|
+
export async function filterDeliveredTo(db, policy, user, rows) {
|
|
73
|
+
const flags = await Promise.all(rows.map((row) => isRowDeliveredTo(db, policy, user, row)));
|
|
74
|
+
return rows.filter((_, index) => flags[index]);
|
|
75
|
+
}
|
|
76
|
+
export async function systemTemplateExists(db, kind, slug) {
|
|
77
|
+
const rows = await selectMany(db, templateResourcesTable, { tenantId: SYSTEM_TENANT_ID, slug, kind }, { limit: 1 });
|
|
78
|
+
return rows.length > 0;
|
|
79
|
+
}
|
|
52
80
|
function pickActiveLayoutRow(rows, locale) {
|
|
53
81
|
const active = rows
|
|
54
82
|
.filter((row) => row.status === "active")
|
|
@@ -139,7 +167,7 @@ export function requireTemplateResolver(ctx, callerName) {
|
|
|
139
167
|
if (!api) {
|
|
140
168
|
throw new InternalError({
|
|
141
169
|
message: `[${callerName}] ctx.templateResolver missing — App-Bootstrap muss ` +
|
|
142
|
-
`extraContext: { templateResolver: createTemplateResolverApi(db) } setzen ` +
|
|
170
|
+
`extraContext: { templateResolver: createTemplateResolverApi(db, registry) } setzen ` +
|
|
143
171
|
`(siehe template-resolver/README.md).`,
|
|
144
172
|
});
|
|
145
173
|
}
|
|
@@ -2,7 +2,7 @@ import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
|
2
2
|
import { isResourceImageContentType } from "../shared/index.js";
|
|
3
3
|
import { rewriteStepsBlock } from "./compile-steps-block.js";
|
|
4
4
|
import { conditionScopeElement, withParsedDocument } from "./document-sanitizer.js";
|
|
5
|
-
import { DOCUMENT_CONDITION_ATTRIBUTE, DOCUMENT_TEXT_ALIGNMENTS, isAllowedDocumentLinkHref, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "./document-schema.js";
|
|
5
|
+
import { DOCUMENT_CONDITION_ATTRIBUTE, DOCUMENT_TEXT_ALIGNMENTS, isAllowedDocumentLinkHref, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "./web/document-schema.js";
|
|
6
6
|
// Private-use characters mark where a Handlebars expression goes. Author text
|
|
7
7
|
// is scrubbed of them first and every `{`/`}` is entity-encoded before the
|
|
8
8
|
// markers are swapped for real expressions, so the only Handlebars syntax in
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { isDocumentReferenceName } from "./document-schema.js";
|
|
2
|
-
import { readDocumentSteps } from "./document-steps.js";
|
|
3
1
|
import { isHexColor } from "./layout-appearance.js";
|
|
2
|
+
import { isDocumentReferenceName } from "./web/document-schema.js";
|
|
3
|
+
import { readDocumentSteps } from "./web/document-steps.js";
|
|
4
4
|
export const DEFAULT_STEPS_COLOR = "#1f5468";
|
|
5
5
|
const TODO_BAR_COLOR = "#ECEDEA";
|
|
6
6
|
const REACHED_LABEL_COLOR = "#0B0D12";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FieldIssue } from "@cosmicdrift/kumiko-framework/errors";
|
|
2
2
|
import { type JSONContent } from "@tiptap/core";
|
|
3
3
|
import * as z from "zod";
|
|
4
|
-
import type { DocumentHtmlKind } from "./constants.ts";
|
|
4
|
+
import type { DocumentHtmlKind } from "./web/constants.ts";
|
|
5
5
|
export declare const MAX_DOCUMENT_OPS = 50;
|
|
6
6
|
export type DocumentBlockType = "paragraph" | "heading" | "list" | "table" | "repeat" | "image" | "button" | "divider" | "pageBreak" | "steps";
|
|
7
7
|
export type DocumentBlock = {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { getSchema } from "@tiptap/core";
|
|
2
2
|
import * as z from "zod";
|
|
3
|
-
import { documentBlocksForKind } from "./document-blocks.js";
|
|
4
|
-
import { DOCUMENT_TEXT_ALIGNMENTS, documentExtensions, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "./document-schema.js";
|
|
5
|
-
import { contentToLine, lineToContent, singleLine } from "./placeholder-text.js";
|
|
6
3
|
import { toVariableDef } from "./template-validation.js";
|
|
4
|
+
import { documentBlocksForKind } from "./web/document-blocks.js";
|
|
5
|
+
import { DOCUMENT_TEXT_ALIGNMENTS, documentExtensions, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "./web/document-schema.js";
|
|
6
|
+
import { contentToLine, lineToContent, singleLine } from "./web/placeholder-text.js";
|
|
7
7
|
export const MAX_DOCUMENT_OPS = 50;
|
|
8
8
|
// Assigning these keys would reach the prototype of the meta object.
|
|
9
9
|
const FORBIDDEN_META_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FieldIssue } from "@cosmicdrift/kumiko-framework/errors";
|
|
2
2
|
import type { JSONContent } from "@tiptap/core";
|
|
3
3
|
import { type Element as ScanElement } from "happy-dom";
|
|
4
|
-
import type { ContentFormat } from "./constants.ts";
|
|
4
|
+
import type { ContentFormat } from "./web/constants.ts";
|
|
5
5
|
export type DocumentViolationCode = "script_element" | "event_handler_attribute" | "disallowed_link_href" | "external_image_source" | "image_without_resource" | "invalid_reference_name" | "embedded_content" | "unsafe_attribute_value" | "images_block_pdf_only" | "button_href_not_placeholder" | "document_requires_html_format" | "layout_requires_mjml_format" | "layout_invalid_structure" | "layout_missing_content_slot" | "layout_source_system_only";
|
|
6
6
|
export type DocumentViolation = {
|
|
7
7
|
readonly code: DocumentViolationCode;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
2
|
import { generateHTML, generateJSON } from "@tiptap/html/server";
|
|
3
3
|
import { Window } from "happy-dom";
|
|
4
|
-
import { DOCUMENT_HTML_KINDS } from "./constants.js";
|
|
5
|
-
import { DOCUMENT_CONDITION_ATTRIBUTE, documentExtensions, isAllowedDocumentLinkHref, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "./document-schema.js";
|
|
6
|
-
import { isDocumentStepKey } from "./document-steps.js";
|
|
4
|
+
import { DOCUMENT_HTML_KINDS } from "./web/constants.js";
|
|
5
|
+
import { DOCUMENT_CONDITION_ATTRIBUTE, documentExtensions, isAllowedDocumentLinkHref, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "./web/document-schema.js";
|
|
6
|
+
import { isDocumentStepKey } from "./web/document-steps.js";
|
|
7
7
|
export function violation(code, detail, message) {
|
|
8
8
|
return { code, detail, message };
|
|
9
9
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ContentCollectionDefinition } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
import type { TemplateDeliveryPolicy } from "./template-delivery-policy.ts";
|
|
2
3
|
import type { TenantEditableTemplate } from "./template-edit-policy.ts";
|
|
3
4
|
export type TemplateResolverOptions = {
|
|
4
5
|
/** Content collections this app mounts. Declared here rather than inside the
|
|
@@ -71,5 +72,6 @@ export declare function createTemplateResolverFeature(opts?: TemplateResolverOpt
|
|
|
71
72
|
};
|
|
72
73
|
};
|
|
73
74
|
}>;
|
|
75
|
+
deliveryPolicy: TemplateDeliveryPolicy;
|
|
74
76
|
};
|
|
75
77
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createSystemConfig, defineFeature, } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
-
import { DEFAULT_COLLECTION_ACCESS, isCollectionRefusedKind } from "./constants.js";
|
|
3
2
|
import { bySlugQuery } from "./handlers/by-slug.query.js";
|
|
4
3
|
import { byTenantQuery } from "./handlers/by-tenant.query.js";
|
|
5
4
|
import { makeCollectionItemQuery } from "./handlers/collection-item.query.js";
|
|
@@ -31,8 +30,10 @@ import { upsertSystemWrite } from "./handlers/upsert-system.write.js";
|
|
|
31
30
|
import { makeUpsertTenantWrite } from "./handlers/upsert-tenant.write.js";
|
|
32
31
|
import { usageQuery } from "./handlers/usage.query.js";
|
|
33
32
|
import { validateQuery } from "./handlers/validate.query.js";
|
|
33
|
+
import { TEMPLATE_RESOLVER_I18N } from "./i18n.js";
|
|
34
34
|
import { templateResourceEntity } from "./table.js";
|
|
35
35
|
import { userContentEntryEntity } from "./user-content-table.js";
|
|
36
|
+
import { DEFAULT_COLLECTION_ACCESS, isCollectionRefusedKind } from "./web/constants.js";
|
|
36
37
|
function assertCollectionKindsAllowed(collections) {
|
|
37
38
|
for (const collection of collections) {
|
|
38
39
|
if (isCollectionRefusedKind(collection.kind)) {
|
|
@@ -62,12 +63,18 @@ export function createTemplateResolverFeature(opts = {}) {
|
|
|
62
63
|
const tenantEditable = opts.tenantEditable ?? [];
|
|
63
64
|
assertTenantEditableValid(tenantEditable);
|
|
64
65
|
const policy = { tenantEditable };
|
|
66
|
+
const deliveryPolicy = {
|
|
67
|
+
tenantEditable: tenantEditable.map(({ kind, slug }) => ({ kind, slug })),
|
|
68
|
+
collectionKinds: collections
|
|
69
|
+
.filter((c) => c.ownership !== "user" && c.access !== undefined)
|
|
70
|
+
.map((c) => c.kind),
|
|
71
|
+
};
|
|
65
72
|
const hasUserOwned = collections.some((c) => c.ownership === "user");
|
|
66
73
|
return defineFeature("template-resolver", (r) => {
|
|
67
74
|
r.describe([
|
|
68
75
|
"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`).",
|
|
69
76
|
"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.",
|
|
70
|
-
'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.
|
|
77
|
+
'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.',
|
|
71
78
|
"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.",
|
|
72
79
|
"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).",
|
|
73
80
|
'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.',
|
|
@@ -86,6 +93,7 @@ export function createTemplateResolverFeature(opts = {}) {
|
|
|
86
93
|
resourceMaxBytes: createSystemConfig("number", { default: 2_097_152, bounds: { min: 1 } }),
|
|
87
94
|
},
|
|
88
95
|
});
|
|
96
|
+
r.translations({ keys: TEMPLATE_RESOLVER_I18N });
|
|
89
97
|
r.entity({ name: "template-resource", ...templateResourceEntity });
|
|
90
98
|
// Only when the app actually mounts a user-owned collection: the entity's
|
|
91
99
|
// `content` is `userOwned`, which makes it subject data — the boot guard
|
|
@@ -136,7 +144,7 @@ export function createTemplateResolverFeature(opts = {}) {
|
|
|
136
144
|
});
|
|
137
145
|
r.queryHandler(makeCollectionListQuery(collection));
|
|
138
146
|
r.queryHandler(makeCollectionItemQuery(collection));
|
|
139
|
-
r.writeHandler(makeCollectionSetWrite(collection));
|
|
147
|
+
r.writeHandler(makeCollectionSetWrite(collection, policy));
|
|
140
148
|
}
|
|
141
149
|
// Visual-tree actions for the text-block content tree. The handle is
|
|
142
150
|
// propagated through the setup export so other features can build
|
|
@@ -148,6 +156,6 @@ export function createTemplateResolverFeature(opts = {}) {
|
|
|
148
156
|
list: {},
|
|
149
157
|
create: { args: { folder: emptyString } },
|
|
150
158
|
});
|
|
151
|
-
return { handlers, queries, treeHandle };
|
|
159
|
+
return { handlers, queries, treeHandle, deliveryPolicy };
|
|
152
160
|
});
|
|
153
161
|
}
|
|
@@ -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.js";
|
|
5
5
|
import { templateResourcesTable } from "../table.js";
|
|
6
|
+
import { deliveryPolicyOf } from "../template-delivery-policy.js";
|
|
7
|
+
import { TEXT_BLOCK_KIND } from "../web/constants.js";
|
|
6
8
|
// Public read of a single text-block by (tenantId, slug, locale). Anonymous
|
|
7
9
|
// must be listed explicitly — `openToAll` alone is auth-only (regression
|
|
8
10
|
// guard). The kind is pinned to `text-block` and takes no parameter: mail
|
|
@@ -37,6 +39,9 @@ export const bySlugQuery = defineQueryHandler({
|
|
|
37
39
|
});
|
|
38
40
|
if (!row)
|
|
39
41
|
return null;
|
|
42
|
+
if (!(await isRowDeliveredTo(ctx.db, deliveryPolicyOf(ctx.registry), query.user, row))) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
40
45
|
return {
|
|
41
46
|
slug: row.slug,
|
|
42
47
|
locale: row.locale,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { castTenantRows, selectMany } 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 { filterDeliveredTo } from "../api.js";
|
|
5
5
|
import { templateResourcesTable } from "../table.js";
|
|
6
|
+
import { deliveryPolicyOf } from "../template-delivery-policy.js";
|
|
7
|
+
import { TEXT_BLOCK_KIND } from "../web/constants.js";
|
|
6
8
|
export const byTenantQuery = defineQueryHandler({
|
|
7
9
|
name: "by-tenant",
|
|
8
10
|
schema: z.object({
|
|
@@ -16,8 +18,10 @@ export const byTenantQuery = defineQueryHandler({
|
|
|
16
18
|
const override = query.payload.tenantIdOverride;
|
|
17
19
|
const tenantId = override ?? query.user.tenantId;
|
|
18
20
|
const rows = castTenantRows(await selectMany(ctx.db, templateResourcesTable, { tenantId, kind: TEXT_BLOCK_KIND }));
|
|
21
|
+
const policy = deliveryPolicyOf(ctx.registry);
|
|
22
|
+
const served = await filterDeliveredTo(ctx.db, policy, query.user, rows);
|
|
19
23
|
return {
|
|
20
|
-
blocks:
|
|
24
|
+
blocks: served.map((row) => ({
|
|
21
25
|
slug: row.slug,
|
|
22
26
|
locale: row.locale,
|
|
23
27
|
title: row.title,
|
|
@@ -1,7 +1,7 @@
|
|
|
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 { DEFAULT_COLLECTION_ACCESS } from "../constants.js";
|
|
4
|
+
import { DEFAULT_COLLECTION_ACCESS } from "../web/constants.js";
|
|
5
5
|
import { collectionStore, toCollectionEntry, } from "./collection-shared.js";
|
|
6
6
|
// Single entry of one collection, for the editor behind a tree node. Same
|
|
7
7
|
// per-collection construction as collection-list — see there for why.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { castTenantRows, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { defineQueryHandler, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import * as z from "zod";
|
|
4
|
-
import { DEFAULT_COLLECTION_ACCESS } from "../constants.js";
|
|
4
|
+
import { DEFAULT_COLLECTION_ACCESS } from "../web/constants.js";
|
|
5
5
|
import { collectionStore, toCollectionEntry, } from "./collection-shared.js";
|
|
6
6
|
// One list handler per declared collection: `kind`, `ownership` and `access`
|
|
7
7
|
// come from the declaration, never from the payload.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ContentCollectionDefinition } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import * as z from "zod";
|
|
3
|
-
|
|
3
|
+
import { type TemplateEditPolicy } from "../template-edit-policy.ts";
|
|
4
|
+
export declare function makeCollectionSetWrite(collection: ContentCollectionDefinition, editPolicy: TemplateEditPolicy): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<`${string}-set`, z.ZodObject<{
|
|
4
5
|
slug: z.ZodString;
|
|
5
6
|
locale: z.ZodString;
|
|
6
7
|
title: z.ZodString;
|
|
@@ -3,8 +3,10 @@ import { defineWriteHandler, } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
3
3
|
import { ValidationError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
import { requireForTenant } from "../../shared/index.js";
|
|
6
|
-
import {
|
|
6
|
+
import { systemTemplateExists } from "../api.js";
|
|
7
7
|
import { documentViolationsToFieldIssues, sanitizeTemplateBody } from "../document-sanitizer.js";
|
|
8
|
+
import { refuseTemplateEdit } from "../template-edit-policy.js";
|
|
9
|
+
import { DEFAULT_COLLECTION_ACCESS, isCollectionRefusedKind } from "../web/constants.js";
|
|
8
10
|
import { collectionStore } from "./collection-shared.js";
|
|
9
11
|
import { contentFormatSchema, folderSchema, localeSchema, slugSchema } from "./shared.js";
|
|
10
12
|
// Upsert inside one collection. Mirrors set.write for text-blocks, but the
|
|
@@ -14,7 +16,7 @@ import { contentFormatSchema, folderSchema, localeSchema, slugSchema } from "./s
|
|
|
14
16
|
//
|
|
15
17
|
// Like set.write this publishes on save (status active, empty variableSchema)
|
|
16
18
|
// — the draft stage lives on upsertTenant + publish.
|
|
17
|
-
export function makeCollectionSetWrite(collection) {
|
|
19
|
+
export function makeCollectionSetWrite(collection, editPolicy) {
|
|
18
20
|
const store = collectionStore(collection);
|
|
19
21
|
return defineWriteHandler({
|
|
20
22
|
name: `${collection.id}-set`,
|
|
@@ -63,6 +65,16 @@ export function makeCollectionSetWrite(collection) {
|
|
|
63
65
|
if (!body.ok) {
|
|
64
66
|
return writeFailure(new ValidationError({ fields: documentViolationsToFieldIssues(body.violations) }));
|
|
65
67
|
}
|
|
68
|
+
// The collection's access must not open a system template that the app did not unlock.
|
|
69
|
+
if (collection.ownership !== "user" &&
|
|
70
|
+
(await systemTemplateExists(db, collection.kind, event.payload.slug))) {
|
|
71
|
+
const refused = refuseTemplateEdit(editPolicy, event.user, {
|
|
72
|
+
slug: event.payload.slug,
|
|
73
|
+
kind: collection.kind,
|
|
74
|
+
});
|
|
75
|
+
if (refused)
|
|
76
|
+
return refused;
|
|
77
|
+
}
|
|
66
78
|
const existing = await fetchOne(db, store.table, {
|
|
67
79
|
tenantId,
|
|
68
80
|
slug: event.payload.slug,
|
|
@@ -4,15 +4,15 @@ import { AccessDeniedError, NotFoundError, ValidationError, writeFailure, } from
|
|
|
4
4
|
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
5
5
|
import * as z from "zod";
|
|
6
6
|
import { requireForTenant } from "../../shared/index.js";
|
|
7
|
-
import { CONTENT_FORMATS } from "../constants.js";
|
|
8
7
|
import { parseLinkedResourceEntries } from "../linked-resources.js";
|
|
9
|
-
import { TemplateResolverErrors } from "../qualified-names.js";
|
|
10
8
|
import { createLinkedResourceCopies, prepareLinkedResourceCopiesBeforeTransaction, } from "../store-template-resource.js";
|
|
11
9
|
import { templateResourcesTable } from "../table.js";
|
|
12
10
|
import { toWorkingRow } from "../template-draft.js";
|
|
13
11
|
import { refuseTemplateEdit, templateEditAccess, } from "../template-edit-policy.js";
|
|
14
12
|
import { attachTemplateResources } from "../template-resources.js";
|
|
15
13
|
import { resolveTemplateVariables } from "../template-validation.js";
|
|
14
|
+
import { CONTENT_FORMATS } from "../web/constants.js";
|
|
15
|
+
import { TemplateResolverErrors } from "../web/qualified-names.js";
|
|
16
16
|
import { targetExistsIssue } from "./bundle-import.js";
|
|
17
17
|
import { kindSchema, localeSchema, templateSlugSchema } from "./shared.js";
|
|
18
18
|
import { parseStoredJson, storedRecord } from "./template-gates.js";
|
|
@@ -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 { templateResourcesTable } from "../table.js";
|
|
6
|
+
import { deliveryPolicyOf, isRowServedTo } from "../template-delivery-policy.js";
|
|
6
7
|
import { isHiddenSystemDraft } from "../template-draft.js";
|
|
7
8
|
import { buildOverrideDiff } from "./override-diff.js";
|
|
8
9
|
export const diffToSystemQuery = defineQueryHandler({
|
|
@@ -14,7 +15,10 @@ export const diffToSystemQuery = defineQueryHandler({
|
|
|
14
15
|
const tenantRow = await fetchOne(ctx.db, templateResourcesTable, {
|
|
15
16
|
id: query.payload.id,
|
|
16
17
|
});
|
|
17
|
-
if (!tenantRow ||
|
|
18
|
+
if (!tenantRow ||
|
|
19
|
+
tenantRow.tenantId !== query.user.tenantId ||
|
|
20
|
+
tenantRow.scope !== "tenant" ||
|
|
21
|
+
!isRowServedTo(deliveryPolicyOf(ctx.registry), query.user, tenantRow)) {
|
|
18
22
|
throw new NotFoundError("template-resource", query.payload.id);
|
|
19
23
|
}
|
|
20
24
|
const systemRow = await fetchOne(ctx.db, templateResourcesTable, {
|
|
@@ -1,8 +1,8 @@
|
|
|
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.js";
|
|
5
4
|
import { refuseMissingTemplate, refuseTemplateEdit, } from "../template-edit-policy.js";
|
|
5
|
+
import { TemplateResolverErrors } from "../web/qualified-names.js";
|
|
6
6
|
import { executor } from "./shared.js";
|
|
7
7
|
import { loadTargetRow, writeAccessFor } from "./toggle-status.write.js";
|
|
8
8
|
function createDiscardDraftHandler(policy, name, target, description) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type HandlerContext, type SessionUser } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
-
import type { DocumentHtmlKind } from "../constants.ts";
|
|
2
|
+
import type { DocumentHtmlKind } from "../web/constants.ts";
|
|
3
3
|
export type DocumentBase = {
|
|
4
4
|
readonly scope: "tenant" | "system";
|
|
5
5
|
/** The stored row's own version, which counts every draft save. */
|
|
@@ -2,6 +2,7 @@ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
|
2
2
|
import { SYSTEM_TENANT_ID, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
4
4
|
import { templateResourcesTable } from "../table.js";
|
|
5
|
+
import { deliveryPolicyOf, isRowServedTo } from "../template-delivery-policy.js";
|
|
5
6
|
import { isHiddenSystemDraft, toWorkingRow } from "../template-draft.js";
|
|
6
7
|
import { isSystemOnlyTemplateHiddenFrom } from "../template-system-only.js";
|
|
7
8
|
import { parseStoredJson } from "./template-gates.js";
|
|
@@ -16,7 +17,11 @@ export async function loadDocumentBase(ctx, user, where) {
|
|
|
16
17
|
tenantId: user.tenantId,
|
|
17
18
|
...where,
|
|
18
19
|
});
|
|
19
|
-
|
|
20
|
+
// A locked override is neither shown nor edited by a non-SystemAdmin; the served system default is.
|
|
21
|
+
const ownIsVisible = own !== undefined &&
|
|
22
|
+
!isSystemOnlyTemplateHiddenFrom(user, ctx.registry, own) &&
|
|
23
|
+
isRowServedTo(deliveryPolicyOf(ctx.registry), user, own);
|
|
24
|
+
if (own !== undefined && ownIsVisible) {
|
|
20
25
|
const working = toWorkingRow(own, user.tenantId);
|
|
21
26
|
return {
|
|
22
27
|
rowId: String(own.id),
|
|
@@ -17,6 +17,6 @@ export declare const documentBlocksQuery: import("@cosmicdrift/kumiko-types/defi
|
|
|
17
17
|
variableSchema: Readonly<Record<string, unknown>>;
|
|
18
18
|
variables: Readonly<Record<string, import("@cosmicdrift/kumiko-types/config").TemplateVariableDef>>;
|
|
19
19
|
variablesDeclaredByFeature: boolean;
|
|
20
|
-
allowedBlocks: readonly import("../document-blocks.ts").DocumentToolbarBlock[];
|
|
20
|
+
allowedBlocks: readonly import("../web/document-blocks.ts").DocumentToolbarBlock[];
|
|
21
21
|
resourceKeys: string[];
|
|
22
22
|
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import { NotFoundError } from "@cosmicdrift/kumiko-framework/errors";
|
|
3
3
|
import * as z from "zod";
|
|
4
|
-
import { DOCUMENT_HTML_KINDS } from "../constants.js";
|
|
5
|
-
import { documentBlocksForKind } from "../document-blocks.js";
|
|
6
4
|
import { documentBlocksOf } from "../document-ops.js";
|
|
7
5
|
import { parseDocumentJson } from "../document-sanitizer.js";
|
|
8
6
|
import { resolveTemplateVariables } from "../template-validation.js";
|
|
7
|
+
import { DOCUMENT_HTML_KINDS } from "../web/constants.js";
|
|
8
|
+
import { documentBlocksForKind } from "../web/document-blocks.js";
|
|
9
9
|
import { loadDocumentBase } from "./document-base.js";
|
|
10
10
|
import { localeSchema, templateSlugSchema } from "./shared.js";
|
|
11
11
|
import { knownResourceKeysFor } from "./validate.query.js";
|