@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,25 +1,25 @@
|
|
|
1
|
-
// Inline
|
|
2
|
-
// subscription
|
|
1
|
+
// Inline projection for `read_subscriptions`. Materializes the 5
|
|
2
|
+
// subscription events into one row per tenant.
|
|
3
3
|
//
|
|
4
|
-
// Apply
|
|
5
|
-
//
|
|
6
|
-
// aggregateId (= deterministic uuidv5
|
|
7
|
-
//
|
|
4
|
+
// Apply runs in the same transaction as ctx.unsafeAppendEvent, so the caller
|
|
5
|
+
// sees its write state immediately (no dispatcher tick required). The PK is
|
|
6
|
+
// event.aggregateId (= deterministic uuidv5 per tenant), so replays collide
|
|
7
|
+
// on the PK instead of creating duplicate rows.
|
|
8
8
|
//
|
|
9
|
-
// **Production-deployment caveat:**
|
|
10
|
-
// `samples/apps/platform/drizzle/generate.ts`
|
|
11
|
-
// `subscriptionsProjectionTable`
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
9
|
+
// **Production-deployment caveat:** the generator in
|
|
10
|
+
// `samples/apps/platform/drizzle/generate.ts` scans `feature.entities` —
|
|
11
|
+
// `subscriptionsProjectionTable` is registered in the projection as a raw
|
|
12
|
+
// drizzle-pgTable, NOT as r.entity. Apps mounting subscription-foundation in
|
|
13
|
+
// production must add the table to their own `drizzle/generate.ts` (via an
|
|
14
|
+
// import of subscriptionsProjectionTable). setupTestStack pushes it
|
|
15
|
+
// automatically via r.projection.table.
|
|
16
16
|
import { buildEntityTable, insertOnConflictDoNothing, requireEntityTableMeta, upsertOnConflict, } from "@cosmicdrift/kumiko-framework/db";
|
|
17
17
|
import { defineApply } from "@cosmicdrift/kumiko-framework/engine";
|
|
18
18
|
import { paymentRowId } from "./aggregate-id.js";
|
|
19
19
|
import { paymentEntity, subscriptionEntity } from "./entities.js";
|
|
20
|
-
// Drizzle
|
|
21
|
-
//
|
|
22
|
-
//
|
|
20
|
+
// This Drizzle table instance is derived from the entity shape and is shared
|
|
21
|
+
// by the projection apply, list query, and get helper so all three use the
|
|
22
|
+
// same column namespace.
|
|
23
23
|
export const subscriptionsProjectionTable = buildEntityTable("subscription", subscriptionEntity);
|
|
24
24
|
// Same production-deployment caveat as subscriptionsProjectionTable above:
|
|
25
25
|
// raw drizzle-pgTable, not an r.entity — apps mounting billing-foundation in
|
|
@@ -27,8 +27,8 @@ export const subscriptionsProjectionTable = buildEntityTable("subscription", sub
|
|
|
27
27
|
export const paymentsProjectionTable = buildEntityTable("payment", paymentEntity);
|
|
28
28
|
// Unbranded metas: the apply functions below ARE the executor of these
|
|
29
29
|
// projections, so they may write through the typed helpers.
|
|
30
|
-
const subscriptionsProjectionMeta = requireEntityTableMeta(subscriptionsProjectionTable, "subscription");
|
|
31
|
-
const paymentsProjectionMeta = requireEntityTableMeta(paymentsProjectionTable, "payment");
|
|
30
|
+
export const subscriptionsProjectionMeta = requireEntityTableMeta(subscriptionsProjectionTable, "subscription");
|
|
31
|
+
export const paymentsProjectionMeta = requireEntityTableMeta(paymentsProjectionTable, "payment");
|
|
32
32
|
// =============================================================================
|
|
33
33
|
// Shared helpers
|
|
34
34
|
// =============================================================================
|
|
@@ -63,10 +63,10 @@ function cancelAtSetFromPayload(p) {
|
|
|
63
63
|
* `getSubscriptionForTenant`'s `lastChangedAt` (staleness check for
|
|
64
64
|
* incomplete subscriptions) depends on that determinism. */
|
|
65
65
|
async function upsert(tx, event, set, fullPayload) {
|
|
66
|
-
// INSERT
|
|
67
|
-
//
|
|
68
|
-
// status+tier),
|
|
69
|
-
//
|
|
66
|
+
// The INSERT fallback requires ALL fields because of NOT NULL constraints.
|
|
67
|
+
// If an update changes only some fields (for example, invoice-payment-failed
|
|
68
|
+
// changes only status+tier), the full payload is still used for the INSERT
|
|
69
|
+
// path, while only the partial `set` is used for ON CONFLICT.
|
|
70
70
|
const insertCols = {
|
|
71
71
|
id: event.aggregateId,
|
|
72
72
|
tenantId: event.tenantId,
|
|
@@ -86,21 +86,21 @@ async function upsert(tx, event, set, fullPayload) {
|
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
// =============================================================================
|
|
89
|
-
// Apply
|
|
89
|
+
// Apply functions — one per event type
|
|
90
90
|
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
91
|
+
// All use UPSERT for defensive consistency: an out-of-order event (for
|
|
92
|
+
// example, during a rebuild-from-events) can arrive in any order and still
|
|
93
|
+
// materialize the row correctly.
|
|
94
94
|
// =============================================================================
|
|
95
|
-
/** subscription-created → UPSERT
|
|
96
|
-
* subscriptionAggregateId(tenantId), one row
|
|
97
|
-
* Disney+-
|
|
98
|
-
*
|
|
95
|
+
/** subscription-created → UPSERT with all fields. PK = aggregateId =
|
|
96
|
+
* subscriptionAggregateId(tenantId), with one row per tenant. UPSERT allows
|
|
97
|
+
* the Disney+-change pattern (a second provider sends create for the same
|
|
98
|
+
* tenant) to overwrite the existing row instead of causing a PK conflict. */
|
|
99
99
|
export const applySubscriptionCreated = defineApply(async (event, tx) => {
|
|
100
100
|
const full = fullSetFromPayload(event.payload);
|
|
101
101
|
await upsert(tx, event, { ...full, ...cancelAtSetFromPayload(event.payload) }, event.payload);
|
|
102
102
|
});
|
|
103
|
-
/** subscription-updated → UPSERT
|
|
103
|
+
/** subscription-updated → UPSERT with all fields. */
|
|
104
104
|
export const applySubscriptionUpdated = defineApply(async (event, tx) => {
|
|
105
105
|
const full = fullSetFromPayload(event.payload);
|
|
106
106
|
await upsert(tx, event, { ...full, ...cancelAtSetFromPayload(event.payload) }, event.payload);
|
|
@@ -115,8 +115,9 @@ export const applySubscriptionCanceled = defineApply(async (event, tx) => {
|
|
|
115
115
|
...cancelAtSetFromPayload(p),
|
|
116
116
|
}, p);
|
|
117
117
|
});
|
|
118
|
-
/** invoice-paid → state
|
|
119
|
-
*
|
|
118
|
+
/** invoice-paid → state update (status, tier, currentPeriodEnd).
|
|
119
|
+
* The invoice history itself lives in the event store, so it remains
|
|
120
|
+
* replayable. */
|
|
120
121
|
export const applyInvoicePaid = defineApply(async (event, tx) => {
|
|
121
122
|
const p = event.payload;
|
|
122
123
|
await upsert(tx, event, {
|
|
@@ -126,10 +127,10 @@ export const applyInvoicePaid = defineApply(async (event, tx) => {
|
|
|
126
127
|
...cancelAtSetFromPayload(p),
|
|
127
128
|
}, p);
|
|
128
129
|
});
|
|
129
|
-
/** invoice-payment-failed → status (
|
|
130
|
-
* engine
|
|
131
|
-
*
|
|
132
|
-
*
|
|
130
|
+
/** invoice-payment-failed → status (typically past_due) + tier. The tier
|
|
131
|
+
* engine reads the row and decides whether to downgrade. currentPeriodEnd is
|
|
132
|
+
* intentionally unchanged: the period has not "ended"; payment simply
|
|
133
|
+
* failed. */
|
|
133
134
|
export const applyInvoicePaymentFailed = defineApply(async (event, tx) => {
|
|
134
135
|
const p = event.payload;
|
|
135
136
|
await upsert(tx, event, { status: p.status, tier: p.tier, ...cancelAtSetFromPayload(p) }, p);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Generic Stripe/PayPal-webhook → tier-engine sync route. Extracted from the
|
|
2
|
-
// near-identical webhook-route.ts app copies in show-pony and publicstatus
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// near-identical webhook-route.ts app copies in show-pony and publicstatus — the
|
|
3
|
+
// only per-app variables were the TierName union/default, so it is now a factory
|
|
4
|
+
// parameter.
|
|
5
5
|
import { isTierAssignmentSource, TierAssignmentSources, TierEngineHandlers, TierEngineQueries, tierAssignmentAggregateId, } from "@cosmicdrift/kumiko-bundled-features/tier-engine";
|
|
6
6
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
7
7
|
import { subscriptionAggregateId } from "./aggregate-id.js";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { type TenantDataHookCtx } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
export declare const SUBSCRIPTION_TENANT_DESTROY_ARCHIVE_REASON = "tenant-destroy looks up the compliance profile and archives the subscription event-stream before the projection row is redacted/deleted";
|
|
3
3
|
export declare const PAYMENT_TENANT_DESTROY_ARCHIVE_REASON = "tenant-destroy looks up the compliance profile and archives the payment event-stream before the projection rows are redacted/deleted";
|
|
4
|
-
/** Tenant-destroy hook for billing PII
|
|
4
|
+
/** Tenant-destroy hook for billing PII. HGB retains the accounting
|
|
5
5
|
* row but redacts the two provider-subject PII fields; other profiles
|
|
6
6
|
* hard-delete the row. Either way the subscription stream is archived so a
|
|
7
7
|
* future projection rebuild can't resurrect what was erased. */
|
|
8
8
|
export declare function subscriptionTenantDestroyHook(ctx: TenantDataHookCtx): Promise<void>;
|
|
9
|
-
/** Tenant-destroy hook for payment PII
|
|
9
|
+
/** Tenant-destroy hook for payment PII. Unlike subscriptionTenantDestroyHook
|
|
10
10
|
* (one row per tenant, targeted by `id`), a tenant can have many payment
|
|
11
11
|
* rows — the predicate here is `tenantId`, not `id`. The payment-stream
|
|
12
12
|
* itself is still one stream per tenant (paymentAggregateId), so
|
|
@@ -3,7 +3,7 @@ import { archiveStream } from "@cosmicdrift/kumiko-framework/event-store";
|
|
|
3
3
|
import { resolveProfileForTenant } from "../compliance-profiles/index.js";
|
|
4
4
|
import { paymentAggregateId, subscriptionAggregateId } from "./aggregate-id.js";
|
|
5
5
|
import { PAYMENT_AGGREGATE_TYPE, SUBSCRIPTION_AGGREGATE_TYPE } from "./events.js";
|
|
6
|
-
import {
|
|
6
|
+
import { paymentsProjectionMeta, subscriptionsProjectionMeta } from "./projection.js";
|
|
7
7
|
// providerCustomerId/providerSubscriptionId are `personal: "tenant"` on the
|
|
8
8
|
// entity (envelope-encrypted with the tenant subject key, see entities.ts) —
|
|
9
9
|
// eraseSubjectKeys crypto-shreds them for tenants that hard-delete. HGB
|
|
@@ -13,7 +13,7 @@ const REDACTED_PII_VALUE = "[erased]";
|
|
|
13
13
|
// Compliance-profile lookup and event-stream archive both sit outside TenantDb's own methods — need the escape hatch.
|
|
14
14
|
export const SUBSCRIPTION_TENANT_DESTROY_ARCHIVE_REASON = "tenant-destroy looks up the compliance profile and archives the subscription event-stream before the projection row is redacted/deleted";
|
|
15
15
|
export const PAYMENT_TENANT_DESTROY_ARCHIVE_REASON = "tenant-destroy looks up the compliance profile and archives the payment event-stream before the projection rows are redacted/deleted";
|
|
16
|
-
/** Tenant-destroy hook for billing PII
|
|
16
|
+
/** Tenant-destroy hook for billing PII. HGB retains the accounting
|
|
17
17
|
* row but redacts the two provider-subject PII fields; other profiles
|
|
18
18
|
* hard-delete the row. Either way the subscription stream is archived so a
|
|
19
19
|
* future projection rebuild can't resurrect what was erased. */
|
|
@@ -25,10 +25,10 @@ export async function subscriptionTenantDestroyHook(ctx) {
|
|
|
25
25
|
});
|
|
26
26
|
const aggregateId = subscriptionAggregateId(ctx.tenantId);
|
|
27
27
|
if (profile.key === "de-hr-dsgvo-hgb") {
|
|
28
|
-
await ctx.db.updateMany(
|
|
28
|
+
await ctx.db.updateMany(subscriptionsProjectionMeta, { providerCustomerId: REDACTED_PII_VALUE, providerSubscriptionId: REDACTED_PII_VALUE }, { id: aggregateId });
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
|
-
await ctx.db.deleteMany(
|
|
31
|
+
await ctx.db.deleteMany(subscriptionsProjectionMeta, { id: aggregateId });
|
|
32
32
|
}
|
|
33
33
|
await archiveStream(ctx.db.unsafeRaw(), {
|
|
34
34
|
tenantId: ctx.tenantId,
|
|
@@ -38,7 +38,7 @@ export async function subscriptionTenantDestroyHook(ctx) {
|
|
|
38
38
|
reason: "tenant_destroy",
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
/** Tenant-destroy hook for payment PII
|
|
41
|
+
/** Tenant-destroy hook for payment PII. Unlike subscriptionTenantDestroyHook
|
|
42
42
|
* (one row per tenant, targeted by `id`), a tenant can have many payment
|
|
43
43
|
* rows — the predicate here is `tenantId`, not `id`. The payment-stream
|
|
44
44
|
* itself is still one stream per tenant (paymentAggregateId), so
|
|
@@ -51,10 +51,10 @@ export async function paymentTenantDestroyHook(ctx) {
|
|
|
51
51
|
});
|
|
52
52
|
const aggregateId = paymentAggregateId(ctx.tenantId);
|
|
53
53
|
if (profile.key === "de-hr-dsgvo-hgb") {
|
|
54
|
-
await ctx.db.updateMany(
|
|
54
|
+
await ctx.db.updateMany(paymentsProjectionMeta, { providerCustomerId: REDACTED_PII_VALUE }, { tenantId: ctx.tenantId });
|
|
55
55
|
}
|
|
56
56
|
else {
|
|
57
|
-
await ctx.db.deleteMany(
|
|
57
|
+
await ctx.db.deleteMany(paymentsProjectionMeta, {
|
|
58
58
|
tenantId: ctx.tenantId,
|
|
59
59
|
});
|
|
60
60
|
}
|
|
@@ -12,32 +12,31 @@ export type SubscriptionEvent = {
|
|
|
12
12
|
* `parsed.kind === BillingEventKinds.payment` correctly, because only
|
|
13
13
|
* PaymentEvent["kind"] can take that value. */
|
|
14
14
|
readonly kind?: typeof BillingEventKinds.subscription;
|
|
15
|
-
/** Provider-
|
|
16
|
-
* Stripe: "evt_..."; Mollie: payment-id
|
|
15
|
+
/** Provider-owned event ID — UNIQUE key for idempotency.
|
|
16
|
+
* Stripe: "evt_..."; Mollie: payment-id or subscription-id. */
|
|
17
17
|
readonly providerEventId: string;
|
|
18
18
|
/** Discriminator — welcher Plugin diesen Event geliefert hat. */
|
|
19
19
|
readonly providerName: string;
|
|
20
20
|
/** Normalisierter Event-Type. Plugin filtert provider-spezifische
|
|
21
21
|
* Sub-Types raus (Stripe hat ~80 Event-types, wir kennen 5). */
|
|
22
22
|
readonly type: SubscriptionEventType;
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
23
|
+
/** Platform tenant ID (provider-customer metadata or lookup via
|
|
24
|
+
* providerCustomerId). The plugin performs the resolution. */
|
|
25
25
|
readonly tenantId: string;
|
|
26
26
|
/** Consent id echoed back from checkout metadata; omitted when absent or
|
|
27
27
|
* malformed. */
|
|
28
28
|
readonly consentId?: string;
|
|
29
|
-
/** Provider-
|
|
30
|
-
*
|
|
29
|
+
/** Provider-owned customer ID for later lookup when events lack
|
|
30
|
+
* metadata. */
|
|
31
31
|
readonly providerCustomerId: string;
|
|
32
32
|
/** Provider-eigene subscription-id. */
|
|
33
33
|
readonly providerSubscriptionId: string;
|
|
34
34
|
/** Normalisierter status. */
|
|
35
35
|
readonly status: SubscriptionStatus;
|
|
36
|
-
/** Resolved tier —
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* ignore"). */
|
|
36
|
+
/** Resolved tier — the plugin reads the price ID from the event and
|
|
37
|
+
* maps it through the plugin's `<plugin>:config:price-to-tier` to a
|
|
38
|
+
* tier name. If the price ID is absent from the mapping, the plugin
|
|
39
|
+
* returns null from verifyAndParseWebhook (= "unknown event, ignore"). */
|
|
41
40
|
readonly tier: string;
|
|
42
41
|
/** ISO-timestamp wann die aktuelle Billing-Period endet. */
|
|
43
42
|
readonly currentPeriodEnd: string;
|
|
@@ -76,6 +75,8 @@ export type PaymentEvent = {
|
|
|
76
75
|
readonly priceId: string;
|
|
77
76
|
};
|
|
78
77
|
export type SubscriptionProviderPlugin = {
|
|
78
|
+
/** Human-readable provider name for the plan panel's provider switch. */
|
|
79
|
+
readonly displayName?: string;
|
|
79
80
|
/**
|
|
80
81
|
* Verify webhook signature + parse provider-event into normalized
|
|
81
82
|
* form. **Pre-tenant-resolution** — no HandlerContext, because at
|
|
@@ -106,30 +107,30 @@ export type SubscriptionProviderPlugin = {
|
|
|
106
107
|
*/
|
|
107
108
|
readonly verifyAndParseWebhook: (rawBody: string, headers: Record<string, string>, systemSecrets?: SecretsContext) => Promise<SubscriptionEvent | PaymentEvent | null>;
|
|
108
109
|
/**
|
|
109
|
-
* **Post-tenant-resolution** —
|
|
110
|
-
* `create-checkout-session
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
110
|
+
* **Post-tenant-resolution** — called from the
|
|
111
|
+
* `create-checkout-session` write handler. The plugin builds a
|
|
112
|
+
* provider-specific checkout session and returns its hosted-page URL;
|
|
113
|
+
* the tenant admin is redirected there to complete payment, and the
|
|
114
|
+
* provider sends a `subscription.created` webhook with
|
|
115
|
+
* `metadata.tenantId`.
|
|
115
116
|
*
|
|
116
|
-
* Optional: Apple-IAP
|
|
117
|
-
* Apps
|
|
117
|
+
* Optional: Apple-IAP has no web checkout (everything happens in the app).
|
|
118
|
+
* Apps that use only Apple-IAP omit this field.
|
|
118
119
|
*/
|
|
119
120
|
readonly createCheckoutSession?: (ctx: HandlerContext, options: {
|
|
120
|
-
/** Provider-
|
|
121
|
+
/** Provider-owned price/plan ID that the customer subscribes to. */
|
|
121
122
|
readonly priceId: string;
|
|
122
|
-
/**
|
|
123
|
-
*
|
|
124
|
-
* `verifyAndParseWebhook`
|
|
123
|
+
/** Platform tenant ID — stored as metadata in the checkout session
|
|
124
|
+
* so the subsequent webhook can resolve the tenant (see the
|
|
125
|
+
* `verifyAndParseWebhook` metadata.tenantId lookup). */
|
|
125
126
|
readonly tenantId: string;
|
|
126
|
-
/**
|
|
127
|
+
/** Where the customer lands after a successful checkout. */
|
|
127
128
|
readonly successUrl: string;
|
|
128
|
-
/**
|
|
129
|
+
/** Where the customer lands if they cancel. */
|
|
129
130
|
readonly cancelUrl: string;
|
|
130
|
-
/** Optional:
|
|
131
|
-
*
|
|
132
|
-
*
|
|
131
|
+
/** Optional: existing provider customer ID when the tenant already
|
|
132
|
+
* has an account with the provider. Otherwise, the provider
|
|
133
|
+
* creates a new customer during checkout. */
|
|
133
134
|
readonly providerCustomerId?: string;
|
|
134
135
|
/** Checkout mode. `"subscription"` (default) starts a recurring
|
|
135
136
|
* billing flow; `"payment"` a one-off checkout (e.g. pay-per-use
|
|
@@ -147,17 +148,17 @@ export type SubscriptionProviderPlugin = {
|
|
|
147
148
|
readonly url: string;
|
|
148
149
|
}>;
|
|
149
150
|
/**
|
|
150
|
-
* **Post-tenant-resolution** —
|
|
151
|
-
*
|
|
151
|
+
* **Post-tenant-resolution** — called from a write handler with a
|
|
152
|
+
* fully resolved ctx. Creates a self-service Portal link.
|
|
152
153
|
* Stripe: customer-portal-session, Mollie: hosted-management-page.
|
|
153
|
-
*
|
|
154
|
-
* (cancel, payment
|
|
154
|
+
* The tenant admin uses it to manage the subscription themselves
|
|
155
|
+
* (cancel, payment method, ...).
|
|
155
156
|
*
|
|
156
|
-
* Optional
|
|
157
|
-
* (Apple-IAP managed
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
157
|
+
* Optional because not every provider has a Portal pattern
|
|
158
|
+
* (Apple-IAP subscriptions are managed in the Apple app, with no web
|
|
159
|
+
* Portal). A plugin that does not support this can omit the field;
|
|
160
|
+
* the foundation then returns a "portal_not_supported" error when a
|
|
161
|
+
* tenant admin requests the Portal link.
|
|
161
162
|
*/
|
|
162
163
|
readonly createPortalSession?: (ctx: HandlerContext, options: {
|
|
163
164
|
readonly providerCustomerId: string;
|
|
@@ -166,10 +167,10 @@ export type SubscriptionProviderPlugin = {
|
|
|
166
167
|
readonly url: string;
|
|
167
168
|
}>;
|
|
168
169
|
/**
|
|
169
|
-
* Optional:
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
170
|
+
* Optional: in-app cancellation API. If not implemented, the tenant
|
|
171
|
+
* can cancel only through the Customer Portal link (or not at all if
|
|
172
|
+
* createPortalSession is also missing — the cancellation flow is then
|
|
173
|
+
* provider-dashboard-only).
|
|
173
174
|
*/
|
|
174
175
|
readonly cancelSubscription?: (ctx: HandlerContext, options: {
|
|
175
176
|
readonly providerSubscriptionId: string;
|
|
@@ -229,6 +230,24 @@ export type SubscriptionProviderPlugin = {
|
|
|
229
230
|
}) => Promise<{
|
|
230
231
|
readonly url: string;
|
|
231
232
|
}>;
|
|
233
|
+
/**
|
|
234
|
+
* In-app plan switch, step 1: what the switch would cost right now. Together
|
|
235
|
+
* with `applyPlanSwitch` an alternative to the hosted `createPlanSwitchSession`.
|
|
236
|
+
*/
|
|
237
|
+
readonly previewPlanSwitch?: (ctx: HandlerContext, options: {
|
|
238
|
+
readonly providerSubscriptionId: string;
|
|
239
|
+
readonly targetPriceId: string;
|
|
240
|
+
}) => Promise<PlanSwitchPreview>;
|
|
241
|
+
/**
|
|
242
|
+
* In-app plan switch, step 2: performs the switch at the provider. The
|
|
243
|
+
* state change itself arrives later through the webhook.
|
|
244
|
+
*/
|
|
245
|
+
readonly applyPlanSwitch?: (ctx: HandlerContext, options: {
|
|
246
|
+
readonly providerSubscriptionId: string;
|
|
247
|
+
readonly targetPriceId: string;
|
|
248
|
+
readonly tenantId: string;
|
|
249
|
+
readonly consentId?: string;
|
|
250
|
+
}) => Promise<void>;
|
|
232
251
|
/**
|
|
233
252
|
* Fetches the live provider-side state of one subscription, for the
|
|
234
253
|
* `sync-subscriptions` backfill job — catches drift (e.g. a `cancel_at`
|
|
@@ -242,6 +261,17 @@ export type SubscriptionProviderPlugin = {
|
|
|
242
261
|
*/
|
|
243
262
|
readonly retrieveSubscription?: (ctx: HandlerContext, providerSubscriptionId: string) => Promise<ProviderSubscriptionSnapshot | null>;
|
|
244
263
|
};
|
|
264
|
+
export type PlanSwitchPreview = {
|
|
265
|
+
/** Charged immediately, smallest currency unit, tax included. */
|
|
266
|
+
readonly amountDueNow: number;
|
|
267
|
+
/** Tax part of `amountDueNow`; null when the provider reports none. */
|
|
268
|
+
readonly tax: number | null;
|
|
269
|
+
/** Lower-case ISO currency code. */
|
|
270
|
+
readonly currency: string;
|
|
271
|
+
/** Credit for the unused time on the old plan, smallest currency unit. */
|
|
272
|
+
readonly credit: number;
|
|
273
|
+
readonly effectiveAt: string;
|
|
274
|
+
};
|
|
245
275
|
export type ProviderSubscriptionSnapshot = {
|
|
246
276
|
readonly providerCustomerId: string;
|
|
247
277
|
readonly providerSubscriptionId: string;
|
|
@@ -297,7 +327,8 @@ export type BillingPlanCatalog<TTier extends string = string> = {
|
|
|
297
327
|
* `baseUrl` itself when unset) and by `switch-plan` after a plan switch
|
|
298
328
|
* (defaults to `successPath` there instead). */
|
|
299
329
|
readonly returnPath?: string;
|
|
300
|
-
/**
|
|
330
|
+
/** Restricts the catalog to one provider; defaults to every registered
|
|
331
|
+
* provider exposing `priceToTier`. */
|
|
301
332
|
readonly providerName?: string;
|
|
302
333
|
/** Rendered as the last card, no price, visible to `viewRoles` regardless of `purchaseRoles`. */
|
|
303
334
|
readonly contact?: BillingPlanContactCard;
|
|
@@ -320,6 +351,14 @@ export type ConsumerProtectionOptions = {
|
|
|
320
351
|
readonly termsTextBlock: string;
|
|
321
352
|
/** Per-locale VAT note; must carry at least `de` and `en`. */
|
|
322
353
|
readonly vatNote: Readonly<Record<string, string>>;
|
|
354
|
+
/** Per-provider texts keyed by provider name, e.g. for a merchant-of-record
|
|
355
|
+
* provider that issues the invoice and VAT itself. `vatNote` here replaces
|
|
356
|
+
* the global one in that provider's confirmation mail; `checkoutNote` is
|
|
357
|
+
* shown under the provider choice. de and en are required for each text. */
|
|
358
|
+
readonly providerTexts?: Readonly<Record<string, {
|
|
359
|
+
readonly vatNote?: Readonly<Record<string, string>>;
|
|
360
|
+
readonly checkoutNote?: Readonly<Record<string, string>>;
|
|
361
|
+
}>>;
|
|
323
362
|
readonly operatorEmail: string;
|
|
324
363
|
/** Where the public § 312k declaration is reachable. `"tenant-host"`
|
|
325
364
|
* (default): on a host that resolves a tenant. `"platform"`: also on a
|
|
@@ -373,6 +412,15 @@ export type BillingPlanView = {
|
|
|
373
412
|
readonly isCurrent: boolean;
|
|
374
413
|
readonly action: BillingPlanAction;
|
|
375
414
|
};
|
|
415
|
+
export type BillingProviderView = {
|
|
416
|
+
readonly name: string;
|
|
417
|
+
readonly displayName: string;
|
|
418
|
+
readonly note?: Readonly<Record<string, string>>;
|
|
419
|
+
readonly plans: readonly BillingPlanView[];
|
|
420
|
+
};
|
|
421
|
+
export declare function canSwitchPlansInApp(plugin: SubscriptionProviderPlugin): boolean;
|
|
422
|
+
/** A provider switches plans via a hosted session or via in-app preview + apply. */
|
|
423
|
+
export declare function canSwitchPlans(plugin: SubscriptionProviderPlugin | null): boolean;
|
|
376
424
|
export type BillingPlansResult = {
|
|
377
425
|
readonly enabled: boolean;
|
|
378
426
|
readonly currentTier: {
|
|
@@ -389,6 +437,13 @@ export type BillingPlansResult = {
|
|
|
389
437
|
} | null;
|
|
390
438
|
readonly canPurchase: boolean;
|
|
391
439
|
readonly plans: readonly BillingPlanView[];
|
|
440
|
+
/** Present when more than one provider is offered, or the single offered
|
|
441
|
+
* provider has a `providerTexts` checkout note. `plans` above are the first
|
|
442
|
+
* entry's plans. */
|
|
443
|
+
readonly providers?: readonly BillingProviderView[];
|
|
444
|
+
/** True when the subscription's provider switches plans in-app (preview +
|
|
445
|
+
* confirm) instead of on a hosted page. */
|
|
446
|
+
readonly inAppPlanSwitch?: true;
|
|
392
447
|
/** Present only when `catalog.contact` is configured. */
|
|
393
448
|
readonly contact?: BillingPlanContactCard;
|
|
394
449
|
/** Present only when `consumerProtection` is configured. */
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
/// <reference types="temporal-polyfill/global" preserve="true" />
|
|
2
|
-
// Plugin
|
|
3
|
-
//
|
|
4
|
-
// `SubscriptionProviderPlugin`
|
|
2
|
+
// Plugin contract and domain types for subscription-foundation. Provider
|
|
3
|
+
// plugins (subscription-stripe, subscription-mollie, ...) implement
|
|
4
|
+
// `SubscriptionProviderPlugin` and register via
|
|
5
5
|
// `r.useExtension("subscriptionProvider", "<name>", { build })`.
|
|
6
6
|
//
|
|
7
7
|
// **Two-phase plugin contract:**
|
|
8
|
-
// 1. **Pre-tenant-resolution:** `verifyAndParseWebhook`
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// Stripe-/PayPal-
|
|
12
|
-
// secret
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// SYSTEM_TENANT_ID. Plugins
|
|
17
|
-
//
|
|
8
|
+
// 1. **Pre-tenant-resolution:** `verifyAndParseWebhook` runs BEFORE
|
|
9
|
+
// a tenant is resolved from the event, so no HandlerContext is
|
|
10
|
+
// available. The **webhook secret is app-wide** (the App Owner's
|
|
11
|
+
// Stripe-/PayPal-account, not tenant-specific). To let a plugin read
|
|
12
|
+
// the secret from the secrets feature AT RUNTIME (instead of a
|
|
13
|
+
// mount-time closure), the webhook handler passes an optional
|
|
14
|
+
// system-scoped `SecretsContext` as the third argument. The plugin
|
|
15
|
+
// reads its app-wide secrets from it without auditing under
|
|
16
|
+
// SYSTEM_TENANT_ID. Plugins that keep their keys in a closure
|
|
17
|
+
// (e.g. mollie) ignore the parameter → backward-compatible.
|
|
18
18
|
// 2. **Post-tenant-resolution:** `createPortalSession` +
|
|
19
|
-
// `cancelSubscription`
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
19
|
+
// `cancelSubscription` are called from regular write handlers with
|
|
20
|
+
// a fully resolved HandlerContext. The plugin can use ctx.config +
|
|
21
|
+
// ctx.secrets for tenant-specific configuration (e.g. tenant-owned
|
|
22
|
+
// customer-id mappings).
|
|
23
23
|
//
|
|
24
|
-
// Foundation
|
|
25
|
-
// proration, multi-currency, coupons etc.
|
|
26
|
-
//
|
|
24
|
+
// Foundation uses only the common subset of provider functionality;
|
|
25
|
+
// proration, multi-currency, coupons, etc. remain provider-specific and
|
|
26
|
+
// are available through the Customer Portal link.
|
|
27
27
|
import { SUBSCRIPTION_PROVIDER_EXTENSION, } from "./web/constants.js";
|
|
28
28
|
// =============================================================================
|
|
29
29
|
// Provider price + billing-plans catalog
|
|
@@ -33,3 +33,12 @@ export const KNOWN_RECURRING_INTERVALS = ["day", "week", "month", "year"];
|
|
|
33
33
|
export function isLegalLinkSet(links) {
|
|
34
34
|
return "terms" in links;
|
|
35
35
|
}
|
|
36
|
+
export function canSwitchPlansInApp(plugin) {
|
|
37
|
+
return plugin.previewPlanSwitch !== undefined && plugin.applyPlanSwitch !== undefined;
|
|
38
|
+
}
|
|
39
|
+
/** A provider switches plans via a hosted session or via in-app preview + apply. */
|
|
40
|
+
export function canSwitchPlans(plugin) {
|
|
41
|
+
if (plugin === null)
|
|
42
|
+
return false;
|
|
43
|
+
return plugin.createPlanSwitchSession !== undefined || canSwitchPlansInApp(plugin);
|
|
44
|
+
}
|
|
@@ -20,6 +20,22 @@ function isRootRelativeOrHttpsUrl(link) {
|
|
|
20
20
|
return false;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
function validateProviderTexts(cp) {
|
|
24
|
+
for (const [providerName, texts] of Object.entries(cp.providerTexts ?? {})) {
|
|
25
|
+
for (const [textName, text] of [
|
|
26
|
+
["vatNote", texts.vatNote],
|
|
27
|
+
["checkoutNote", texts.checkoutNote],
|
|
28
|
+
]) {
|
|
29
|
+
if (text === undefined)
|
|
30
|
+
continue;
|
|
31
|
+
for (const locale of ["de", "en"]) {
|
|
32
|
+
if (!text[locale]?.trim()) {
|
|
33
|
+
throw new Error(`createBillingFoundationFeature: consumerProtection.providerTexts.${providerName}.${textName} needs a non-empty "${locale}" entry.`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
23
39
|
function validateConsumerProtection(cp) {
|
|
24
40
|
if (cp.termsTextBlock.trim() === "") {
|
|
25
41
|
throw new Error("createBillingFoundationFeature: consumerProtection.termsTextBlock is empty.");
|
|
@@ -29,6 +45,7 @@ function validateConsumerProtection(cp) {
|
|
|
29
45
|
throw new Error(`createBillingFoundationFeature: consumerProtection.vatNote needs a non-empty "${locale}" entry.`);
|
|
30
46
|
}
|
|
31
47
|
}
|
|
48
|
+
validateProviderTexts(cp);
|
|
32
49
|
if (!z.email().safeParse(cp.operatorEmail).success) {
|
|
33
50
|
throw new Error(`createBillingFoundationFeature: consumerProtection.operatorEmail "${cp.operatorEmail}" is not a valid email address.`);
|
|
34
51
|
}
|