@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,6 +1,6 @@
|
|
|
1
|
-
// imapflow
|
|
2
|
-
//
|
|
3
|
-
// UIDVALIDITY:lastUid
|
|
1
|
+
// imapflow wiring and pure helpers for IMAP providers.
|
|
2
|
+
// Reference implementation: /Users/marc/code/doc-o-mat (HEINZ), but uses an
|
|
3
|
+
// incremental UIDVALIDITY:lastUid cursor instead of a '1:*' full scan.
|
|
4
4
|
import { BlockedHostError, readAllowedPrivateMailHostsFromEnv, resolveMailConnectTarget, } from "@cosmicdrift/kumiko-bundled-features/foundation-shared";
|
|
5
5
|
import { InboundAuthError, InboundCursorInvalidError, InboundTransientError, } from "@cosmicdrift/kumiko-bundled-features/inbound-mail-foundation";
|
|
6
6
|
import { createFallbackLogger } from "@cosmicdrift/kumiko-framework/logging";
|
|
@@ -71,9 +71,9 @@ export async function createImapClient(doc, hostGuard = {}) {
|
|
|
71
71
|
}
|
|
72
72
|
/** Server-Fehler → typisierte Foundation-Fehlerklassen (Plan §2). */
|
|
73
73
|
export function mapImapError(err, host) {
|
|
74
|
-
// imapflow
|
|
75
|
-
// message
|
|
76
|
-
// authenticationFailed
|
|
74
|
+
// imapflow errors carry the server response in responseText; the
|
|
75
|
+
// message is only "Command failed", so both are included in the match;
|
|
76
|
+
// authenticationFailed is the reliable flag.
|
|
77
77
|
const carrier = isPlainObject(err) ? err : undefined;
|
|
78
78
|
const responseText = typeof carrier?.["responseText"] === "string" ? carrier["responseText"] : "";
|
|
79
79
|
const msg = `${err instanceof Error ? err.message : String(err)} ${responseText}`.trim();
|
|
@@ -95,9 +95,9 @@ export function parseImapCursor(cursor) {
|
|
|
95
95
|
return null;
|
|
96
96
|
return { uidValidity, lastUid };
|
|
97
97
|
}
|
|
98
|
-
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
98
|
+
/** Throws InboundCursorInvalidError when UIDVALIDITY changes; the
|
|
99
|
+
* foundation resets the cursor and performs a full resync within the
|
|
100
|
+
* backfill window (deduplication catches duplicates). */
|
|
101
101
|
export function assertUidValidity(cursor, serverUidValidity) {
|
|
102
102
|
if (cursor && cursor.uidValidity !== serverUidValidity) {
|
|
103
103
|
throw new InboundCursorInvalidError(`UIDVALIDITY changed (${cursor.uidValidity} → ${serverUidValidity}) — full resync required`);
|
|
@@ -109,8 +109,9 @@ export function assertUidValidity(cursor, serverUidValidity) {
|
|
|
109
109
|
function stripAngles(id) {
|
|
110
110
|
return id.replace(/^<|>$/g, "").trim();
|
|
111
111
|
}
|
|
112
|
-
/** References
|
|
113
|
-
* | undefined;
|
|
112
|
+
/** Normalizes the References chain: mailparser returns string | string[]
|
|
113
|
+
* | undefined; when References is missing, In-Reply-To provides the thread
|
|
114
|
+
* anchor. */
|
|
114
115
|
export function normalizeReferences(parsed) {
|
|
115
116
|
const raw = parsed.references;
|
|
116
117
|
const list = raw === undefined ? [] : Array.isArray(raw) ? raw : raw.split(/\s+/);
|
|
@@ -128,15 +129,15 @@ function addressList(a) {
|
|
|
128
129
|
const arr = Array.isArray(a) ? a : [a];
|
|
129
130
|
return arr.map((x) => x.text).filter((t) => Boolean(t));
|
|
130
131
|
}
|
|
131
|
-
/** imapflow
|
|
132
|
-
*
|
|
133
|
-
* no-date-api)
|
|
134
|
-
* Date
|
|
132
|
+
/** imapflow provides internalDate as either a Date or string depending on
|
|
133
|
+
* the code path. The string form is deliberately discarded (no date parsing
|
|
134
|
+
* in feature code, no-date-api); toRawInboundMessage then falls back to the
|
|
135
|
+
* mailparser Date header, which is always a real Date. */
|
|
135
136
|
export function coerceDate(d) {
|
|
136
137
|
return d instanceof Date ? d : undefined;
|
|
137
138
|
}
|
|
138
|
-
/** providerMessageId: UID
|
|
139
|
-
*
|
|
139
|
+
/** providerMessageId: a UID is unique only within a UIDVALIDITY; together,
|
|
140
|
+
* they form the stable idempotency anchor. */
|
|
140
141
|
export function buildProviderMessageId(uidValidity, uid) {
|
|
141
142
|
return `${uidValidity}:${uid}`;
|
|
142
143
|
}
|
|
@@ -155,8 +156,8 @@ export async function toRawInboundMessage(args) {
|
|
|
155
156
|
cc: addressList(parsed.cc),
|
|
156
157
|
subject: parsed.subject ?? "",
|
|
157
158
|
snippet: text.slice(0, SNIPPET_MAX),
|
|
158
|
-
// Lib-
|
|
159
|
-
//
|
|
159
|
+
// Lib-boundary bridge (Date from imapflow/mailparser) → Temporal;
|
|
160
|
+
// when no date exists, Epoch is the honest marker.
|
|
160
161
|
receivedAtIso: (receivedAt
|
|
161
162
|
? legacyDateToInstant(receivedAt)
|
|
162
163
|
: Temporal.Instant.fromEpochMilliseconds(0)).toString(),
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import type { InboundMailProviderPlugin, RawInboundMessage } from "@cosmicdrift/kumiko-bundled-features/inbound-mail-foundation";
|
|
2
2
|
export declare const INMEMORY_PROVIDER_KEY = "inmemory";
|
|
3
|
-
/** Test
|
|
4
|
-
*
|
|
5
|
-
* cursor
|
|
3
|
+
/** Test helper: adds a message to the mailbox. If a watch is active, it is
|
|
4
|
+
* pushed immediately (IDLE simulation); the next fetch also returns it by
|
|
5
|
+
* cursor — the foundation's deduplication makes this idempotent. */
|
|
6
6
|
export declare function seedInboundMessage(accountId: string, msg: RawInboundMessage): Promise<void>;
|
|
7
|
-
/** Test
|
|
8
|
-
* InboundAuthError
|
|
7
|
+
/** Test helper: injects a one-shot error into the next fetch (e.g.
|
|
8
|
+
* InboundAuthError or InboundCursorInvalidError). */
|
|
9
9
|
export declare function failNextFetchWith(accountId: string, err: unknown): void;
|
|
10
|
-
/** Test
|
|
10
|
+
/** Test helper: injects a one-shot error into the next verify. */
|
|
11
11
|
export declare function failNextVerifyWith(accountId: string, err: unknown): void;
|
|
12
|
-
/** Test
|
|
13
|
-
*
|
|
12
|
+
/** Test helper: simulates the live connection terminating (the supervisor
|
|
13
|
+
* must restart with backoff). */
|
|
14
14
|
export declare function emitWatchError(accountId: string, err: unknown): void;
|
|
15
|
-
/** Test
|
|
15
|
+
/** Test helper: reports whether an account currently has an active watch. */
|
|
16
16
|
export declare function isWatching(accountId: string): boolean;
|
|
17
17
|
/** Test-Helper: kompletter State-Reset (Test-Isolation — Mock-States
|
|
18
18
|
* nie zwischen Tests teilen). */
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// kumiko-feature-version: 1
|
|
2
2
|
//
|
|
3
|
-
// inbound-provider-inmemory —
|
|
4
|
-
// inbound-mail-foundation
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// (IDLE
|
|
8
|
-
// (
|
|
9
|
-
//
|
|
3
|
+
// inbound-provider-inmemory — scriptable in-memory provider for the
|
|
4
|
+
// inbound-mail-foundation plugin API. For tests, demos, and sample apps:
|
|
5
|
+
// messages are supplied via `seedInboundMessage()` instead of being fetched
|
|
6
|
+
// from a real mailbox; `watch()` immediately pushes seeded messages
|
|
7
|
+
// (IDLE simulation), while `fetch()` returns them by cursor
|
|
8
|
+
// (reconciliation path). Together, both paths exercise the foundation's
|
|
9
|
+
// deduplication guarantee exactly.
|
|
10
10
|
//
|
|
11
|
-
// **Pattern
|
|
12
|
-
//
|
|
11
|
+
// **Pattern basis:** mail-transport-inmemory (module-level state +
|
|
12
|
+
// test-helper exports). Not for production.
|
|
13
13
|
import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
|
|
14
14
|
const FEATURE_NAME = "inbound-provider-inmemory";
|
|
15
15
|
export const INMEMORY_PROVIDER_KEY = "inmemory";
|
|
@@ -22,26 +22,26 @@ function stateFor(accountId) {
|
|
|
22
22
|
}
|
|
23
23
|
return state;
|
|
24
24
|
}
|
|
25
|
-
/** Test
|
|
26
|
-
*
|
|
27
|
-
* cursor
|
|
25
|
+
/** Test helper: adds a message to the mailbox. If a watch is active, it is
|
|
26
|
+
* pushed immediately (IDLE simulation); the next fetch also returns it by
|
|
27
|
+
* cursor — the foundation's deduplication makes this idempotent. */
|
|
28
28
|
export async function seedInboundMessage(accountId, msg) {
|
|
29
29
|
const state = stateFor(accountId);
|
|
30
30
|
state.log.push(msg);
|
|
31
31
|
if (state.watch)
|
|
32
32
|
await state.watch.onMessages([msg]);
|
|
33
33
|
}
|
|
34
|
-
/** Test
|
|
35
|
-
* InboundAuthError
|
|
34
|
+
/** Test helper: injects a one-shot error into the next fetch (e.g.
|
|
35
|
+
* InboundAuthError or InboundCursorInvalidError). */
|
|
36
36
|
export function failNextFetchWith(accountId, err) {
|
|
37
37
|
stateFor(accountId).nextFetchError = err;
|
|
38
38
|
}
|
|
39
|
-
/** Test
|
|
39
|
+
/** Test helper: injects a one-shot error into the next verify. */
|
|
40
40
|
export function failNextVerifyWith(accountId, err) {
|
|
41
41
|
stateFor(accountId).nextVerifyError = err;
|
|
42
42
|
}
|
|
43
|
-
/** Test
|
|
44
|
-
*
|
|
43
|
+
/** Test helper: simulates the live connection terminating (the supervisor
|
|
44
|
+
* must restart with backoff). */
|
|
45
45
|
export function emitWatchError(accountId, err) {
|
|
46
46
|
const state = accounts.get(accountId);
|
|
47
47
|
if (state?.watch) {
|
|
@@ -50,7 +50,7 @@ export function emitWatchError(accountId, err) {
|
|
|
50
50
|
handlers.onError(err);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
/** Test
|
|
53
|
+
/** Test helper: reports whether an account currently has an active watch. */
|
|
54
54
|
export function isWatching(accountId) {
|
|
55
55
|
return accounts.get(accountId)?.watch != null;
|
|
56
56
|
}
|
|
@@ -60,7 +60,7 @@ export function resetInboundInMemory() {
|
|
|
60
60
|
accounts.clear();
|
|
61
61
|
}
|
|
62
62
|
// =============================================================================
|
|
63
|
-
// Plugin — cursor = { offset: number }
|
|
63
|
+
// Plugin — cursor = { offset: number } over the append-only log.
|
|
64
64
|
// =============================================================================
|
|
65
65
|
function offsetOf(cursor) {
|
|
66
66
|
const raw = cursor?.["offset"];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Job-run retention
|
|
1
|
+
// Job-run retention: store_job_runs/store_job_run_logs are
|
|
2
2
|
// direct-write stores now, not event-sourced projections — nothing else
|
|
3
3
|
// purges them, so without this query they grow forever with the run count
|
|
4
4
|
// instead of the runtime. Not the retention-cleanup executor: that executor
|
|
@@ -18,7 +18,7 @@ export async function deleteStaleJobRuns(db, retentionDays) {
|
|
|
18
18
|
const cutoff = Temporal.Now.instant().subtract({ hours: retentionDays * 24 });
|
|
19
19
|
const logsResult = await deleteManyBatched(db, jobRunLogsTable, { timestamp: { lt: cutoff } }, { limit: RETENTION_DELETE_BATCH_SIZE });
|
|
20
20
|
const runsResult = await deleteManyBatched(db, jobRunsTable, { insertedAt: { lt: cutoff } }, { limit: RETENTION_DELETE_BATCH_SIZE });
|
|
21
|
-
// Same window for the tenant-visible failure records
|
|
21
|
+
// Same window for the tenant-visible failure records: the run
|
|
22
22
|
// they point at is gone by now, and a job whose subject never ran again
|
|
23
23
|
// would otherwise keep its record forever.
|
|
24
24
|
const tenantFailuresResult = await deleteManyBatched(db, tenantJobFailuresTable, { failedAt: { lt: cutoff } }, { limit: RETENTION_DELETE_BATCH_SIZE });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Stale job-run sweep
|
|
2
|
-
//
|
|
1
|
+
// Stale job-run sweep: store_job_runs is a direct-write store
|
|
2
|
+
// Status is set to "running" once at onJobStart and only ever
|
|
3
3
|
// flipped to "completed"/"failed" by onJobComplete/onJobFailed. If the
|
|
4
4
|
// process dies mid-run (crash, OOM, kill -9), those callbacks never fire and
|
|
5
5
|
// the row is stuck on "running" forever — nothing else on the read side
|
|
@@ -31,7 +31,7 @@ export async function markStaleJobRunsFailed(db, timeoutHours, queuedRetentionDa
|
|
|
31
31
|
// user subject annotation as job-run-logger.ts's onJobFailed path
|
|
32
32
|
// (personal: { of: "triggeredById" } on job-run-table.ts), so it is encrypted
|
|
33
33
|
// under the triggering user's DEK, or the system tenant key when
|
|
34
|
-
// triggeredById is null (whenAbsent: "tenant"
|
|
34
|
+
// triggeredById is null (whenAbsent: "tenant"). Runs are grouped by
|
|
35
35
|
// that subject: one encrypt and one updateMany per subject instead of per run.
|
|
36
36
|
const stale = await selectMany(db, jobRunsTable, {
|
|
37
37
|
status: "running",
|
package/dist/jobs/events.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Payload schemas for the jobRun direct-write path
|
|
1
|
+
// Payload schemas for the jobRun direct-write path. Previously these
|
|
2
2
|
// backed jobRun's event-store payloads (r.defineEvent + inline projections);
|
|
3
3
|
// now job-run-logger.ts parses against them before writing straight into
|
|
4
4
|
// jobRunsTable/jobRunLogsTable, so an out-of-dispatcher write still gets the
|
package/dist/jobs/feature.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ import { type FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
2
2
|
export type JobsFeatureOptions = {
|
|
3
3
|
readonly retentionDays?: number;
|
|
4
4
|
readonly staleRunTimeoutHours?: number;
|
|
5
|
+
readonly readRoles?: readonly string[];
|
|
5
6
|
};
|
|
6
7
|
export declare function createJobsFeature(options?: JobsFeatureOptions): FeatureDefinition;
|
package/dist/jobs/feature.js
CHANGED
|
@@ -9,8 +9,8 @@ import { reindexEntityJob, reindexEntityPayloadSchema } from "./handlers/reindex
|
|
|
9
9
|
import { createRetentionCleanupJob, DEFAULT_JOB_RUN_RETENTION_DAYS, } from "./handlers/retention-cleanup.job.js";
|
|
10
10
|
import { retryWrite } from "./handlers/retry.write.js";
|
|
11
11
|
import { createStaleRunSweepJob, DEFAULT_JOB_RUN_STALE_TIMEOUT_HOURS, } from "./handlers/stale-run-sweep.job.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { createTenantFailuresQuery } from "./handlers/tenant-failures.query.js";
|
|
13
|
+
import { createTenantRunsQuery } from "./handlers/tenant-runs.query.js";
|
|
14
14
|
import { triggerWrite } from "./handlers/trigger.write.js";
|
|
15
15
|
import { jobRunLogsTableMeta, jobRunsTableMeta } from "./job-run-table.js";
|
|
16
16
|
import { eventConsumerDetailScreen, eventConsumersScreen, jobRunDetailScreen, jobRunsScreen, jobTriggerScreen, } from "./screens.js";
|
|
@@ -20,6 +20,10 @@ import { JOBS_I18N } from "./web/i18n.js";
|
|
|
20
20
|
export function createJobsFeature(options = {}) {
|
|
21
21
|
const retentionDays = options.retentionDays ?? DEFAULT_JOB_RUN_RETENTION_DAYS;
|
|
22
22
|
const staleRunTimeoutHours = options.staleRunTimeoutHours ?? DEFAULT_JOB_RUN_STALE_TIMEOUT_HOURS;
|
|
23
|
+
const readRoles = options.readRoles ?? [];
|
|
24
|
+
if (readRoles.includes("anonymous")) {
|
|
25
|
+
throw new Error(`createJobsFeature: readRoles must not contain "anonymous" — job status and failures are only readable by members of the tenant.`);
|
|
26
|
+
}
|
|
23
27
|
return defineFeature("jobs", (r) => {
|
|
24
28
|
r.describe("Persistence and operator tooling for background jobs registered via `r.job(...)`. Every job execution writes directly into `store_job_runs` (current status + duration) and `store_job_run_logs` (per-line log rows) from the BullMQ callbacks — no event stream in between (#2243). A daily `retention-cleanup` job deletes runs (and their logs) older than `retentionDays`; an hourly `stale-run-sweep` job marks runs stuck at status `running` past `staleRunTimeoutHours` as `failed` (#2246 — a crashed worker never fires the completion callback, so nothing else ever revisits the row). Exposes `jobs:write:trigger` (manual run) and `jobs:write:retry` (operator retry of a failed run), plus `jobs:query:list`, `jobs:query:details`, and `jobs:query:catalog` (manual jobs) for the operator UI. A job that declares `tenantVisibleFailure` also records its last failed attempt per tenant and subject in `store_tenant_job_failures`, which the tenant itself reads through `jobs:query:failures` — a translation key only, never the provider's message (fw#3079). A job that declares `tenantVisibleRun` also keeps its run state per tenant and subject in `store_tenant_job_runs` (queued, running, plus the latest completed or failed run, no payload, error text or logs), which the tenant reads through `jobs:query:tenant-runs` (fw#3616); the stale-run sweep fails its stuck `running` rows and drops `queued` rows older than `retentionDays`.");
|
|
25
29
|
r.uiHints({
|
|
@@ -31,11 +35,10 @@ export function createJobsFeature(options = {}) {
|
|
|
31
35
|
r.storeTable(jobRunsTableMeta, {
|
|
32
36
|
reason: "direct_write.job_runs",
|
|
33
37
|
// payload/error carry personal:{of:"triggeredById"} (job-run-table.ts): encrypted under the
|
|
34
|
-
// triggering user's DEK, or the system tenant key when triggeredById is null
|
|
35
|
-
// (whenAbsent: "tenant", fw#3654).
|
|
38
|
+
// triggering user's DEK, or the system tenant key when triggeredById is null.
|
|
36
39
|
// job-run-logger.ts manually encrypts both before every insert/update
|
|
37
40
|
// (encryptStartedPayload/encryptFailureError) since this store bypasses
|
|
38
|
-
// the executor's automatic PII pipeline
|
|
41
|
+
// the executor's automatic PII pipeline.
|
|
39
42
|
piiEncryptedOnWrite: true,
|
|
40
43
|
});
|
|
41
44
|
r.storeTable(jobRunLogsTableMeta, {
|
|
@@ -49,7 +52,7 @@ export function createJobsFeature(options = {}) {
|
|
|
49
52
|
});
|
|
50
53
|
// Framework-provided rebuild job — available whenever `jobs` is composed; enqueueProjectionRebuild dispatches it.
|
|
51
54
|
r.job("projectionRebuild", { trigger: { manual: true }, concurrency: "skip", schema: projectionRebuildPayloadSchema }, projectionRebuildJob);
|
|
52
|
-
// Retroactive search backfill
|
|
55
|
+
// Retroactive search backfill — manual + perTenant, so one
|
|
53
56
|
// `jobs:write:trigger` call with { entity } fans out to every active
|
|
54
57
|
// tenant (job-runner.ts perTenant dispatch applies to manual triggers
|
|
55
58
|
// too, not just cron).
|
|
@@ -60,10 +63,10 @@ export function createJobsFeature(options = {}) {
|
|
|
60
63
|
schema: reindexEntityPayloadSchema,
|
|
61
64
|
}, reindexEntityJob);
|
|
62
65
|
// store_job_runs/store_job_run_logs are direct-write, unbounded-growth
|
|
63
|
-
// stores
|
|
66
|
+
// stores — nothing else purges them.
|
|
64
67
|
r.job("retention-cleanup", { trigger: { cron: "0 3 * * *" }, concurrency: "skip" }, createRetentionCleanupJob(retentionDays));
|
|
65
68
|
// Sweeps store_job_runs for rows stuck at status "running" past the
|
|
66
|
-
// timeout
|
|
69
|
+
// timeout. Hourly matches the timeout's own granularity —
|
|
67
70
|
// frequent enough to catch a stuck run soon after it crosses the
|
|
68
71
|
// threshold, cheap enough that an (almost always empty) result set
|
|
69
72
|
// doesn't matter.
|
|
@@ -80,8 +83,8 @@ export function createJobsFeature(options = {}) {
|
|
|
80
83
|
list: r.queryHandler(listQuery),
|
|
81
84
|
detail: r.queryHandler(detailQuery),
|
|
82
85
|
catalog: r.queryHandler(catalogQuery),
|
|
83
|
-
failures: r.queryHandler(
|
|
84
|
-
tenantRuns: r.queryHandler(
|
|
86
|
+
failures: r.queryHandler(createTenantFailuresQuery(readRoles)),
|
|
87
|
+
tenantRuns: r.queryHandler(createTenantRunsQuery(readRoles)),
|
|
85
88
|
consumers: r.queryHandler(consumersQuery),
|
|
86
89
|
consumerDetails: r.queryHandler(consumerDetailQuery),
|
|
87
90
|
};
|
|
@@ -27,11 +27,11 @@ export const detailQuery = defineQueryHandler({
|
|
|
27
27
|
const row = await fetchOne(db, jobRunsTable, { id: query.payload.runId });
|
|
28
28
|
if (!row)
|
|
29
29
|
return null;
|
|
30
|
-
// payload is stored encrypted under the triggering user's DEK
|
|
30
|
+
// payload is stored encrypted under the triggering user's DEK.
|
|
31
31
|
if (typeof row["payload"] === "string") {
|
|
32
32
|
row["payload"] = await decryptStoredPii(row["payload"], "payload", "job-run-detail");
|
|
33
33
|
}
|
|
34
|
-
// error is stored encrypted under the triggering user's DEK
|
|
34
|
+
// error is stored encrypted under the triggering user's DEK,
|
|
35
35
|
// same mechanism as row.payload above.
|
|
36
36
|
if (typeof row["error"] === "string") {
|
|
37
37
|
row["error"] = await decryptStoredPii(row["error"], "error", "job-run-detail");
|
|
@@ -39,8 +39,8 @@ export const detailQuery = defineQueryHandler({
|
|
|
39
39
|
const logs = await selectMany(db, jobRunLogsTable, { runId: query.payload.runId }, {
|
|
40
40
|
orderBy: { col: "id", direction: "asc" },
|
|
41
41
|
});
|
|
42
|
-
// message is stored encrypted under the triggering user's DEK
|
|
43
|
-
// same mechanism as row.payload above. Bounded concurrency
|
|
42
|
+
// message is stored encrypted under the triggering user's DEK,
|
|
43
|
+
// same mechanism as row.payload above. Bounded concurrency —
|
|
44
44
|
// unbounded Promise.all would fire one decrypt per log line at once
|
|
45
45
|
// against the KMS adapter's pool.
|
|
46
46
|
const decryptedLogs = await mapWithConcurrency(logs, KMS_POOL_CONCURRENCY, async (log) => {
|
|
@@ -88,7 +88,7 @@ export const listQuery = defineQueryHandler({
|
|
|
88
88
|
// countWhere reruns the SAME `where` without the limit — `rows.length` is
|
|
89
89
|
// capped at the page size and would silently undercount the total.
|
|
90
90
|
const total = query.payload.totalCount === true ? await countWhere(db, jobRunsTable, where) : undefined;
|
|
91
|
-
// payload/error are stored encrypted under the triggering user's DEK
|
|
91
|
+
// payload/error are stored encrypted under the triggering user's DEK.
|
|
92
92
|
return {
|
|
93
93
|
rows: await mapWithConcurrency(rows, KMS_POOL_CONCURRENCY, decryptRunRow),
|
|
94
94
|
nextCursor: hasMore ? encodeCursor(String(offset + limit)) : null,
|
|
@@ -4,7 +4,7 @@ import { rebuildProjectionOrMultiStream } from "@cosmicdrift/kumiko-framework/mi
|
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
export const projectionRebuildPayloadSchema = z.object({
|
|
6
6
|
projection: z.string().min(1),
|
|
7
|
-
// Quarantine mode
|
|
7
|
+
// Quarantine mode: skip + dead-letter poison events instead of
|
|
8
8
|
// failing the whole rebuild. Operator opt-in per run.
|
|
9
9
|
skipApplyErrors: z.boolean().optional(),
|
|
10
10
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Manual, perTenant backfill job
|
|
1
|
+
// Manual, perTenant backfill job — indexes existing rows for
|
|
2
2
|
// an entity that only got `searchable: true` after rows already existed.
|
|
3
3
|
// perTenant fan-out (job-runner.ts) also applies to a manual dispatch, not
|
|
4
4
|
// just cron: one `jobs:write:trigger` call with { entity } re-runs once per
|
|
@@ -35,7 +35,7 @@ export const retryWrite = defineWriteHandler({
|
|
|
35
35
|
details: { status: run.status },
|
|
36
36
|
}));
|
|
37
37
|
}
|
|
38
|
-
// payload is stored encrypted under the triggering user's DEK
|
|
38
|
+
// payload is stored encrypted under the triggering user's DEK,
|
|
39
39
|
// same mechanism as detail.query.ts/list.query.ts — decrypt before
|
|
40
40
|
// parsing it as JSON. A key erased since the run finished decrypts to
|
|
41
41
|
// PII_ERASED_SENTINEL, which is not JSON; reject the retry rather than
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
-
export declare
|
|
2
|
+
export declare function createTenantFailuresQuery(readRoles: readonly string[]): import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"failures", z.ZodObject<{
|
|
3
3
|
jobName: z.ZodOptional<z.ZodString>;
|
|
4
4
|
subject: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
5
5
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
@@ -20,45 +20,49 @@ function parseSubject(stored) {
|
|
|
20
20
|
return null;
|
|
21
21
|
return Object.fromEntries(parsed.filter(isSubjectEntry));
|
|
22
22
|
}
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
23
|
+
export function createTenantFailuresQuery(readRoles) {
|
|
24
|
+
return defineQueryHandler({
|
|
25
|
+
name: "failures",
|
|
26
|
+
description: "Lists the calling tenant's own failed jobs — one record per job and subject, newest first, each carrying a translation key for the reason, never the provider's own error message; the optional subject filter matches exactly: all declared subjectFields with the same JSON types as the job payload; use it to tell a tenant that their asynchronous job failed instead of leaving the screen waiting.",
|
|
27
|
+
schema: z.object({
|
|
28
|
+
jobName: z.string().optional(),
|
|
29
|
+
subject: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
|
|
30
|
+
limit: z.number().int().min(1).max(200).optional(),
|
|
31
|
+
}),
|
|
32
|
+
// Every membership rank: a failure record carries a job name and a
|
|
33
|
+
// translation key, nothing a team member of the tenant may not see.
|
|
34
|
+
access: {
|
|
35
|
+
roles: [...new Set([...access.roles("User", "Editor", ...access.admin), ...readRoles])],
|
|
36
|
+
},
|
|
37
|
+
handler: async (query, ctx) => {
|
|
38
|
+
if (!ctx.systemDb) {
|
|
39
|
+
throw new InternalError({
|
|
40
|
+
message: "jobs:query:failures requires ctx.systemDb (feature must declare r.systemScope())",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// assertTenantMatch is a self-check on the caller and returns the same
|
|
44
|
+
// unfiltered system-mode db (tenant-db.ts) — the explicit tenantId below
|
|
45
|
+
// is the filter, assertRowsTenant the second net. There is no
|
|
46
|
+
// cross-tenant mode here: SystemAdmin reads runs via jobs:query:list.
|
|
47
|
+
const db = ctx.systemDb.assertTenantMatch(query.user.tenantId);
|
|
48
|
+
const where = { tenantId: [query.user.tenantId] };
|
|
49
|
+
if (query.payload.jobName)
|
|
50
|
+
where["jobName"] = query.payload.jobName;
|
|
51
|
+
if (query.payload.subject)
|
|
52
|
+
where["subject"] = serializeJobSubject(query.payload.subject);
|
|
53
|
+
const rows = await selectMany(db, tenantJobFailuresTable, where, {
|
|
54
|
+
orderBy: { col: "failedAt", direction: "desc" },
|
|
55
|
+
limit: query.payload.limit ?? DEFAULT_LIMIT,
|
|
38
56
|
});
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
orderBy: { col: "failedAt", direction: "desc" },
|
|
52
|
-
limit: query.payload.limit ?? DEFAULT_LIMIT,
|
|
53
|
-
});
|
|
54
|
-
return {
|
|
55
|
-
rows: ctx.systemDb.assertRowsTenant(rows, "tenantId").map((row) => ({
|
|
56
|
-
jobName: row.jobName,
|
|
57
|
-
subject: parseSubject(row.subject),
|
|
58
|
-
messageKey: row.messageKey,
|
|
59
|
-
failedAt: row.failedAt,
|
|
60
|
-
})),
|
|
61
|
-
nextCursor: null,
|
|
62
|
-
};
|
|
63
|
-
},
|
|
64
|
-
});
|
|
57
|
+
return {
|
|
58
|
+
rows: ctx.systemDb.assertRowsTenant(rows, "tenantId").map((row) => ({
|
|
59
|
+
jobName: row.jobName,
|
|
60
|
+
subject: parseSubject(row.subject),
|
|
61
|
+
messageKey: row.messageKey,
|
|
62
|
+
failedAt: row.failedAt,
|
|
63
|
+
})),
|
|
64
|
+
nextCursor: null,
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
2
|
import { type TenantJobRunStatus } from "../tenant-job-run-table.ts";
|
|
3
|
-
export declare
|
|
3
|
+
export declare function createTenantRunsQuery(readRoles: readonly string[]): import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"tenant-runs", z.ZodObject<{
|
|
4
4
|
jobName: z.ZodOptional<z.ZodString>;
|
|
5
5
|
subject: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
6
6
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
@@ -19,54 +19,58 @@ function parseSubject(stored) {
|
|
|
19
19
|
return null;
|
|
20
20
|
return Object.fromEntries(parsed.filter(isSubjectEntry));
|
|
21
21
|
}
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
22
|
+
export function createTenantRunsQuery(readRoles) {
|
|
23
|
+
return defineQueryHandler({
|
|
24
|
+
name: "tenant-runs",
|
|
25
|
+
description: "Lists the calling tenant's own job runs that opted in via tenantVisibleRun — per job and subject every queued or running run plus the latest completed or failed one, active runs first, then newest first; each row carries only status and queuedAt/startedAt/finishedAt, never payloads, error text or logs; the optional subject filter matches exactly: all declared subjectFields with the same JSON types as the job payload; use it to show whether work for a subject is waiting, running or done, and to tell a failed run from a finished one.",
|
|
26
|
+
schema: z.object({
|
|
27
|
+
jobName: z.string().optional(),
|
|
28
|
+
subject: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
|
|
29
|
+
limit: z.number().int().min(1).max(200).optional(),
|
|
30
|
+
}),
|
|
31
|
+
// Every membership rank: a run state carries a job name, a status and
|
|
32
|
+
// times, nothing a team member of the tenant may not see.
|
|
33
|
+
access: {
|
|
34
|
+
roles: [...new Set([...access.roles("User", "Editor", ...access.admin), ...readRoles])],
|
|
35
|
+
},
|
|
36
|
+
handler: async (query, ctx) => {
|
|
37
|
+
if (!ctx.systemDb) {
|
|
38
|
+
throw new InternalError({
|
|
39
|
+
message: "jobs:query:tenant-runs requires ctx.systemDb (feature must declare r.systemScope())",
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// assertTenantMatch returns the same unfiltered system-mode db — the
|
|
43
|
+
// explicit tenantId below is the filter, assertRowsTenant the second net.
|
|
44
|
+
const db = ctx.systemDb.assertTenantMatch(query.user.tenantId);
|
|
45
|
+
const where = { tenantId: [query.user.tenantId] };
|
|
46
|
+
if (query.payload.jobName)
|
|
47
|
+
where["jobName"] = query.payload.jobName;
|
|
48
|
+
if (query.payload.subject)
|
|
49
|
+
where["subject"] = serializeJobSubject(query.payload.subject);
|
|
50
|
+
const limit = query.payload.limit ?? DEFAULT_LIMIT;
|
|
51
|
+
const newestFirst = { col: "updatedAt", direction: "desc" };
|
|
52
|
+
const activeRows = await selectMany(db, tenantJobRunsTable, { ...where, status: { in: ["queued", "running"] } }, { orderBy: newestFirst, limit });
|
|
53
|
+
const finishedRows = await selectMany(db, tenantJobRunsTable, { ...where, status: { in: ["completed", "failed"] } }, { orderBy: newestFirst, limit });
|
|
54
|
+
const seenFinishedKeys = new Set();
|
|
55
|
+
const finishedNewestPerKey = finishedRows.filter((row) => {
|
|
56
|
+
const key = JSON.stringify([row.jobName, row.subject]);
|
|
57
|
+
if (seenFinishedKeys.has(key))
|
|
58
|
+
return false;
|
|
59
|
+
seenFinishedKeys.add(key);
|
|
60
|
+
return true;
|
|
37
61
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const key = JSON.stringify([row.jobName, row.subject]);
|
|
54
|
-
if (seenFinishedKeys.has(key))
|
|
55
|
-
return false;
|
|
56
|
-
seenFinishedKeys.add(key);
|
|
57
|
-
return true;
|
|
58
|
-
});
|
|
59
|
-
const activeFirst = [...activeRows, ...finishedNewestPerKey];
|
|
60
|
-
return {
|
|
61
|
-
rows: ctx.systemDb.assertRowsTenant(activeFirst.slice(0, limit), "tenantId").map((row) => ({
|
|
62
|
-
jobName: row.jobName,
|
|
63
|
-
subject: parseSubject(row.subject),
|
|
64
|
-
status: row.status,
|
|
65
|
-
queuedAt: row.queuedAt,
|
|
66
|
-
startedAt: row.startedAt,
|
|
67
|
-
finishedAt: row.finishedAt,
|
|
68
|
-
})),
|
|
69
|
-
nextCursor: null,
|
|
70
|
-
};
|
|
71
|
-
},
|
|
72
|
-
});
|
|
62
|
+
const activeFirst = [...activeRows, ...finishedNewestPerKey];
|
|
63
|
+
return {
|
|
64
|
+
rows: ctx.systemDb.assertRowsTenant(activeFirst.slice(0, limit), "tenantId").map((row) => ({
|
|
65
|
+
jobName: row.jobName,
|
|
66
|
+
subject: parseSubject(row.subject),
|
|
67
|
+
status: row.status,
|
|
68
|
+
queuedAt: row.queuedAt,
|
|
69
|
+
startedAt: row.startedAt,
|
|
70
|
+
finishedAt: row.finishedAt,
|
|
71
|
+
})),
|
|
72
|
+
nextCursor: null,
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
package/dist/jobs/job-instant.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
2
|
-
//
|
|
2
|
+
// The five value-position Temporal.Instant.from
|
|
3
3
|
// call sites in feature.ts live inside defineApply callbacks with no
|
|
4
4
|
// exported seam, so this thin wrapper gives the ambient-global-independence
|
|
5
5
|
// regression test something to import directly.
|