@cosmicdrift/kumiko-bundled-features 0.385.0 → 0.387.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.js +0 -2
- 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/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 +3 -3
- 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-verify-screen.js +6 -6
- package/dist/billing-foundation/aggregate-id.d.ts +5 -5
- package/dist/billing-foundation/aggregate-id.js +10 -11
- package/dist/billing-foundation/entities.js +27 -27
- package/dist/billing-foundation/events.js +18 -17
- package/dist/billing-foundation/feature.js +42 -43
- 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/create-checkout-session.write.js +18 -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/process-event.write.js +20 -20
- 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 +40 -41
- package/dist/billing-foundation/types.js +20 -20
- package/dist/billing-foundation/web/billing-plans-panel.js +4 -4
- package/dist/cap-counter/aggregate-id.js +8 -9
- 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 +47 -48
- 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 +1 -1
- package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
- 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/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/resolver.js +4 -4
- package/dist/config/table.js +10 -10
- package/dist/config/write-helpers.js +1 -1
- package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
- package/dist/crypto-shredding/handlers/forget-subject.write.js +12 -11
- 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/feature.js +2 -2
- package/dist/delivery/handlers/log.query.js +1 -1
- package/dist/delivery/tables.js +9 -8
- package/dist/delivery/unsubscribe.js +4 -4
- 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-provider-inmemory/feature.d.ts +1 -1
- package/dist/file-provider-inmemory/feature.js +16 -16
- 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 +1 -1
- package/dist/form-draft/db/queries/owned-file-refs.js +1 -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/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.js +11 -11
- 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/tenant-destroy-hook.js +14 -16
- package/dist/inbound-mail-foundation/types.d.ts +45 -46
- 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 +57 -56
- 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.js +5 -6
- 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/job-instant.js +1 -1
- package/dist/jobs/job-run-logger.js +10 -11
- 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 +2 -2
- package/dist/mail-foundation/feature.js +24 -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.js +5 -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/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.js +8 -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.js +1 -1
- package/dist/shared/encrypt-for-direct-write.js +1 -1
- 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/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 +35 -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 +1 -1
- 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.js +10 -10
- package/dist/template-resolver/handlers/find-by-id.query.js +5 -5
- package/dist/template-resolver/handlers/list.query.js +1 -1
- package/dist/template-resolver/handlers/shared.js +2 -2
- package/dist/template-resolver/handlers/template-write.js +3 -3
- 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/seeding.js +4 -4
- package/dist/template-resolver/table.js +10 -11
- package/dist/template-resolver/web/client-plugin.js +2 -2
- package/dist/tenant/feature.js +7 -7
- package/dist/tenant/handlers/member-directory.query.js +1 -1
- 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.js +1 -1
- 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/feature.js +1 -1
- 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 +5 -5
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +3 -3
- package/dist/tier-engine/tier-resolver.js +2 -2
- package/dist/tier-engine/trial.js +8 -8
- 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 +127 -233
- package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
- package/dist/user-data-rights/run-forget-cleanup.js +63 -82
- 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/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 +10 -10
|
@@ -2,7 +2,7 @@ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
|
|
|
2
2
|
import { createEntity, createJsonbField, createLongTextField, createTextField, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
// documentExtract — implicit entity-projection (r.entity, NOT r.projection):
|
|
4
4
|
// an explicit r.projection would make `forget` non-rebuild-safe and require
|
|
5
|
-
// archiveStream instead of the regular forget path
|
|
5
|
+
// archiveStream instead of the regular forget path.
|
|
6
6
|
// fileRefId points at the source file_refs row; storageKey duplicates it for
|
|
7
7
|
// direct provider access without a join.
|
|
8
8
|
export const documentExtractEntity = createEntity({
|
|
@@ -15,11 +15,11 @@ export const documentExtractEntity = createEntity({
|
|
|
15
15
|
reason: "technical_reference",
|
|
16
16
|
}),
|
|
17
17
|
// Holds the full extracted document text (PII). `personal: "tenant"`,
|
|
18
|
-
// NOT `encrypted: true
|
|
18
|
+
// NOT `encrypted: true`: the master-key path has no erasure subject,
|
|
19
19
|
// so nothing here would ever be shreddable. Tenant-subject ciphertext
|
|
20
|
-
// dies with eraseSubjectKeys on tenant-destroy
|
|
20
|
+
// dies with eraseSubjectKeys on tenant-destroy. Whose
|
|
21
21
|
// subject a third party named inside a document is stays open, same as
|
|
22
|
-
// inbound-mail-foundation
|
|
22
|
+
// inbound-mail-foundation. meta is provider telemetry only and
|
|
23
23
|
// stays plaintext jsonb.
|
|
24
24
|
pages: createLongTextField({
|
|
25
25
|
personal: "tenant",
|
|
@@ -3,8 +3,8 @@ import * as z from "zod";
|
|
|
3
3
|
// stream per fileRef with aggregateId derived from the fileRefId
|
|
4
4
|
// (documentIngestAggregateId), never the fileRefId itself: foreign events on
|
|
5
5
|
// the fileRef stream would break the fileRef's optimistic lock. Not backed by an r.entity;
|
|
6
|
-
// this is a pure saga-anchor event (kumiko-
|
|
7
|
-
//
|
|
6
|
+
// this is a pure saga-anchor event that the worker job (kumiko-enterprise LiteParse provider)
|
|
7
|
+
// subscribes to.
|
|
8
8
|
export const DOCUMENT_INGEST_AGGREGATE_TYPE = "document-ingest";
|
|
9
9
|
// Stream name of stored extract events; differs from the camelCase r.entity name
|
|
10
10
|
// "documentExtract", so the projection replays this stream through an extension.
|
|
@@ -114,7 +114,7 @@ export function createDocumentIngestFoundationFeature() {
|
|
|
114
114
|
default: "deu+eng",
|
|
115
115
|
// Tesseract -l argument syntax: one or more 3-letter language codes
|
|
116
116
|
// joined by "+" (e.g. "deu+eng"). Unconstrained free text here would
|
|
117
|
-
// reach the OCR provider call unvalidated
|
|
117
|
+
// reach the OCR provider call unvalidated.
|
|
118
118
|
pattern: { regex: "^[a-z]{3}(\\+[a-z]{3})*$" },
|
|
119
119
|
write: access.roles("TenantAdmin", "SystemAdmin"),
|
|
120
120
|
read: access.roles("TenantAdmin", "SystemAdmin", "User"),
|
|
@@ -123,7 +123,7 @@ export function createDocumentIngestFoundationFeature() {
|
|
|
123
123
|
default: 50,
|
|
124
124
|
// Without a bound a tenant could set 0 (silently kills ingest) or an
|
|
125
125
|
// unbounded value (OCR worker runs per-file for as long as the PDF
|
|
126
|
-
// has pages — job-queue starvation)
|
|
126
|
+
// has pages — job-queue starvation).
|
|
127
127
|
bounds: { min: 1, max: 500 },
|
|
128
128
|
write: access.roles("TenantAdmin", "SystemAdmin"),
|
|
129
129
|
read: access.roles("TenantAdmin", "SystemAdmin", "User"),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// longText (jsonb has no encryption support), so writers must persist
|
|
3
3
|
// JSON.stringify(IngestPage[]) and readers must parse back. Centralising
|
|
4
4
|
// the codec here keeps liteparse + recipe consumers lockstep with the
|
|
5
|
-
// entity shape
|
|
5
|
+
// entity shape.
|
|
6
6
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
7
7
|
export function writeIngestPages(pages) {
|
|
8
8
|
return JSON.stringify(pages);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Tenant-destroy hook for the documentExtract entity-projection
|
|
1
|
+
// Tenant-destroy hook for the documentExtract entity-projection.
|
|
2
2
|
//
|
|
3
3
|
// Per-row forget() through the executor, not a bulk deleteMany: documentExtract
|
|
4
4
|
// is an ES-managed implicit projection, so a store-table write here would be
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
// resurrect every row this hook removed. forget() (Art. 17 hard-purge) is
|
|
7
7
|
// replayed by the implicit projection itself, which keeps the erasure
|
|
8
8
|
// rebuild-safe — the same reasoning as tenant-lifecycle's membership stage,
|
|
9
|
-
// and the reason the feature owns an r.entity instead of an r.projection
|
|
10
|
-
//
|
|
11
|
-
//
|
|
9
|
+
// and the reason the feature owns an r.entity instead of an r.projection.
|
|
10
|
+
// The `pages` ciphertext dies separately when the pipeline's later
|
|
11
|
+
// `subject-keys` stage erases the tenant subject key.
|
|
12
12
|
import { createSystemUser } from "@cosmicdrift/kumiko-framework/engine";
|
|
13
13
|
import { documentExtractsTable } from "./entity.js";
|
|
14
14
|
import { documentExtractExecutor } from "./executor.js";
|
|
@@ -53,7 +53,7 @@ registry) {
|
|
|
53
53
|
// Non-toggleable (always-on) names must keep reaching `result` through the
|
|
54
54
|
// globalCascade loop below even if this resolver's SYSTEM_TENANT_ID answer
|
|
55
55
|
// satisfies the emptiness guard above without also merging always-on into
|
|
56
|
-
// every per-tenant tierSet
|
|
56
|
+
// every per-tenant tierSet.
|
|
57
57
|
tierManaged = new Set([...managed].filter((name) => {
|
|
58
58
|
const feature = registry.getFeature(name);
|
|
59
59
|
return feature !== undefined && isToggleableFeature(feature);
|
|
@@ -60,7 +60,7 @@ export function createFeatureTogglesFeature(options = {}) {
|
|
|
60
60
|
});
|
|
61
61
|
r.translations({ keys: FEATURE_TOGGLES_I18N });
|
|
62
62
|
// toggle-cache-sync — multi-instance snapshot propagation. One shared
|
|
63
|
-
// cursor reads every toggle-set event once
|
|
63
|
+
// cursor reads every toggle-set event once; the winning
|
|
64
64
|
// process's handler calls runtime.broadcastToggle, which publishes on
|
|
65
65
|
// GlobalFeatureToggleRuntime's syncSignal so every process (including
|
|
66
66
|
// the one that won the cursor) applies the flip to its own snapshot —
|
|
@@ -21,7 +21,7 @@ export const globalFeatureStateTable = declareGlobalTenancy(pgTable("store_globa
|
|
|
21
21
|
// sees the table, so `kumiko schema generate` reports no changes and no
|
|
22
22
|
// app ever gets a migration for it (framework gap, not app-local). Derived
|
|
23
23
|
// from the pgTable above instead of hand-written a second time — the two
|
|
24
|
-
// used to drift independently
|
|
24
|
+
// used to drift independently: a column added only to
|
|
25
25
|
// the pgTable made queries type-check while the migration generator stayed
|
|
26
26
|
// blind to it, failing in prod with "column ... does not exist" while every
|
|
27
27
|
// mocked-stack test stayed green.
|
|
@@ -30,11 +30,11 @@ export const registeredQuery = defineQueryHandler({
|
|
|
30
30
|
const db = ctx.systemDb.acknowledgeCrossTenant(FEATURE_TOGGLE_CROSS_TENANT_REASON);
|
|
31
31
|
const overrideRows = await db.global(globalFeatureStateTable).selectMany();
|
|
32
32
|
const overrides = new Map(overrideRows.map((r) => [r.featureName, r.enabled]));
|
|
33
|
-
// SystemAdmin operator
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
33
|
+
// SystemAdmin operator tooling: the listing must show platform truth
|
|
34
|
+
// (all features in the registry), not its own tier cut.
|
|
35
|
+
// The per-tenant signature requires SYSTEM_TENANT_ID; the app resolver
|
|
36
|
+
// returns the union of all tier features. The sentinel convention is
|
|
37
|
+
// documented in DispatcherOptions.effectiveFeatures.
|
|
38
38
|
const effective = ctx.effectiveFeatures?.(SYSTEM_TENANT_ID);
|
|
39
39
|
const rows = [];
|
|
40
40
|
for (const feature of ctx.registry.features.values()) {
|
|
@@ -8,7 +8,7 @@ function isTogglePayload(value) {
|
|
|
8
8
|
typeof value["featureName"] === "string" &&
|
|
9
9
|
typeof value["enabled"] === "boolean");
|
|
10
10
|
}
|
|
11
|
-
//
|
|
11
|
+
// Gives toggle-cache-sync the cross-replica transport its shared
|
|
12
12
|
// dispatcher cursor needs — without this, only the one process that won
|
|
13
13
|
// the shared cursor's toggle-set event would ever learn about a flip.
|
|
14
14
|
// Standalone Redis transport for callers that want their own connections;
|
|
@@ -8,7 +8,7 @@ export const FEATURE_TOGGLE_SET_EVENT_NAME = "feature-toggles:event:toggle-set";
|
|
|
8
8
|
export const FEATURE_TOGGLE_AGGREGATE_TYPE = "feature-toggles";
|
|
9
9
|
// Shared acknowledgeCrossTenant() reason across all three handlers that read
|
|
10
10
|
// or write globalFeatureStateTable — one string so the three call sites
|
|
11
|
-
// can't drift
|
|
11
|
+
// can't drift.
|
|
12
12
|
export const FEATURE_TOGGLE_CROSS_TENANT_REASON = "global feature-toggle state, no tenant scope by design";
|
|
13
13
|
// Error reasons surfaced from feature-toggle handlers. Scoped to the
|
|
14
14
|
// feature's namespace per the framework's reason-convention.
|
|
@@ -2,7 +2,7 @@ import { type FeatureDefinition, type TenantId } from "@cosmicdrift/kumiko-frame
|
|
|
2
2
|
/** Host → tenantId for the anonymous media route.
|
|
3
3
|
* MUST be cheap/synchronous (in-memory map or cached lookup): it runs
|
|
4
4
|
* *before* the query-handler rate limit, so a DB round-trip here is an
|
|
5
|
-
* unthrottled DoS surface for anonymous callers rotating Host headers
|
|
5
|
+
* unthrottled DoS surface for anonymous callers rotating Host headers. */
|
|
6
6
|
export type PublicVariantResolveApexTenant = (host: string) => Promise<TenantId | null> | TenantId | null;
|
|
7
7
|
export type PublicVariantTenantResolution = "host" | "fileRef";
|
|
8
8
|
export type FileDerivativesOptions = {
|
|
@@ -21,7 +21,7 @@ const FEATURE_NAME = "file-derivatives";
|
|
|
21
21
|
// charset constraint (`Readonly<Record<string, VariantSpec>>`), so this
|
|
22
22
|
// stays permissive rather than guessing a convention — narrower than this
|
|
23
23
|
// would silently 404 a legitimately declared name again. Do not reintroduce
|
|
24
|
-
// a name list here "for safety"
|
|
24
|
+
// a name list here "for safety".
|
|
25
25
|
const VARIANT_NAME_RE = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
26
26
|
// file-derivatives — derive-on-first-use file variants (thumbnails,
|
|
27
27
|
// resized/reformatted images) plus an opt-in ANONYMOUS route that serves any
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Public-Read of a derived FileRef variant — the anonymous counterpart to
|
|
2
|
-
// GET /files/:id/variant/:name (
|
|
2
|
+
// GET /files/:id/variant/:name (auth-gated). Both routes resolve the
|
|
3
3
|
// same way: the variant spec comes from the FileRef's field declaration
|
|
4
4
|
// (`createImageField({ variants: {...} })`), not a fixed list — an app that
|
|
5
5
|
// declares its own variant name gets it served here too. This route never
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Ready-made specs to spread into a field's own `variants` declaration
|
|
2
2
|
// (`createImageField({ variants: { thumb, full: { ...full, maxEdge: 4096 } } })`)
|
|
3
3
|
// — not an allow-list. Which names a route serves is decided entirely by
|
|
4
|
-
// what a field declares
|
|
4
|
+
// what a field declares; these are just common defaults.
|
|
5
5
|
export const thumb = { maxEdge: 160, fit: "cover", format: "webp" };
|
|
6
6
|
export const card = { maxEdge: 640, fit: "inside", format: "webp" };
|
|
7
7
|
export const hero = { maxEdge: 1600, fit: "inside", format: "webp" };
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
// erasure hit the same store by construction. This feature re-exports the moved
|
|
9
9
|
// symbols unchanged so existing imports keep working.
|
|
10
10
|
//
|
|
11
|
-
// **Pattern
|
|
12
|
-
//
|
|
13
|
-
// -s3-env,
|
|
14
|
-
//
|
|
11
|
+
// **Pattern reference:** identical to `mail-foundation`. The foundation declares
|
|
12
|
+
// the `fileProvider` extension point; provider features (file-provider-s3,
|
|
13
|
+
// -inmemory, -s3-env, later -gcs/-azure-blob) register themselves by name. The
|
|
14
|
+
// tenant selects one at runtime via the `provider` config key.
|
|
15
15
|
//
|
|
16
|
-
// **Boot
|
|
17
|
-
//
|
|
16
|
+
// **Boot dependencies:** config (for the provider selector). No secrets, because
|
|
17
|
+
// the foundation itself does not hold any secrets.
|
|
18
18
|
import { access, createTenantConfig, defineFeature, EXT_FILE_PROVIDER, FILE_STORAGE_PROVIDER_ENV, } from "@cosmicdrift/kumiko-framework/engine";
|
|
19
19
|
// Moved into the framework — re-exported here so `@cosmicdrift/kumiko-bundled-
|
|
20
20
|
// features/file-foundation` consumers (user-data-rights, app code) keep working.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Demo/Test-Helper: liste die Keys eines Tenant-Storage. */
|
|
2
2
|
export declare function listKeys(tenantId: string): readonly string[];
|
|
3
|
-
/** Demo/
|
|
3
|
+
/** Demo/test helper: clears a tenant's storage. */
|
|
4
4
|
export declare function clearStorage(tenantId: string): void;
|
|
5
5
|
export declare function createFileProviderInMemoryFeature(): import("@cosmicdrift/kumiko-types/feature").FeatureDefinition & {
|
|
6
6
|
readonly exports: void;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
// kumiko-feature-version: 1
|
|
2
2
|
//
|
|
3
|
-
// file-provider-inmemory — In-
|
|
4
|
-
// foundation
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// file-provider-inmemory — In-memory file provider for the file-
|
|
4
|
+
// foundation plugin API. Stores files in a per-tenant Map instead
|
|
5
|
+
// of S3/Hetzner object storage. Intended for demos, sample apps,
|
|
6
|
+
// and tests without a MinIO container.
|
|
7
7
|
//
|
|
8
|
-
// **
|
|
9
|
-
// 1. Plugin
|
|
8
|
+
// **What this feature provides:**
|
|
9
|
+
// 1. Plugin registration via `r.useExtension("fileProvider",
|
|
10
10
|
// "inmemory", { build })`.
|
|
11
|
-
// 2. **
|
|
12
|
-
// InMemoryFileProvider
|
|
13
|
-
//
|
|
11
|
+
// 2. **Per-tenant storage.** Each tenant gets its own
|
|
12
|
+
// InMemoryFileProvider, providing tenant isolation by design
|
|
13
|
+
// without requiring a path convention.
|
|
14
14
|
//
|
|
15
|
-
// **Pattern
|
|
15
|
+
// **Pattern reference:** mirrors file-provider-s3.
|
|
16
16
|
//
|
|
17
|
-
// **
|
|
18
|
-
//
|
|
17
|
+
// **NOT for production.** The buffer is process memory, is lost on
|
|
18
|
+
// restart, and grows monotonically with every write.
|
|
19
19
|
import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
|
|
20
20
|
import { createInMemoryFileProvider, } from "@cosmicdrift/kumiko-framework/files";
|
|
21
21
|
const FEATURE_NAME = "file-provider-inmemory";
|
|
@@ -35,7 +35,7 @@ function getOrCreateProviderForTenant(tenantId) {
|
|
|
35
35
|
export function listKeys(tenantId) {
|
|
36
36
|
return providersByTenant.get(tenantId)?.keys() ?? [];
|
|
37
37
|
}
|
|
38
|
-
/** Demo/
|
|
38
|
+
/** Demo/test helper: clears a tenant's storage. */
|
|
39
39
|
export function clearStorage(tenantId) {
|
|
40
40
|
providersByTenant.get(tenantId)?.clear();
|
|
41
41
|
}
|
|
@@ -50,9 +50,9 @@ export function createFileProviderInMemoryFeature() {
|
|
|
50
50
|
category: "storage",
|
|
51
51
|
recommended: false,
|
|
52
52
|
});
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
// file-foundation
|
|
53
|
+
// No requirement for "config" or "secrets": the
|
|
54
|
+
// in-memory provider has neither configuration nor secrets. Only
|
|
55
|
+
// file-foundation must be present as the plugin extension point.
|
|
56
56
|
r.requires({ features: ["file-foundation"] });
|
|
57
57
|
const plugin = {
|
|
58
58
|
build: async (_ctx, tenantId) => {
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
// kumiko-feature-version: 1
|
|
2
2
|
//
|
|
3
|
-
// file-provider-s3 — concrete S3
|
|
4
|
-
// file-foundation plugin
|
|
3
|
+
// file-provider-s3 — concrete S3 implementation for the
|
|
4
|
+
// file-foundation plugin API.
|
|
5
5
|
//
|
|
6
|
-
// **
|
|
7
|
-
// 1. Provider-
|
|
8
|
-
// forcePathStyle/accessKeyId)
|
|
9
|
-
// Self-contained — file-foundation
|
|
10
|
-
// 2. Plugin
|
|
11
|
-
// { build })`. file-foundation's
|
|
12
|
-
// registry.
|
|
13
|
-
// 3. build(ctx, tenantId)
|
|
14
|
-
//
|
|
15
|
-
//
|
|
6
|
+
// **What this feature provides:**
|
|
7
|
+
// 1. Provider-specific tenant config (bucket/region/endpoint/
|
|
8
|
+
// forcePathStyle/accessKeyId) and secret (s3.secretAccessKey).
|
|
9
|
+
// Self-contained — file-foundation does not know about these.
|
|
10
|
+
// 2. Plugin registration via `r.useExtension("fileProvider", "s3",
|
|
11
|
+
// { build })`. file-foundation's factory finds the plugin through
|
|
12
|
+
// the registry.
|
|
13
|
+
// 3. build(ctx, tenantId) reads the config and secret, then calls
|
|
14
|
+
// `createS3Provider` from ./lib. This is the plugin's only
|
|
15
|
+
// cross-feature import, intentionally kept local.
|
|
16
16
|
//
|
|
17
|
-
// **Pattern
|
|
17
|
+
// **Pattern reference:** mirrors mail-transport-smtp.
|
|
18
18
|
//
|
|
19
|
-
// **Boot
|
|
19
|
+
// **Boot dependencies:** config + secrets + file-foundation.
|
|
20
20
|
import { requireDefined, requireNonEmpty, requireSecretSet, } from "@cosmicdrift/kumiko-bundled-features/foundation-shared";
|
|
21
21
|
import { requireSecretsContext } from "@cosmicdrift/kumiko-bundled-features/secrets";
|
|
22
22
|
import { access, createTenantConfig, defineFeature } from "@cosmicdrift/kumiko-framework/engine";
|
|
@@ -83,8 +83,8 @@ function createTenantConfigFileProviderS3Feature() {
|
|
|
83
83
|
}),
|
|
84
84
|
},
|
|
85
85
|
});
|
|
86
|
-
// Plugin
|
|
87
|
-
// file-foundation's `provider` config
|
|
86
|
+
// Plugin registration. The entityName "s3" is what tenants set in
|
|
87
|
+
// file-foundation's `provider` config key.
|
|
88
88
|
const plugin = {
|
|
89
89
|
build: async (ctx, tenantId) => buildS3Provider(ctx, tenantId), // @wrapper-known semantic-alias
|
|
90
90
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { assertSafeStorageKey, } from "@cosmicdrift/kumiko-framework/files";
|
|
2
2
|
// =============================================================================
|
|
3
|
-
//
|
|
3
|
+
// Required operator setup (multipart-upload cleanup)
|
|
4
4
|
// =============================================================================
|
|
5
5
|
//
|
|
6
6
|
// `writeStream` uses Bun's S3 writer for real multipart streaming. S3
|
|
@@ -10,7 +10,7 @@ import { assertSafeStorageKey, } from "@cosmicdrift/kumiko-framework/files";
|
|
|
10
10
|
// OPEN in S3 and bills storage for the parts already uploaded — until a
|
|
11
11
|
// lifecycle rule aborts it.
|
|
12
12
|
//
|
|
13
|
-
// **
|
|
13
|
+
// **Required operator setup on every bucket:**
|
|
14
14
|
//
|
|
15
15
|
// {
|
|
16
16
|
// "Rules": [{
|
|
@@ -26,7 +26,7 @@ import { assertSafeStorageKey, } from "@cosmicdrift/kumiko-framework/files";
|
|
|
26
26
|
// R2 and Minio support the same syntax.
|
|
27
27
|
//
|
|
28
28
|
// =============================================================================
|
|
29
|
-
//
|
|
29
|
+
// Required operator setup (IAM: list permission)
|
|
30
30
|
// =============================================================================
|
|
31
31
|
//
|
|
32
32
|
// GDPR-forget/tenant-destroy erasure (user-data-rights-defaults) calls
|
|
@@ -134,9 +134,9 @@ export function createS3Provider(config) {
|
|
|
134
134
|
},
|
|
135
135
|
async getSignedUrl(key, expiresInSeconds, options) {
|
|
136
136
|
assertSafeStorageKey(key);
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
//
|
|
137
|
+
// Bun signs contentDisposition as the response-content-disposition
|
|
138
|
+
// query parameter (a response override for the GET download) —
|
|
139
|
+
// the browser sees the original filename instead of the UUID key.
|
|
140
140
|
return client.presign(key, {
|
|
141
141
|
expiresIn: expiresInSeconds,
|
|
142
142
|
method: "GET",
|
package/dist/files/feature.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// files —
|
|
2
|
-
// files:event:*-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// `@cosmicdrift/kumiko-bundled-features/files`
|
|
1
|
+
// files — complete event sourcing for file metadata. The implementation (entity,
|
|
2
|
+
// files:event:*-events, inline projection) lives in the framework alongside
|
|
3
|
+
// file-routes and fileRefsTable because file-routes depends on registered events
|
|
4
|
+
// and a projection, as required by appendDomainEventCore.
|
|
5
|
+
// This module only re-exports the feature to keep the app import path
|
|
6
|
+
// `@cosmicdrift/kumiko-bundled-features/files` stable.
|
|
7
7
|
export { createFilesFeature, fileRefEntity } from "@cosmicdrift/kumiko-framework/files";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Backfill/GC job for derivatives orphaned by a forget/tenant-destroy that ran
|
|
2
|
-
// before
|
|
2
|
+
// before binary cleanup was wired into those flows. Those older runs
|
|
3
3
|
// left the FileRef row gone with no audit trail of what was ever forgotten —
|
|
4
4
|
// so this sweep works forward from the deterministic derivative-key grammar
|
|
5
5
|
// alone: for every key under a tenant's storage prefix that parses as a
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
// a soft-deleted one sitting in trash — means the derivative is still
|
|
9
9
|
// legitimate; only genuinely unreferenced derivatives are swept.
|
|
10
10
|
//
|
|
11
|
-
// Manual trigger only (no cron) — an operator runs this once after upgrading
|
|
12
|
-
//
|
|
11
|
+
// Manual trigger only (no cron) — an operator runs this once after upgrading,
|
|
12
|
+
// or on demand for spot-checks.
|
|
13
13
|
//
|
|
14
14
|
// Row unit for runChunkedMigration is a discovered derivative CANDIDATE KEY,
|
|
15
15
|
// not a tenant: one tenant's storage listing produces a variable number of
|
|
@@ -94,7 +94,7 @@ export async function sweepOrphanedDerivativesJob(rawPayload, ctx, db) {
|
|
|
94
94
|
async function migrateRow(candidate) {
|
|
95
95
|
// No isDeleted filter: a soft-deleted (trashed, not yet forgotten) fileRef
|
|
96
96
|
// still legitimately backs its derivatives — only an ABSENT row (forgotten,
|
|
97
|
-
// or a tenant destroyed
|
|
97
|
+
// or a tenant destroyed with no row left at all) makes a
|
|
98
98
|
// derivative orphaned.
|
|
99
99
|
const owners = await selectMany(db, fileRefsTable, { tenantId: candidate.tenantId, storageKey: candidate.originalKey }, { limit: 1 });
|
|
100
100
|
if (owners.length > 0)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// EXT_TENANT_DATA + EXT_STORAGE_PROVIDER destroy hooks for the `fileRef`
|
|
2
|
-
// entity
|
|
2
|
+
// entity. Kept apart from the `files` feature (like folders-user-data
|
|
3
3
|
// does for EXT_USER_DATA) so file consumers without the tenant-lifecycle
|
|
4
4
|
// pipeline don't pull a hard dependency — `files` stays usable standalone.
|
|
5
5
|
//
|
|
@@ -10,18 +10,17 @@
|
|
|
10
10
|
// isDeleted filter: tenant-destroy purges trashed rows too, a destroyed
|
|
11
11
|
// tenant has no "restore from trash" future. ALSO sweeps, per row, any
|
|
12
12
|
// storageKey that does NOT sit under one of this tenant's own
|
|
13
|
-
// tenantStoragePrefixes() — the shape a tenant-handover
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
// derivatives together.
|
|
13
|
+
// tenantStoragePrefixes() — the shape a tenant-handover leaves behind:
|
|
14
|
+
// the fileRef row's tenantId moved to this tenant, but the bytes stayed
|
|
15
|
+
// under the SOURCE tenant's prefix (moving them would mean copying bytes,
|
|
16
|
+
// which the handover design explicitly rejects). Must run here, not in
|
|
17
|
+
// the "files" stage below — that stage's own prefix sweep only reaches
|
|
18
|
+
// keys under ITS tenant's prefixes by construction, and by the time it
|
|
19
|
+
// runs this hook has already forgotten (hard-deleted) the rows it would
|
|
20
|
+
// need to read the storageKey off. Deleted by STEM prefix
|
|
21
|
+
// (storageKeyStemPrefix), not the exact key: a derived variant
|
|
22
|
+
// (thumbnail, resized render) has no `file_refs` row of its own, so only
|
|
23
|
+
// the stem reaches original + derivatives together.
|
|
25
24
|
// - fileRefStorageDestroyHook ("files" stage, EXT_STORAGE_PROVIDER): wipes
|
|
26
25
|
// every BINARY (original + derivatives + anything else) under the
|
|
27
26
|
// tenant's storage prefixes. A full prefix sweep per tenantStoragePrefixes()
|
|
@@ -32,19 +31,18 @@
|
|
|
32
31
|
// (the provider's own list() prefix already scopes it). Still catches a
|
|
33
32
|
// blob with no fileRef row at all (the orphan case the row-driven sweep
|
|
34
33
|
// above cannot see) — REFINED, not replaced, to skip a key a FOREIGN
|
|
35
|
-
// tenant's fileRef row still references (a tenant-handover
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
// not one query per key.
|
|
34
|
+
// tenant's fileRef row still references (a tenant-handover leaves the
|
|
35
|
+
// row's tenantId moved but the storageKey under THIS tenant's prefix
|
|
36
|
+
// unchanged). By the time this stage runs, the "app-data" stage
|
|
37
|
+
// (stages.ts DESTRUCTION_STAGES: "app-data" before "files") has already
|
|
38
|
+
// hard-deleted every row THIS tenant owned, so any surviving row a listed
|
|
39
|
+
// key still matches is, by construction, a foreign tenant's — no tenant
|
|
40
|
+
// comparison needed, existence is enough. The exception is computed from
|
|
41
|
+
// the SURVIVING row's storageKeyStemPrefix (mirroring the deletion side
|
|
42
|
+
// above), not the listed key's exact match: a derivative has no fileRef row
|
|
43
|
+
// of its own, so excluding only exact matches would still delete it out
|
|
44
|
+
// from under the tenant that claimed its original. Batched: one existence
|
|
45
|
+
// query per chunk of listed keys, not one query per key.
|
|
48
46
|
import { createEventStoreExecutor, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
49
47
|
import { createSystemUser, parseTenantId, } from "@cosmicdrift/kumiko-framework/engine";
|
|
50
48
|
import { assertSafeStorageKey, fileRefEntity, fileRefsTable, storageKeyStemPrefix, tenantStoragePrefixes, } from "@cosmicdrift/kumiko-framework/files";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// GDPR tenant-destroy + orphaned-derivative backfill coverage for the `files`
|
|
2
|
-
// feature's `fileRef` entity
|
|
2
|
+
// feature's `fileRef` entity. Kept apart from `files` — like
|
|
3
3
|
// folders-user-data does for EXT_USER_DATA — so file consumers without the
|
|
4
4
|
// tenant-lifecycle pipeline don't pull a hard dependency; `files` stays usable
|
|
5
5
|
// standalone (e.g. user-data-rights-demo mounts `files` + user-data-rights
|
|
@@ -21,7 +21,7 @@ export type FoldersFeatureOptions = {
|
|
|
21
21
|
/** Row-level ownership on the folder-assignment rows themselves — orthogonal
|
|
22
22
|
* to `access`, which only gates whether a caller may dispatch set/clear/list
|
|
23
23
|
* at all. Not needed to keep a caller from reading assignments on host
|
|
24
|
-
* entities they can't see: that gate is default-on
|
|
24
|
+
* entities they can't see: that gate is default-on and derives
|
|
25
25
|
* from the entity's `parentRef`. Use `ownership.read` for an ADDITIONAL row
|
|
26
26
|
* rule on the assignment row itself; it is AND-ed with the host-visibility
|
|
27
27
|
* gate. Applies only to `folder-assignment`; the `folder` catalog stays
|
|
@@ -285,8 +285,8 @@ export function FolderManager({ renderMeta, filing, }) {
|
|
|
285
285
|
walk(tree, 0);
|
|
286
286
|
// The bucket itself must stay in the tree even when nothing is currently
|
|
287
287
|
// unfiled — it's the only drop target to un-file a leaf back out of a
|
|
288
|
-
// folder.
|
|
289
|
-
//
|
|
288
|
+
// folder. An empty `unfiled` array made the bucket vanish entirely, silently
|
|
289
|
+
// removing that escape hatch.
|
|
290
290
|
const hasUnfiled = filing !== undefined;
|
|
291
291
|
if (hasUnfiled) {
|
|
292
292
|
out.push(bucketRow(stripeNext()));
|
package/dist/folders/web/tree.js
CHANGED
|
@@ -33,11 +33,11 @@ export function buildFolderTree(rows) {
|
|
|
33
33
|
.map((row) => ({ ...row, depth, children: build(row.id, depth + 1) }));
|
|
34
34
|
return build(null, 0);
|
|
35
35
|
}
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
// not
|
|
40
|
-
// cap, not run one iteration past it.
|
|
36
|
+
// Returns a path such as "Properties / Berlin" for a folder id by walking
|
|
37
|
+
// parentId upward, or an empty string if the id is unknown. The row-count cap
|
|
38
|
+
// stops a parent cycle (currently impossible, since there is no reparent yet)
|
|
39
|
+
// from spinning forever. Use `<`, not `<=`: a cycle of exactly rows.length
|
|
40
|
+
// nodes must stop at the cap, not run one iteration past it.
|
|
41
41
|
export function folderPath(rows, id, separator = " / ") {
|
|
42
42
|
const byId = new Map(rows.map((r) => [r.id, r]));
|
|
43
43
|
const names = [];
|
|
@@ -6,7 +6,7 @@ import { readStoredDraft } from "../../decrypt-draft.js";
|
|
|
6
6
|
// once; a draft saved exactly once (create, never updated) has no
|
|
7
7
|
// modified_at yet, so falls back to inserted_at.
|
|
8
8
|
//
|
|
9
|
-
// Reads the blob + tenantId BEFORE anything is deleted
|
|
9
|
+
// Reads the blob + tenantId BEFORE anything is deleted — the
|
|
10
10
|
// caller (cleanup.job.ts) walks each row's blob for FileRefs and releases
|
|
11
11
|
// them per-tenant via ctx._fileProviderResolver, then deletes the batch
|
|
12
12
|
// per-row via formDraftExecutor.delete (event-sourced, not raw SQL — a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { instantToTimestamptzParam, toPostgresArrayLiteral, unsafeReadRetrying, } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
// Narrows a draft blob's raw FileRef-shaped storageKeys (collectDraftFileRefKeys
|
|
3
|
-
// output — extracted from free-form, client-supplied JSON
|
|
3
|
+
// output — extracted from free-form, client-supplied JSON) down to
|
|
4
4
|
// the ones with a real, non-deleted file_refs row owned by this exact
|
|
5
5
|
// (tenantId, ownerId). Without this, a crafted draft value like
|
|
6
6
|
// { storageKey: "<someone-else's-real-key>" } would reach the storage
|
|
@@ -6,8 +6,8 @@ import { FORM_DRAFT_KEY_MAX_LENGTH, FORM_DRAFT_UNIQUE_KEY_CONSTRAINT } from "./w
|
|
|
6
6
|
// (tenant, ownerId): the same key from two different users, or the same
|
|
7
7
|
// user in two different tenants, is a different draft.
|
|
8
8
|
//
|
|
9
|
-
// Boundary
|
|
10
|
-
// lives in a domain stream — it's
|
|
9
|
+
// Boundary: form-draft never holds anything that already
|
|
10
|
+
// lives in a domain stream — it's an intermediate state BEFORE the domain entity
|
|
11
11
|
// is created. Consumers delete the draft (discard handler) once the real
|
|
12
12
|
// submit succeeds; partially-created domain data past that point is the
|
|
13
13
|
// consuming app's concern, not this feature's.
|
|
@@ -29,7 +29,7 @@ export const formDraftEntity = createEntity({
|
|
|
29
29
|
personal: false,
|
|
30
30
|
reason: "technical_reference",
|
|
31
31
|
}),
|
|
32
|
-
// The blob shape is fixed
|
|
32
|
+
// The blob shape is fixed, not left to the caller:
|
|
33
33
|
// { values: Record<string, unknown>, stepIndex: number, savedAt: string }.
|
|
34
34
|
// Free-form because `values` mirrors whatever fields the in-progress
|
|
35
35
|
// form has, so it can carry arbitrary user-entered PII. Encrypted under
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// form-draft — a per-user, per-tenant working copy of an in-progress form,
|
|
2
|
-
// saved BEFORE the real domain entity exists. Backing for wizard-mode resume
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// uniqueness model.
|
|
2
|
+
// saved BEFORE the real domain entity exists. Backing for wizard-mode resume.
|
|
3
|
+
// A caller-assigned draftKey (typically screenId + optional hostEntityId)
|
|
4
|
+
// round-trips { values, stepIndex, savedAt } through save/discard/get. See
|
|
5
|
+
// entity.ts for the ownership + uniqueness model.
|
|
7
6
|
import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
|
|
8
7
|
import { formDraftEntity } from "./entity.js";
|
|
9
8
|
import { cleanupDraftsJob, formDraftRetentionDaysConfig } from "./handlers/cleanup.job.js";
|