@flowdular/sdk 0.2.3 → 0.3.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/.ai/agents/sandbox/business-manager.md +5 -1
- package/.ai/blueprints/author-spec/README.md +1 -1
- package/.ai/blueprints/author-spec/spec-requirements.yaml +44 -0
- package/.ai/blueprints/author-spec/steps.yaml +5 -5
- package/.ai/blueprints/author-spec/templates/module.yaml +99 -3
- package/.ai/blueprints/edit-module/gates.yaml +4 -0
- package/.ai/blueprints/edit-module/required-files.yaml +9 -0
- package/.ai/blueprints/new-module/gates.yaml +4 -0
- package/.ai/blueprints/new-module/spec-requirements.yaml +2 -2
- package/.ai/blueprints/release/gates.yaml +4 -0
- package/.ai/platform-capabilities.md +128 -0
- package/.ai/policies/capabilities.yaml +100 -0
- package/.ai/policies/path-ownership.yaml +5 -2
- package/.ai/policies/task-budgets.yaml +5 -3
- package/.ai/references/catalog/module.json +4 -4
- package/.ai/references/catalog/package.json +2 -2
- package/.ai/references/catalog/spec/module.yaml +5 -3
- package/.ai/references/catalog/src/platform.ts +2 -0
- package/.ai/references/catalog/src/services/catalog-service.ts +89 -1
- package/.ai/references/catalog/src/services/data-classes.ts +47 -0
- package/.ai/references/catalog/src/services/database-repository.ts +98 -1
- package/.ai/references/catalog/src/services/repository.ts +22 -1
- package/.ai/references/catalog/tests/data-classes.test.ts +157 -0
- package/.ai/references/catalog.provenance.json +12 -10
- package/.ai/skills/README.md +10 -0
- package/.ai/skills/agent-tool-design/SKILL.md +1 -2
- package/.ai/skills/auth-security-review/SKILL.md +1 -1
- package/.ai/skills/business-agent-design/SKILL.md +0 -1
- package/.ai/skills/deploy-operate/SKILL.md +114 -0
- package/.ai/skills/module-new/SKILL.md +29 -3
- package/.ai/skills/module-update/SKILL.md +9 -3
- package/.ai/skills/perf-audit/SKILL.md +0 -1
- package/.ai/skills/release-eject-pr/SKILL.md +0 -1
- package/.ai/skills/spec-interview/SKILL.md +120 -0
- package/.ai/skills/test-hardening/SKILL.md +1 -0
- package/.ai/skills/ux-design/SKILL.md +34 -3
- package/.ai/skills/variables/SKILL.md +0 -2
- package/.ai/skills/workflow-development/SKILL.md +0 -1
- package/AGENTS.md +4 -0
- package/docs/agent-contract.md +2 -2
- package/docs/design-system.md +185 -31
- package/modules/access/migrations/0001_access_core.down.sql +1 -0
- package/modules/access/migrations/0001_access_core.up.sql +28 -0
- package/modules/access/migrations/README.md +3 -0
- package/modules/access/module.json +33 -0
- package/modules/access/package.json +43 -0
- package/modules/access/spec/module.yaml +225 -0
- package/modules/access/src/acl/permissions.ts +6 -0
- package/modules/access/src/api/endpoints.ts +244 -0
- package/modules/access/src/client/ActivityView.tsrx +245 -0
- package/modules/access/src/client/AttestationsView.tsrx +176 -0
- package/modules/access/src/client/ReviewView.tsrx +586 -0
- package/modules/access/src/client/api.ts +132 -0
- package/modules/access/src/client/contribution.tsrx +41 -0
- package/modules/access/src/client/index.ts +41 -0
- package/modules/access/src/client/navigation.ts +57 -0
- package/modules/access/src/client/presentation.ts +69 -0
- package/modules/access/src/client/state.ts +72 -0
- package/modules/access/src/domain/types.ts +189 -0
- package/modules/access/src/index.ts +38 -0
- package/modules/access/src/platform.ts +60 -0
- package/modules/access/src/server/index.ts +42 -0
- package/modules/access/src/server/runtime.ts +105 -0
- package/modules/access/src/services/access-service.ts +298 -0
- package/modules/access/src/services/audit-window.ts +78 -0
- package/modules/access/src/services/auth-directory.ts +72 -0
- package/modules/access/src/services/changes.ts +91 -0
- package/modules/access/src/services/data-classes.ts +28 -0
- package/modules/access/src/services/database-repository.ts +185 -0
- package/modules/access/src/services/directory.ts +102 -0
- package/modules/access/src/services/index.ts +33 -0
- package/modules/access/src/services/list-exports.ts +150 -0
- package/modules/access/src/services/migration.ts +54 -0
- package/modules/access/src/services/repository.ts +30 -0
- package/modules/access/src/services/review.ts +178 -0
- package/modules/access/translations/en.json +155 -0
- package/modules/access/translations/pl.json +155 -0
- package/modules/agents/migrations/0022_credential_rotation_inventory.down.sql +2 -0
- package/modules/agents/migrations/0022_credential_rotation_inventory.up.sql +7 -0
- package/modules/agents/migrations/0023_agents_retention_indexes.down.sql +2 -0
- package/modules/agents/migrations/0023_agents_retention_indexes.up.sql +9 -0
- package/modules/agents/migrations/0024_agent_meter_refusals.down.sql +3 -0
- package/modules/agents/migrations/0024_agent_meter_refusals.up.sql +22 -0
- package/modules/agents/migrations/0025_agent_list_indexes.down.sql +3 -0
- package/modules/agents/migrations/0025_agent_list_indexes.up.sql +11 -0
- package/modules/agents/module.json +30 -4
- package/modules/agents/package.json +3 -2
- package/modules/agents/spec/module.yaml +63 -5
- package/modules/agents/src/api/endpoints.ts +291 -33
- package/modules/agents/src/cli/commands.json +11 -0
- package/modules/agents/src/cli/index.ts +45 -0
- package/modules/agents/src/client/AgentDashboardWidget.tsrx +19 -11
- package/modules/agents/src/client/AgentDefinitionList.tsrx +53 -10
- package/modules/agents/src/client/AgentPlaygroundView.tsrx +4 -4
- package/modules/agents/src/client/AgentProceduresView.tsrx +2 -2
- package/modules/agents/src/client/AgentRunsView.tsrx +143 -40
- package/modules/agents/src/client/AgentsView.tsrx +109 -33
- package/modules/agents/src/client/api.ts +99 -21
- package/modules/agents/src/client/state.ts +97 -0
- package/modules/agents/src/domain/types.ts +44 -4
- package/modules/agents/src/platform.ts +42 -0
- package/modules/agents/src/server/action-execution.ts +201 -106
- package/modules/agents/src/server/runtime.ts +32 -0
- package/modules/agents/src/services/agent-service.ts +158 -30
- package/modules/agents/src/services/credential-rotation.ts +185 -0
- package/modules/agents/src/services/credential-vault.ts +71 -46
- package/modules/agents/src/services/data-classes.ts +176 -0
- package/modules/agents/src/services/database-repository.ts +393 -101
- package/modules/agents/src/services/metering.ts +111 -0
- package/modules/agents/src/services/migration.ts +109 -0
- package/modules/agents/src/services/module-agent-preflight.ts +17 -9
- package/modules/agents/src/services/notifications.ts +98 -0
- package/modules/agents/src/services/provider-repository.ts +9 -18
- package/modules/agents/src/services/provider-service.ts +1 -9
- package/modules/agents/src/services/reports.ts +107 -0
- package/modules/agents/src/services/repository.ts +86 -6
- package/modules/agents/src/services/usage-service.ts +2 -0
- package/modules/agents/src/services/worker.ts +114 -4
- package/modules/agents/src/settings.ts +14 -3
- package/modules/agents/translations/en.json +14 -4
- package/modules/agents/translations/pl.json +14 -4
- package/modules/approvals/migrations/0001_approvals_core.down.sql +3 -0
- package/modules/approvals/migrations/0001_approvals_core.up.sql +78 -0
- package/modules/approvals/migrations/0002_approvals_expiry_routing_role.down.sql +2 -0
- package/modules/approvals/migrations/0002_approvals_expiry_routing_role.up.sql +19 -0
- package/modules/approvals/migrations/0003_approvals_retention_indexes.down.sql +6 -0
- package/modules/approvals/migrations/0003_approvals_retention_indexes.up.sql +14 -0
- package/modules/approvals/migrations/0004_approvals_inbox_keyset_indexes.down.sql +5 -0
- package/modules/approvals/migrations/0004_approvals_inbox_keyset_indexes.up.sql +12 -0
- package/modules/approvals/migrations/README.md +3 -0
- package/modules/approvals/module.json +34 -0
- package/modules/approvals/package.json +43 -0
- package/modules/approvals/spec/module.yaml +318 -0
- package/modules/approvals/src/acl/permissions.ts +7 -0
- package/modules/approvals/src/api/endpoints.ts +457 -0
- package/modules/approvals/src/client/ApprovalRequestDrawer.tsrx +138 -0
- package/modules/approvals/src/client/ApprovalsView.tsrx +562 -0
- package/modules/approvals/src/client/PendingCountWidget.tsrx +52 -0
- package/modules/approvals/src/client/api.ts +203 -0
- package/modules/approvals/src/client/approvals.css +51 -0
- package/modules/approvals/src/client/contribution.tsrx +44 -0
- package/modules/approvals/src/client/index.ts +26 -0
- package/modules/approvals/src/client/navigation.ts +39 -0
- package/modules/approvals/src/client/pending-count.ts +26 -0
- package/modules/approvals/src/client/presentation.ts +52 -0
- package/modules/approvals/src/client/state.ts +141 -0
- package/modules/approvals/src/domain/capability.ts +95 -0
- package/modules/approvals/src/domain/types.ts +154 -0
- package/modules/approvals/src/index.ts +52 -0
- package/modules/approvals/src/platform.ts +128 -0
- package/modules/approvals/src/server/index.ts +42 -0
- package/modules/approvals/src/server/runtime.ts +181 -0
- package/modules/approvals/src/services/approvals-service.ts +557 -0
- package/modules/approvals/src/services/callbacks.ts +75 -0
- package/modules/approvals/src/services/data-classes.ts +167 -0
- package/modules/approvals/src/services/database-repository.ts +724 -0
- package/modules/approvals/src/services/eligibility.ts +121 -0
- package/modules/approvals/src/services/expiry-runner.ts +81 -0
- package/modules/approvals/src/services/index.ts +31 -0
- package/modules/approvals/src/services/migration.ts +222 -0
- package/modules/approvals/src/services/notifications.ts +95 -0
- package/modules/approvals/src/services/repository.ts +161 -0
- package/modules/approvals/src/services/service-error.ts +70 -0
- package/modules/approvals/src/settings.ts +102 -0
- package/modules/approvals/translations/en.json +104 -0
- package/modules/approvals/translations/pl.json +104 -0
- package/modules/audit/migrations/0001_audit_core.down.sql +8 -0
- package/modules/audit/migrations/0001_audit_core.up.sql +107 -0
- package/modules/audit/migrations/0002_audit_sweep_routing_role.down.sql +2 -0
- package/modules/audit/migrations/0002_audit_sweep_routing_role.up.sql +21 -0
- package/modules/audit/migrations/0003_audit_export_request.down.sql +12 -0
- package/modules/audit/migrations/0003_audit_export_request.up.sql +40 -0
- package/modules/audit/migrations/0004_audit_hold_seal_erasure.down.sql +17 -0
- package/modules/audit/migrations/0004_audit_hold_seal_erasure.up.sql +192 -0
- package/modules/audit/migrations/0005_audit_event_format.down.sql +17 -0
- package/modules/audit/migrations/0005_audit_event_format.up.sql +60 -0
- package/modules/audit/migrations/0006_audit_own_class_walks.down.sql +3 -0
- package/modules/audit/migrations/0006_audit_own_class_walks.up.sql +14 -0
- package/modules/audit/migrations/README.md +3 -0
- package/modules/audit/module.json +32 -0
- package/modules/audit/package.json +49 -0
- package/modules/audit/spec/module.yaml +809 -0
- package/modules/audit/src/acl/permissions.ts +7 -0
- package/modules/audit/src/api/endpoints.ts +315 -0
- package/modules/audit/src/cli/commands.json +95 -0
- package/modules/audit/src/cli/index.ts +658 -0
- package/modules/audit/src/client/DataClassesView.tsrx +420 -0
- package/modules/audit/src/client/ExportsView.tsrx +256 -0
- package/modules/audit/src/client/HoldsView.tsrx +604 -0
- package/modules/audit/src/client/SweepsView.tsrx +251 -0
- package/modules/audit/src/client/api.ts +185 -0
- package/modules/audit/src/client/contribution.tsrx +52 -0
- package/modules/audit/src/client/index.ts +23 -0
- package/modules/audit/src/client/navigation.ts +74 -0
- package/modules/audit/src/client/presentation.ts +105 -0
- package/modules/audit/src/client/state.ts +86 -0
- package/modules/audit/src/domain/data-classes.ts +16 -0
- package/modules/audit/src/domain/types.ts +339 -0
- package/modules/audit/src/index.ts +76 -0
- package/modules/audit/src/platform.ts +44 -0
- package/modules/audit/src/server/index.ts +177 -0
- package/modules/audit/src/server/runtime.ts +303 -0
- package/modules/audit/src/services/anchor-key.ts +143 -0
- package/modules/audit/src/services/anchor-rotation.ts +147 -0
- package/modules/audit/src/services/audit-runners.ts +278 -0
- package/modules/audit/src/services/backup-guard.ts +95 -0
- package/modules/audit/src/services/database-repository.ts +1946 -0
- package/modules/audit/src/services/declared-classes.ts +64 -0
- package/modules/audit/src/services/erasure-port.ts +126 -0
- package/modules/audit/src/services/erasure-service.ts +770 -0
- package/modules/audit/src/services/export-directory.ts +106 -0
- package/modules/audit/src/services/export-service.ts +714 -0
- package/modules/audit/src/services/hold-service.ts +295 -0
- package/modules/audit/src/services/index.ts +17 -0
- package/modules/audit/src/services/migration.ts +658 -0
- package/modules/audit/src/services/own-classes.ts +318 -0
- package/modules/audit/src/services/platform-version.ts +23 -0
- package/modules/audit/src/services/repository.ts +495 -0
- package/modules/audit/src/services/retention-service.ts +191 -0
- package/modules/audit/src/services/seal-service.ts +769 -0
- package/modules/audit/src/services/service-error.ts +61 -0
- package/modules/audit/src/services/subject-keys.ts +90 -0
- package/modules/audit/src/services/sweep-service.ts +298 -0
- package/modules/audit/src/services/zip.ts +217 -0
- package/modules/audit/src/settings.ts +69 -0
- package/modules/audit/translations/en.json +210 -0
- package/modules/audit/translations/pl.json +210 -0
- package/modules/auth/README.md +77 -29
- package/modules/auth/migrations/0016_external_identities.up.sql +16 -0
- package/modules/auth/migrations/0017_mfa_key_id.up.sql +8 -0
- package/modules/auth/migrations/0018_retire_bundled_module_scopes.up.sql +29 -0
- package/modules/auth/migrations/0019_notifications_member_scopes.up.sql +44 -0
- package/modules/auth/migrations/0020_identity_providers.up.sql +61 -0
- package/modules/auth/migrations/0021_membership_status.up.sql +19 -0
- package/modules/auth/migrations/0022_auth_provider_scopes.up.sql +45 -0
- package/modules/auth/migrations/0023_enterprise_module_scopes.down.sql +19 -0
- package/modules/auth/migrations/0023_enterprise_module_scopes.up.sql +71 -0
- package/modules/auth/migrations/0024_approvals_member_scopes.down.sql +22 -0
- package/modules/auth/migrations/0024_approvals_member_scopes.up.sql +48 -0
- package/modules/auth/migrations/0025_audit_holds_owner_scope.down.sql +21 -0
- package/modules/auth/migrations/0025_audit_holds_owner_scope.up.sql +47 -0
- package/modules/auth/migrations/0026_auth_export_keyset_indexes.down.sql +6 -0
- package/modules/auth/migrations/0026_auth_export_keyset_indexes.up.sql +15 -0
- package/modules/auth/migrations/0027_workflow_automation_profile_scopes.down.sql +34 -0
- package/modules/auth/migrations/0027_workflow_automation_profile_scopes.up.sql +72 -0
- package/modules/auth/migrations/0028_auth_member_search_prefix_indexes.down.sql +6 -0
- package/modules/auth/migrations/0028_auth_member_search_prefix_indexes.up.sql +21 -0
- package/modules/auth/migrations/0029_reports_exports_access_scopes.down.sql +22 -0
- package/modules/auth/migrations/0029_reports_exports_access_scopes.up.sql +56 -0
- package/modules/auth/migrations/0030_auth_membership_keyset_index.down.sql +4 -0
- package/modules/auth/migrations/0030_auth_membership_keyset_index.up.sql +10 -0
- package/modules/auth/migrations/0031_membership_scope_backfills_under_rls.down.sql +4 -0
- package/modules/auth/migrations/0031_membership_scope_backfills_under_rls.up.sql +31 -0
- package/modules/auth/migrations/0032_audit_actor_service.down.sql +9 -0
- package/modules/auth/migrations/0032_audit_actor_service.up.sql +10 -0
- package/modules/auth/migrations/0033_auth_account_keyset_indexes.down.sql +5 -0
- package/modules/auth/migrations/0033_auth_account_keyset_indexes.up.sql +23 -0
- package/modules/auth/module.json +3 -3
- package/modules/auth/package.json +3 -2
- package/modules/auth/spec/module.yaml +372 -3
- package/modules/auth/src/acl/scopes.ts +50 -6
- package/modules/auth/src/cli/commands.json +11 -0
- package/modules/auth/src/cli/greenfield.ts +2 -2
- package/modules/auth/src/cli/index.ts +14 -0
- package/modules/auth/src/cli/secrets.ts +114 -0
- package/modules/auth/src/client/AuthenticationCore.tsrx +61 -8
- package/modules/auth/src/client/api.ts +72 -6
- package/modules/auth/src/client/contribution.tsrx +23 -0
- package/modules/auth/src/client/index.ts +6 -0
- package/modules/auth/src/client/providers/IdentityProviderForm.tsrx +191 -0
- package/modules/auth/src/client/providers/IdentityProvidersView.tsrx +358 -0
- package/modules/auth/src/client/providers/api.ts +128 -0
- package/modules/auth/src/client/providers/provider-columns.tsrx +60 -0
- package/modules/auth/src/client/providers/state.ts +35 -0
- package/modules/auth/src/client/security/SecurityView.tsrx +9 -1
- package/modules/auth/src/client/state.ts +15 -1
- package/modules/auth/src/domain/types.ts +55 -0
- package/modules/auth/src/index.ts +11 -1
- package/modules/auth/src/middleware/authentication.ts +4 -0
- package/modules/auth/src/server/endpoints.ts +467 -171
- package/modules/auth/src/server/http.ts +3 -2
- package/modules/auth/src/server/index.ts +22 -1
- package/modules/auth/src/server/membership-endpoints.ts +62 -0
- package/modules/auth/src/server/mfa-enforcement.ts +156 -0
- package/modules/auth/src/server/oidc.ts +389 -0
- package/modules/auth/src/server/provider-endpoints.ts +246 -0
- package/modules/auth/src/server/provider-host.ts +77 -0
- package/modules/auth/src/server/runtime.ts +231 -55
- package/modules/auth/src/services/auth-service-error.ts +7 -2
- package/modules/auth/src/services/auth-service.ts +948 -51
- package/modules/auth/src/services/data-classes.ts +236 -0
- package/modules/auth/src/services/database-repository.ts +853 -71
- package/modules/auth/src/services/identity-provider-service.ts +571 -0
- package/modules/auth/src/services/mail-delivery.ts +16 -16
- package/modules/auth/src/services/mail-message.ts +54 -0
- package/modules/auth/src/services/mail-port.ts +24 -0
- package/modules/auth/src/services/mail-smtp.ts +85 -0
- package/modules/auth/src/services/mfa-rotation.ts +144 -0
- package/modules/auth/src/services/migration.ts +810 -0
- package/modules/auth/src/services/password.ts +14 -0
- package/modules/auth/src/services/provider-secret-rotation.ts +169 -0
- package/modules/auth/src/services/provider-secrets.ts +136 -0
- package/modules/auth/src/services/repository.ts +321 -5
- package/modules/auth/src/services/session-sweep-runner.ts +73 -0
- package/modules/auth/src/services/settings-store.ts +10 -83
- package/modules/auth/src/services/totp.ts +88 -62
- package/modules/auth/src/services/validation.ts +194 -7
- package/modules/auth/src/settings.ts +18 -0
- package/modules/auth/translations/en.json +84 -1
- package/modules/auth/translations/pl.json +84 -1
- package/modules/automations/migrations/0005_secret_rotation_inventory.down.sql +1 -0
- package/modules/automations/migrations/0005_secret_rotation_inventory.up.sql +6 -0
- package/modules/automations/migrations/0006_automations_list_sort_indexes.down.sql +4 -0
- package/modules/automations/migrations/0006_automations_list_sort_indexes.up.sql +11 -0
- package/modules/automations/module.json +24 -6
- package/modules/automations/package.json +5 -2
- package/modules/automations/spec/module.yaml +81 -7
- package/modules/automations/src/api/endpoints.ts +202 -28
- package/modules/automations/src/cli/commands.json +17 -0
- package/modules/automations/src/cli/index.ts +114 -0
- package/modules/automations/src/client/AutomationScheduleForm.tsrx +77 -19
- package/modules/automations/src/client/AutomationSchedulesView.tsrx +144 -40
- package/modules/automations/src/client/AutomationTriggersView.tsrx +131 -32
- package/modules/automations/src/client/api.ts +62 -19
- package/modules/automations/src/client/presentation.ts +20 -2
- package/modules/automations/src/client/state.ts +84 -0
- package/modules/automations/src/domain/cadence.ts +99 -3
- package/modules/automations/src/domain/cron.ts +366 -0
- package/modules/automations/src/domain/time-zone.ts +61 -0
- package/modules/automations/src/platform.ts +38 -4
- package/modules/automations/src/server/index.ts +11 -0
- package/modules/automations/src/server/runtime.ts +46 -22
- package/modules/{automations-workflows-integration/src/server/adapter.ts → automations/src/server/workflow-target.ts} +13 -14
- package/modules/{automations-workflows-integration/src/server/tools.ts → automations/src/server/workflow-tools.ts} +0 -0
- package/modules/automations/src/services/data-classes.ts +62 -0
- package/modules/automations/src/services/database-repository.ts +152 -38
- package/modules/automations/src/services/migration.ts +119 -9
- package/modules/automations/src/services/repository.ts +52 -1
- package/modules/automations/src/services/schedule-runner.ts +84 -0
- package/modules/automations/src/services/schedule-service.ts +152 -26
- package/modules/automations/src/services/secret-rotation.ts +176 -0
- package/modules/automations/src/services/secret-vault.ts +68 -41
- package/modules/automations/src/services/trigger-service.ts +13 -10
- package/modules/automations/translations/en.json +15 -2
- package/modules/automations/translations/pl.json +15 -2
- package/modules/connectors/migrations/0001_connectors_core.down.sql +3 -0
- package/modules/connectors/migrations/0001_connectors_core.up.sql +72 -0
- package/modules/connectors/migrations/0002_connectors_call_keys.down.sql +3 -0
- package/modules/connectors/migrations/0002_connectors_call_keys.up.sql +18 -0
- package/modules/connectors/migrations/README.md +3 -0
- package/modules/connectors/module.json +28 -0
- package/modules/{automations-workflows-integration → connectors}/package.json +27 -26
- package/modules/connectors/spec/module.yaml +447 -0
- package/modules/connectors/src/acl/permissions.ts +6 -0
- package/modules/connectors/src/agent/tools.ts +180 -0
- package/modules/connectors/src/api/endpoints.ts +572 -0
- package/modules/connectors/src/client/ConnectorCallsView.tsrx +358 -0
- package/modules/connectors/src/client/ConnectorForm.tsrx +424 -0
- package/modules/connectors/src/client/ConnectorsView.tsrx +711 -0
- package/modules/connectors/src/client/api.ts +281 -0
- package/modules/connectors/src/client/consent.ts +48 -0
- package/modules/connectors/src/client/contribution.tsrx +37 -0
- package/modules/connectors/src/client/index.ts +22 -0
- package/modules/connectors/src/client/navigation.ts +42 -0
- package/modules/connectors/src/client/presentation.ts +38 -0
- package/modules/connectors/src/client/state.ts +175 -0
- package/modules/connectors/src/domain/calls.ts +70 -0
- package/modules/connectors/src/domain/definitions.ts +190 -0
- package/modules/connectors/src/domain/http-json.ts +68 -0
- package/modules/connectors/src/domain/types.ts +185 -0
- package/modules/connectors/src/index.ts +64 -0
- package/modules/connectors/src/platform.ts +56 -0
- package/modules/connectors/src/server/index.ts +66 -0
- package/modules/connectors/src/server/runtime.ts +163 -0
- package/modules/connectors/src/services/call-service.ts +903 -0
- package/modules/connectors/src/services/connectors-service.ts +653 -0
- package/modules/connectors/src/services/credential-vault.ts +188 -0
- package/modules/connectors/src/services/data-classes.ts +158 -0
- package/modules/connectors/src/services/database-repository.ts +897 -0
- package/modules/connectors/src/services/egress.ts +261 -0
- package/modules/connectors/src/services/index.ts +19 -0
- package/modules/connectors/src/services/migration.ts +166 -0
- package/modules/connectors/src/services/repository.ts +175 -0
- package/modules/connectors/src/services/service-error.ts +46 -0
- package/modules/connectors/src/settings.ts +69 -0
- package/modules/connectors/translations/en.json +191 -0
- package/modules/connectors/translations/pl.json +191 -0
- package/modules/directory/migrations/0001_directory_core.down.sql +5 -0
- package/modules/directory/migrations/0001_directory_core.up.sql +111 -0
- package/modules/directory/migrations/README.md +3 -0
- package/modules/directory/module.json +27 -0
- package/modules/directory/package.json +46 -0
- package/modules/directory/spec/module.yaml +351 -0
- package/modules/directory/src/acl/permissions.ts +7 -0
- package/modules/directory/src/api/endpoints.ts +478 -0
- package/modules/directory/src/api/scim-endpoints.ts +516 -0
- package/modules/directory/src/client/GroupMappingsView.tsrx +430 -0
- package/modules/directory/src/client/ProvisioningLogView.tsrx +248 -0
- package/modules/directory/src/client/ScimTokensView.tsrx +587 -0
- package/modules/directory/src/client/api.ts +222 -0
- package/modules/directory/src/client/contribution.tsrx +46 -0
- package/modules/directory/src/client/index.ts +22 -0
- package/modules/directory/src/client/navigation.ts +57 -0
- package/modules/directory/src/client/presentation.ts +143 -0
- package/modules/directory/src/client/state.ts +173 -0
- package/modules/directory/src/domain/scim.ts +346 -0
- package/modules/directory/src/domain/types.ts +166 -0
- package/modules/directory/src/index.ts +44 -0
- package/modules/directory/src/platform.ts +43 -0
- package/modules/directory/src/server/index.ts +17 -0
- package/modules/directory/src/server/runtime.ts +124 -0
- package/modules/directory/src/services/auth-port.ts +127 -0
- package/modules/directory/src/services/data-classes.ts +41 -0
- package/modules/directory/src/services/database-repository.ts +1067 -0
- package/modules/directory/src/services/directory-service.ts +311 -0
- package/modules/directory/src/services/index.ts +43 -0
- package/modules/directory/src/services/migration.ts +146 -0
- package/modules/directory/src/services/provisioning-service.ts +1420 -0
- package/modules/directory/src/services/rate-limiter.ts +103 -0
- package/modules/directory/src/services/repository.ts +208 -0
- package/modules/directory/src/services/service-error.ts +42 -0
- package/modules/directory/src/services/token-service.ts +215 -0
- package/modules/directory/src/settings.ts +86 -0
- package/modules/directory/translations/en.json +185 -0
- package/modules/directory/translations/pl.json +185 -0
- package/modules/documents/migrations/0001_documents_core.down.sql +1 -0
- package/modules/documents/migrations/0001_documents_core.up.sql +35 -0
- package/modules/documents/migrations/0002_documents_files_page.down.sql +1 -0
- package/modules/documents/migrations/0002_documents_files_page.up.sql +6 -0
- package/modules/documents/migrations/README.md +3 -0
- package/modules/documents/module.json +28 -0
- package/modules/documents/package.json +49 -0
- package/modules/documents/spec/module.yaml +247 -0
- package/modules/documents/src/acl/permissions.ts +6 -0
- package/modules/documents/src/api/endpoints.ts +401 -0
- package/modules/documents/src/client/DocumentUploader.tsrx +148 -0
- package/modules/documents/src/client/DocumentsView.tsrx +540 -0
- package/modules/documents/src/client/api.ts +209 -0
- package/modules/documents/src/client/contribution.tsrx +29 -0
- package/modules/documents/src/client/download.ts +70 -0
- package/modules/documents/src/client/index.ts +22 -0
- package/modules/documents/src/client/navigation.ts +25 -0
- package/modules/documents/src/client/presentation.ts +110 -0
- package/modules/documents/src/client/state.ts +117 -0
- package/modules/documents/src/domain/attachments.ts +84 -0
- package/modules/documents/src/domain/types.ts +80 -0
- package/modules/documents/src/index.ts +46 -0
- package/modules/documents/src/platform.ts +61 -0
- package/modules/documents/src/server/index.ts +30 -0
- package/modules/documents/src/server/runtime.ts +107 -0
- package/modules/documents/src/services/attachments.ts +39 -0
- package/modules/documents/src/services/data-classes.ts +25 -0
- package/modules/documents/src/services/database-repository.ts +259 -0
- package/modules/documents/src/services/documents-service.ts +586 -0
- package/modules/documents/src/services/index.ts +18 -0
- package/modules/documents/src/services/migration.ts +82 -0
- package/modules/documents/src/services/repository.ts +48 -0
- package/modules/documents/src/settings.ts +107 -0
- package/modules/documents/translations/en.json +111 -0
- package/modules/documents/translations/pl.json +111 -0
- package/modules/exports/migrations/0001_exports_core.down.sql +2 -0
- package/modules/exports/migrations/0001_exports_core.up.sql +28 -0
- package/modules/exports/migrations/0002_exports_job_routing_role.down.sql +4 -0
- package/modules/exports/migrations/0002_exports_job_routing_role.up.sql +21 -0
- package/modules/exports/migrations/README.md +3 -0
- package/modules/exports/module.json +28 -0
- package/modules/exports/package.json +44 -0
- package/modules/exports/spec/module.yaml +229 -0
- package/modules/exports/src/acl/permissions.ts +6 -0
- package/modules/exports/src/api/endpoints.ts +211 -0
- package/modules/exports/src/client/ExportsView.tsrx +327 -0
- package/modules/exports/src/client/api.ts +133 -0
- package/modules/exports/src/client/contribution.tsrx +31 -0
- package/modules/exports/src/client/index.ts +20 -0
- package/modules/exports/src/client/navigation.ts +25 -0
- package/modules/exports/src/client/presentation.ts +53 -0
- package/modules/exports/src/client/state.ts +56 -0
- package/modules/exports/src/domain/lists.ts +29 -0
- package/modules/exports/src/domain/types.ts +120 -0
- package/modules/exports/src/index.ts +41 -0
- package/modules/exports/src/platform.ts +80 -0
- package/modules/exports/src/server/index.ts +51 -0
- package/modules/exports/src/server/runtime.ts +160 -0
- package/modules/exports/src/services/data-classes.ts +56 -0
- package/modules/exports/src/services/database-repository.ts +405 -0
- package/modules/exports/src/services/export-runner.ts +123 -0
- package/modules/exports/src/services/export-service.ts +356 -0
- package/modules/exports/src/services/index.ts +6 -0
- package/modules/exports/src/services/list-registry.ts +105 -0
- package/modules/exports/src/services/migration.ts +89 -0
- package/modules/exports/src/services/repository.ts +97 -0
- package/modules/exports/src/settings.ts +70 -0
- package/modules/exports/translations/en.json +69 -0
- package/modules/exports/translations/pl.json +69 -0
- package/modules/import/migrations/0001_import_core.down.sql +6 -0
- package/modules/import/migrations/0001_import_core.up.sql +61 -0
- package/modules/import/migrations/0002_import_job_routing_role.down.sql +4 -0
- package/modules/import/migrations/0002_import_job_routing_role.up.sql +20 -0
- package/modules/import/migrations/0003_import_jobs_export_index.down.sql +1 -0
- package/modules/import/migrations/0003_import_jobs_export_index.up.sql +7 -0
- package/modules/import/migrations/0004_import_jobs_traceparent.down.sql +1 -0
- package/modules/import/migrations/0004_import_jobs_traceparent.up.sql +7 -0
- package/modules/import/migrations/README.md +3 -0
- package/modules/import/module.json +37 -0
- package/modules/import/package.json +50 -0
- package/modules/import/spec/module.yaml +335 -0
- package/modules/import/src/acl/permissions.ts +6 -0
- package/modules/import/src/api/endpoints.ts +400 -0
- package/modules/import/src/client/ImportJobDrawer.tsrx +229 -0
- package/modules/import/src/client/ImportsView.tsrx +455 -0
- package/modules/import/src/client/NewImportForm.tsrx +274 -0
- package/modules/import/src/client/api.ts +243 -0
- package/modules/import/src/client/contribution.tsrx +29 -0
- package/modules/import/src/client/index.ts +23 -0
- package/modules/import/src/client/navigation.ts +25 -0
- package/modules/import/src/client/presentation.ts +59 -0
- package/modules/import/src/client/state.ts +43 -0
- package/modules/import/src/domain/csv.ts +258 -0
- package/modules/import/src/domain/ports.ts +157 -0
- package/modules/import/src/domain/types.ts +179 -0
- package/modules/import/src/index.ts +58 -0
- package/modules/import/src/platform.ts +60 -0
- package/modules/import/src/server/index.ts +49 -0
- package/modules/import/src/server/runtime.ts +158 -0
- package/modules/import/src/services/csv-source.ts +121 -0
- package/modules/import/src/services/data-classes.ts +63 -0
- package/modules/import/src/services/database-repository.ts +780 -0
- package/modules/import/src/services/import-runner.ts +127 -0
- package/modules/import/src/services/import-service.ts +872 -0
- package/modules/import/src/services/index.ts +6 -0
- package/modules/import/src/services/migration.ts +156 -0
- package/modules/import/src/services/port-registry.ts +158 -0
- package/modules/import/src/services/repository.ts +147 -0
- package/modules/import/src/settings.ts +70 -0
- package/modules/import/translations/en.json +175 -0
- package/modules/import/translations/pl.json +175 -0
- package/modules/metering/migrations/0001_metering_core.down.sql +6 -0
- package/modules/metering/migrations/0001_metering_core.up.sql +119 -0
- package/modules/metering/migrations/0002_metering_bucket_export.down.sql +3 -0
- package/modules/metering/migrations/0002_metering_bucket_export.up.sql +5 -0
- package/modules/metering/migrations/README.md +3 -0
- package/modules/metering/module.json +46 -0
- package/modules/metering/package.json +50 -0
- package/modules/metering/spec/module.yaml +269 -0
- package/modules/metering/src/acl/permissions.ts +5 -0
- package/modules/metering/src/api/endpoints.ts +104 -0
- package/modules/metering/src/cli/commands.json +28 -0
- package/modules/metering/src/cli/index.ts +246 -0
- package/modules/metering/src/client/LimitsView.tsrx +170 -0
- package/modules/metering/src/client/UsageSummaryWidget.tsrx +63 -0
- package/modules/metering/src/client/UsageView.tsrx +205 -0
- package/modules/metering/src/client/api.ts +91 -0
- package/modules/metering/src/client/contribution.tsrx +42 -0
- package/modules/metering/src/client/index.ts +26 -0
- package/modules/metering/src/client/navigation.ts +54 -0
- package/modules/metering/src/client/presentation.ts +63 -0
- package/modules/metering/src/client/state.ts +31 -0
- package/modules/metering/src/domain/meters.ts +100 -0
- package/modules/metering/src/domain/types.ts +71 -0
- package/modules/metering/src/index.ts +51 -0
- package/modules/metering/src/platform.ts +84 -0
- package/modules/metering/src/server/index.ts +40 -0
- package/modules/metering/src/server/runtime.ts +165 -0
- package/modules/metering/src/services/data-classes.ts +34 -0
- package/modules/metering/src/services/database-repository.ts +574 -0
- package/modules/metering/src/services/index.ts +9 -0
- package/modules/metering/src/services/meter-registry.ts +145 -0
- package/modules/metering/src/services/metering-service.ts +441 -0
- package/modules/metering/src/services/migration.ts +183 -0
- package/modules/metering/src/services/notifications.ts +75 -0
- package/modules/metering/src/services/reports.ts +105 -0
- package/modules/metering/src/services/repository.ts +132 -0
- package/modules/metering/src/services/service-error.ts +46 -0
- package/modules/metering/src/settings.ts +47 -0
- package/modules/metering/translations/en.json +68 -0
- package/modules/metering/translations/pl.json +68 -0
- package/modules/notifications/migrations/0001_notifications_core.down.sql +1 -0
- package/modules/notifications/migrations/0001_notifications_core.up.sql +26 -0
- package/modules/notifications/migrations/0002_notifications_preferences.down.sql +1 -0
- package/modules/notifications/migrations/0002_notifications_preferences.up.sql +17 -0
- package/modules/notifications/migrations/0003_notifications_webhook_subscriptions.down.sql +1 -0
- package/modules/notifications/migrations/0003_notifications_webhook_subscriptions.up.sql +30 -0
- package/modules/notifications/migrations/0004_notifications_deliveries.down.sql +1 -0
- package/modules/notifications/migrations/0004_notifications_deliveries.up.sql +35 -0
- package/modules/notifications/migrations/0005_notifications_delivery_routing_role.down.sql +2 -0
- package/modules/notifications/migrations/0005_notifications_delivery_routing_role.up.sql +17 -0
- package/modules/notifications/migrations/0006_notifications_delivery_title.down.sql +1 -0
- package/modules/notifications/migrations/0006_notifications_delivery_title.up.sql +11 -0
- package/modules/notifications/migrations/0007_notifications_secret_rotation_inventory.down.sql +2 -0
- package/modules/notifications/migrations/0007_notifications_secret_rotation_inventory.up.sql +19 -0
- package/modules/notifications/migrations/0008_notifications_delivery_claim.down.sql +8 -0
- package/modules/notifications/migrations/0008_notifications_delivery_claim.up.sql +19 -0
- package/modules/notifications/migrations/0009_notifications_kind_approvals.down.sql +16 -0
- package/modules/notifications/migrations/0009_notifications_kind_approvals.up.sql +18 -0
- package/modules/notifications/migrations/0010_notifications_kind_meter_threshold.down.sql +16 -0
- package/modules/notifications/migrations/0010_notifications_kind_meter_threshold.up.sql +18 -0
- package/modules/notifications/migrations/0011_notifications_retention_keyset.down.sql +5 -0
- package/modules/notifications/migrations/0011_notifications_retention_keyset.up.sql +15 -0
- package/modules/notifications/migrations/0012_notifications_email_channel.down.sql +12 -0
- package/modules/notifications/migrations/0012_notifications_email_channel.up.sql +38 -0
- package/modules/notifications/migrations/0013_notifications_list_pages.down.sql +5 -0
- package/modules/notifications/migrations/0013_notifications_list_pages.up.sql +13 -0
- package/modules/notifications/migrations/README.md +3 -0
- package/modules/notifications/module.json +32 -0
- package/modules/notifications/package.json +49 -0
- package/modules/notifications/spec/module.yaml +718 -0
- package/modules/notifications/src/acl/permissions.ts +11 -0
- package/modules/notifications/src/api/endpoints.ts +814 -0
- package/modules/notifications/src/cli/commands.json +17 -0
- package/modules/notifications/src/cli/index.ts +126 -0
- package/modules/notifications/src/client/DeliveriesView.tsrx +483 -0
- package/modules/notifications/src/client/FactList.tsrx +24 -0
- package/modules/notifications/src/client/NotificationPreferencesView.tsrx +240 -0
- package/modules/notifications/src/client/NotificationsInboxView.tsrx +592 -0
- package/modules/notifications/src/client/UnreadCountWidget.tsrx +62 -0
- package/modules/notifications/src/client/WebhookForm.tsrx +297 -0
- package/modules/notifications/src/client/WebhooksView.tsrx +637 -0
- package/modules/notifications/src/client/api.ts +382 -0
- package/modules/notifications/src/client/contribution.tsrx +83 -0
- package/modules/notifications/src/client/inbox.ts +41 -0
- package/modules/notifications/src/client/index.ts +29 -0
- package/modules/notifications/src/client/navigation.ts +92 -0
- package/modules/notifications/src/client/notifications.css +70 -0
- package/modules/notifications/src/client/presentation.ts +81 -0
- package/modules/notifications/src/client/state.ts +246 -0
- package/modules/notifications/src/client/unread-count.ts +26 -0
- package/modules/notifications/src/domain/locale.ts +47 -0
- package/modules/notifications/src/domain/publish.ts +46 -0
- package/modules/notifications/src/domain/types.ts +186 -0
- package/modules/notifications/src/index.ts +62 -0
- package/modules/notifications/src/platform.ts +85 -0
- package/modules/notifications/src/server/index.ts +82 -0
- package/modules/notifications/src/server/runtime.ts +251 -0
- package/modules/notifications/src/services/data-classes.ts +139 -0
- package/modules/notifications/src/services/database-repository.ts +1334 -0
- package/modules/notifications/src/services/delivery-payload.ts +93 -0
- package/modules/notifications/src/services/delivery-runner.ts +170 -0
- package/modules/notifications/src/services/delivery-service.ts +811 -0
- package/modules/notifications/src/services/egress.ts +239 -0
- package/modules/notifications/src/services/email-channel.ts +93 -0
- package/modules/notifications/src/services/index.ts +23 -0
- package/modules/notifications/src/services/migration.ts +572 -0
- package/modules/notifications/src/services/notifications-service.ts +297 -0
- package/modules/notifications/src/services/paging.ts +60 -0
- package/modules/notifications/src/services/publish-service.ts +133 -0
- package/modules/notifications/src/services/repository.ts +342 -0
- package/modules/notifications/src/services/secret-rotation.ts +177 -0
- package/modules/notifications/src/services/secret-vault.ts +168 -0
- package/modules/notifications/src/services/service-error.ts +67 -0
- package/modules/notifications/src/services/signature.ts +81 -0
- package/modules/notifications/src/services/webhook-service.ts +307 -0
- package/modules/notifications/src/settings.ts +130 -0
- package/modules/notifications/translations/en.json +255 -0
- package/modules/notifications/translations/pl.json +255 -0
- package/modules/profile/module.json +3 -3
- package/modules/profile/package.json +2 -2
- package/modules/profile/spec/module.yaml +3 -3
- package/modules/profile/src/services/database-repository.ts +3 -13
- package/modules/reports/module.json +28 -0
- package/modules/reports/package.json +42 -0
- package/modules/reports/spec/module.yaml +231 -0
- package/modules/reports/src/acl/permissions.ts +5 -0
- package/modules/reports/src/api/endpoints.ts +72 -0
- package/modules/reports/src/client/ReportsSummaryWidget.tsrx +52 -0
- package/modules/reports/src/client/ReportsView.tsrx +246 -0
- package/modules/reports/src/client/api.ts +65 -0
- package/modules/reports/src/client/contribution.tsrx +36 -0
- package/modules/reports/src/client/index.ts +18 -0
- package/modules/reports/src/client/navigation.ts +39 -0
- package/modules/reports/src/client/presentation.ts +123 -0
- package/modules/reports/src/client/state.ts +28 -0
- package/modules/reports/src/domain/providers.ts +115 -0
- package/modules/reports/src/domain/types.ts +44 -0
- package/modules/reports/src/index.ts +47 -0
- package/modules/reports/src/platform.ts +37 -0
- package/modules/reports/src/server/index.ts +21 -0
- package/modules/reports/src/server/runtime.ts +40 -0
- package/modules/reports/src/services/index.ts +17 -0
- package/modules/reports/src/services/provider-registry.ts +144 -0
- package/modules/reports/src/services/range.ts +65 -0
- package/modules/reports/src/services/reports-service.ts +316 -0
- package/modules/reports/src/services/service-error.ts +26 -0
- package/modules/reports/src/settings.ts +49 -0
- package/modules/reports/translations/en.json +35 -0
- package/modules/reports/translations/pl.json +35 -0
- package/modules/sandbox/module.json +4 -4
- package/modules/sandbox/package.json +2 -2
- package/modules/sandbox/spec/module.yaml +3 -3
- package/modules/sandbox/src/services/database-repository.ts +14 -23
- package/modules/sandbox/src/services/directory.ts +16 -0
- package/modules/sandbox/src/services/sandbox-service.ts +13 -11
- package/modules/search/migrations/0001_search_core.down.sql +1 -0
- package/modules/search/migrations/0001_search_core.up.sql +22 -0
- package/modules/search/migrations/0002_search_recent_export.down.sql +3 -0
- package/modules/search/migrations/0002_search_recent_export.up.sql +5 -0
- package/modules/search/migrations/README.md +3 -0
- package/modules/search/module.json +28 -0
- package/modules/search/package.json +43 -0
- package/modules/search/spec/module.yaml +177 -0
- package/modules/search/src/acl/permissions.ts +5 -0
- package/modules/search/src/api/endpoints.ts +221 -0
- package/modules/search/src/client/SearchView.tsrx +346 -0
- package/modules/search/src/client/api.ts +157 -0
- package/modules/search/src/client/contribution.tsrx +31 -0
- package/modules/search/src/client/index.ts +17 -0
- package/modules/search/src/client/navigation.ts +97 -0
- package/modules/search/src/client/search.css +56 -0
- package/modules/search/src/client/state.ts +113 -0
- package/modules/search/src/domain/data-classes.ts +73 -0
- package/modules/search/src/domain/providers.ts +88 -0
- package/modules/search/src/domain/types.ts +56 -0
- package/modules/search/src/index.ts +46 -0
- package/modules/search/src/platform.ts +42 -0
- package/modules/search/src/server/index.ts +25 -0
- package/modules/search/src/server/runtime.ts +123 -0
- package/modules/search/src/services/database-repository.ts +163 -0
- package/modules/search/src/services/index.ts +21 -0
- package/modules/search/src/services/migration.ts +65 -0
- package/modules/search/src/services/provider-registry.ts +137 -0
- package/modules/search/src/services/repository.ts +43 -0
- package/modules/search/src/services/search-service.ts +442 -0
- package/modules/search/src/services/service-error.ts +35 -0
- package/modules/search/src/settings.ts +68 -0
- package/modules/search/translations/en.json +45 -0
- package/modules/search/translations/pl.json +45 -0
- package/modules/system/module.json +2 -2
- package/modules/system/package.json +2 -2
- package/modules/system/spec/module.yaml +30 -3
- package/modules/system/src/client/FlagsPanel.tsrx +127 -0
- package/modules/system/src/client/ModuleSettingRow.tsrx +17 -7
- package/modules/system/src/client/ModuleSettingsSection.tsrx +10 -71
- package/modules/system/src/client/ModulesView.tsrx +91 -65
- package/modules/system/src/client/flags.ts +35 -0
- package/modules/system/src/client/index.ts +8 -0
- package/modules/system/src/client/navigation.ts +8 -0
- package/modules/system/src/client/settings-state.ts +159 -0
- package/modules/system/src/client/state.ts +2 -0
- package/modules/system/src/domain/time-zone.ts +105 -0
- package/modules/system/src/index.ts +12 -0
- package/modules/system/src/platform.ts +5 -1
- package/modules/system/src/server/endpoints.ts +72 -21
- package/modules/system/src/settings.ts +28 -0
- package/modules/system/translations/en.json +17 -0
- package/modules/system/translations/pl.json +17 -0
- package/modules/users/module.json +30 -4
- package/modules/users/package.json +5 -2
- package/modules/users/spec/module.yaml +290 -7
- package/modules/users/src/api/endpoints.ts +228 -15
- package/modules/users/src/client/InviteMemberForm.tsrx +2 -2
- package/modules/users/src/client/MemberDrawer.tsrx +142 -26
- package/modules/users/src/client/UserAccountForm.tsrx +2 -2
- package/modules/users/src/client/UsersView.tsrx +432 -71
- package/modules/users/src/client/api.ts +106 -12
- package/modules/users/src/client/contribution.tsrx +5 -0
- package/modules/users/src/client/member-columns.tsrx +22 -9
- package/modules/users/src/client/state.ts +172 -7
- package/modules/users/src/domain/lists.ts +9 -0
- package/modules/users/src/index.ts +11 -0
- package/modules/users/src/platform.ts +50 -1
- package/modules/users/src/services/member-export.ts +51 -0
- package/modules/users/src/services/member-import.ts +249 -0
- package/modules/users/src/services/member-search.ts +145 -0
- package/modules/users/src/services/users-service.ts +117 -4
- package/modules/users/translations/en.json +57 -8
- package/modules/users/translations/pl.json +57 -8
- package/modules/workflows/migrations/0004_payload_rotation_inventory.up.sql +17 -0
- package/modules/workflows/migrations/0005_workflows_human_approval.up.sql +28 -0
- package/modules/workflows/migrations/0006_workflows_retention_indexes.up.sql +11 -0
- package/modules/workflows/migrations/0007_workflows_erasure_subject_indexes.up.sql +17 -0
- package/modules/workflows/migrations/0008_workflows_subject_account.up.sql +24 -0
- package/modules/workflows/migrations/0009_workflows_definition_list_indexes.up.sql +9 -0
- package/modules/workflows/module.json +34 -6
- package/modules/workflows/package.json +3 -2
- package/modules/workflows/spec/module.yaml +26 -9
- package/modules/workflows/src/api/endpoints.ts +131 -25
- package/modules/workflows/src/cli/commands.json +17 -0
- package/modules/workflows/src/cli/index.ts +114 -0
- package/modules/workflows/src/client/WorkflowExecutionHistory.tsrx +36 -27
- package/modules/workflows/src/client/WorkflowInspector.tsrx +116 -0
- package/modules/workflows/src/client/WorkflowNodePalette.tsrx +1 -0
- package/modules/workflows/src/client/WorkflowsView.tsrx +236 -99
- package/modules/workflows/src/client/api.ts +54 -34
- package/modules/workflows/src/client/canvas-model.ts +12 -0
- package/modules/workflows/src/client/state.ts +95 -0
- package/modules/workflows/src/domain/events.ts +25 -11
- package/modules/workflows/src/domain/graph.ts +135 -1
- package/modules/workflows/src/domain/types.ts +91 -4
- package/modules/workflows/src/platform.ts +12 -0
- package/modules/workflows/src/server/runtime.ts +78 -5
- package/modules/workflows/src/services/approvals.ts +62 -0
- package/modules/workflows/src/services/cursors.ts +37 -0
- package/modules/workflows/src/services/data-classes.ts +232 -0
- package/modules/workflows/src/services/database-repository.ts +660 -171
- package/modules/workflows/src/services/migration.ts +240 -0
- package/modules/workflows/src/services/notifications.ts +98 -0
- package/modules/workflows/src/services/payload-codec.ts +51 -28
- package/modules/workflows/src/services/payload-rotation.ts +171 -0
- package/modules/workflows/src/services/repository.ts +123 -8
- package/modules/workflows/src/services/simulation.ts +7 -0
- package/modules/workflows/src/services/worker.ts +446 -25
- package/modules/workflows/src/services/workflows-service.ts +264 -103
- package/modules/workflows/translations/en.json +12 -4
- package/modules/workflows/translations/pl.json +12 -4
- package/modules.json +48 -4
- package/package.json +66 -7
- package/packages/client/package.json +2 -1
- package/packages/client/src/ApplicationShell.tsrx +43 -0
- package/packages/client/src/contributions.ts +55 -0
- package/packages/client/src/i18n/locales/en.json +5 -0
- package/packages/client/src/i18n/locales/pl.json +5 -0
- package/packages/client/src/index.ts +13 -1
- package/packages/client/src/routing.ts +22 -0
- package/packages/client/src/shell/CommandPalette.tsrx +223 -11
- package/packages/client/src/shell/command-search.ts +126 -0
- package/packages/client/src/shell/command.ts +30 -0
- package/packages/client/src/shell/navigation.ts +12 -0
- package/packages/client/src/shell/palette-keys.ts +27 -0
- package/packages/client/src/shell/shell.css +7 -0
- package/packages/contracts/schemas/module-spec.schema.json +287 -1
- package/packages/contracts/schemas/module.schema.json +25 -0
- package/packages/contracts/src/index.ts +144 -1
- package/packages/database/src/backup.ts +179 -0
- package/packages/database/src/decoders.ts +25 -0
- package/packages/database/src/index.ts +17 -0
- package/packages/database/src/record-history.ts +5 -14
- package/packages/dev-console/package.json +2 -1
- package/packages/dev-console/src/brand.d.mts +8 -0
- package/packages/dev-console/src/brand.mjs +33 -0
- package/packages/dev-console/src/index.mjs +2 -1
- package/packages/harness/src/index.ts +2 -0
- package/packages/harness/src/runtime.ts +218 -1
- package/packages/harness/src/tool-adapters.ts +19 -1
- package/packages/kernel/src/acl.ts +179 -0
- package/packages/kernel/src/capability-registry.ts +69 -2
- package/packages/kernel/src/data-class-registry.ts +354 -0
- package/packages/kernel/src/index.ts +65 -4
- package/packages/kernel/src/keyring.ts +208 -0
- package/packages/kernel/src/module-compatibility.ts +35 -4
- package/packages/kernel/src/module-registry.ts +49 -2
- package/packages/kernel/src/module-settings.ts +189 -27
- package/packages/server/package.json +2 -1
- package/packages/server/src/composition.ts +38 -0
- package/packages/server/src/endpoint.ts +104 -47
- package/packages/server/src/export/csv.ts +34 -0
- package/packages/server/src/export/definition.ts +346 -0
- package/packages/server/src/export/index.ts +61 -0
- package/packages/server/src/export/run.ts +116 -0
- package/packages/server/src/index.ts +155 -0
- package/packages/server/src/jobs/index.ts +93 -0
- package/packages/server/src/jobs/runner.ts +486 -0
- package/packages/server/src/log.ts +291 -0
- package/packages/server/src/mail/config.ts +184 -0
- package/packages/server/src/mail/contracts.ts +251 -0
- package/packages/server/src/mail/index.ts +31 -0
- package/packages/server/src/mail/port.ts +101 -0
- package/packages/server/src/mail/smtp.ts +191 -0
- package/packages/server/src/mail/template.ts +105 -0
- package/packages/server/src/metrics.ts +447 -0
- package/packages/server/src/pagination.ts +246 -0
- package/packages/server/src/trace/context.ts +103 -0
- package/packages/server/src/trace/egress.ts +66 -0
- package/packages/server/src/trace/error-sink.ts +296 -0
- package/packages/server/src/trace/exporter.ts +295 -0
- package/packages/server/src/trace/index.ts +60 -0
- package/packages/server/src/trace/job-sink.ts +172 -0
- package/packages/server/src/trace/tracer.ts +338 -0
- package/packages/server/src/web.ts +5 -1
- package/packages/storage/package.json +40 -0
- package/packages/storage/src/config.ts +189 -0
- package/packages/storage/src/content-type.ts +124 -0
- package/packages/storage/src/contracts.ts +112 -0
- package/packages/storage/src/envelope.ts +189 -0
- package/packages/storage/src/index.ts +43 -0
- package/packages/storage/src/local.ts +75 -0
- package/packages/storage/src/port.ts +251 -0
- package/packages/storage/src/read-token.ts +130 -0
- package/packages/storage/src/s3.ts +144 -0
- package/packages/storage/src/scanner.ts +22 -0
- package/packages/storage/src/sigv4.ts +104 -0
- package/packages/storage/src/store.ts +13 -0
- package/packages/ui/package.json +1 -0
- package/packages/ui/src/components/Button.tsrx +3 -0
- package/packages/ui/src/components/ConfirmDialog.tsrx +13 -2
- package/packages/ui/src/components/DateField.tsrx +92 -0
- package/packages/ui/src/components/DatePicker.tsrx +525 -0
- package/packages/ui/src/components/DateRangeField.tsrx +93 -0
- package/packages/ui/src/components/Drawer.tsrx +10 -1
- package/packages/ui/src/components/FileUpload.tsrx +158 -0
- package/packages/ui/src/components/Pagination.tsrx +130 -0
- package/packages/ui/src/components/Select.tsrx +78 -0
- package/packages/ui/src/components/Table.tsrx +498 -81
- package/packages/ui/src/components/Tabs.tsrx +53 -0
- package/packages/ui/src/components/ToastHost.tsrx +48 -0
- package/packages/ui/src/components/calendar.ts +243 -0
- package/packages/ui/src/components/date-field.ts +62 -0
- package/packages/ui/src/components/file-upload.ts +49 -0
- package/packages/ui/src/components/focus-trap.ts +62 -0
- package/packages/ui/src/components/pagination.ts +68 -0
- package/packages/ui/src/components/table-sorting.ts +49 -0
- package/packages/ui/src/components/tabs.ts +61 -0
- package/packages/ui/src/components/toast-store.ts +116 -0
- package/packages/ui/src/icons/Icon.tsrx +5 -0
- package/packages/ui/src/index.ts +45 -0
- package/packages/ui/src/styles/components.css +598 -0
- package/modules/automations-workflows-integration/module.json +0 -27
- package/modules/automations-workflows-integration/spec/module.yaml +0 -93
- package/modules/automations-workflows-integration/src/index.ts +0 -14
- package/modules/automations-workflows-integration/src/platform.ts +0 -24
- package/modules/automations-workflows-integration/src/server/index.ts +0 -11
- package/modules/automations-workflows-integration/translations/en.json +0 -21
- package/modules/automations-workflows-integration/translations/pl.json +0 -21
- package/modules/workflows/src/services/cursor-codec.ts +0 -62
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import { monitorEventLoopDelay } from 'node:perf_hooks';
|
|
2
|
+
|
|
3
|
+
export interface HttpRequestSample {
|
|
4
|
+
/** Endpoint id, never the request path: a path carries record ids. */
|
|
5
|
+
readonly endpoint: string;
|
|
6
|
+
readonly method: string;
|
|
7
|
+
readonly status: number;
|
|
8
|
+
readonly durationSeconds: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ModuleMetricLabels {
|
|
12
|
+
readonly [name: string]: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Counters and histograms a module owns, bound to its id. Series are named
|
|
17
|
+
* `flowdular_module_<module id>_<name>` and carry the labels the module names,
|
|
18
|
+
* under the same ceilings the request series have: a module cannot open an
|
|
19
|
+
* unbounded number of series and cannot slow a request down by recording one.
|
|
20
|
+
*
|
|
21
|
+
* A module calls `context.metrics` once while it composes and keeps the
|
|
22
|
+
* binder; every refused sample is counted in the dropped samples series.
|
|
23
|
+
*/
|
|
24
|
+
export interface ModuleMetrics {
|
|
25
|
+
/** Adds one to `flowdular_module_<module>_<name>_total`. */
|
|
26
|
+
counter(name: string, labels?: ModuleMetricLabels): void;
|
|
27
|
+
/**
|
|
28
|
+
* Observes `value` into `flowdular_module_<module>_<name>`, with the same
|
|
29
|
+
* buckets the request duration histogram uses (seconds, 0.005 to 10).
|
|
30
|
+
*/
|
|
31
|
+
histogram(name: string, value: number, labels?: ModuleMetricLabels): void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface MetricsRegistry {
|
|
35
|
+
/** Called once per served request; never throws into the request path. */
|
|
36
|
+
recordHttpRequest(sample: HttpRequestSample): void;
|
|
37
|
+
/** A binder for one module's own series. Call it once while composing. */
|
|
38
|
+
moduleMetrics(moduleId: string): ModuleMetrics;
|
|
39
|
+
setBuildVersion(version: string): void;
|
|
40
|
+
/** Prometheus text exposition, format version 0.0.4. */
|
|
41
|
+
expose(): string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* One request writes at most one counter series and one histogram series, so a
|
|
45
|
+
deployment that composes more endpoints than this stops admitting new label
|
|
46
|
+
sets instead of growing. The refused samples are published as their own
|
|
47
|
+
counter, so a scrape shows that the ceiling was reached. */
|
|
48
|
+
const MAX_SERIES = 2_000;
|
|
49
|
+
const MAX_LABEL = 128;
|
|
50
|
+
const BUCKETS = Object.freeze([
|
|
51
|
+
0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10,
|
|
52
|
+
]);
|
|
53
|
+
const BUCKET_LABELS = Object.freeze(BUCKETS.map((bound) => String(bound)));
|
|
54
|
+
const METHODS = new Set([
|
|
55
|
+
'GET',
|
|
56
|
+
'HEAD',
|
|
57
|
+
'POST',
|
|
58
|
+
'PUT',
|
|
59
|
+
'PATCH',
|
|
60
|
+
'DELETE',
|
|
61
|
+
'OPTIONS',
|
|
62
|
+
]);
|
|
63
|
+
const UNSAFE_LABEL = /["\\\n]/;
|
|
64
|
+
/* Every control character the exposition format cannot carry escaped. A raw
|
|
65
|
+
carriage return ends the line a scrape reads, so one label value would forge
|
|
66
|
+
the next series; the newline below it is escaped instead, as the format
|
|
67
|
+
allows. */
|
|
68
|
+
const UNESCAPABLE_CHARACTER = /[\u0000-\u0009\u000b-\u001f\u007f]/g;
|
|
69
|
+
const SEPARATOR = '\u0000';
|
|
70
|
+
|
|
71
|
+
/* A module names its own series, so the name space is the one thing a module
|
|
72
|
+
could grow without bound. Families are capped per process and label sets per
|
|
73
|
+
family reuse the request ceiling; a refusal is a dropped sample, never an
|
|
74
|
+
error thrown back into the module's work. */
|
|
75
|
+
const MAX_MODULE_FAMILIES = 256;
|
|
76
|
+
const MAX_MODULE_LABELS = 8;
|
|
77
|
+
const METRIC_NAME = /^[a-z][a-z0-9_]{0,63}$/;
|
|
78
|
+
const UNSAFE_NAME_CHARACTER = /[^a-z0-9_]/g;
|
|
79
|
+
|
|
80
|
+
interface ModuleCounter {
|
|
81
|
+
readonly labels: string;
|
|
82
|
+
count: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface ModuleHistogram {
|
|
86
|
+
readonly labels: string;
|
|
87
|
+
readonly buckets: number[];
|
|
88
|
+
count: number;
|
|
89
|
+
sum: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
interface RequestCounter {
|
|
93
|
+
readonly endpoint: string;
|
|
94
|
+
readonly method: string;
|
|
95
|
+
readonly status: string;
|
|
96
|
+
count: number;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
interface DurationHistogram {
|
|
100
|
+
readonly endpoint: string;
|
|
101
|
+
readonly buckets: number[];
|
|
102
|
+
count: number;
|
|
103
|
+
sum: number;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function labelValue(value: string): string {
|
|
107
|
+
const bounded = (
|
|
108
|
+
value.length <= MAX_LABEL ? value : value.slice(0, MAX_LABEL)
|
|
109
|
+
).replace(UNESCAPABLE_CHARACTER, ' ');
|
|
110
|
+
return UNSAFE_LABEL.test(bounded)
|
|
111
|
+
? bounded.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n')
|
|
112
|
+
: bounded;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* A status class instead of the status keeps the label set bounded by a
|
|
116
|
+
constant, and an unknown method keeps a hostile request line from opening a
|
|
117
|
+
series of its own. */
|
|
118
|
+
function statusClass(status: number): string {
|
|
119
|
+
return Number.isInteger(status) && status >= 100 && status < 600
|
|
120
|
+
? `${Math.floor(status / 100)}xx`
|
|
121
|
+
: 'unknown';
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function methodLabel(method: string): string {
|
|
125
|
+
const normalized = method.toUpperCase();
|
|
126
|
+
return METHODS.has(normalized) ? normalized : 'other';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** `agents.core` becomes `agents_core`: a dot is not a Prometheus name. */
|
|
130
|
+
function moduleNamePart(moduleId: string): string {
|
|
131
|
+
return (
|
|
132
|
+
moduleId
|
|
133
|
+
.toLowerCase()
|
|
134
|
+
.slice(0, 64)
|
|
135
|
+
.replace(UNSAFE_NAME_CHARACTER, '_')
|
|
136
|
+
.replace(/^[^a-z]+/, '') || 'unknown'
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* Sorted so one label set is always one series key, whatever order the module
|
|
141
|
+
wrote the object in. Null refuses the sample. */
|
|
142
|
+
function moduleLabels(labels: ModuleMetricLabels | undefined): string | null {
|
|
143
|
+
if (!labels) return '';
|
|
144
|
+
const names = Object.keys(labels).sort();
|
|
145
|
+
if (names.length > MAX_MODULE_LABELS) return null;
|
|
146
|
+
const parts: string[] = [];
|
|
147
|
+
for (const name of names) {
|
|
148
|
+
if (!METRIC_NAME.test(name)) return null;
|
|
149
|
+
parts.push(`${name}="${labelValue(String(labels[name]))}"`);
|
|
150
|
+
}
|
|
151
|
+
return parts.join(',');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let eventLoopDelay: ReturnType<typeof monitorEventLoopDelay> | null | undefined;
|
|
155
|
+
|
|
156
|
+
/* Sampling starts on the first scrape, never at import: a deployment that does
|
|
157
|
+
not expose metrics must not pay for the timer. The histogram is drained on
|
|
158
|
+
every read, so a scrape reports the interval since the previous one and a
|
|
159
|
+
scrape with no sample yet reports zero. */
|
|
160
|
+
function eventLoopLagSeconds(): number | null {
|
|
161
|
+
if (eventLoopDelay === undefined) {
|
|
162
|
+
try {
|
|
163
|
+
eventLoopDelay =
|
|
164
|
+
typeof monitorEventLoopDelay === 'function'
|
|
165
|
+
? monitorEventLoopDelay({ resolution: 10 })
|
|
166
|
+
: null;
|
|
167
|
+
eventLoopDelay?.enable();
|
|
168
|
+
} catch {
|
|
169
|
+
eventLoopDelay = null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (!eventLoopDelay) return null;
|
|
173
|
+
const mean = eventLoopDelay.mean;
|
|
174
|
+
eventLoopDelay.reset();
|
|
175
|
+
return Number.isFinite(mean) ? mean / 1e9 : 0;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function residentMemoryBytes(): number | null {
|
|
179
|
+
try {
|
|
180
|
+
const rss = process.memoryUsage.rss();
|
|
181
|
+
return Number.isFinite(rss) ? rss : null;
|
|
182
|
+
} catch {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export function createMetricsRegistry(): MetricsRegistry {
|
|
188
|
+
const counters = new Map<string, RequestCounter>();
|
|
189
|
+
const durations = new Map<string, DurationHistogram>();
|
|
190
|
+
const moduleCounters = new Map<string, Map<string, ModuleCounter>>();
|
|
191
|
+
const moduleHistograms = new Map<string, Map<string, ModuleHistogram>>();
|
|
192
|
+
const startTimeSeconds = Date.now() / 1000 - process.uptime();
|
|
193
|
+
let dropped = 0;
|
|
194
|
+
let version: string | null = null;
|
|
195
|
+
|
|
196
|
+
const recordHttpRequest = (sample: HttpRequestSample): void => {
|
|
197
|
+
const endpoint = labelValue(sample.endpoint);
|
|
198
|
+
const method = methodLabel(sample.method);
|
|
199
|
+
const status = statusClass(sample.status);
|
|
200
|
+
const key = `${endpoint}${SEPARATOR}${method}${SEPARATOR}${status}`;
|
|
201
|
+
const counter = counters.get(key);
|
|
202
|
+
let timing = durations.get(endpoint);
|
|
203
|
+
/* A sample is admitted or refused whole, so the counter and the histogram
|
|
204
|
+
can never disagree about a request that was served. */
|
|
205
|
+
if (
|
|
206
|
+
(!counter && counters.size >= MAX_SERIES) ||
|
|
207
|
+
(!timing && durations.size >= MAX_SERIES)
|
|
208
|
+
) {
|
|
209
|
+
dropped += 1;
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (counter) counter.count += 1;
|
|
213
|
+
else counters.set(key, { endpoint, method, status, count: 1 });
|
|
214
|
+
|
|
215
|
+
if (!timing) {
|
|
216
|
+
timing = {
|
|
217
|
+
endpoint,
|
|
218
|
+
buckets: new Array<number>(BUCKETS.length).fill(0),
|
|
219
|
+
count: 0,
|
|
220
|
+
sum: 0,
|
|
221
|
+
};
|
|
222
|
+
durations.set(endpoint, timing);
|
|
223
|
+
}
|
|
224
|
+
const seconds =
|
|
225
|
+
Number.isFinite(sample.durationSeconds) && sample.durationSeconds > 0
|
|
226
|
+
? sample.durationSeconds
|
|
227
|
+
: 0;
|
|
228
|
+
timing.count += 1;
|
|
229
|
+
timing.sum += seconds;
|
|
230
|
+
for (let index = 0; index < BUCKETS.length; index += 1) {
|
|
231
|
+
if (seconds <= BUCKETS[index]!) {
|
|
232
|
+
timing.buckets[index]! += 1;
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/* One lookup and at most one insertion per sample, so a module pays O(1)
|
|
239
|
+
whether it records its first series or its two thousandth. */
|
|
240
|
+
function moduleSeries<Series>(
|
|
241
|
+
families: Map<string, Map<string, Series>>,
|
|
242
|
+
moduleId: string,
|
|
243
|
+
name: string,
|
|
244
|
+
labels: ModuleMetricLabels | undefined,
|
|
245
|
+
create: (labels: string) => Series,
|
|
246
|
+
): Series | null {
|
|
247
|
+
if (!METRIC_NAME.test(name)) {
|
|
248
|
+
dropped += 1;
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
const rendered = moduleLabels(labels);
|
|
252
|
+
if (rendered === null) {
|
|
253
|
+
dropped += 1;
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
const family = `flowdular_module_${moduleNamePart(moduleId)}_${name}`;
|
|
257
|
+
let series = families.get(family);
|
|
258
|
+
if (!series) {
|
|
259
|
+
if (families.size >= MAX_MODULE_FAMILIES) {
|
|
260
|
+
dropped += 1;
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
series = new Map<string, Series>();
|
|
264
|
+
families.set(family, series);
|
|
265
|
+
}
|
|
266
|
+
const existing = series.get(rendered);
|
|
267
|
+
if (existing) return existing;
|
|
268
|
+
if (series.size >= MAX_SERIES) {
|
|
269
|
+
dropped += 1;
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
const created = create(rendered);
|
|
273
|
+
series.set(rendered, created);
|
|
274
|
+
return created;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const moduleMetrics = (moduleId: string): ModuleMetrics =>
|
|
278
|
+
Object.freeze({
|
|
279
|
+
counter: (name: string, labels?: ModuleMetricLabels): void => {
|
|
280
|
+
const series = moduleSeries(
|
|
281
|
+
moduleCounters,
|
|
282
|
+
moduleId,
|
|
283
|
+
name,
|
|
284
|
+
labels,
|
|
285
|
+
(rendered) => ({ labels: rendered, count: 0 }),
|
|
286
|
+
);
|
|
287
|
+
if (series) series.count += 1;
|
|
288
|
+
},
|
|
289
|
+
histogram: (
|
|
290
|
+
name: string,
|
|
291
|
+
value: number,
|
|
292
|
+
labels?: ModuleMetricLabels,
|
|
293
|
+
): void => {
|
|
294
|
+
const series = moduleSeries(
|
|
295
|
+
moduleHistograms,
|
|
296
|
+
moduleId,
|
|
297
|
+
name,
|
|
298
|
+
labels,
|
|
299
|
+
(rendered) => ({
|
|
300
|
+
labels: rendered,
|
|
301
|
+
buckets: new Array<number>(BUCKETS.length).fill(0),
|
|
302
|
+
count: 0,
|
|
303
|
+
sum: 0,
|
|
304
|
+
}),
|
|
305
|
+
);
|
|
306
|
+
if (!series) return;
|
|
307
|
+
const observed = Number.isFinite(value) && value > 0 ? value : 0;
|
|
308
|
+
series.count += 1;
|
|
309
|
+
series.sum += observed;
|
|
310
|
+
for (let index = 0; index < BUCKETS.length; index += 1) {
|
|
311
|
+
if (observed <= BUCKETS[index]!) {
|
|
312
|
+
series.buckets[index]! += 1;
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
const exposeModuleSeries = (lines: string[]): void => {
|
|
320
|
+
for (const [family, series] of moduleCounters) {
|
|
321
|
+
lines.push(
|
|
322
|
+
`# HELP ${family} Counter owned by a module.`,
|
|
323
|
+
`# TYPE ${family} counter`,
|
|
324
|
+
);
|
|
325
|
+
for (const entry of series.values()) {
|
|
326
|
+
lines.push(
|
|
327
|
+
`${family}_total${entry.labels ? `{${entry.labels}}` : ''} ${entry.count}`,
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
for (const [family, series] of moduleHistograms) {
|
|
332
|
+
lines.push(
|
|
333
|
+
`# HELP ${family} Histogram owned by a module.`,
|
|
334
|
+
`# TYPE ${family} histogram`,
|
|
335
|
+
);
|
|
336
|
+
for (const entry of series.values()) {
|
|
337
|
+
const prefix = entry.labels ? `${entry.labels},` : '';
|
|
338
|
+
let cumulative = 0;
|
|
339
|
+
for (let index = 0; index < BUCKETS.length; index += 1) {
|
|
340
|
+
cumulative += entry.buckets[index]!;
|
|
341
|
+
lines.push(
|
|
342
|
+
`${family}_bucket{${prefix}le="${BUCKET_LABELS[index]!}"} ${cumulative}`,
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
const suffix = entry.labels ? `{${entry.labels}}` : '';
|
|
346
|
+
lines.push(
|
|
347
|
+
`${family}_bucket{${prefix}le="+Inf"} ${entry.count}`,
|
|
348
|
+
`${family}_sum${suffix} ${entry.sum}`,
|
|
349
|
+
`${family}_count${suffix} ${entry.count}`,
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const expose = (): string => {
|
|
356
|
+
const lines: string[] = [
|
|
357
|
+
'# HELP flowdular_http_requests_total Requests completed by a defined endpoint.',
|
|
358
|
+
'# TYPE flowdular_http_requests_total counter',
|
|
359
|
+
];
|
|
360
|
+
for (const series of counters.values()) {
|
|
361
|
+
lines.push(
|
|
362
|
+
`flowdular_http_requests_total{endpoint="${series.endpoint}",method="${series.method}",status="${series.status}"} ${series.count}`,
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
lines.push(
|
|
366
|
+
'# HELP flowdular_http_request_duration_seconds Endpoint handler duration in seconds.',
|
|
367
|
+
'# TYPE flowdular_http_request_duration_seconds histogram',
|
|
368
|
+
);
|
|
369
|
+
for (const series of durations.values()) {
|
|
370
|
+
let cumulative = 0;
|
|
371
|
+
for (let index = 0; index < BUCKETS.length; index += 1) {
|
|
372
|
+
cumulative += series.buckets[index]!;
|
|
373
|
+
lines.push(
|
|
374
|
+
`flowdular_http_request_duration_seconds_bucket{endpoint="${series.endpoint}",le="${BUCKET_LABELS[index]!}"} ${cumulative}`,
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
lines.push(
|
|
378
|
+
`flowdular_http_request_duration_seconds_bucket{endpoint="${series.endpoint}",le="+Inf"} ${series.count}`,
|
|
379
|
+
`flowdular_http_request_duration_seconds_sum{endpoint="${series.endpoint}"} ${series.sum}`,
|
|
380
|
+
`flowdular_http_request_duration_seconds_count{endpoint="${series.endpoint}"} ${series.count}`,
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
exposeModuleSeries(lines);
|
|
384
|
+
lines.push(
|
|
385
|
+
'# HELP flowdular_metrics_dropped_samples_total Samples refused because the label set ceiling was reached.',
|
|
386
|
+
'# TYPE flowdular_metrics_dropped_samples_total counter',
|
|
387
|
+
`flowdular_metrics_dropped_samples_total ${dropped}`,
|
|
388
|
+
'# HELP flowdular_process_start_time_seconds Process start time in seconds since the unix epoch.',
|
|
389
|
+
'# TYPE flowdular_process_start_time_seconds gauge',
|
|
390
|
+
`flowdular_process_start_time_seconds ${startTimeSeconds}`,
|
|
391
|
+
);
|
|
392
|
+
const resident = residentMemoryBytes();
|
|
393
|
+
if (resident !== null) {
|
|
394
|
+
lines.push(
|
|
395
|
+
'# HELP process_resident_memory_bytes Resident set size of the process in bytes.',
|
|
396
|
+
'# TYPE process_resident_memory_bytes gauge',
|
|
397
|
+
`process_resident_memory_bytes ${resident}`,
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
const lag = eventLoopLagSeconds();
|
|
401
|
+
if (lag !== null) {
|
|
402
|
+
lines.push(
|
|
403
|
+
'# HELP nodejs_eventloop_lag_seconds Mean event loop delay in seconds since the previous scrape.',
|
|
404
|
+
'# TYPE nodejs_eventloop_lag_seconds gauge',
|
|
405
|
+
`nodejs_eventloop_lag_seconds ${lag}`,
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
if (version !== null) {
|
|
409
|
+
lines.push(
|
|
410
|
+
'# HELP flowdular_build_info Version of the running platform build.',
|
|
411
|
+
'# TYPE flowdular_build_info gauge',
|
|
412
|
+
`flowdular_build_info{version="${version}"} 1`,
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
return `${lines.join('\n')}\n`;
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
return Object.freeze({
|
|
419
|
+
recordHttpRequest,
|
|
420
|
+
moduleMetrics,
|
|
421
|
+
setBuildVersion: (value: string) => {
|
|
422
|
+
version = labelValue(value);
|
|
423
|
+
},
|
|
424
|
+
expose,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
let processMetrics: MetricsRegistry | undefined;
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* The metrics of this process. Recording is always on and bounded; exposing it
|
|
432
|
+
* is the platform's decision. Tests and libraries that need their own series
|
|
433
|
+
* call `createMetricsRegistry` instead.
|
|
434
|
+
*/
|
|
435
|
+
export function serverMetrics(): MetricsRegistry {
|
|
436
|
+
return (processMetrics ??= createMetricsRegistry());
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* The counters and histograms one module owns, on the process registry. A
|
|
441
|
+
* module calls it once while it composes: the binder is what `context.metrics`
|
|
442
|
+
* hands over, and every series it opens is exposed on `/api/metrics` under the
|
|
443
|
+
* same `FD_METRICS_TOKEN` the request series are.
|
|
444
|
+
*/
|
|
445
|
+
export function createModuleMetrics(moduleId: string): ModuleMetrics {
|
|
446
|
+
return serverMetrics().moduleMetrics(moduleId);
|
|
447
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { HttpProblem, jsonResponse } from './http.ts';
|
|
3
|
+
|
|
4
|
+
export const DEFAULT_PAGE_LIMIT = 50;
|
|
5
|
+
export const MAX_PAGE_LIMIT = 200;
|
|
6
|
+
/* A cursor travels in a query string and is never stored, so it stays small
|
|
7
|
+
enough for a URL and for a log line that records one. */
|
|
8
|
+
export const MAX_CURSOR_LENGTH = 1024;
|
|
9
|
+
export const MAX_KEYSET_COLUMNS = 4;
|
|
10
|
+
|
|
11
|
+
const CURSOR_VERSION = 'c1';
|
|
12
|
+
const CURSOR_SECRET_BYTES = 32;
|
|
13
|
+
const CURSOR_CHARACTERS = /^[A-Za-z0-9._-]+$/;
|
|
14
|
+
const SQL_IDENTIFIER = /^[a-z_][a-z0-9_]*$/;
|
|
15
|
+
|
|
16
|
+
export interface PageQuery {
|
|
17
|
+
readonly limit: number;
|
|
18
|
+
/** The opaque cursor as it arrived; `decodeCursor` reads it. */
|
|
19
|
+
readonly cursor: string | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface PageQueryOptions {
|
|
23
|
+
readonly maxLimit?: number;
|
|
24
|
+
readonly defaultLimit?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The `limit` and `cursor` of a list request. Bad input is the caller's, so it
|
|
29
|
+
* throws `HttpProblem` with status 400 for `problemResponse` to answer.
|
|
30
|
+
*/
|
|
31
|
+
export function readPageQuery(
|
|
32
|
+
url: URL,
|
|
33
|
+
options: PageQueryOptions = {},
|
|
34
|
+
): PageQuery {
|
|
35
|
+
const maxLimit = options.maxLimit ?? MAX_PAGE_LIMIT;
|
|
36
|
+
const defaultLimit =
|
|
37
|
+
options.defaultLimit ?? Math.min(maxLimit, DEFAULT_PAGE_LIMIT);
|
|
38
|
+
if (!Number.isSafeInteger(maxLimit) || maxLimit < 1) {
|
|
39
|
+
throw new Error('A page maxLimit must be a positive integer.');
|
|
40
|
+
}
|
|
41
|
+
if (maxLimit > MAX_PAGE_LIMIT) {
|
|
42
|
+
throw new Error(`A page maxLimit is at most ${MAX_PAGE_LIMIT}.`);
|
|
43
|
+
}
|
|
44
|
+
if (
|
|
45
|
+
!Number.isSafeInteger(defaultLimit) ||
|
|
46
|
+
defaultLimit < 1 ||
|
|
47
|
+
defaultLimit > maxLimit
|
|
48
|
+
) {
|
|
49
|
+
throw new Error('A page defaultLimit must be between 1 and maxLimit.');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const requested = url.searchParams.get('limit');
|
|
53
|
+
let limit = defaultLimit;
|
|
54
|
+
if (requested !== null && requested.trim() !== '') {
|
|
55
|
+
limit = Number(requested);
|
|
56
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > maxLimit) {
|
|
57
|
+
throw new HttpProblem(
|
|
58
|
+
'INVALID_INPUT',
|
|
59
|
+
`limit must be an integer between 1 and ${maxLimit}.`,
|
|
60
|
+
400,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const cursor = url.searchParams.get('cursor');
|
|
66
|
+
if (cursor === null || cursor === '') return { limit, cursor: null };
|
|
67
|
+
if (cursor.length > MAX_CURSOR_LENGTH || !CURSOR_CHARACTERS.test(cursor)) {
|
|
68
|
+
throw invalidCursor();
|
|
69
|
+
}
|
|
70
|
+
return { limit, cursor };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The keyset of the last row of a page, signed so a caller cannot move the
|
|
75
|
+
* page boundary onto a row the query would otherwise have excluded.
|
|
76
|
+
*/
|
|
77
|
+
export function encodeCursor(
|
|
78
|
+
payload: Record<string, string | number>,
|
|
79
|
+
secret: Uint8Array,
|
|
80
|
+
): string {
|
|
81
|
+
assertCursorSecret(secret);
|
|
82
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
83
|
+
if (typeof value === 'number' && !Number.isFinite(value)) {
|
|
84
|
+
throw new Error(`Cursor field ${key} must be a finite number.`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const body = Buffer.from(JSON.stringify(payload), 'utf8').toString(
|
|
88
|
+
'base64url',
|
|
89
|
+
);
|
|
90
|
+
const signed = `${CURSOR_VERSION}.${body}`;
|
|
91
|
+
const cursor = `${signed}.${signature(signed, secret).toString('base64url')}`;
|
|
92
|
+
if (cursor.length > MAX_CURSOR_LENGTH) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`A page cursor is at most ${MAX_CURSOR_LENGTH} characters; page by keyset, not by state.`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
return cursor;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Throws `HttpProblem` `CURSOR_INVALID` (400) for anything this server did not sign. */
|
|
101
|
+
export function decodeCursor(
|
|
102
|
+
cursor: string,
|
|
103
|
+
secret: Uint8Array,
|
|
104
|
+
): Record<string, string | number> {
|
|
105
|
+
assertCursorSecret(secret);
|
|
106
|
+
if (
|
|
107
|
+
typeof cursor !== 'string' ||
|
|
108
|
+
cursor.length === 0 ||
|
|
109
|
+
cursor.length > MAX_CURSOR_LENGTH
|
|
110
|
+
) {
|
|
111
|
+
throw invalidCursor();
|
|
112
|
+
}
|
|
113
|
+
const parts = cursor.split('.');
|
|
114
|
+
const version = parts[0];
|
|
115
|
+
const body = parts[1];
|
|
116
|
+
const suppliedSignature = parts[2];
|
|
117
|
+
if (
|
|
118
|
+
parts.length !== 3 ||
|
|
119
|
+
version !== CURSOR_VERSION ||
|
|
120
|
+
!body ||
|
|
121
|
+
!suppliedSignature
|
|
122
|
+
) {
|
|
123
|
+
throw invalidCursor();
|
|
124
|
+
}
|
|
125
|
+
/* base64url decoding drops characters it cannot read, so the signature is
|
|
126
|
+
compared by length and in constant time rather than by its text. */
|
|
127
|
+
const expected = signature(`${version}.${body}`, secret);
|
|
128
|
+
const supplied = Buffer.from(suppliedSignature, 'base64url');
|
|
129
|
+
if (
|
|
130
|
+
supplied.length !== expected.length ||
|
|
131
|
+
!timingSafeEqual(supplied, expected)
|
|
132
|
+
) {
|
|
133
|
+
throw invalidCursor();
|
|
134
|
+
}
|
|
135
|
+
let value: unknown;
|
|
136
|
+
try {
|
|
137
|
+
value = JSON.parse(Buffer.from(body, 'base64url').toString('utf8'));
|
|
138
|
+
} catch {
|
|
139
|
+
throw invalidCursor();
|
|
140
|
+
}
|
|
141
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
142
|
+
throw invalidCursor();
|
|
143
|
+
}
|
|
144
|
+
for (const field of Object.values(value as Record<string, unknown>)) {
|
|
145
|
+
if (typeof field === 'string') continue;
|
|
146
|
+
if (typeof field === 'number' && Number.isFinite(field)) continue;
|
|
147
|
+
throw invalidCursor();
|
|
148
|
+
}
|
|
149
|
+
return value as Record<string, string | number>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface PageResult<T> {
|
|
153
|
+
readonly items: readonly T[];
|
|
154
|
+
readonly limit: number;
|
|
155
|
+
/** Null on the last page: a client stops when the cursor stops. */
|
|
156
|
+
readonly nextCursor: string | null;
|
|
157
|
+
/** Only where the count is cheap; a count over every row of a tenant is not. */
|
|
158
|
+
readonly total?: number;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function pageResponse<T>(page: PageResult<T>): Response {
|
|
162
|
+
return jsonResponse({
|
|
163
|
+
items: page.items,
|
|
164
|
+
page: {
|
|
165
|
+
nextCursor: page.nextCursor,
|
|
166
|
+
limit: page.limit,
|
|
167
|
+
...(page.total === undefined ? {} : { total: page.total }),
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface KeysetOptions {
|
|
173
|
+
/** The ORDER BY direction of every keyset column. Defaults to `desc`. */
|
|
174
|
+
readonly direction?: 'asc' | 'desc';
|
|
175
|
+
/** How many parameters the statement already binds before this predicate. */
|
|
176
|
+
readonly parameterOffset?: number;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface KeysetPredicate {
|
|
180
|
+
readonly text: string;
|
|
181
|
+
readonly parameters: readonly (string | number)[];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* The row-order predicate of a keyset page, for `(created_at, id)` and any
|
|
186
|
+
* other unique ordering: `(created_at < $1 OR (created_at = $1 AND id < $2))`.
|
|
187
|
+
* Column names are interpolated, so they are checked as plain identifiers and
|
|
188
|
+
* must never come from a request; the cursor values are bound.
|
|
189
|
+
*/
|
|
190
|
+
export function keysetWhere(
|
|
191
|
+
columns: readonly string[],
|
|
192
|
+
cursorValues: readonly (string | number)[],
|
|
193
|
+
options: KeysetOptions = {},
|
|
194
|
+
): KeysetPredicate {
|
|
195
|
+
if (columns.length === 0 || columns.length > MAX_KEYSET_COLUMNS) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`A keyset orders by 1 to ${MAX_KEYSET_COLUMNS} columns, ending in a unique one.`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
if (columns.length !== cursorValues.length) {
|
|
201
|
+
throw new Error('A keyset needs one cursor value per column.');
|
|
202
|
+
}
|
|
203
|
+
const offset = options.parameterOffset ?? 0;
|
|
204
|
+
if (!Number.isSafeInteger(offset) || offset < 0) {
|
|
205
|
+
throw new Error('A keyset parameterOffset must be a whole number.');
|
|
206
|
+
}
|
|
207
|
+
for (const column of columns) {
|
|
208
|
+
if (!SQL_IDENTIFIER.test(column)) {
|
|
209
|
+
throw new Error(`Keyset column ${column} is not a plain identifier.`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const comparison = (options.direction ?? 'desc') === 'desc' ? '<' : '>';
|
|
213
|
+
const terms: string[] = [];
|
|
214
|
+
for (let index = 0; index < columns.length; index += 1) {
|
|
215
|
+
const conditions = columns
|
|
216
|
+
.slice(0, index)
|
|
217
|
+
.map((column, position) => `${column} = $${offset + position + 1}`);
|
|
218
|
+
conditions.push(`${columns[index]} ${comparison} $${offset + index + 1}`);
|
|
219
|
+
terms.push(
|
|
220
|
+
conditions.length === 1
|
|
221
|
+
? conditions[0]!
|
|
222
|
+
: `(${conditions.join(' AND ')})`,
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
return { text: `(${terms.join(' OR ')})`, parameters: [...cursorValues] };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function signature(body: string, secret: Uint8Array): Buffer {
|
|
229
|
+
return createHmac('sha256', secret).update(body).digest();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function assertCursorSecret(secret: Uint8Array): void {
|
|
233
|
+
if (secret.length < CURSOR_SECRET_BYTES) {
|
|
234
|
+
throw new Error(`Cursor signing requires ${CURSOR_SECRET_BYTES} bytes.`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* One answer for a cursor this server did not sign, one it no longer accepts
|
|
239
|
+
and one a caller edited: a client that meets it restarts from the first page. */
|
|
240
|
+
function invalidCursor(): HttpProblem {
|
|
241
|
+
return new HttpProblem(
|
|
242
|
+
'CURSOR_INVALID',
|
|
243
|
+
'The page cursor is not valid.',
|
|
244
|
+
400,
|
|
245
|
+
);
|
|
246
|
+
}
|