@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.388.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/LICENSE +21 -57
- package/dist/agent-tools/tool-catalog.js +1 -1
- package/dist/agent-tools/tool-dispatch.d.ts +7 -7
- package/dist/agent-tools/tool-dispatch.js +9 -9
- package/dist/audit/handlers/audit-events.js +1 -1
- package/dist/audit/screens.js +1 -1
- package/dist/auth-email-password/feature.js +1 -1
- package/dist/auth-email-password/handlers/change-password.write.js +3 -3
- package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
- package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
- package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
- package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
- package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
- package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
- package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/login.write.js +1 -1
- package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
- package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
- package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
- package/dist/auth-email-password/index.js +5 -5
- package/dist/auth-email-password/lockout-store.js +1 -1
- package/dist/auth-email-password/seeding.d.ts +42 -45
- package/dist/auth-email-password/seeding.js +51 -53
- package/dist/auth-email-password/signup-token-store.js +8 -8
- package/dist/auth-email-password/testing.js +3 -3
- package/dist/auth-email-password/web/auth-client.d.ts +2 -2
- package/dist/auth-email-password/web/auth-client.js +36 -37
- package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
- package/dist/auth-email-password/web/auth-gate.js +15 -16
- package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
- package/dist/auth-email-password/web/client-plugin.js +4 -5
- package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
- package/dist/auth-email-password/web/constants.js +3 -3
- package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
- package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
- package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
- package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
- package/dist/auth-email-password/web/index.js +5 -5
- package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
- package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
- package/dist/auth-email-password/web/login-screen.d.ts +1 -1
- package/dist/auth-email-password/web/login-screen.js +2 -3
- package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
- package/dist/auth-email-password/web/reset-password-screen.js +12 -13
- package/dist/auth-email-password/web/session.d.ts +10 -9
- package/dist/auth-email-password/web/session.js +28 -29
- package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
- package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
- package/dist/auth-email-password/web/signup-screen.js +13 -13
- package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
- package/dist/auth-email-password/web/tenant-switcher.js +21 -22
- package/dist/auth-email-password/web/use-shell-user.js +12 -13
- package/dist/auth-email-password/web/user-menu.d.ts +4 -4
- package/dist/auth-email-password/web/user-menu.js +12 -13
- package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
- package/dist/auth-email-password/web/verify-email-screen.js +9 -10
- package/dist/auth-foundation/boot-checks.js +4 -4
- package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
- package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
- package/dist/auth-foundation/types.js +2 -2
- package/dist/auth-mfa/feature-exports.d.ts +2 -2
- package/dist/auth-mfa/feature.js +8 -0
- package/dist/auth-mfa/handlers/disable.write.js +3 -3
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
- package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
- package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
- package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
- package/dist/auth-mfa/handlers/verify.write.js +1 -1
- package/dist/auth-mfa/token-secrets.js +1 -1
- package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
- package/dist/auth-mfa/web/client-plugin.js +1 -1
- package/dist/auth-mfa/web/i18n.js +8 -4
- package/dist/auth-mfa/web/index.js +4 -4
- package/dist/auth-mfa/web/mfa-client.js +17 -16
- package/dist/auth-mfa/web/mfa-code-or-recovery-field.d.ts +11 -0
- package/dist/auth-mfa/web/mfa-code-or-recovery-field.js +12 -0
- package/dist/auth-mfa/web/mfa-disable-dialog.js +14 -3
- package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +14 -3
- package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +10 -5
- package/dist/auth-mfa/web/mfa-verify-screen.js +32 -11
- package/dist/billing-foundation/aggregate-id.d.ts +5 -5
- package/dist/billing-foundation/aggregate-id.js +10 -11
- package/dist/billing-foundation/checkout-core.d.ts +9 -14
- package/dist/billing-foundation/checkout-core.js +24 -39
- package/dist/billing-foundation/consumer-protection/confirmation-mail.js +8 -2
- package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +1 -0
- package/dist/billing-foundation/consumer-protection/consent-gate.js +1 -0
- package/dist/billing-foundation/consumer-protection/issue-confirmation.js +9 -3
- package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +4 -2
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +6 -5
- package/dist/billing-foundation/consumer-protection/termination-record.d.ts +5 -1
- package/dist/billing-foundation/consumer-protection/termination-record.js +27 -17
- package/dist/billing-foundation/consumer-protection/termination-request.js +12 -7
- package/dist/billing-foundation/consumer-protection/termination-revoke.js +12 -7
- package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
- package/dist/billing-foundation/consumer-protection/termination-texts.js +3 -0
- package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +5 -2
- package/dist/billing-foundation/consumer-protection/withdrawal-period.js +8 -9
- package/dist/billing-foundation/entities.js +27 -27
- package/dist/billing-foundation/events.d.ts +1 -0
- package/dist/billing-foundation/events.js +19 -17
- package/dist/billing-foundation/feature.js +45 -44
- package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
- package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
- package/dist/billing-foundation/handlers/billing-plans.query.js +35 -5
- package/dist/billing-foundation/handlers/create-checkout-session.write.js +19 -17
- package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
- package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
- package/dist/billing-foundation/handlers/plan-switch-preview.query.d.ts +13 -0
- package/dist/billing-foundation/handlers/plan-switch-preview.query.js +48 -0
- package/dist/billing-foundation/handlers/process-event.write.d.ts +6 -0
- package/dist/billing-foundation/handlers/process-event.write.js +28 -22
- package/dist/billing-foundation/handlers/start-plan-checkout.write.js +32 -5
- package/dist/billing-foundation/handlers/switch-plan.write.d.ts +2 -2
- package/dist/billing-foundation/handlers/switch-plan.write.js +56 -64
- package/dist/billing-foundation/handlers/sync-subscription.write.js +12 -1
- package/dist/billing-foundation/i18n.js +22 -0
- package/dist/billing-foundation/index.d.ts +1 -1
- package/dist/billing-foundation/plan-catalog.d.ts +21 -5
- package/dist/billing-foundation/plan-catalog.js +25 -16
- package/dist/billing-foundation/plan-switch.d.ts +12 -0
- package/dist/billing-foundation/plan-switch.js +60 -0
- package/dist/billing-foundation/projection.d.ts +15 -11
- package/dist/billing-foundation/projection.js +38 -37
- package/dist/billing-foundation/subscription-tier-sync.js +3 -3
- package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
- package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
- package/dist/billing-foundation/types.d.ts +97 -42
- package/dist/billing-foundation/types.js +29 -20
- package/dist/billing-foundation/validate-options.js +17 -0
- package/dist/billing-foundation/web/billing-plans-panel.js +82 -36
- package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +17 -3
- package/dist/billing-foundation/web/checkout-consent-dialog.js +14 -10
- package/dist/billing-foundation/web/constants.d.ts +4 -0
- package/dist/billing-foundation/web/constants.js +4 -0
- package/dist/billing-foundation/web/plan-price.d.ts +15 -0
- package/dist/billing-foundation/web/plan-price.js +32 -0
- package/dist/billing-foundation/web/plan-switch-confirm-dialog.d.ts +15 -0
- package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +66 -0
- package/dist/cap-counter/aggregate-id.js +8 -9
- package/dist/cap-counter/cap-reservation.js +5 -1
- package/dist/cap-counter/constants.js +11 -12
- package/dist/cap-counter/enforce-cap.d.ts +59 -62
- package/dist/cap-counter/enforce-cap.js +49 -49
- package/dist/cap-counter/entity.js +29 -29
- package/dist/cap-counter/feature.js +34 -35
- package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
- package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
- package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
- package/dist/cap-counter/stock-cap-guard.js +8 -2
- package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
- package/dist/channel-email/feature.js +1 -1
- package/dist/channel-email/smtp-transport.d.ts +18 -17
- package/dist/channel-email/smtp-transport.js +24 -21
- package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
- package/dist/compliance-profiles/feature.js +4 -4
- package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
- package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
- package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
- package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
- package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
- package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
- package/dist/compliance-profiles/schema/profile-selection.js +18 -23
- package/dist/compliance-profiles/seeding.js +14 -15
- package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
- package/dist/compliance-profiles-ops/index.js +2 -2
- package/dist/config/handlers/cascade.query.d.ts +5 -0
- package/dist/config/handlers/cascade.query.js +4 -3
- package/dist/config/handlers/readiness.query.d.ts +4 -4
- package/dist/config/handlers/readiness.query.js +1 -1
- package/dist/config/handlers/reencrypt.job.js +4 -5
- package/dist/config/handlers/set.write.js +4 -4
- package/dist/config/handlers/values.query.d.ts +5 -0
- package/dist/config/handlers/values.query.js +4 -3
- package/dist/config/resolver.js +4 -4
- package/dist/config/table.js +10 -10
- package/dist/config/write-helpers.d.ts +1 -0
- package/dist/config/write-helpers.js +19 -10
- package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
- package/dist/crypto-shredding/handlers/forget-subject.write.js +25 -21
- package/dist/custom-fields/aggregate-id.d.ts +12 -13
- package/dist/custom-fields/aggregate-id.js +16 -17
- package/dist/custom-fields/entity.js +49 -47
- package/dist/custom-fields/events.js +7 -8
- package/dist/custom-fields/feature.d.ts +14 -14
- package/dist/custom-fields/feature.js +53 -54
- package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
- package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
- package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
- package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
- package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
- package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
- package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
- package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
- package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
- package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
- package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
- package/dist/custom-fields/lib/field-access.js +2 -2
- package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
- package/dist/custom-fields/lib/quota.js +1 -1
- package/dist/custom-fields/lib/value-schema.js +10 -12
- package/dist/custom-fields/run-retention.js +3 -3
- package/dist/custom-fields/schemas.js +14 -14
- package/dist/custom-fields/web/client-plugin.js +2 -5
- package/dist/custom-fields/web/constants.js +2 -2
- package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
- package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
- package/dist/custom-fields/wire-for-entity.js +65 -67
- package/dist/custom-fields/wire-user-data-rights.js +3 -3
- package/dist/data-retention/_internal/parse-override.js +2 -3
- package/dist/data-retention/feature.js +11 -18
- package/dist/data-retention/handlers/policy-for.query.js +6 -6
- package/dist/data-retention/keep-for.d.ts +7 -7
- package/dist/data-retention/keep-for.js +15 -15
- package/dist/data-retention/override-schema.d.ts +3 -4
- package/dist/data-retention/override-schema.js +13 -15
- package/dist/data-retention/presets.d.ts +4 -5
- package/dist/data-retention/presets.js +18 -23
- package/dist/data-retention/resolve-tenant-preset.js +17 -16
- package/dist/data-retention/resolver.d.ts +12 -12
- package/dist/data-retention/resolver.js +24 -23
- package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
- package/dist/data-retention/run-retention-cleanup.js +61 -51
- package/dist/data-retention/schema/tenant-retention-override.js +13 -11
- package/dist/delivery/channel-context.js +6 -3
- package/dist/delivery/db/queries/preferences.js +2 -2
- package/dist/delivery/delivery-service.js +22 -7
- package/dist/delivery/feature.js +2 -2
- package/dist/delivery/handlers/log.query.js +1 -1
- package/dist/delivery/handlers/preferences.query.d.ts +1 -1
- package/dist/delivery/handlers/preferences.query.js +20 -1
- package/dist/delivery/handlers/unsubscribe-page-chrome.query.js +1 -1
- package/dist/delivery/tables.js +9 -8
- package/dist/delivery/unsubscribe-link.d.ts +3 -1
- package/dist/delivery/unsubscribe-page-strings.d.ts +1 -0
- package/dist/delivery/unsubscribe-page-strings.js +1 -0
- package/dist/delivery/unsubscribe-page.d.ts +2 -0
- package/dist/delivery/unsubscribe-page.js +5 -0
- package/dist/delivery/unsubscribe.js +29 -11
- package/dist/document-ingest-foundation/entity.js +4 -4
- package/dist/document-ingest-foundation/events.js +2 -2
- package/dist/document-ingest-foundation/feature.js +2 -2
- package/dist/document-ingest-foundation/pages.js +1 -1
- package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
- package/dist/feature-toggles/compose-tier-resolver.js +1 -1
- package/dist/feature-toggles/feature.js +1 -1
- package/dist/feature-toggles/global-feature-state-table.js +1 -1
- package/dist/feature-toggles/handlers/registered.query.js +5 -5
- package/dist/feature-toggles/toggle-sync-signal.js +1 -1
- package/dist/feature-toggles/web/constants.js +1 -1
- package/dist/file-derivatives/feature.d.ts +1 -1
- package/dist/file-derivatives/feature.js +1 -1
- package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
- package/dist/file-derivatives/presets.js +1 -1
- package/dist/file-foundation/feature.js +6 -6
- package/dist/file-foundation/index.d.ts +1 -1
- package/dist/file-foundation/index.js +1 -1
- package/dist/file-foundation/read-file-ref-content.d.ts +3 -0
- package/dist/file-foundation/read-file-ref-content.js +6 -1
- package/dist/file-provider-inmemory/feature.d.ts +1 -1
- package/dist/file-provider-inmemory/feature.js +16 -16
- package/dist/file-provider-s3/env-named-feature.d.ts +0 -2
- package/dist/file-provider-s3/feature.js +16 -16
- package/dist/file-provider-s3/lib/s3-provider.js +6 -6
- package/dist/files/feature.js +6 -6
- package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
- package/dist/files-tenant-data/hooks.js +24 -26
- package/dist/files-tenant-data/index.js +1 -1
- package/dist/folders/feature.d.ts +1 -1
- package/dist/folders/web/folder-manager.js +2 -2
- package/dist/folders/web/tree.js +5 -5
- package/dist/form-draft/db/queries/cleanup.js +3 -3
- package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
- package/dist/form-draft/decrypt-draft.js +5 -1
- package/dist/form-draft/entity.js +3 -3
- package/dist/form-draft/feature.js +4 -5
- package/dist/form-draft/handlers/discard.write.js +1 -1
- package/dist/form-draft/release-file-refs.js +6 -6
- package/dist/form-draft/schemas.js +3 -3
- package/dist/form-draft/web/constants.js +0 -2
- package/dist/host-routing/dispatch.js +11 -20
- package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
- package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
- package/dist/inbound-mail-foundation/connect-routes.js +4 -3
- package/dist/inbound-mail-foundation/constants.d.ts +22 -24
- package/dist/inbound-mail-foundation/constants.js +30 -33
- package/dist/inbound-mail-foundation/entities.d.ts +12 -12
- package/dist/inbound-mail-foundation/entities.js +47 -48
- package/dist/inbound-mail-foundation/events.d.ts +4 -3
- package/dist/inbound-mail-foundation/events.js +50 -47
- package/dist/inbound-mail-foundation/feature.js +39 -39
- package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
- package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
- package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
- package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
- package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
- package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
- package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
- package/dist/inbound-mail-foundation/handlers/update-account.write.d.ts +2 -2
- package/dist/inbound-mail-foundation/handlers/update-account.write.js +22 -14
- package/dist/inbound-mail-foundation/i18n.js +0 -1
- package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
- package/dist/inbound-mail-foundation/oauth-state.js +11 -10
- package/dist/inbound-mail-foundation/projection.d.ts +4 -4
- package/dist/inbound-mail-foundation/projection.js +31 -29
- package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
- package/dist/inbound-mail-foundation/provider-factory.js +9 -9
- package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
- package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
- package/dist/inbound-mail-foundation/screens.js +0 -3
- package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
- package/dist/inbound-mail-foundation/types.d.ts +49 -49
- package/dist/inbound-mail-foundation/types.js +21 -21
- package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
- package/dist/inbound-mail-foundation/watch-supervisor.js +85 -67
- package/dist/inbound-provider-imap/credential-document.js +13 -13
- package/dist/inbound-provider-imap/feature.d.ts +2 -2
- package/dist/inbound-provider-imap/feature.js +42 -40
- package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
- package/dist/inbound-provider-imap/imap-client.js +20 -19
- package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
- package/dist/inbound-provider-inmemory/feature.js +19 -19
- package/dist/jobs/db/queries/retention.js +2 -2
- package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
- package/dist/jobs/events.js +1 -1
- package/dist/jobs/feature.d.ts +1 -0
- package/dist/jobs/feature.js +13 -10
- package/dist/jobs/handlers/detail.query.js +4 -4
- package/dist/jobs/handlers/list.query.js +1 -1
- package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
- package/dist/jobs/handlers/reindex-entity.job.js +1 -1
- package/dist/jobs/handlers/retry.write.js +1 -1
- package/dist/jobs/handlers/tenant-failures.query.d.ts +1 -1
- package/dist/jobs/handlers/tenant-failures.query.js +45 -41
- package/dist/jobs/handlers/tenant-runs.query.d.ts +1 -1
- package/dist/jobs/handlers/tenant-runs.query.js +54 -50
- package/dist/jobs/job-instant.js +1 -1
- package/dist/jobs/job-run-logger.js +15 -15
- package/dist/jobs/job-run-table.js +3 -3
- package/dist/jobs/screens.js +1 -1
- package/dist/jobs/tenant-job-failure-table.js +1 -1
- package/dist/jobs/tenant-job-run-table.js +1 -1
- package/dist/ledger/entity.js +5 -5
- package/dist/ledger/feature.js +3 -3
- package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
- package/dist/ledger/recurring.js +12 -12
- package/dist/ledger/schemas.js +1 -1
- package/dist/ledger/web/constants.js +2 -2
- package/dist/ledger/web/index.js +7 -7
- package/dist/legal-pages/feature.d.ts +4 -4
- package/dist/legal-pages/feature.js +25 -26
- package/dist/legal-pages/markdown.js +3 -3
- package/dist/legal-pages/web/client-plugin.js +23 -24
- package/dist/legal-pages/web/index.js +0 -1
- package/dist/mail-foundation/feature.d.ts +5 -5
- package/dist/mail-foundation/feature.js +27 -25
- package/dist/mail-transport-inmemory/feature.d.ts +4 -4
- package/dist/mail-transport-inmemory/feature.js +27 -28
- package/dist/mail-transport-smtp/feature.js +20 -20
- package/dist/managed-pages/branding.js +6 -6
- package/dist/managed-pages/feature.d.ts +26 -26
- package/dist/managed-pages/feature.js +34 -34
- package/dist/managed-pages/handlers/by-slug.query.js +5 -6
- package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
- package/dist/managed-pages/handlers/set.write.js +5 -7
- package/dist/managed-pages/screens/page-screens.js +11 -11
- package/dist/managed-pages/seeding.js +8 -8
- package/dist/managed-pages/table.js +13 -12
- package/dist/managed-pages/web/client-plugin.d.ts +1 -1
- package/dist/managed-pages/web/client-plugin.js +5 -5
- package/dist/managed-pages/web/i18n.js +1 -1
- package/dist/notes-history/entity.js +4 -4
- package/dist/notes-history/feature.d.ts +2 -2
- package/dist/notes-history-user-data/hooks.js +1 -1
- package/dist/page-render/layout.js +9 -9
- package/dist/page-render/markdown.js +11 -11
- package/dist/page-render/security-headers.js +7 -6
- package/dist/personal-access-tokens/feature.d.ts +1 -1
- package/dist/personal-access-tokens/feature.js +9 -5
- package/dist/personal-access-tokens/roles.js +2 -2
- package/dist/readiness/handlers/status.query.js +3 -3
- package/dist/renderer-foundation/api.js +12 -13
- package/dist/renderer-foundation/constants.js +2 -2
- package/dist/renderer-foundation/feature.js +7 -7
- package/dist/renderer-pdf/render-table-pdf.d.ts +1 -1
- package/dist/renderer-pdf/render-table-pdf.js +22 -10
- package/dist/secrets/feature.js +9 -9
- package/dist/secrets/web/constants.js +2 -2
- package/dist/seo/feature.js +3 -3
- package/dist/sessions/constants.d.ts +1 -1
- package/dist/sessions/constants.js +1 -1
- package/dist/sessions/feature.d.ts +2 -2
- package/dist/sessions/feature.js +12 -8
- package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
- package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
- package/dist/sessions/handlers/revoke.write.js +1 -1
- package/dist/sessions/schema/user-session.js +4 -4
- package/dist/sessions/screens.js +2 -2
- package/dist/sessions/session-callbacks.js +2 -2
- package/dist/sessions/session-revoked-event.js +2 -2
- package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
- package/dist/shared/decrypt-stored-pii.d.ts +1 -0
- package/dist/shared/decrypt-stored-pii.js +7 -2
- package/dist/shared/encrypt-for-direct-write.js +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/mail-template-body.d.ts +6 -2
- package/dist/shared/mail-template-body.js +7 -4
- package/dist/shared/map-with-concurrency.js +5 -4
- package/dist/shared/parent-visibility.js +2 -2
- package/dist/shared/password-hashing.js +1 -1
- package/dist/shared/signup-handover.js +1 -2
- package/dist/shared/single-use-token-store.js +1 -1
- package/dist/step-dispatcher/feature.js +1 -0
- package/dist/subscription-dodo/client.d.ts +17 -0
- package/dist/subscription-dodo/client.js +31 -0
- package/dist/subscription-dodo/constants.d.ts +12 -0
- package/dist/subscription-dodo/constants.js +19 -0
- package/dist/subscription-dodo/feature.d.ts +37 -0
- package/dist/subscription-dodo/feature.js +144 -0
- package/dist/subscription-dodo/index.d.ts +2 -0
- package/dist/subscription-dodo/index.js +4 -0
- package/dist/subscription-dodo/plugin-methods.d.ts +23 -0
- package/dist/subscription-dodo/plugin-methods.js +260 -0
- package/dist/subscription-dodo/runtime.d.ts +27 -0
- package/dist/subscription-dodo/runtime.js +89 -0
- package/dist/subscription-dodo/verify-webhook.d.ts +37 -0
- package/dist/subscription-dodo/verify-webhook.js +189 -0
- package/dist/subscription-mollie/constants.js +15 -17
- package/dist/subscription-mollie/feature.d.ts +17 -18
- package/dist/subscription-mollie/feature.js +24 -24
- package/dist/subscription-mollie/index.js +3 -3
- package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
- package/dist/subscription-mollie/plugin-methods.js +15 -14
- package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
- package/dist/subscription-mollie/verify-webhook.js +27 -27
- package/dist/subscription-stripe/constants.js +4 -6
- package/dist/subscription-stripe/feature.d.ts +14 -14
- package/dist/subscription-stripe/feature.js +36 -34
- package/dist/subscription-stripe/index.js +6 -6
- package/dist/subscription-stripe/plugin-methods.js +18 -18
- package/dist/subscription-stripe/runtime.d.ts +1 -1
- package/dist/subscription-stripe/runtime.js +8 -7
- package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
- package/dist/subscription-stripe/verify-webhook.js +59 -61
- package/dist/tags/feature.d.ts +3 -3
- package/dist/tags/screens.js +1 -1
- package/dist/template-resolver/api.d.ts +3 -2
- package/dist/template-resolver/api.js +34 -12
- package/dist/template-resolver/compile-document-body.js +1 -0
- package/dist/template-resolver/feature.js +2 -2
- package/dist/template-resolver/handlers/bundle-import.js +3 -3
- package/dist/template-resolver/handlers/copy-locale.write.d.ts +5 -1
- package/dist/template-resolver/handlers/copy-locale.write.js +22 -7
- package/dist/template-resolver/handlers/diff-to-system.query.js +3 -2
- package/dist/template-resolver/handlers/document-base.js +3 -2
- package/dist/template-resolver/handlers/find-by-id.query.js +8 -7
- package/dist/template-resolver/handlers/list.query.js +6 -7
- package/dist/template-resolver/handlers/overview.query.d.ts +3 -0
- package/dist/template-resolver/handlers/overview.query.js +6 -3
- package/dist/template-resolver/handlers/shared.js +2 -2
- package/dist/template-resolver/handlers/template-write.js +3 -3
- package/dist/template-resolver/handlers/tenant-override-counts.query.js +1 -3
- package/dist/template-resolver/handlers/tenant-override-selection.d.ts +2 -1
- package/dist/template-resolver/handlers/tenant-overrides.query.js +28 -5
- package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
- package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
- package/dist/template-resolver/handlers/usage.query.d.ts +2 -1
- package/dist/template-resolver/handlers/usage.query.js +26 -16
- package/dist/template-resolver/handlers/validate.query.js +7 -2
- package/dist/template-resolver/seeding.js +30 -14
- package/dist/template-resolver/store-template-resource.d.ts +1 -0
- package/dist/template-resolver/store-template-resource.js +19 -4
- package/dist/template-resolver/table.js +10 -11
- package/dist/template-resolver/template-delivery-policy.d.ts +0 -5
- package/dist/template-resolver/template-delivery-policy.js +0 -6
- package/dist/template-resolver/template-meta.js +7 -4
- package/dist/template-resolver/template-preview.js +4 -3
- package/dist/template-resolver/web/client-plugin.js +2 -2
- package/dist/template-resolver/web/constants.d.ts +2 -2
- package/dist/template-resolver/web/constants.js +3 -3
- package/dist/template-resolver/web/index.d.ts +1 -0
- package/dist/template-resolver/web/index.js +1 -0
- package/dist/template-resolver/web/mail-layout-constants.d.ts +5 -0
- package/dist/template-resolver/web/mail-layout-constants.js +7 -0
- package/dist/tenant/feature.js +7 -7
- package/dist/tenant/handlers/member-directory.query.d.ts +1 -0
- package/dist/tenant/handlers/member-directory.query.js +11 -4
- package/dist/tenant/handlers/members.query.js +1 -1
- package/dist/tenant/handlers/team-list.query.js +1 -1
- package/dist/tenant/handlers/tenant-directory.query.d.ts +1 -0
- package/dist/tenant/handlers/tenant-directory.query.js +9 -5
- package/dist/tenant/invitation-table.js +37 -40
- package/dist/tenant/membership-table.js +3 -3
- package/dist/tenant/schema/tenant.js +7 -9
- package/dist/tenant/screens.js +1 -1
- package/dist/tenant/seeding.d.ts +6 -5
- package/dist/tenant/seeding.js +12 -12
- package/dist/tenant/testing.js +5 -6
- package/dist/tenant/web/constants.js +2 -2
- package/dist/tenant-handover/events.js +5 -7
- package/dist/tenant-handover/feature.js +1 -1
- package/dist/tenant-handover/grant.js +1 -1
- package/dist/tenant-handover/handlers/claim.write.js +1 -1
- package/dist/tenant-handover/move-entity-graph.js +8 -9
- package/dist/tenant-handover/signup-handover-provider.js +1 -2
- package/dist/tenant-handover/transfer-graph.js +4 -5
- package/dist/tenant-lifecycle/boot-checks.js +1 -1
- package/dist/tenant-lifecycle/constants.d.ts +1 -0
- package/dist/tenant-lifecycle/constants.js +4 -0
- package/dist/tenant-lifecycle/feature.js +1 -1
- package/dist/tenant-lifecycle/run-tenant-destroy.js +2 -2
- package/dist/tenant-settings/constants.js +1 -1
- package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
- package/dist/tenant-settings/tenant-defaults.js +9 -2
- package/dist/tier-engine/aggregate-id.d.ts +11 -11
- package/dist/tier-engine/aggregate-id.js +15 -16
- package/dist/tier-engine/compose-app.d.ts +14 -14
- package/dist/tier-engine/compose-app.js +1 -1
- package/dist/tier-engine/entity.js +18 -19
- package/dist/tier-engine/feature.d.ts +19 -17
- package/dist/tier-engine/feature.js +68 -69
- package/dist/tier-engine/handlers/active-tier.query.js +6 -7
- package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
- package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +7 -8
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +7 -4
- package/dist/tier-engine/tier-resolver.js +2 -2
- package/dist/tier-engine/trial.js +8 -8
- package/dist/tier-engine/web/constants.js +2 -2
- package/dist/tier-engine/web/index.js +4 -4
- package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
- package/dist/user/handlers/create.write.js +4 -4
- package/dist/user/schema/user.d.ts +11 -11
- package/dist/user/schema/user.js +45 -44
- package/dist/user/seeding.d.ts +15 -15
- package/dist/user/seeding.js +28 -28
- package/dist/user/testing.js +3 -3
- package/dist/user-data-rights/audit-download.d.ts +8 -8
- package/dist/user-data-rights/audit-download.js +19 -20
- package/dist/user-data-rights/boot-checks.js +1 -1
- package/dist/user-data-rights/deletion-token.js +1 -1
- package/dist/user-data-rights/feature.d.ts +49 -50
- package/dist/user-data-rights/feature.js +54 -53
- package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
- package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
- package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
- package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
- package/dist/user-data-rights/handlers/export-status.query.js +8 -9
- package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
- package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
- package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
- package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
- package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
- package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
- package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
- package/dist/user-data-rights/handlers/request-export.write.js +42 -41
- package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
- package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
- package/dist/user-data-rights/index.js +8 -10
- package/dist/user-data-rights/lib/default-mailers.js +3 -3
- package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
- package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
- package/dist/user-data-rights/run-export-jobs.js +130 -237
- package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
- package/dist/user-data-rights/run-forget-cleanup.js +65 -83
- package/dist/user-data-rights/run-user-export.d.ts +34 -33
- package/dist/user-data-rights/run-user-export.js +55 -57
- package/dist/user-data-rights/schema/download-attempt.js +11 -11
- package/dist/user-data-rights/schema/download-token.js +37 -41
- package/dist/user-data-rights/schema/export-job.d.ts +4 -4
- package/dist/user-data-rights/schema/export-job.js +65 -67
- package/dist/user-data-rights/token-helpers.d.ts +8 -9
- package/dist/user-data-rights/token-helpers.js +21 -25
- package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
- package/dist/user-data-rights/web/client-plugin.js +1 -1
- package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
- package/dist/user-data-rights/web/constants.js +1 -1
- package/dist/user-data-rights/web/index.js +5 -5
- package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
- package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
- package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
- package/dist/user-data-rights/zip-path.d.ts +15 -15
- package/dist/user-data-rights/zip-path.js +41 -40
- package/dist/user-data-rights-defaults/feature.js +15 -15
- package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
- package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
- package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
- package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
- package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
- package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
- package/dist/user-profile/handlers/change-email.write.js +13 -13
- package/dist/user-profile/index.js +3 -3
- package/dist/user-profile/web/client-plugin.js +1 -1
- package/dist/user-profile/web/constants.js +1 -1
- package/dist/user-profile/web/profile-screen.js +1 -1
- package/dist/waitlist/handlers/export-purge.write.js +2 -1
- package/dist/waitlist/handlers/submit.write.js +5 -5
- package/dist/waitlist/import.d.ts +1 -0
- package/dist/waitlist/import.js +4 -0
- package/dist/waitlist/legacy-migrate.js +17 -6
- package/dist/waitlist/link-on-signup.js +18 -6
- package/dist/waitlist/options.d.ts +3 -0
- package/dist/workflow-runner/aggregate-id.d.ts +1 -1
- package/dist/workflow-runner/aggregate-id.js +1 -1
- package/dist/workflow-runner/event-subscriber.js +4 -5
- package/dist/workflow-runner/event-trigger.js +4 -17
- package/dist/workflow-runner/feature.js +2 -2
- package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
- package/dist/workflow-runner/pending-projection.js +6 -7
- package/dist/workflow-runner/runner.js +6 -6
- package/dist/workflow-runner/tables.js +6 -6
- package/dist/workflow-runner/workflow-registry.js +1 -1
- package/package.json +20 -10
- package/src/agent-tools/changes.json +6 -0
- package/src/audit/changes.json +12 -0
- package/src/auth-mfa/changes.json +6 -0
- package/src/billing-foundation/changes.json +55 -0
- package/src/cap-counter/changes.json +18 -0
- package/src/channel-email/changes.json +6 -0
- package/src/config/changes.json +12 -0
- package/src/crypto-shredding/changes.json +6 -0
- package/src/delivery/changes.json +30 -0
- package/src/form-draft/changes.json +6 -0
- package/src/host-routing/changes.json +6 -0
- package/src/inbound-mail-foundation/changes.json +18 -0
- package/src/jobs/changes.json +13 -0
- package/src/mail-foundation/changes.json +6 -0
- package/src/renderer-pdf/changes.json +6 -0
- package/src/step-dispatcher/changes.json +6 -0
- package/src/subscription-dodo/changes.json +14 -0
- package/src/subscription-stripe/changes.json +12 -0
- package/src/template-resolver/changes.json +48 -0
- package/src/tenant/changes.json +6 -0
- package/src/tenant-lifecycle/changes.json +6 -0
- package/src/tier-engine/changes.json +6 -0
- package/src/waitlist/changes.json +18 -0
- package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +0 -1
- package/dist/billing-foundation/consumer-protection/stored-user-email.js +0 -8
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
// Stripe
|
|
1
|
+
// Stripe plugin methods for the POST-tenant-resolution phase:
|
|
2
2
|
// createCheckoutSession, createPortalSession, cancelSubscription,
|
|
3
|
-
// retrieveSubscription, retrievePrices, planSwitchSession.
|
|
3
|
+
// retrieveSubscription, retrievePrices, and planSwitchSession.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
// SubscriptionProviderPlugin
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
5
|
+
// The plugin build (`feature.ts`) registers these as methods on
|
|
6
|
+
// `SubscriptionProviderPlugin`. Unlike verifyAndParseWebhook (= pre-tenant),
|
|
7
|
+
// they receive the full HandlerContext and resolve the Stripe client from
|
|
8
|
+
// the runtime at call time (using the audited api-key from system-secrets),
|
|
9
|
+
// rather than from a mount-time closure. Key rotation therefore works
|
|
10
|
+
// without a redeploy.
|
|
11
11
|
//
|
|
12
|
-
// **Type
|
|
13
|
-
//
|
|
14
|
-
// <SubscriptionProviderPlugin["...method"]>>[1]`).
|
|
15
|
-
//
|
|
16
|
-
//
|
|
12
|
+
// **Type derivation:** method option shapes are derived **directly from the
|
|
13
|
+
// plugin contract** (`Parameters<NonNullable
|
|
14
|
+
// <SubscriptionProviderPlugin["...method"]>>[1]`). If Foundation extends the
|
|
15
|
+
// contract (for example, with a new optional field), the Stripe plugin detects
|
|
16
|
+
// it at TypeScript compile time rather than at runtime.
|
|
17
17
|
import { createHash } from "node:crypto";
|
|
18
18
|
import { KNOWN_RECURRING_INTERVALS, SubscriptionCancelTimings, } from "@cosmicdrift/kumiko-bundled-features/billing-foundation";
|
|
19
19
|
import { ConflictError, UnprocessableError } from "@cosmicdrift/kumiko-framework/errors";
|
|
@@ -79,11 +79,11 @@ function isUnknownCustomerStripeError(error) {
|
|
|
79
79
|
}
|
|
80
80
|
export function createStripeCheckoutSession(runtime, { paymentInvoiceCreation = true } = {}) {
|
|
81
81
|
return async (ctx, options) => {
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
// billing-live-config-key write
|
|
82
|
+
// Invariant: without billing-live, no Stripe session may be created
|
|
83
|
+
// (sk_test_-keys in production would otherwise create a test-mode checkout).
|
|
84
|
+
// Throw before every Stripe call. The guard used to be provided by the
|
|
85
|
+
// unmounted plugin; Stripe is now always mounted, so the
|
|
86
|
+
// billing-live-config-key gates the write side.
|
|
87
87
|
await runtime.assertBillingLive(ctx);
|
|
88
88
|
const stripe = await runtime.clientForCtx(ctx);
|
|
89
89
|
const mode = options.mode ?? "subscription";
|
|
@@ -19,7 +19,7 @@ export type StripeRuntimeDeps = {
|
|
|
19
19
|
export type StripeCtxRuntime = {
|
|
20
20
|
readonly clientForCtx: (ctx: HandlerContext) => Promise<Stripe>;
|
|
21
21
|
/** Throws FeatureDisabledError unless `billing-live` config is true. The
|
|
22
|
-
*
|
|
22
|
+
* invariant: no Stripe session may be created while billing is not
|
|
23
23
|
* live (sk_test_ keys in prod must not produce a live checkout).
|
|
24
24
|
* `handlerName` names the write-handler in the thrown error — defaults to
|
|
25
25
|
* "create-checkout-session" for existing callers, but plan-switch/portal
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
import { requireSecretsContext } from "@cosmicdrift/kumiko-bundled-features/secrets";
|
|
28
28
|
import { SYSTEM_TENANT_ID, } from "@cosmicdrift/kumiko-framework/engine";
|
|
29
29
|
import { FeatureDisabledError, UnconfiguredError } from "@cosmicdrift/kumiko-framework/errors";
|
|
30
|
-
import {
|
|
30
|
+
import { parseJsonSafe } from "@cosmicdrift/kumiko-framework/utils";
|
|
31
31
|
import Stripe from "stripe";
|
|
32
32
|
import { SUBSCRIPTION_STRIPE_FEATURE } from "./constants.js";
|
|
33
33
|
const API_KEY_HINT = "Set the Stripe API key via config:write:set on `subscription-stripe:config:api-key` (or seed it from STRIPE_API_KEY during the env bridge).";
|
|
@@ -41,7 +41,7 @@ export function createStripeClientCache() {
|
|
|
41
41
|
if (cached)
|
|
42
42
|
return cached;
|
|
43
43
|
// No apiVersion pin — a string literal breaks consumers' typecheck on newer
|
|
44
|
-
// stripe SDKs
|
|
44
|
+
// stripe SDKs; the SDK's own default keeps wire-version and types aligned.
|
|
45
45
|
const client = new Stripe(apiKey);
|
|
46
46
|
cache.set(apiKey, client);
|
|
47
47
|
return client;
|
|
@@ -52,14 +52,15 @@ export function createStripeClientCache() {
|
|
|
52
52
|
// (the un-audited webhook path + the audited ctx read here) therefore returns
|
|
53
53
|
// the JSON-quoted string and must parse it back. The factory fallback is a
|
|
54
54
|
// plain env string and stays raw — so parsing is applied only to the store
|
|
55
|
-
// read, never to the fallback.
|
|
55
|
+
// read, never to the fallback. The error must not carry the input: the JSON
|
|
56
|
+
// parser's own message would repeat the credential into logs and the 401 body.
|
|
56
57
|
function parseStoredSecret(raw) {
|
|
57
58
|
if (raw === undefined || raw.length === 0)
|
|
58
59
|
return undefined;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
const parsed = parseJsonSafe(raw, undefined);
|
|
61
|
+
if (parsed === undefined) {
|
|
62
|
+
throw new Error("subscription-stripe credential (backing:secrets) is not valid JSON");
|
|
63
|
+
}
|
|
63
64
|
return typeof parsed === "string" && parsed.length > 0 ? parsed : undefined;
|
|
64
65
|
}
|
|
65
66
|
export function createStripeRuntimes(deps) {
|
|
@@ -5,17 +5,17 @@ import Stripe from "stripe";
|
|
|
5
5
|
import type { StripeWebhookRuntime } from "./runtime.ts";
|
|
6
6
|
export declare function isResourceMissingStripeError(error: unknown): error is Stripe.errors.StripeInvalidRequestError;
|
|
7
7
|
export type StripeWebhookOptions = {
|
|
8
|
-
/** Price-to-tier
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
/** Price-to-tier map. The plugin reads the price ID from the event and
|
|
9
|
+
* maps it to a tier name. Returns null when the price ID is not mapped.
|
|
10
|
+
* App-specific and remains a factory option, not a secret. */
|
|
11
11
|
readonly priceToTier: Readonly<Record<string, string>>;
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
|
-
* Stripe
|
|
15
|
-
* `verifyAndParseWebhook`. **Pre-tenant
|
|
16
|
-
* HandlerContext;
|
|
17
|
-
* Stripe
|
|
18
|
-
* system
|
|
14
|
+
* Stripe webhook handler implementing the plugin contract
|
|
15
|
+
* `verifyAndParseWebhook`. **Pre-tenant resolution** — there is no
|
|
16
|
+
* HandlerContext; instead of using a mount-time client, `runtime` resolves
|
|
17
|
+
* the Stripe client and webhook secret at call time from the optional
|
|
18
|
+
* system SecretsContext (third argument).
|
|
19
19
|
*/
|
|
20
20
|
export declare function verifyAndParseStripeWebhook(runtime: StripeWebhookRuntime, options: StripeWebhookOptions): (rawBody: string, headers: Record<string, string>, systemSecrets?: SecretsContext) => Promise<SubscriptionEvent | PaymentEvent | null>;
|
|
21
21
|
export type MappedStripeSubscriptionState = {
|
|
@@ -37,7 +37,7 @@ export declare function mapStripeSubscriptionState(sub: Pick<Stripe.Subscription
|
|
|
37
37
|
export declare function stripeCancelAtIso(sub: Pick<Stripe.Subscription, "cancel_at" | "cancel_at_period_end">, currentPeriodEndIso: string): string | null;
|
|
38
38
|
/** Stripe-event-type → normalisiert. null = ignore. */
|
|
39
39
|
export declare function mapStripeEventType(stripeType: string): SubscriptionEventType | null;
|
|
40
|
-
/** Stripe
|
|
41
|
-
* incomplete
|
|
42
|
-
*
|
|
40
|
+
/** Maps Stripe statuses to normalized statuses. Unknown statuses are
|
|
41
|
+
* mapped defensively to incomplete; the plugin should not receive them, but
|
|
42
|
+
* an invalid status string must not be stored in the database. */
|
|
43
43
|
export declare function mapStripeStatus(stripeStatus: Stripe.Subscription.Status): SubscriptionStatus;
|
|
@@ -1,35 +1,34 @@
|
|
|
1
|
-
// verifyAndParseStripeWebhook — Stripe-
|
|
2
|
-
// event
|
|
3
|
-
// `verifyAndParseWebhook
|
|
1
|
+
// verifyAndParseStripeWebhook — Stripe-specific signature verification +
|
|
2
|
+
// event mapping. Registered by the plugin build (feature.ts) as
|
|
3
|
+
// `verifyAndParseWebhook`.
|
|
4
4
|
//
|
|
5
5
|
// **Steps:**
|
|
6
|
-
// 1.
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// 1. Verify the signature via stripe.webhooks.constructEvent (HMAC-SHA-256
|
|
7
|
+
// against rawBody + Stripe-Signature header). Throws on mismatch or
|
|
8
|
+
// timestamps older than 5 minutes (replay protection).
|
|
9
9
|
// 1b. checkout.session.completed / .async_payment_succeeded branch off
|
|
10
10
|
// here into a PaymentEvent (one-off-payment, own aggregate) — see
|
|
11
|
-
// "One-off-payment" section below. Everything else falls through.
|
|
12
|
-
// 2. Event-type
|
|
13
|
-
// SubscriptionEventTypes
|
|
14
|
-
//
|
|
15
|
-
// 3. Stripe
|
|
16
|
-
// (status
|
|
11
|
+
// the "One-off-payment" section below. Everything else falls through.
|
|
12
|
+
// 2. Event-type filter: only the 5 event types mapped to
|
|
13
|
+
// SubscriptionEventTypes continue; everything else returns null
|
|
14
|
+
// (the foundation responds with 200 ignored).
|
|
15
|
+
// 3. Normalize the Stripe payload into a SubscriptionEvent
|
|
16
|
+
// (status mapping, tenant ID from metadata, price-to-tier lookup).
|
|
17
17
|
//
|
|
18
|
-
// **Runtime
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// sig-verify, kein split-brain.
|
|
18
|
+
// **Runtime keys (pre-tenant):** the API key and webhook secret no longer
|
|
19
|
+
// come from a mount-time closure; they are resolved from `StripeWebhookRuntime`
|
|
20
|
+
// at webhook time. The foundation webhook handler passes a system-scoped
|
|
21
|
+
// SecretsContext as the third argument; the runtime reads both keys from it
|
|
22
|
+
// (unaudited, system-internal), falling back to the factory options. This
|
|
23
|
+
// allows key rotation without a redeploy, and the invoice lazy-fetch below
|
|
24
|
+
// uses the same rotated client as signature verification, avoiding split-brain.
|
|
26
25
|
//
|
|
27
26
|
// **Invoice-event lazy-fetch:**
|
|
28
|
-
// Invoice payloads carry only the subscription
|
|
29
|
-
//
|
|
27
|
+
// Invoice payloads carry only the subscription ID (Stripe does not expand
|
|
28
|
+
// subscriptions in webhooks), so the plugin lazy-fetches via
|
|
30
29
|
// `stripe.subscriptions.retrieve(subId)` to get the full subscription for
|
|
31
30
|
// status/tier/period-end mapping. resource_missing (deleted between webhook
|
|
32
|
-
// and
|
|
31
|
+
// and retrieval) returns null; any other Stripe error becomes 503 so Stripe
|
|
33
32
|
// redelivers.
|
|
34
33
|
import { BillingEventKinds, parseProviderConsentId, SubscriptionEventTypes, SubscriptionStatuses, } from "@cosmicdrift/kumiko-bundled-features/billing-foundation";
|
|
35
34
|
import { ExtraRouteRejection } from "@cosmicdrift/kumiko-framework/api";
|
|
@@ -47,11 +46,11 @@ function transientProviderRejection(error) {
|
|
|
47
46
|
return new ExtraRouteRejection(503, { error: { code: "subscription_provider_transient" } }, `stripe retrieve failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
48
47
|
}
|
|
49
48
|
/**
|
|
50
|
-
* Stripe
|
|
51
|
-
* `verifyAndParseWebhook`. **Pre-tenant
|
|
52
|
-
* HandlerContext;
|
|
53
|
-
* Stripe
|
|
54
|
-
* system
|
|
49
|
+
* Stripe webhook handler implementing the plugin contract
|
|
50
|
+
* `verifyAndParseWebhook`. **Pre-tenant resolution** — there is no
|
|
51
|
+
* HandlerContext; instead of using a mount-time client, `runtime` resolves
|
|
52
|
+
* the Stripe client and webhook secret at call time from the optional
|
|
53
|
+
* system SecretsContext (third argument).
|
|
55
54
|
*/
|
|
56
55
|
export function verifyAndParseStripeWebhook(runtime, options) {
|
|
57
56
|
return async (rawBody, headers, systemSecrets) => {
|
|
@@ -59,15 +58,15 @@ export function verifyAndParseStripeWebhook(runtime, options) {
|
|
|
59
58
|
if (!sigHeader) {
|
|
60
59
|
throw new Error("subscription-stripe: stripe-signature header missing");
|
|
61
60
|
}
|
|
62
|
-
// 0.
|
|
63
|
-
// secret (
|
|
64
|
-
// options.
|
|
61
|
+
// 0. Resolve at runtime: obtain the API key (for the client and lazy fetch)
|
|
62
|
+
// and webhook secret (for signature verification) from system secrets,
|
|
63
|
+
// falling back to the factory options. Throws if neither is configured.
|
|
65
64
|
const { stripe, webhookSecret } = await runtime.resolve(systemSecrets);
|
|
66
|
-
// 1.
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
// payment
|
|
70
|
-
// path
|
|
65
|
+
// 1. Verify the signature. constructEvent throws on a mismatch (invalid
|
|
66
|
+
// signature) or timestamp-tolerance violation (default: 5 minutes).
|
|
67
|
+
// The foundation maps the thrown error to HTTP 401. This applies to
|
|
68
|
+
// BOTH branches below: the payment branch is selected only AFTER this
|
|
69
|
+
// check, so no path bypasses signature verification.
|
|
71
70
|
let event;
|
|
72
71
|
try {
|
|
73
72
|
event = await stripe.webhooks.constructEventAsync(rawBody, sigHeader, webhookSecret);
|
|
@@ -84,28 +83,27 @@ export function verifyAndParseStripeWebhook(runtime, options) {
|
|
|
84
83
|
if (isCheckoutSessionEventType(event.type)) {
|
|
85
84
|
return await parsePaymentEvent(event, stripe);
|
|
86
85
|
}
|
|
87
|
-
// 2. Event-type
|
|
86
|
+
// 2. Event-type filter — only 5 event types are supported.
|
|
88
87
|
const normalizedType = mapStripeEventType(event.type);
|
|
89
88
|
if (!normalizedType) {
|
|
90
89
|
return null; // foundation returnt 200 ignored
|
|
91
90
|
}
|
|
92
|
-
// 3.
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
// oder via lazy-fetch (invoice-events).
|
|
91
|
+
// 3. Extract the payload. Stripe uses different data.object shapes
|
|
92
|
+
// depending on event.type. Extract subscription data either directly
|
|
93
|
+
// (subscription events) or through a lazy fetch (invoice events).
|
|
96
94
|
const sub = await extractSubscriptionFromEvent(event, stripe);
|
|
97
95
|
if (!sub) {
|
|
98
|
-
// event
|
|
99
|
-
//
|
|
96
|
+
// The event type passed the 5-item filter, but its payload shape did not
|
|
97
|
+
// match — treat this as Stripe SDK schema drift and return null defensively.
|
|
100
98
|
return null;
|
|
101
99
|
}
|
|
102
|
-
// 4.
|
|
103
|
-
// `metadata.tenantId`
|
|
100
|
+
// 4. Resolve the tenant from metadata. The app builder sets
|
|
101
|
+
// `metadata.tenantId` when calling createCheckoutSession.
|
|
104
102
|
const tenantId = sub.metadata?.["tenantId"];
|
|
105
103
|
if (!tenantId || tenantId.length === 0) {
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
104
|
+
// A subscription without tenant metadata cannot be created without tenant
|
|
105
|
+
// resolution. Drop the event silently (the foundation responds with 200
|
|
106
|
+
// ignored). This is an app-owner error, not a foundation error.
|
|
109
107
|
return null;
|
|
110
108
|
}
|
|
111
109
|
// 5+6. Price-to-tier-Mapping + status/period-end/cancel_at — shared with
|
|
@@ -151,7 +149,7 @@ export function mapStripeSubscriptionState(sub, priceToTier) {
|
|
|
151
149
|
const periodEndUnixSec = sub.items.data[0]?.current_period_end ?? 0;
|
|
152
150
|
// Stripe returns Unix-seconds; Temporal.Instant.fromEpochMilliseconds
|
|
153
151
|
// expects ms. Multiply, then ISO. (No-Date-API-Guard forbids
|
|
154
|
-
// `new Date()` — static import above, not the ambient global
|
|
152
|
+
// `new Date()` — static import above, not the ambient global.)
|
|
155
153
|
const currentPeriodEnd = Temporal.Instant.fromEpochMilliseconds(periodEndUnixSec * 1000).toString();
|
|
156
154
|
const cancelAt = stripeCancelAtIso(sub, currentPeriodEnd);
|
|
157
155
|
return { status, tier, currentPeriodEnd, cancelAt };
|
|
@@ -187,9 +185,9 @@ export function mapStripeEventType(stripeType) {
|
|
|
187
185
|
return null;
|
|
188
186
|
}
|
|
189
187
|
}
|
|
190
|
-
/** Stripe
|
|
191
|
-
* incomplete
|
|
192
|
-
*
|
|
188
|
+
/** Maps Stripe statuses to normalized statuses. Unknown statuses are
|
|
189
|
+
* mapped defensively to incomplete; the plugin should not receive them, but
|
|
190
|
+
* an invalid status string must not be stored in the database. */
|
|
193
191
|
export function mapStripeStatus(stripeStatus) {
|
|
194
192
|
switch (stripeStatus) {
|
|
195
193
|
case "active":
|
|
@@ -215,9 +213,9 @@ export function mapStripeStatus(stripeStatus) {
|
|
|
215
213
|
return SubscriptionStatuses.incomplete;
|
|
216
214
|
}
|
|
217
215
|
}
|
|
218
|
-
/**
|
|
219
|
-
*
|
|
220
|
-
*
|
|
216
|
+
/** Gets the subscription from the event. Subscription events include it
|
|
217
|
+
* directly in data.object; invoice events include only the subscription ID
|
|
218
|
+
* and require a lazy fetch via stripe.subscriptions.retrieve. */
|
|
221
219
|
// @wrapper-known semantic-alias
|
|
222
220
|
async function extractSubscriptionFromEvent(event, stripe) {
|
|
223
221
|
switch (event.type) {
|
|
@@ -227,16 +225,16 @@ async function extractSubscriptionFromEvent(event, stripe) {
|
|
|
227
225
|
return event.data.object; // @cast-boundary engine-bridge
|
|
228
226
|
case StripeEventTypes.invoicePaid:
|
|
229
227
|
case StripeEventTypes.invoicePaymentFailed: {
|
|
230
|
-
// Lazy-fetch
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
//
|
|
228
|
+
// Lazy-fetch the subscription. invoice.subscription is a string ID because
|
|
229
|
+
// Stripe webhooks do not expand it automatically. Fetch the full
|
|
230
|
+
// subscription so downstream status, tier via priceId, and period-end
|
|
231
|
+
// mapping remain consistent.
|
|
234
232
|
const invoice = event.data.object; // @cast-boundary engine-bridge
|
|
235
233
|
const subRef = invoice // @cast-boundary engine-payload
|
|
236
234
|
.subscription;
|
|
237
235
|
if (!subRef) {
|
|
238
|
-
//
|
|
239
|
-
// recurring
|
|
236
|
+
// An invoice without a subscription reference is a one-shot invoice, not a
|
|
237
|
+
// recurring invoice. It is outside this domain and should be ignored.
|
|
240
238
|
return null;
|
|
241
239
|
}
|
|
242
240
|
const subId = typeof subRef === "string" ? subRef : subRef.id;
|
package/dist/tags/feature.d.ts
CHANGED
|
@@ -21,9 +21,9 @@ export type TagsFeatureOptions = {
|
|
|
21
21
|
/** Row-level ownership on the tag-assignment rows themselves — orthogonal to
|
|
22
22
|
* `access`, which only gates whether a caller may dispatch assign/remove/list
|
|
23
23
|
* at all. `ownership.read` is no longer what keeps a caller from reading
|
|
24
|
-
* assignments on host entities they can't see: that gate is default-on
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* assignments on host entities they can't see: that gate is default-on and
|
|
25
|
+
* derives from the entity's `parentRef`. Use `ownership.read` for an
|
|
26
|
+
* ADDITIONAL row rule on the assignment row itself; it is AND-ed with the
|
|
27
27
|
* host-visibility gate, never a replacement for it. Applies only to
|
|
28
28
|
* `tag-assignment`; the `tag` catalog stays tenant-wide by design.
|
|
29
29
|
*
|
package/dist/tags/screens.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i18nKey, } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import { DEFAULT_TAG_ACCESS, TAGS_EDIT_SCREEN_ID, TAGS_SCREEN_ID } from "./web/constants.js";
|
|
3
|
-
// Declarative catalog screens
|
|
3
|
+
// Declarative catalog screens. Access matches create/update/
|
|
4
4
|
// delete so createTagsFeature({ access|roles }) stays consistent. TagManager
|
|
5
5
|
// remains for TagPicker/TagSection — only the standalone admin screen moved.
|
|
6
6
|
export function createTagListScreen(access = DEFAULT_TAG_ACCESS) {
|
|
@@ -80,10 +80,11 @@ export type TemplateResolverApi = {
|
|
|
80
80
|
readonly resolveLayout: (args: ResolveLayoutRequest) => Promise<TemplateResource>;
|
|
81
81
|
};
|
|
82
82
|
export declare function createTemplateResolverApi(db: DbRunner | TenantDb, registry: Registry): TemplateResolverApi;
|
|
83
|
-
|
|
83
|
+
type DeliveredRowKey = Pick<TemplateResourceRow, "tenantId" | "kind" | "slug">;
|
|
84
|
+
export declare function isRowDelivered(db: DbRunner | TenantDb, policy: TemplateDeliveryPolicy, row: DeliveredRowKey): Promise<boolean>;
|
|
84
85
|
export declare function isRowDeliveredTo(db: DbRunner | TenantDb, policy: TemplateDeliveryPolicy, user: {
|
|
85
86
|
readonly roles: readonly string[];
|
|
86
|
-
}, row:
|
|
87
|
+
}, row: DeliveredRowKey): Promise<boolean>;
|
|
87
88
|
export declare function filterDeliveredTo(db: DbRunner | TenantDb, policy: TemplateDeliveryPolicy, user: {
|
|
88
89
|
readonly roles: readonly string[];
|
|
89
90
|
}, rows: readonly TemplateResourceRow[]): Promise<TemplateResourceRow[]>;
|
|
@@ -69,9 +69,31 @@ export async function isRowDelivered(db, policy, row) {
|
|
|
69
69
|
export async function isRowDeliveredTo(db, policy, user, row) {
|
|
70
70
|
return isSystemAdmin(user) || (await isRowDelivered(db, policy, row));
|
|
71
71
|
}
|
|
72
|
+
// One system-slug lookup per kind instead of one query per row, because by-tenant is anonymous.
|
|
72
73
|
export async function filterDeliveredTo(db, policy, user, rows) {
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
if (isSystemAdmin(user))
|
|
75
|
+
return [...rows];
|
|
76
|
+
const served = rows.filter((row) => isRowServed(policy, row));
|
|
77
|
+
const shadowable = served.filter((row) => row.tenantId !== SYSTEM_TENANT_ID && isServedByCollectionOnly(policy, row));
|
|
78
|
+
const slugsByKind = new Map();
|
|
79
|
+
for (const row of shadowable) {
|
|
80
|
+
const slugs = slugsByKind.get(row.kind) ?? new Set();
|
|
81
|
+
slugs.add(row.slug);
|
|
82
|
+
slugsByKind.set(row.kind, slugs);
|
|
83
|
+
}
|
|
84
|
+
const systemKeys = new Set();
|
|
85
|
+
for (const [kind, slugs] of slugsByKind) {
|
|
86
|
+
const systemRows = await selectMany(db, templateResourcesTable, {
|
|
87
|
+
tenantId: SYSTEM_TENANT_ID,
|
|
88
|
+
kind,
|
|
89
|
+
slug: [...slugs],
|
|
90
|
+
});
|
|
91
|
+
for (const systemRow of systemRows)
|
|
92
|
+
systemKeys.add(`${kind}|${systemRow.slug}`);
|
|
93
|
+
}
|
|
94
|
+
return served.filter((row) => row.tenantId === SYSTEM_TENANT_ID ||
|
|
95
|
+
!isServedByCollectionOnly(policy, row) ||
|
|
96
|
+
!systemKeys.has(`${row.kind}|${row.slug}`));
|
|
75
97
|
}
|
|
76
98
|
export async function systemTemplateExists(db, kind, slug) {
|
|
77
99
|
const rows = await selectMany(db, templateResourcesTable, { tenantId: SYSTEM_TENANT_ID, slug, kind }, { limit: 1 });
|
|
@@ -89,19 +111,19 @@ function pickActiveLayoutRow(rows, locale) {
|
|
|
89
111
|
async function fetchTemplate(db, tenantId, slug, kind, locale) {
|
|
90
112
|
const rows = await selectMany(db, templateResourcesTable, { tenantId, slug, kind, locale }, { limit: 1 });
|
|
91
113
|
// @cast-boundary db-row — db.select returnt unbenanntes unknown[],
|
|
92
|
-
//
|
|
114
|
+
// The row shape is guaranteed by templateResourcesTable + buildBaseColumns.
|
|
93
115
|
return rows[0] ?? null;
|
|
94
116
|
}
|
|
95
117
|
function toPublic(row) {
|
|
96
118
|
// @cast-boundary db-row — Drizzle-Schema typisiert kind/contentFormat/
|
|
97
|
-
// scope/status
|
|
98
|
-
//
|
|
119
|
+
// scope/status as generic text. Database CHECK constraints restrict
|
|
120
|
+
// them to the union types; the cast asserts that schema knowledge.
|
|
99
121
|
const kind = row.kind;
|
|
100
|
-
// @cast-boundary db-row —
|
|
122
|
+
// @cast-boundary db-row — see kind.
|
|
101
123
|
const contentFormat = row.contentFormat;
|
|
102
|
-
// @cast-boundary db-row —
|
|
124
|
+
// @cast-boundary db-row — see kind.
|
|
103
125
|
const scope = row.scope;
|
|
104
|
-
// @cast-boundary db-row —
|
|
126
|
+
// @cast-boundary db-row — see kind.
|
|
105
127
|
const status = row.status;
|
|
106
128
|
const linkedEntries = parseLinkedResourceEntries(row.linkedResources);
|
|
107
129
|
return {
|
|
@@ -143,7 +165,7 @@ function parseJson(raw) {
|
|
|
143
165
|
try {
|
|
144
166
|
const parsed = JSON.parse(raw);
|
|
145
167
|
// @cast-boundary engine-payload — JSON.parse returnt unknown, typeof-Guard
|
|
146
|
-
//
|
|
168
|
+
// narrows it to object; Record<string, unknown> is the minimal common shape.
|
|
147
169
|
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
148
170
|
}
|
|
149
171
|
catch {
|
|
@@ -158,11 +180,11 @@ export class TemplateNotFoundError extends Error {
|
|
|
158
180
|
this.name = "TemplateNotFoundError";
|
|
159
181
|
}
|
|
160
182
|
}
|
|
161
|
-
// Single
|
|
162
|
-
// Pattern
|
|
183
|
+
// Single source of truth for "this handler requires template-resolver".
|
|
184
|
+
// Pattern symmetric with requireTextContent.
|
|
163
185
|
export function requireTemplateResolver(ctx, callerName) {
|
|
164
186
|
// @cast-boundary engine-bridge — templateResolver kommt per extraContext
|
|
165
|
-
//
|
|
187
|
+
// from App-Bootstrap; the framework container does not know this field on its own.
|
|
166
188
|
const api = ctx.templateResolver;
|
|
167
189
|
if (!api) {
|
|
168
190
|
throw new InternalError({
|
|
@@ -320,6 +320,7 @@ export function compileDocumentBodyToHandlebars(html, variables, options = {}) {
|
|
|
320
320
|
for (const element of Array.from(root.querySelectorAll("div[data-images]"))) {
|
|
321
321
|
rewriteImagesBlock(element, state, options);
|
|
322
322
|
}
|
|
323
|
+
// Order matters: the conditional wraps first so the row's #each lands inside the #if (evaluated once per list).
|
|
323
324
|
for (const block of Array.from(root.querySelectorAll(`[${DOCUMENT_CONDITION_ATTRIBUTE}]`))) {
|
|
324
325
|
rewriteConditionalBlock(block, state);
|
|
325
326
|
}
|
|
@@ -29,7 +29,7 @@ import { tenantOverridesQuery } from "./handlers/tenant-overrides.query.js";
|
|
|
29
29
|
import { makeArchiveSystemWrite, makeArchiveWrite, makePublishSystemWrite, makePublishWrite, } from "./handlers/toggle-status.write.js";
|
|
30
30
|
import { upsertSystemWrite } from "./handlers/upsert-system.write.js";
|
|
31
31
|
import { makeUpsertTenantWrite } from "./handlers/upsert-tenant.write.js";
|
|
32
|
-
import {
|
|
32
|
+
import { makeUsageQuery } from "./handlers/usage.query.js";
|
|
33
33
|
import { validateQuery } from "./handlers/validate.query.js";
|
|
34
34
|
import { TEMPLATE_RESOLVER_I18N } from "./i18n.js";
|
|
35
35
|
import { templateResourceEntity } from "./table.js";
|
|
@@ -127,7 +127,7 @@ export function createTemplateResolverFeature(opts = {}) {
|
|
|
127
127
|
list: r.queryHandler(listQuery),
|
|
128
128
|
bySlug: r.queryHandler(bySlugQuery),
|
|
129
129
|
byTenant: r.queryHandler(byTenantQuery),
|
|
130
|
-
usage: r.queryHandler(
|
|
130
|
+
usage: r.queryHandler(makeUsageQuery(policy)),
|
|
131
131
|
overview: r.queryHandler(makeOverviewQuery(policy)),
|
|
132
132
|
layoutSource: r.queryHandler(layoutSourceQuery),
|
|
133
133
|
tenantOverrides: r.queryHandler(tenantOverridesQuery),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { ValidationError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
3
3
|
import { requireForTenant } from "../../shared/index.js";
|
|
4
|
-
import { attachmentLimitFailure, attachmentNeedsMailTemplate, createPreparedBundleResourceEntry, prepareTemplateAttachmentBeforeTransaction, prepareTemplateResourceBeforeTransaction, readTemplateResourceMaxBytes, releaseAll, } from "../store-template-resource.js";
|
|
4
|
+
import { attachmentLimitFailure, attachmentNeedsMailTemplate, createPreparedBundleResourceEntry, prepareTemplateAttachmentBeforeTransaction, prepareTemplateResourceBeforeTransaction, readTemplateResourceMaxBytes, releaseAfterFailure, releaseAll, } from "../store-template-resource.js";
|
|
5
5
|
import { templateResourcesTable } from "../table.js";
|
|
6
6
|
import { attachTemplateResources } from "../template-resources.js";
|
|
7
7
|
import { resolveTemplateVariables } from "../template-validation.js";
|
|
@@ -94,7 +94,7 @@ export async function prepareTemplateBundleBeforeTransaction(args) {
|
|
|
94
94
|
})
|
|
95
95
|
: await prepareTemplateResourceBeforeTransaction(common);
|
|
96
96
|
if (!result.isSuccess) {
|
|
97
|
-
await
|
|
97
|
+
await releaseAfterFailure(args.ctx, releases);
|
|
98
98
|
return result;
|
|
99
99
|
}
|
|
100
100
|
if (result.release)
|
|
@@ -103,7 +103,7 @@ export async function prepareTemplateBundleBeforeTransaction(args) {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
catch (cause) {
|
|
106
|
-
await
|
|
106
|
+
await releaseAfterFailure(args.ctx, releases);
|
|
107
107
|
throw cause;
|
|
108
108
|
}
|
|
109
109
|
return { isSuccess: true, data: prepared, release: () => releaseAll(releases) };
|
|
@@ -17,4 +17,8 @@ export declare function makeCopyLocaleWrite(policy: TemplateEditPolicy): import(
|
|
|
17
17
|
system: "system";
|
|
18
18
|
tenant: "tenant";
|
|
19
19
|
}>>;
|
|
20
|
-
}, z.core.$strip>, import("./template-write.ts").WrittenTemplateRow, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap,
|
|
20
|
+
}, z.core.$strip>, import("./template-write.ts").WrittenTemplateRow, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, {
|
|
21
|
+
sourceId: string | number;
|
|
22
|
+
sourceVersion: number;
|
|
23
|
+
copies: readonly import("../store-template-resource.ts").PreparedLinkedResourceCopy[];
|
|
24
|
+
}>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { defineWriteHandler, SYSTEM_TENANT_ID, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
-
import { AccessDeniedError, NotFoundError, ValidationError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
3
|
+
import { AccessDeniedError, NotFoundError, ValidationError, VersionConflictError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
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";
|
|
@@ -111,14 +111,19 @@ export function makeCopyLocaleWrite(policy) {
|
|
|
111
111
|
const request = await checkCopyRequest(ctx, policy, event);
|
|
112
112
|
if (!request.isSuccess)
|
|
113
113
|
return request;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
const { source, tenantId, sourceIsForeign, sourceResources } = request.data;
|
|
115
|
+
const sourceStamp = { sourceId: source.id, sourceVersion: source.version };
|
|
116
|
+
if (!sourceIsForeign)
|
|
117
|
+
return { isSuccess: true, data: { ...sourceStamp, copies: [] } };
|
|
118
|
+
const prepared = await prepareLinkedResourceCopiesBeforeTransaction({
|
|
117
119
|
ctx,
|
|
118
120
|
user: event.user,
|
|
119
|
-
tenantId
|
|
120
|
-
resources:
|
|
121
|
+
tenantId,
|
|
122
|
+
resources: sourceResources,
|
|
121
123
|
});
|
|
124
|
+
if (!prepared.isSuccess)
|
|
125
|
+
return prepared;
|
|
126
|
+
return { ...prepared, data: { ...sourceStamp, copies: prepared.data } };
|
|
122
127
|
},
|
|
123
128
|
handler: async (event, ctx) => {
|
|
124
129
|
const { slug, kind, toLocale } = event.payload;
|
|
@@ -126,6 +131,16 @@ export function makeCopyLocaleWrite(policy) {
|
|
|
126
131
|
if (!request.isSuccess)
|
|
127
132
|
return request;
|
|
128
133
|
const { scope, tenantId, source, contentFormat, sourceResources, sourceIsForeign } = request.data;
|
|
134
|
+
// The uploads were prepared for the source as it was before the transaction; a source that
|
|
135
|
+
// changed since (own row created or deleted, edited) no longer matches them.
|
|
136
|
+
if (event.prepared.sourceId !== source.id ||
|
|
137
|
+
event.prepared.sourceVersion !== source.version) {
|
|
138
|
+
return writeFailure(new VersionConflictError({
|
|
139
|
+
entityId: source.id,
|
|
140
|
+
expectedVersion: event.prepared.sourceVersion,
|
|
141
|
+
currentVersion: source.version,
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
129
144
|
const variableSchema = storedRecord(source.variableSchema);
|
|
130
145
|
const written = await writeTemplateRow({
|
|
131
146
|
ctx,
|
|
@@ -149,7 +164,7 @@ export function makeCopyLocaleWrite(policy) {
|
|
|
149
164
|
if (!written.isSuccess)
|
|
150
165
|
return written;
|
|
151
166
|
const resources = sourceIsForeign
|
|
152
|
-
? await createLinkedResourceCopies({ ctx, user: event.user, tenantId }, event.prepared)
|
|
167
|
+
? await createLinkedResourceCopies({ ctx, user: event.user, tenantId }, event.prepared.copies)
|
|
153
168
|
: { isSuccess: true, data: sourceResources };
|
|
154
169
|
if (!resources.isSuccess)
|
|
155
170
|
return resources;
|