@pikku/core 0.12.72 → 0.12.77
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/CHANGELOG.md +1171 -0
- package/dist/column-form.d.ts +32 -0
- package/dist/column-form.js +42 -0
- package/dist/crypto-utils.d.ts +43 -7
- package/dist/crypto-utils.js +163 -42
- package/dist/data-classification.d.ts +44 -0
- package/dist/dev/hot-reload.js +11 -30
- package/dist/dev/module-runner.d.ts +3 -7
- package/dist/dev/module-runner.js +4 -10
- package/dist/dev/reload-meta.d.ts +8 -20
- package/dist/dev/reload-meta.js +9 -29
- package/dist/errors/error-handler.d.ts +5 -30
- package/dist/errors/error-handler.js +16 -32
- package/dist/errors/errors.d.ts +32 -151
- package/dist/errors/errors.js +55 -157
- package/dist/function/abort-scope.d.ts +47 -0
- package/dist/function/abort-scope.js +63 -0
- package/dist/function/function-runner.js +37 -32
- package/dist/function/functions.types.d.ts +57 -136
- package/dist/function/functions.types.js +0 -58
- package/dist/function/index.d.ts +1 -1
- package/dist/function/list.types.d.ts +12 -62
- package/dist/function/list.types.js +4 -25
- package/dist/handle-error.d.ts +0 -13
- package/dist/handle-error.js +0 -18
- package/dist/index.d.ts +11 -5
- package/dist/index.js +7 -2
- package/dist/middleware/auth-apikey.d.ts +3 -18
- package/dist/middleware/auth-apikey.js +0 -17
- package/dist/middleware/auth-bearer.d.ts +6 -41
- package/dist/middleware/auth-bearer.js +5 -41
- package/dist/middleware/auth-cookie.d.ts +5 -27
- package/dist/middleware/auth-cookie.js +2 -26
- package/dist/middleware/cors.d.ts +7 -34
- package/dist/middleware/cors.js +7 -34
- package/dist/middleware/remote-auth.d.ts +3 -1
- package/dist/middleware/remote-auth.js +4 -3
- package/dist/middleware/telemetry.d.ts +8 -33
- package/dist/middleware/telemetry.js +2 -31
- package/dist/middleware-runner.d.ts +4 -55
- package/dist/middleware-runner.js +5 -74
- package/dist/permissions.d.ts +3 -44
- package/dist/permissions.js +19 -71
- package/dist/pikku-request.d.ts +0 -6
- package/dist/pikku-request.js +0 -6
- package/dist/pikku-state.d.ts +0 -26
- package/dist/pikku-state.js +2 -30
- package/dist/remote.d.ts +3 -5
- package/dist/remote.js +9 -8
- package/dist/schema.d.ts +5 -39
- package/dist/schema.js +5 -39
- package/dist/scopes.d.ts +4 -23
- package/dist/scopes.js +7 -48
- package/dist/secret-value.d.ts +56 -0
- package/dist/secret-value.js +46 -0
- package/dist/services/ai-agent-runner-service.d.ts +20 -0
- package/dist/services/ai-embedding-service.d.ts +2 -25
- package/dist/services/audit-service.d.ts +74 -4
- package/dist/services/audit-service.js +8 -7
- package/dist/services/content-service.d.ts +1 -46
- package/dist/services/credential-service.d.ts +3 -40
- package/dist/services/credential-wire-service.d.ts +5 -0
- package/dist/services/credential-wire-service.js +9 -1
- package/dist/services/deployment-service.d.ts +3 -9
- package/dist/services/email-service.d.ts +2 -1
- package/dist/services/gateway-service.d.ts +0 -15
- package/dist/services/http-personas.d.ts +80 -0
- package/dist/services/http-personas.js +233 -0
- package/dist/services/in-memory-queue-service.d.ts +0 -14
- package/dist/services/in-memory-queue-service.js +1 -15
- package/dist/services/in-memory-trigger-service.d.ts +0 -18
- package/dist/services/in-memory-trigger-service.js +1 -18
- package/dist/services/in-memory-workflow-service.d.ts +0 -16
- package/dist/services/in-memory-workflow-service.js +4 -33
- package/dist/services/index.d.ts +8 -9
- package/dist/services/index.js +3 -6
- package/dist/services/istanbul-coverage-service.d.ts +1 -5
- package/dist/services/istanbul-coverage-service.js +2 -8
- package/dist/services/jwt-service.d.ts +1 -16
- package/dist/services/local-content-request-handler.d.ts +29 -0
- package/dist/services/local-content-request-handler.js +176 -0
- package/dist/services/local-content.d.ts +13 -2
- package/dist/services/local-content.js +40 -13
- package/dist/services/local-gateway-service.d.ts +0 -16
- package/dist/services/local-gateway-service.js +2 -17
- package/dist/services/local-secrets.d.ts +4 -7
- package/dist/services/local-secrets.js +7 -7
- package/dist/services/logger-console.d.ts +3 -7
- package/dist/services/logger-console.js +3 -7
- package/dist/services/logger.d.ts +22 -40
- package/dist/services/meta-service.d.ts +23 -26
- package/dist/services/meta-service.js +22 -36
- package/dist/services/personas-service.d.ts +134 -0
- package/dist/services/personas-service.js +40 -0
- package/dist/services/pikku-user-id.js +0 -4
- package/dist/services/queue-webhook-service.d.ts +2 -36
- package/dist/services/queue-webhook-service.js +10 -42
- package/dist/services/scheduler-service.d.ts +1 -50
- package/dist/services/scheduler-service.js +0 -10
- package/dist/services/schema-service.d.ts +1 -24
- package/dist/services/scope-service.d.ts +49 -34
- package/dist/services/scoped-secret-service.d.ts +4 -7
- package/dist/services/scoped-secret-service.js +0 -4
- package/dist/services/secret-host-binding.d.ts +8 -0
- package/dist/services/secret-host-binding.js +36 -0
- package/dist/services/secret-service.d.ts +12 -35
- package/dist/services/secretless.d.ts +6 -0
- package/dist/services/secretless.js +21 -0
- package/dist/services/stub-tracker.d.ts +7 -18
- package/dist/services/stub-tracker.js +8 -18
- package/dist/services/system-role-guard.d.ts +33 -0
- package/dist/services/system-role-guard.js +38 -0
- package/dist/services/trigger-service.d.ts +0 -12
- package/dist/services/typed-secret-service.d.ts +5 -11
- package/dist/services/typed-secret-service.js +1 -7
- package/dist/services/v8-coverage-service.d.ts +2 -3
- package/dist/services/v8-coverage-service.js +1 -2
- package/dist/services/variables-service.d.ts +1 -8
- package/dist/services/webhook-service.d.ts +21 -64
- package/dist/services/webhook-service.js +6 -20
- package/dist/services/workflow-service.d.ts +3 -15
- package/dist/testing/service-tests.js +6 -23
- package/dist/time-utils.d.ts +0 -16
- package/dist/time-utils.js +1 -19
- package/dist/types/core.types.d.ts +120 -219
- package/dist/types/core.types.js +0 -42
- package/dist/types/state.types.d.ts +4 -9
- package/dist/utils/hmac.d.ts +4 -10
- package/dist/utils/hmac.js +4 -10
- package/dist/utils/safe-fetch.d.ts +7 -35
- package/dist/utils/safe-fetch.js +13 -53
- package/dist/utils.d.ts +1 -6
- package/dist/utils.js +6 -15
- package/dist/wirings/actor-flow/actor-flow.types.d.ts +1 -34
- package/dist/wirings/actor-flow/index.d.ts +0 -9
- package/dist/wirings/actor-flow/run-conversation.d.ts +5 -5
- package/dist/wirings/actor-flow/run-conversation.js +14 -7
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -5
- package/dist/wirings/ai-agent/ai-agent-agui.js +46 -12
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +7 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +7 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +153 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +256 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +0 -2
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -9
- package/dist/wirings/ai-agent/ai-agent-model-config.js +1 -9
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -99
- package/dist/wirings/ai-agent/ai-agent-prepare.js +65 -132
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-registry.js +5 -1
- package/dist/wirings/ai-agent/ai-agent-runner.js +63 -22
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +180 -64
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +124 -4
- package/dist/wirings/ai-agent/index.d.ts +6 -4
- package/dist/wirings/ai-agent/index.js +5 -4
- package/dist/wirings/ai-agent/voice-input.d.ts +59 -1
- package/dist/wirings/ai-agent/voice-input.js +90 -12
- package/dist/wirings/ai-agent/voice-output.d.ts +69 -1
- package/dist/wirings/ai-agent/voice-output.js +162 -50
- package/dist/wirings/channel/channel-common.d.ts +7 -20
- package/dist/wirings/channel/channel-common.js +7 -21
- package/dist/wirings/channel/channel-handler.js +25 -6
- package/dist/wirings/channel/channel-host-rpc.d.ts +25 -0
- package/dist/wirings/channel/channel-host-rpc.js +38 -0
- package/dist/wirings/channel/channel-middleware-runner.d.ts +0 -12
- package/dist/wirings/channel/channel-middleware-runner.js +0 -12
- package/dist/wirings/channel/channel-rpc-registry.d.ts +31 -0
- package/dist/wirings/channel/channel-rpc-registry.js +89 -0
- package/dist/wirings/channel/channel-rpc-responder.d.ts +15 -0
- package/dist/wirings/channel/channel-rpc-responder.js +71 -0
- package/dist/wirings/channel/channel-rpc-service.d.ts +40 -0
- package/dist/wirings/channel/channel-rpc-service.js +106 -0
- package/dist/wirings/channel/channel-rpc-validators.d.ts +14 -0
- package/dist/wirings/channel/channel-rpc-validators.js +30 -0
- package/dist/wirings/channel/channel-rpc.d.ts +5 -0
- package/dist/wirings/channel/channel-rpc.js +5 -0
- package/dist/wirings/channel/channel-rpc.types.d.ts +90 -0
- package/dist/wirings/channel/channel-rpc.types.js +50 -0
- package/dist/wirings/channel/channel-runner.d.ts +0 -4
- package/dist/wirings/channel/channel-runner.js +0 -14
- package/dist/wirings/channel/channel-store.d.ts +0 -10
- package/dist/wirings/channel/channel.types.d.ts +12 -1
- package/dist/wirings/channel/define-channel-routes.d.ts +0 -20
- package/dist/wirings/channel/define-channel-routes.js +0 -20
- package/dist/wirings/channel/eventhub-service.d.ts +0 -18
- package/dist/wirings/channel/index.d.ts +4 -1
- package/dist/wirings/channel/index.js +2 -0
- package/dist/wirings/channel/local/local-channel-runner.js +3 -1
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +0 -33
- package/dist/wirings/channel/local/local-eventhub-service.js +2 -36
- package/dist/wirings/channel/log-channels.d.ts +0 -4
- package/dist/wirings/channel/log-channels.js +0 -4
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +6 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +2 -5
- package/dist/wirings/cli/channel/cli-approval.d.ts +41 -0
- package/dist/wirings/cli/channel/cli-approval.js +81 -0
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +0 -4
- package/dist/wirings/cli/channel/cli-channel-runner.js +3 -25
- package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +47 -9
- package/dist/wirings/cli/channel/cli-raw-channel-runner.js +24 -16
- package/dist/wirings/cli/channel/cli-raw-client-runner.d.ts +38 -0
- package/dist/wirings/cli/channel/cli-raw-client-runner.js +129 -0
- package/dist/wirings/cli/channel/index.d.ts +5 -0
- package/dist/wirings/cli/channel/index.js +2 -0
- package/dist/wirings/cli/cli-runner.d.ts +20 -20
- package/dist/wirings/cli/cli-runner.js +28 -89
- package/dist/wirings/cli/cli.types.d.ts +14 -3
- package/dist/wirings/cli/command-parser.d.ts +1 -10
- package/dist/wirings/cli/command-parser.js +10 -87
- package/dist/wirings/cli/define-cli-commands.d.ts +1 -17
- package/dist/wirings/cli/define-cli-commands.js +1 -17
- package/dist/wirings/credential/credential.types.d.ts +0 -12
- package/dist/wirings/credential/define-credential.d.ts +48 -0
- package/dist/wirings/credential/define-credential.js +47 -0
- package/dist/wirings/credential/index.d.ts +1 -1
- package/dist/wirings/credential/index.js +1 -1
- package/dist/wirings/credential/validate-credential-definitions.d.ts +2 -4
- package/dist/wirings/gateway/gateway-runner.d.ts +1 -20
- package/dist/wirings/gateway/gateway-runner.js +8 -105
- package/dist/wirings/gateway/gateway.types.d.ts +7 -80
- package/dist/wirings/http/http-routes.d.ts +0 -63
- package/dist/wirings/http/http-routes.js +0 -63
- package/dist/wirings/http/http-runner.d.ts +0 -99
- package/dist/wirings/http/http-runner.js +9 -165
- package/dist/wirings/http/http.types.d.ts +14 -55
- package/dist/wirings/http/log-http-routes.d.ts +0 -4
- package/dist/wirings/http/log-http-routes.js +0 -4
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +0 -40
- package/dist/wirings/http/pikku-fetch-http-request.js +0 -58
- package/dist/wirings/http/pikku-fetch-http-response.js +0 -3
- package/dist/wirings/http/routers/path-to-regex.js +2 -13
- package/dist/wirings/http/web-request.d.ts +0 -8
- package/dist/wirings/http/web-request.js +25 -17
- package/dist/wirings/mcp/mcp-runner.d.ts +1 -4
- package/dist/wirings/mcp/mcp-runner.js +1 -14
- package/dist/wirings/mcp/mcp.types.d.ts +2 -35
- package/dist/wirings/oauth2/oauth2.types.d.ts +0 -28
- package/dist/wirings/oauth2/oauth2.types.js +0 -3
- package/dist/wirings/persona/define-personas.d.ts +32 -0
- package/dist/wirings/persona/define-personas.js +31 -0
- package/dist/wirings/persona/index.d.ts +21 -0
- package/dist/wirings/persona/index.js +17 -0
- package/dist/wirings/persona/persona-email.d.ts +37 -0
- package/dist/wirings/persona/persona-email.js +69 -0
- package/dist/wirings/persona/persona-environments.d.ts +45 -0
- package/dist/wirings/persona/persona-environments.js +81 -0
- package/dist/wirings/persona/persona-mailbox.d.ts +101 -0
- package/dist/wirings/persona/persona-mailbox.js +53 -0
- package/dist/wirings/persona/persona.types.d.ts +136 -0
- package/dist/wirings/persona/persona.types.js +1 -0
- package/dist/wirings/persona/validate-personas.d.ts +53 -0
- package/dist/wirings/persona/validate-personas.js +94 -0
- package/dist/wirings/queue/index.d.ts +3 -0
- package/dist/wirings/queue/index.js +2 -3
- package/dist/wirings/queue/queue-identity.d.ts +28 -0
- package/dist/wirings/queue/queue-identity.js +103 -0
- package/dist/wirings/queue/queue-runner.d.ts +0 -19
- package/dist/wirings/queue/queue-runner.js +9 -30
- package/dist/wirings/queue/queue.types.d.ts +20 -90
- package/dist/wirings/queue/register-queue-helper.d.ts +0 -12
- package/dist/wirings/queue/register-queue-helper.js +0 -11
- package/dist/wirings/queue/signed-queue-service.d.ts +17 -0
- package/dist/wirings/queue/signed-queue-service.js +42 -0
- package/dist/wirings/queue/validate-worker-config.d.ts +2 -23
- package/dist/wirings/queue/validate-worker-config.js +0 -14
- package/dist/wirings/role/define-system-role.d.ts +32 -0
- package/dist/wirings/role/define-system-role.js +31 -0
- package/dist/wirings/role/index.d.ts +3 -0
- package/dist/wirings/role/index.js +2 -0
- package/dist/wirings/role/role.types.d.ts +43 -0
- package/dist/wirings/role/role.types.js +1 -0
- package/dist/wirings/role/validate-role-definitions.d.ts +21 -0
- package/dist/wirings/role/validate-role-definitions.js +71 -0
- package/dist/wirings/rpc/addon-runner.d.ts +0 -19
- package/dist/wirings/rpc/addon-runner.js +0 -51
- package/dist/wirings/rpc/remote-addon-auth.d.ts +3 -13
- package/dist/wirings/rpc/remote-addon-auth.js +7 -11
- package/dist/wirings/rpc/rpc-runner.d.ts +11 -18
- package/dist/wirings/rpc/rpc-runner.js +88 -105
- package/dist/wirings/rpc/rpc-types.d.ts +7 -6
- package/dist/wirings/rpc/wire-addon.d.ts +25 -0
- package/dist/wirings/rpc/wire-addon.js +62 -0
- package/dist/wirings/rpc/wire-remote-addon.d.ts +3 -28
- package/dist/wirings/rpc/wire-remote-addon.js +0 -8
- package/dist/wirings/scheduler/log-schedulers.d.ts +0 -4
- package/dist/wirings/scheduler/log-schedulers.js +0 -4
- package/dist/wirings/scheduler/scheduler-runner.d.ts +0 -1
- package/dist/wirings/scheduler/scheduler-runner.js +0 -1
- package/dist/wirings/scheduler/scheduler.types.d.ts +1 -14
- package/dist/wirings/scope/define-scope.d.ts +32 -0
- package/dist/wirings/scope/define-scope.js +31 -0
- package/dist/wirings/scope/index.d.ts +1 -1
- package/dist/wirings/scope/index.js +1 -1
- package/dist/wirings/scope/scope.types.d.ts +7 -9
- package/dist/wirings/scope/validate-scope-definitions.d.ts +2 -21
- package/dist/wirings/scope/validate-scope-definitions.js +3 -21
- package/dist/wirings/secret/index.d.ts +1 -1
- package/dist/wirings/secret/index.js +1 -1
- package/dist/wirings/secret/secret.types.d.ts +19 -15
- package/dist/wirings/secret/secret.types.js +1 -1
- package/dist/wirings/secret/validate-secret-definitions.d.ts +2 -4
- package/dist/wirings/trigger/trigger-runner.d.ts +0 -27
- package/dist/wirings/trigger/trigger-runner.js +1 -24
- package/dist/wirings/trigger/trigger.types.d.ts +1 -82
- package/dist/wirings/trigger/trigger.types.js +0 -34
- package/dist/wirings/variable/index.d.ts +1 -1
- package/dist/wirings/variable/index.js +1 -1
- package/dist/wirings/variable/validate-variable-definitions.d.ts +2 -4
- package/dist/wirings/variable/variable.types.d.ts +1 -13
- package/dist/wirings/variable/variable.types.js +1 -1
- package/dist/wirings/virtual-user/index.d.ts +30 -0
- package/dist/wirings/virtual-user/index.js +10 -0
- package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +54 -0
- package/dist/wirings/virtual-user/prepare-virtual-user-run.js +49 -0
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +92 -0
- package/dist/wirings/virtual-user/run-virtual-user.js +478 -0
- package/dist/wirings/virtual-user/virtual-user-agents.d.ts +38 -0
- package/dist/wirings/virtual-user/virtual-user-agents.js +24 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +92 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.js +134 -0
- package/dist/wirings/virtual-user/virtual-user-derive.d.ts +26 -0
- package/dist/wirings/virtual-user/virtual-user-derive.js +137 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +79 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.js +128 -0
- package/dist/wirings/virtual-user/virtual-user-intents.d.ts +78 -0
- package/dist/wirings/virtual-user/virtual-user-intents.js +142 -0
- package/dist/wirings/virtual-user/virtual-user-rng.d.ts +24 -0
- package/dist/wirings/virtual-user/virtual-user-rng.js +44 -0
- package/dist/wirings/virtual-user/virtual-user-run-store.d.ts +90 -0
- package/dist/wirings/virtual-user/virtual-user-run-store.js +1 -0
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +21 -0
- package/dist/wirings/virtual-user/virtual-user-target.js +34 -0
- package/dist/wirings/virtual-user/virtual-user.types.d.ts +199 -0
- package/dist/wirings/virtual-user/virtual-user.types.js +8 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +19 -15
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +0 -4
- package/dist/wirings/workflow/dsl/workflow-runner.js +0 -4
- package/dist/wirings/workflow/feature.d.ts +0 -19
- package/dist/wirings/workflow/feature.js +0 -19
- package/dist/wirings/workflow/graph/graph-node.d.ts +0 -98
- package/dist/wirings/workflow/graph/graph-node.js +0 -34
- package/dist/wirings/workflow/graph/graph-runner.js +6 -41
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +0 -4
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -58
- package/dist/wirings/workflow/graph/workflow-graph.types.js +0 -6
- package/dist/wirings/workflow/index.d.ts +5 -7
- package/dist/wirings/workflow/index.js +3 -17
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +87 -5
- package/dist/wirings/workflow/pikku-scenario-service.js +204 -43
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +7 -459
- package/dist/wirings/workflow/pikku-workflow-service.js +58 -551
- package/dist/wirings/workflow/run-timeline.d.ts +0 -47
- package/dist/wirings/workflow/run-timeline.js +0 -22
- package/dist/wirings/workflow/scenario-cookie-jar.d.ts +0 -23
- package/dist/wirings/workflow/scenario-cookie-jar.js +0 -16
- package/dist/wirings/workflow/scenario-poll.d.ts +0 -15
- package/dist/wirings/workflow/scenario-poll.js +0 -12
- package/dist/wirings/workflow/scenario-prose.d.ts +0 -28
- package/dist/wirings/workflow/scenario-prose.js +1 -19
- package/dist/wirings/workflow/scenario-step-guards.d.ts +0 -13
- package/dist/wirings/workflow/scenario-step-guards.js +1 -14
- package/dist/wirings/workflow/scenario-step.types.d.ts +84 -12
- package/dist/wirings/workflow/scenario-step.types.js +5 -1
- package/dist/wirings/workflow/scenario-surface.d.ts +16 -0
- package/dist/wirings/workflow/scenario-surface.js +56 -0
- package/dist/wirings/workflow/workflow-invocation-id.d.ts +0 -18
- package/dist/wirings/workflow/workflow-invocation-id.js +2 -22
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +0 -20
- package/dist/wirings/workflow/workflow-queue-workers.js +0 -19
- package/dist/wirings/workflow/workflow.types.d.ts +5 -195
- package/knowledge/decisions/index.md +19 -0
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +49 -0
- package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +48 -0
- package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +23 -0
- package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +24 -0
- package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +25 -0
- package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +26 -0
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +33 -0
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +28 -0
- package/knowledge/decisions/internals/ai-agent-agui-bridge-obeys-the-client-ordering-contract.md +29 -0
- package/knowledge/decisions/internals/ai-agent-audio-chunks-carry-the-format-the-provider-returned.md +20 -0
- package/knowledge/decisions/internals/ai-agent-credential-suspensions-hide-the-tool-result.md +26 -0
- package/knowledge/decisions/internals/ai-agent-delegate-and-supervise-hide-different-text.md +26 -0
- package/knowledge/decisions/internals/ai-agent-llm-tool-arguments-have-nulls-stripped.md +23 -0
- package/knowledge/decisions/internals/ai-agent-model-config-stays-a-single-resolution-seam.md +25 -0
- package/knowledge/decisions/internals/ai-agent-onerror-hooks-cannot-change-the-failure.md +22 -0
- package/knowledge/decisions/internals/ai-agent-runner-methods-must-keep-their-receiver.md +22 -0
- package/knowledge/decisions/internals/ai-agent-stream-persistence-is-best-effort.md +27 -0
- package/knowledge/decisions/internals/ai-agent-sub-agents-inherit-the-parent-context-block.md +26 -0
- package/knowledge/decisions/internals/ai-agent-tool-execute-failures-are-logged-unconditionally.md +25 -0
- package/knowledge/decisions/internals/ai-agent-voice-input-transcribes-audio-parts-in-place.md +22 -0
- package/knowledge/decisions/internals/ai-agent-working-memory-is-persisted-only-when-valid.md +25 -0
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +30 -0
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +31 -0
- package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +29 -0
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +28 -0
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +27 -0
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +28 -0
- package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +34 -0
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +29 -0
- package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +84 -0
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +41 -0
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +44 -0
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +39 -0
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +42 -0
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +39 -0
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +43 -0
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +38 -0
- package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +44 -0
- package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +27 -0
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +32 -0
- package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +28 -0
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +31 -0
- package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +26 -0
- package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +32 -0
- package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +28 -0
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +30 -0
- package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +26 -0
- package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +28 -0
- package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +32 -0
- package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +26 -0
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +25 -0
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +26 -0
- package/knowledge/decisions/internals/index.md +117 -0
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +25 -0
- package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +26 -0
- package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +24 -0
- package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +53 -0
- package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +28 -0
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +27 -0
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +31 -0
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +32 -0
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +27 -0
- package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +26 -0
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +27 -0
- package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +48 -0
- package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +30 -0
- package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +28 -0
- package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +30 -0
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +29 -0
- package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +27 -0
- package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +40 -0
- package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +26 -0
- package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +33 -0
- package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +26 -0
- package/knowledge/decisions/internals/validate-checks-personas-through-a-shared-module.md +43 -0
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +26 -0
- package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +25 -0
- package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +58 -0
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +34 -0
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +42 -0
- package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +38 -0
- package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +29 -0
- package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +42 -0
- package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +25 -0
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +29 -0
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +43 -0
- package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +29 -0
- package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +42 -0
- package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +33 -0
- package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +32 -0
- package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +31 -0
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +39 -0
- package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +29 -0
- package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +33 -0
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +37 -0
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +50 -0
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +43 -0
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +32 -0
- package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +18 -0
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +34 -0
- package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +26 -0
- package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +33 -0
- package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +27 -0
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +34 -0
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +38 -0
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +30 -0
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +26 -0
- package/knowledge/decisions/security/actor-flow-missing-approval-decisions-default-to-denied.md +22 -0
- package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +27 -0
- package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +27 -0
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +43 -0
- package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +52 -0
- package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +46 -0
- package/knowledge/decisions/security/ai-agent-approval-forwarding-requires-a-symbol-brand.md +27 -0
- package/knowledge/decisions/security/ai-agent-credential-requests-are-symbol-branded.md +37 -0
- package/knowledge/decisions/security/ai-agent-gate-requires-a-session-only-when-auth-is-true.md +31 -0
- package/knowledge/decisions/security/ai-agent-ownership-failures-never-echo-the-resource.md +23 -0
- package/knowledge/decisions/security/ai-agent-resume-re-runs-the-authorization-gate.md +22 -0
- package/knowledge/decisions/security/ai-agent-sessionless-deployments-have-no-thread-ownership.md +39 -0
- package/knowledge/decisions/security/ai-agent-thread-ownership-composes-the-session-principal.md +30 -0
- package/knowledge/decisions/security/ai-agent-tool-filtering-reads-the-live-function-config.md +24 -0
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +30 -0
- package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +49 -0
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +76 -0
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +39 -0
- package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +37 -0
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +31 -0
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +30 -0
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +40 -0
- package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +33 -0
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +46 -0
- package/knowledge/decisions/security/index.md +55 -0
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +27 -0
- package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +40 -0
- package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +31 -0
- package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +26 -0
- package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +69 -0
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +39 -0
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +34 -0
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +49 -0
- package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +30 -0
- package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +28 -0
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +34 -0
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +37 -0
- package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +25 -0
- package/knowledge/decisions/security/workflow-actor-steps-always-use-the-real-transport.md +34 -0
- package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +40 -0
- package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +31 -0
- package/knowledge/index.md +24 -0
- package/knowledge/questions/index.md +15 -0
- package/package.json +6 -2
- package/run-tests.sh +0 -0
- package/src/column-form.test.ts +97 -0
- package/src/column-form.ts +58 -0
- package/src/crypto-utils.test.ts +460 -19
- package/src/crypto-utils.ts +306 -59
- package/src/data-classification.ts +45 -7
- package/src/dev/hot-reload.test.ts +0 -4
- package/src/dev/hot-reload.ts +11 -30
- package/src/dev/module-runner.ts +7 -32
- package/src/dev/reload-meta.ts +9 -29
- package/src/errors/error-handler.ts +20 -35
- package/src/errors/error.test.ts +30 -1
- package/src/errors/errors.ts +73 -157
- package/src/function/abort-scope.test.ts +97 -0
- package/src/function/abort-scope.ts +80 -0
- package/src/function/function-runner.test.ts +0 -7
- package/src/function/function-runner.ts +62 -32
- package/src/function/functions.types.ts +95 -138
- package/src/function/index.ts +1 -0
- package/src/function/list.types.test.ts +3 -25
- package/src/function/list.types.ts +12 -62
- package/src/handle-error.ts +0 -18
- package/src/index.ts +84 -3
- package/src/middleware/auth-apikey.test.ts +0 -1
- package/src/middleware/auth-apikey.ts +0 -17
- package/src/middleware/auth-bearer.test.ts +3 -5
- package/src/middleware/auth-bearer.ts +5 -41
- package/src/middleware/auth-cookie.test.ts +0 -6
- package/src/middleware/auth-cookie.ts +2 -26
- package/src/middleware/cors.test.ts +34 -0
- package/src/middleware/cors.ts +12 -33
- package/src/middleware/remote-auth.test.ts +26 -10
- package/src/middleware/remote-auth.ts +11 -3
- package/src/middleware/telemetry.ts +2 -31
- package/src/middleware-runner.test.ts +0 -2
- package/src/middleware-runner.ts +5 -74
- package/src/permissions.test.ts +30 -0
- package/src/permissions.ts +24 -74
- package/src/pikku-request.ts +0 -6
- package/src/pikku-state.ts +2 -30
- package/src/production-barrels-stay-lean.test.ts +110 -0
- package/src/remote.test.ts +173 -0
- package/src/remote.ts +18 -8
- package/src/schema.ts +5 -39
- package/src/scopes.ts +7 -48
- package/src/secret-value.test.ts +204 -0
- package/src/secret-value.ts +111 -0
- package/src/services/ai-agent-runner-service.ts +20 -0
- package/src/services/ai-embedding-service.ts +3 -25
- package/src/services/audit-service.ts +88 -11
- package/src/services/content-service.ts +1 -46
- package/src/services/credential-service.ts +3 -40
- package/src/services/credential-wire-service.test.ts +0 -2
- package/src/services/credential-wire-service.ts +9 -1
- package/src/services/deployment-service.ts +3 -9
- package/src/services/email-service.ts +3 -1
- package/src/services/gateway-service.ts +0 -15
- package/src/services/{http-scenario-actors-converse.test.ts → http-personas-converse.test.ts} +38 -9
- package/src/services/{http-scenario-actors.test.ts → http-personas.test.ts} +39 -22
- package/src/services/{http-scenario-actors.ts → http-personas.ts} +85 -45
- package/src/services/in-memory-queue-service.ts +1 -15
- package/src/services/in-memory-trigger-service.ts +1 -18
- package/src/services/in-memory-workflow-service.test.ts +0 -13
- package/src/services/in-memory-workflow-service.ts +4 -38
- package/src/services/index.ts +23 -18
- package/src/services/istanbul-coverage-service.ts +2 -8
- package/src/services/jwt-service.ts +1 -16
- package/src/services/local-content-request-handler.test.ts +202 -0
- package/src/services/local-content-request-handler.ts +267 -0
- package/src/services/local-content.test.ts +159 -27
- package/src/services/local-content.ts +55 -23
- package/src/services/local-gateway-service.ts +2 -17
- package/src/services/local-secrets.test.ts +20 -5
- package/src/services/local-secrets.ts +15 -11
- package/src/services/logger-console.test.ts +0 -1
- package/src/services/logger-console.ts +3 -7
- package/src/services/logger.ts +31 -46
- package/src/services/meta-service.test.ts +1 -5
- package/src/services/meta-service.ts +41 -61
- package/src/services/{scenario-actors-service.ts → personas-service.ts} +48 -43
- package/src/services/pikku-user-id.ts +0 -4
- package/src/services/queue-webhook-service.test.ts +2 -1
- package/src/services/queue-webhook-service.ts +10 -42
- package/src/services/scheduler-service.ts +1 -50
- package/src/services/schema-service.ts +1 -24
- package/src/services/scope-service.ts +50 -34
- package/src/services/scoped-secret-service.ts +4 -7
- package/src/services/secret-host-binding.test.ts +138 -0
- package/src/services/secret-host-binding.ts +51 -0
- package/src/services/secret-service.ts +12 -35
- package/src/services/secretless.test.ts +54 -0
- package/src/services/secretless.ts +29 -0
- package/src/services/stub-tracker.ts +8 -18
- package/src/services/system-role-guard.test.ts +93 -0
- package/src/services/system-role-guard.ts +71 -0
- package/src/services/trigger-service.ts +0 -12
- package/src/services/typed-secret-service.ts +12 -14
- package/src/services/v8-coverage-service.ts +3 -6
- package/src/services/variables-service.ts +1 -8
- package/src/services/webhook-service.ts +23 -64
- package/src/services/workflow-service.ts +3 -20
- package/src/testing/service-tests.ts +6 -32
- package/src/time-utils.ts +1 -19
- package/src/types/core.types.ts +137 -229
- package/src/types/state.types.ts +7 -9
- package/src/utils/hmac.ts +4 -10
- package/src/utils/safe-fetch.ts +13 -54
- package/src/utils.test.ts +11 -2
- package/src/utils.ts +6 -15
- package/src/wirings/actor-flow/actor-flow.types.ts +1 -34
- package/src/wirings/actor-flow/index.ts +0 -9
- package/src/wirings/actor-flow/run-conversation.test.ts +11 -6
- package/src/wirings/actor-flow/run-conversation.ts +19 -12
- package/src/wirings/ai-agent/ai-agent-agui.test.ts +91 -10
- package/src/wirings/ai-agent/ai-agent-agui.ts +49 -17
- package/src/wirings/ai-agent/ai-agent-helpers.ts +20 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +842 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.ts +399 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-model-config.ts +1 -9
- package/src/wirings/ai-agent/ai-agent-prepare.test.ts +202 -31
- package/src/wirings/ai-agent/ai-agent-prepare.ts +89 -139
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +191 -6
- package/src/wirings/ai-agent/ai-agent-registry.ts +18 -1
- package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +11 -9
- package/src/wirings/ai-agent/ai-agent-runner.ts +85 -35
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
- package/src/wirings/ai-agent/ai-agent-stream.ts +224 -76
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +130 -5
- package/src/wirings/ai-agent/index.ts +37 -3
- package/src/wirings/ai-agent/voice-input.test.ts +137 -7
- package/src/wirings/ai-agent/voice-input.ts +96 -12
- package/src/wirings/ai-agent/voice-output.test.ts +512 -0
- package/src/wirings/ai-agent/voice-output.ts +243 -56
- package/src/wirings/channel/channel-common.ts +15 -20
- package/src/wirings/channel/channel-handler.test.ts +50 -0
- package/src/wirings/channel/channel-handler.ts +32 -11
- package/src/wirings/channel/channel-host-rpc.test.ts +150 -0
- package/src/wirings/channel/channel-host-rpc.ts +69 -0
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -1
- package/src/wirings/channel/channel-middleware-runner.ts +0 -12
- package/src/wirings/channel/channel-rpc-registry.ts +116 -0
- package/src/wirings/channel/channel-rpc-responder.ts +117 -0
- package/src/wirings/channel/channel-rpc-service.ts +146 -0
- package/src/wirings/channel/channel-rpc-validators.ts +65 -0
- package/src/wirings/channel/channel-rpc.test.ts +820 -0
- package/src/wirings/channel/channel-rpc.ts +5 -0
- package/src/wirings/channel/channel-rpc.types.ts +150 -0
- package/src/wirings/channel/channel-runner.ts +0 -14
- package/src/wirings/channel/channel-store.ts +0 -10
- package/src/wirings/channel/channel.types.ts +19 -8
- package/src/wirings/channel/define-channel-routes.ts +0 -20
- package/src/wirings/channel/eventhub-service.ts +0 -18
- package/src/wirings/channel/index.ts +35 -0
- package/src/wirings/channel/local/local-channel-handler.ts +3 -1
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -10
- package/src/wirings/channel/local/local-channel-runner.ts +3 -1
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -13
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -37
- package/src/wirings/channel/log-channels.ts +0 -4
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +83 -2
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +7 -0
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +2 -5
- package/src/wirings/cli/channel/cli-approval.test.ts +177 -0
- package/src/wirings/cli/channel/cli-approval.ts +135 -0
- package/src/wirings/cli/channel/cli-channel-runner.ts +4 -26
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +169 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +59 -16
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +480 -0
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +185 -0
- package/src/wirings/cli/channel/index.ts +13 -0
- package/src/wirings/cli/cli-runner.test.ts +0 -1
- package/src/wirings/cli/cli-runner.ts +46 -88
- package/src/wirings/cli/cli.types.ts +14 -3
- package/src/wirings/cli/command-parser.test.ts +0 -4
- package/src/wirings/cli/command-parser.ts +11 -91
- package/src/wirings/cli/define-cli-commands.ts +1 -17
- package/src/wirings/credential/credential.types.ts +0 -12
- package/src/wirings/credential/{wire-credential.ts → define-credential.ts} +7 -7
- package/src/wirings/credential/index.ts +1 -1
- package/src/wirings/credential/validate-credential-definitions.ts +2 -4
- package/src/wirings/gateway/gateway-runner.test.ts +1 -21
- package/src/wirings/gateway/gateway-runner.ts +8 -110
- package/src/wirings/gateway/gateway.types.ts +7 -80
- package/src/wirings/http/http-routes.test.ts +0 -3
- package/src/wirings/http/http-routes.ts +0 -86
- package/src/wirings/http/http-runner.test.ts +0 -1
- package/src/wirings/http/http-runner.ts +8 -167
- package/src/wirings/http/http.types.ts +15 -62
- package/src/wirings/http/log-http-routes.ts +0 -4
- package/src/wirings/http/pikku-fetch-http-request.test.ts +2 -10
- package/src/wirings/http/pikku-fetch-http-request.ts +0 -58
- package/src/wirings/http/pikku-fetch-http-response.test.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -3
- package/src/wirings/http/routers/path-to-regex.test.ts +4 -17
- package/src/wirings/http/routers/path-to-regex.ts +2 -13
- package/src/wirings/http/web-request.test.ts +33 -2
- package/src/wirings/http/web-request.ts +30 -17
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -1
- package/src/wirings/mcp/mcp-runner.ts +2 -17
- package/src/wirings/mcp/mcp.types.ts +7 -42
- package/src/wirings/oauth2/oauth2.types.ts +0 -30
- package/src/wirings/persona/define-personas.ts +33 -0
- package/src/wirings/persona/index.ts +62 -0
- package/src/wirings/persona/persona-email.ts +87 -0
- package/src/wirings/persona/persona-environments.test.ts +183 -0
- package/src/wirings/persona/persona-environments.ts +138 -0
- package/src/wirings/persona/persona-mailbox.ts +156 -0
- package/src/wirings/persona/persona.test.ts +220 -0
- package/src/wirings/persona/persona.types.ts +142 -0
- package/src/wirings/persona/validate-personas.ts +133 -0
- package/src/wirings/queue/index.ts +13 -3
- package/src/wirings/queue/queue-identity.test.ts +454 -0
- package/src/wirings/queue/queue-identity.ts +176 -0
- package/src/wirings/queue/queue-runner.ts +12 -31
- package/src/wirings/queue/queue.types.ts +25 -90
- package/src/wirings/queue/register-queue-helper.ts +0 -14
- package/src/wirings/queue/signed-queue-service.ts +60 -0
- package/src/wirings/queue/validate-worker-config.ts +2 -28
- package/src/wirings/role/define-system-role.ts +33 -0
- package/src/wirings/role/index.ts +13 -0
- package/src/wirings/role/role.test.ts +104 -0
- package/src/wirings/role/role.types.ts +47 -0
- package/src/wirings/role/validate-role-definitions.ts +93 -0
- package/src/wirings/rpc/addon-auth-tags.test.ts +223 -0
- package/src/wirings/rpc/addon-runner.ts +0 -56
- package/src/wirings/rpc/addon-scopes.test.ts +225 -0
- package/src/wirings/rpc/remote-addon-auth.ts +9 -16
- package/src/wirings/rpc/rpc-runner.test.ts +192 -6
- package/src/wirings/rpc/rpc-runner.ts +145 -127
- package/src/wirings/rpc/rpc-types.ts +11 -6
- package/src/wirings/rpc/wire-addon.test.ts +43 -1
- package/src/wirings/rpc/wire-addon.ts +99 -0
- package/src/wirings/rpc/wire-remote-addon.ts +9 -29
- package/src/wirings/scheduler/log-schedulers.ts +0 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +1 -8
- package/src/wirings/scheduler/scheduler-runner.ts +0 -2
- package/src/wirings/scheduler/scheduler.types.ts +1 -14
- package/src/wirings/scope/{wire-scope.ts → define-scope.ts} +5 -6
- package/src/wirings/scope/index.ts +1 -1
- package/src/wirings/scope/scope.test.ts +1 -2
- package/src/wirings/scope/scope.types.ts +7 -9
- package/src/wirings/scope/validate-scope-definitions.ts +3 -21
- package/src/wirings/secret/index.ts +1 -1
- package/src/wirings/secret/secret.types.ts +19 -15
- package/src/wirings/secret/validate-secret-definitions.ts +2 -4
- package/src/wirings/trigger/trigger-runner.ts +1 -27
- package/src/wirings/trigger/trigger.types.ts +1 -82
- package/src/wirings/variable/index.ts +1 -1
- package/src/wirings/variable/validate-variable-definitions.ts +2 -4
- package/src/wirings/variable/variable.types.ts +1 -13
- package/src/wirings/virtual-user/index.ts +88 -0
- package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +115 -0
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +95 -0
- package/src/wirings/virtual-user/run-virtual-user.test.ts +765 -0
- package/src/wirings/virtual-user/run-virtual-user.ts +671 -0
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +65 -0
- package/src/wirings/virtual-user/virtual-user-agents.ts +57 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +215 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +184 -0
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +398 -0
- package/src/wirings/virtual-user/virtual-user-derive.ts +173 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +63 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +213 -0
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +208 -0
- package/src/wirings/virtual-user/virtual-user-intents.ts +185 -0
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +72 -0
- package/src/wirings/virtual-user/virtual-user-rng.ts +50 -0
- package/src/wirings/virtual-user/virtual-user-run-store.ts +98 -0
- package/src/wirings/virtual-user/virtual-user-target.ts +47 -0
- package/src/wirings/virtual-user/virtual-user.types.ts +219 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +19 -20
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -4
- package/src/wirings/workflow/feature.ts +0 -19
- package/src/wirings/workflow/graph/graph-node.ts +0 -136
- package/src/wirings/workflow/graph/graph-runner.test.ts +20 -19
- package/src/wirings/workflow/graph/graph-runner.ts +6 -41
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -4
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -58
- package/src/wirings/workflow/index.ts +10 -44
- package/src/wirings/workflow/pikku-scenario-service.ts +235 -61
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -39
- package/src/wirings/workflow/pikku-workflow-service.ts +77 -674
- package/src/wirings/workflow/run-timeline.test.ts +7 -19
- package/src/wirings/workflow/run-timeline.ts +0 -56
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -1
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -25
- package/src/wirings/workflow/scenario-expectations.test.ts +2 -7
- package/src/wirings/workflow/scenario-hooks.test.ts +2 -7
- package/src/wirings/workflow/scenario-poll.test.ts +0 -2
- package/src/wirings/workflow/scenario-poll.ts +0 -15
- package/src/wirings/workflow/scenario-prose.test.ts +5 -7
- package/src/wirings/workflow/scenario-prose.ts +1 -29
- package/src/wirings/workflow/scenario-service.test.ts +2 -10
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +163 -19
- package/src/wirings/workflow/scenario-step.types.ts +94 -12
- package/src/wirings/workflow/scenario-surface.test.ts +146 -0
- package/src/wirings/workflow/scenario-surface.ts +71 -0
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +14 -15
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -4
- package/src/wirings/workflow/workflow-inline-authority.test.ts +169 -0
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -2
- package/src/wirings/workflow/workflow-invocation-id.ts +2 -22
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -7
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -9
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -21
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +8 -7
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -5
- package/src/wirings/workflow/workflow-run-context.test.ts +5 -10
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -5
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +19 -4
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -7
- package/src/wirings/workflow/workflow.types.ts +5 -201
- package/tsconfig.tsbuildinfo +1 -1
- package/tsconfig.type-tests.json +12 -0
- package/src/middleware/timeout.ts +0 -22
- package/src/pikku-response.ts +0 -5
- package/src/wirings/mcp/mcp-endpoint-registry.test.d.ts +0 -1
- package/src/wirings/workflow/dsl/index.ts +0 -36
- package/src/wirings/workflow/graph/index.ts +0 -15
|
@@ -2,23 +2,11 @@ import { getSingletonServices } from '../pikku-state.js';
|
|
|
2
2
|
import { getDurationInMilliseconds } from '../time-utils.js';
|
|
3
3
|
import { safeFetch } from '../utils/safe-fetch.js';
|
|
4
4
|
import { DEFAULT_WEBHOOK_RETRIES, DEFAULT_WEBHOOK_SIGNATURE_HEADER, PIKKU_OUTGOING_WEBHOOK_QUEUE_NAME, WebhookService, } from './webhook-service.js';
|
|
5
|
-
/** Cap on the response body captured on a failed attempt. */
|
|
6
5
|
const MAX_CAPTURED_RESPONSE_BODY = 2_000;
|
|
7
|
-
|
|
8
|
-
* Default {@link WebhookService} implementation: serializes and signs the
|
|
9
|
-
* payload, then enqueues a delivery job onto the `pikku-outgoing-webhooks`
|
|
10
|
-
* queue. The signature is computed at enqueue time so the signing key never
|
|
11
|
-
* enters the queue payload; the actual HTTP POST happens in
|
|
12
|
-
* {@link pikkuWebhookWorkerFunc}, and the queue's `attempts`/`backoff`
|
|
13
|
-
* options drive retries.
|
|
14
|
-
*/
|
|
6
|
+
// knowledge: decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md
|
|
15
7
|
export class QueueWebhookService extends WebhookService {
|
|
16
8
|
queueService;
|
|
17
|
-
|
|
18
|
-
* The queue is a constructor dependency rather than a `getSingletonServices()`
|
|
19
|
-
* lookup so that a project wiring up outgoing webhooks without a queue fails
|
|
20
|
-
* to compile, instead of throwing on the first `send()`.
|
|
21
|
-
*/
|
|
9
|
+
// knowledge: decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md
|
|
22
10
|
constructor(queueService) {
|
|
23
11
|
super();
|
|
24
12
|
this.queueService = queueService;
|
|
@@ -29,10 +17,8 @@ export class QueueWebhookService extends WebhookService {
|
|
|
29
17
|
return { jobId };
|
|
30
18
|
}
|
|
31
19
|
/**
|
|
32
|
-
*
|
|
33
|
-
* `
|
|
34
|
-
* store-backed subclass can persist a delivery row and attach its
|
|
35
|
-
* `deliveryId` without re-implementing signing or the retry policy.
|
|
20
|
+
* `protected` so a store-backed subclass can persist a delivery row and attach
|
|
21
|
+
* its `deliveryId` without re-implementing signing or the retry policy.
|
|
36
22
|
*/
|
|
37
23
|
async prepareDelivery(input) {
|
|
38
24
|
const services = getSingletonServices();
|
|
@@ -45,8 +31,8 @@ export class QueueWebhookService extends WebhookService {
|
|
|
45
31
|
};
|
|
46
32
|
let secret = input.secret;
|
|
47
33
|
if (secret === undefined && webhookConfig?.secret) {
|
|
48
|
-
// Naive read
|
|
49
|
-
secret = await services.secrets.getSecret(webhookConfig.secret);
|
|
34
|
+
// Naive read: caching is the secret service's concern, not ours.
|
|
35
|
+
secret = (await services.secrets.getSecret(webhookConfig.secret)).reveal();
|
|
50
36
|
if (!secret) {
|
|
51
37
|
services.logger.error(`Webhook signing secret '${webhookConfig.secret}' (config.webhook.secret) resolved to nothing — outgoing webhooks will be sent UNSIGNED.`);
|
|
52
38
|
}
|
|
@@ -63,13 +49,7 @@ export class QueueWebhookService extends WebhookService {
|
|
|
63
49
|
};
|
|
64
50
|
return { jobData, options: this.resolveJobOptions(input) };
|
|
65
51
|
}
|
|
66
|
-
|
|
67
|
-
* Resolve a delivery's retry policy into queue job options, mirroring the
|
|
68
|
-
* workflow service: per-call values win over `config.webhook` defaults, an
|
|
69
|
-
* explicitly-set `retries` (including 0) is always honored, and `attempts`
|
|
70
|
-
* is ALWAYS passed so the queue can never fall back to its own default.
|
|
71
|
-
* Backoff is exponential unless a concrete `retryDelay` selects a fixed one.
|
|
72
|
-
*/
|
|
52
|
+
// knowledge: decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md
|
|
73
53
|
resolveJobOptions(input) {
|
|
74
54
|
const webhookConfig = getSingletonServices().config?.webhook;
|
|
75
55
|
const retries = input.retries ?? webhookConfig?.retries ?? DEFAULT_WEBHOOK_RETRIES;
|
|
@@ -82,18 +62,7 @@ export class QueueWebhookService extends WebhookService {
|
|
|
82
62
|
return { attempts: retries + 1, ...(backoff ? { backoff } : {}) };
|
|
83
63
|
}
|
|
84
64
|
}
|
|
85
|
-
|
|
86
|
-
* Queue worker for the `pikku-outgoing-webhooks` queue: POSTs the delivery to its
|
|
87
|
-
* target URL. Any non-2xx response (or network error) throws so the queue
|
|
88
|
-
* retries the job according to the `attempts`/`backoff` set at enqueue time;
|
|
89
|
-
* the queue runner logs each failed attempt.
|
|
90
|
-
*
|
|
91
|
-
* A `deliveryId` is only present when a store-backed `webhookService` (e.g.
|
|
92
|
-
* `KyselyWebhookService`) enqueued the job, so each attempt (success or failure)
|
|
93
|
-
* is persisted via `webhookService.recordAttempt` before the throw — the console
|
|
94
|
-
* delivery history reflects every try, not just the outcome. The queue-only
|
|
95
|
-
* default never sets a `deliveryId`, so its base `recordAttempt` is never hit.
|
|
96
|
-
*/
|
|
65
|
+
// knowledge: decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md
|
|
97
66
|
export async function pikkuWebhookWorkerFunc(services, { url, body, headers, deliveryId }) {
|
|
98
67
|
let statusCode;
|
|
99
68
|
let responseBody;
|
|
@@ -104,8 +73,8 @@ export async function pikkuWebhookWorkerFunc(services, { url, body, headers, del
|
|
|
104
73
|
allowedHosts = getSingletonServices().config?.webhook?.allowedHosts;
|
|
105
74
|
}
|
|
106
75
|
catch {
|
|
107
|
-
//
|
|
108
|
-
//
|
|
76
|
+
// Uninitialised singletons (a bare worker invocation): fall back to the
|
|
77
|
+
// default private-host block rather than failing the delivery.
|
|
109
78
|
}
|
|
110
79
|
try {
|
|
111
80
|
const response = await safeFetch(url, {
|
|
@@ -125,7 +94,6 @@ export async function pikkuWebhookWorkerFunc(services, { url, body, headers, del
|
|
|
125
94
|
error = e instanceof Error ? e.message : String(e);
|
|
126
95
|
}
|
|
127
96
|
if (deliveryId && services.webhookService) {
|
|
128
|
-
// Best-effort history: a store failure must not mask the delivery result.
|
|
129
97
|
await services.webhookService
|
|
130
98
|
.recordAttempt(deliveryId, { statusCode, responseBody, error, delivered })
|
|
131
99
|
.catch((storeError) => services.logger.error(`Failed to record webhook delivery attempt for ${deliveryId}`, storeError));
|
|
@@ -1,71 +1,22 @@
|
|
|
1
1
|
import type { CoreUserSession } from '../types/core.types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Minimal metadata for listing scheduled tasks
|
|
4
|
-
*/
|
|
5
2
|
export interface ScheduledTaskSummary {
|
|
6
|
-
/** Unique task ID */
|
|
7
3
|
taskId: string;
|
|
8
|
-
/** RPC function name to invoke */
|
|
9
4
|
rpcName: string;
|
|
10
|
-
/** Scheduled execution time */
|
|
11
5
|
scheduledFor: Date;
|
|
12
6
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Full metadata for a scheduled task retrieved from the queue
|
|
15
|
-
*/
|
|
16
7
|
export interface ScheduledTaskInfo extends ScheduledTaskSummary {
|
|
17
|
-
/** Data to pass to the RPC function */
|
|
18
8
|
data?: any;
|
|
19
|
-
/** User session */
|
|
20
9
|
session?: CoreUserSession;
|
|
21
|
-
/** Task status */
|
|
22
10
|
status?: 'scheduled' | 'active' | 'completed' | 'failed';
|
|
23
11
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Abstract scheduler service for persistent scheduled task management
|
|
26
|
-
* Implementations use queue backends (pg-boss, BullMQ) for distributed scheduling
|
|
27
|
-
*/
|
|
28
12
|
export declare abstract class SchedulerService {
|
|
29
|
-
/**
|
|
30
|
-
* Initialize the scheduler service
|
|
31
|
-
*/
|
|
32
13
|
abstract init(): Promise<void>;
|
|
33
|
-
/**
|
|
34
|
-
* Schedule a one-off delayed RPC call
|
|
35
|
-
* @param delay - Delay before execution (number in milliseconds or duration string like "5h", "30m")
|
|
36
|
-
* @param rpcName - RPC function name to invoke
|
|
37
|
-
* @param data - Data to pass to the RPC function
|
|
38
|
-
* @param session - Optional user session
|
|
39
|
-
* @returns Task ID
|
|
40
|
-
*/
|
|
14
|
+
/** `delay` is milliseconds as a number, or a duration string such as `"5h"` / `"30m"`. */
|
|
41
15
|
abstract scheduleRPC(delay: number | string, rpcName: string, data?: any, session?: CoreUserSession): Promise<string>;
|
|
42
|
-
/**
|
|
43
|
-
* Unschedule a task by ID
|
|
44
|
-
* @param taskId - Task ID
|
|
45
|
-
* @returns Success status
|
|
46
|
-
*/
|
|
47
16
|
abstract unschedule(taskId: string): Promise<boolean>;
|
|
48
|
-
/**
|
|
49
|
-
* Get a scheduled task by ID with full details
|
|
50
|
-
* @param taskId - Task ID
|
|
51
|
-
* @returns Task info or null if not found
|
|
52
|
-
*/
|
|
53
17
|
abstract getTask(taskId: string): Promise<ScheduledTaskInfo | null>;
|
|
54
|
-
/**
|
|
55
|
-
* Get all scheduled tasks with minimal info
|
|
56
|
-
* @returns Array of task summaries with taskId, rpcName, and schedule
|
|
57
|
-
*/
|
|
58
18
|
abstract getAllTasks(): Promise<ScheduledTaskSummary[]>;
|
|
59
|
-
/**
|
|
60
|
-
* Close any open connections
|
|
61
|
-
*/
|
|
62
19
|
abstract close(): Promise<void>;
|
|
63
|
-
/**
|
|
64
|
-
* Start recurring scheduled tasks
|
|
65
|
-
*/
|
|
66
20
|
start(): Promise<void>;
|
|
67
|
-
/**
|
|
68
|
-
* Stop recurring scheduled tasks
|
|
69
|
-
*/
|
|
70
21
|
stop(): Promise<void>;
|
|
71
22
|
}
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Abstract scheduler service for persistent scheduled task management
|
|
3
|
-
* Implementations use queue backends (pg-boss, BullMQ) for distributed scheduling
|
|
4
|
-
*/
|
|
5
1
|
export class SchedulerService {
|
|
6
|
-
/**
|
|
7
|
-
* Start recurring scheduled tasks
|
|
8
|
-
*/
|
|
9
2
|
async start() { }
|
|
10
|
-
/**
|
|
11
|
-
* Stop recurring scheduled tasks
|
|
12
|
-
*/
|
|
13
3
|
async stop() { }
|
|
14
4
|
}
|
|
@@ -1,30 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interface for a schema service that handles schema compilation, validation, and management.
|
|
3
|
-
*/
|
|
4
1
|
export interface SchemaService {
|
|
5
|
-
/**
|
|
6
|
-
* Compiles a schema with the provided name and value, making it available for use.
|
|
7
|
-
* @param {string} name - The unique name for the schema.
|
|
8
|
-
* @param {any} value - The schema definition or configuration to be compiled.
|
|
9
|
-
* @returns {Promise<void> | void} A promise if asynchronous, or void if synchronous.
|
|
10
|
-
*/
|
|
11
2
|
compileSchema: (name: string, value: any) => Promise<void> | void;
|
|
12
|
-
/**
|
|
13
|
-
* Validates data against a specified schema.
|
|
14
|
-
* @param {string} schema - The name of the schema to validate against.
|
|
15
|
-
* @param {any} data - The data to validate against the schema.
|
|
16
|
-
* @returns {Promise<void> | void} A promise if asynchronous, or void if synchronous.
|
|
17
|
-
*/
|
|
18
3
|
validateSchema: (schema: string, data: any) => Promise<void> | void;
|
|
19
|
-
/**
|
|
20
|
-
* Retrieves a set of all registered schema names.
|
|
21
|
-
* @returns {Set<string>} A set containing the names of all available schemas.
|
|
22
|
-
*/
|
|
23
4
|
getSchemaNames: () => Set<string>;
|
|
24
|
-
/**
|
|
25
|
-
* Retrieves the property keys from a compiled JSON schema.
|
|
26
|
-
* @param {string} schemaName - The name of the schema.
|
|
27
|
-
* @returns {string[]} An array of property keys, or empty array if schema not found.
|
|
28
|
-
*/
|
|
5
|
+
/** Empty when the schema is not registered. */
|
|
29
6
|
getSchemaKeys: (schemaName: string) => string[];
|
|
30
7
|
}
|
|
@@ -1,67 +1,82 @@
|
|
|
1
1
|
import type { FlatScope } from '../wirings/scope/scope.types.js';
|
|
2
|
-
|
|
2
|
+
import type { SystemRole } from '../wirings/role/role.types.js';
|
|
3
3
|
export interface Role {
|
|
4
4
|
name: string;
|
|
5
5
|
description?: string;
|
|
6
6
|
scopes: string[];
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Resolves and administers the scopes granted to a user.
|
|
10
|
-
*
|
|
11
|
-
* Implementations are called at the **session boundary** — e.g. better-auth's
|
|
12
|
-
* `mapSession` — never by the function runner. The runner reads
|
|
13
|
-
* `session.scopes` and never performs I/O, which keeps it viable on Workers
|
|
14
|
-
* and Lambda. Because the session is rebuilt per request, a scope change takes
|
|
15
|
-
* effect on the next call with nothing cached and nothing to invalidate.
|
|
16
|
-
*
|
|
17
|
-
* `syncScopes` is deliberately additive: scopes are declared in code, so a
|
|
18
|
-
* removed declaration leaves an inert row rather than silently revoking a
|
|
19
|
-
* grant mid-deploy. Removal is an explicit operation (`pikku scopes prune`).
|
|
20
|
-
*/
|
|
21
|
-
export interface ScopeService {
|
|
22
7
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
8
|
+
* True when the role was declared in code with `defineSystemRole` rather
|
|
9
|
+
* than composed by an admin. System roles may be granted, but not renamed,
|
|
10
|
+
* re-scoped or deleted — see {@link ScopeService.syncSystemRoles}.
|
|
25
11
|
*/
|
|
26
|
-
|
|
12
|
+
system?: boolean;
|
|
27
13
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
14
|
+
* False when a system role's declaration has been removed from code but its
|
|
15
|
+
* row survives: still held by whoever holds it, no longer offered for new
|
|
16
|
+
* grants, awaiting `pikku roles prune`.
|
|
30
17
|
*/
|
|
18
|
+
declared?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface ScopeService {
|
|
21
|
+
syncScopes(scopes: FlatScope[]): Promise<void>;
|
|
22
|
+
/** The union of role-derived scopes and scopes granted directly. */
|
|
31
23
|
resolveScopes(userId: string): Promise<string[]>;
|
|
32
24
|
/**
|
|
33
|
-
* The
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* declared in code — inert (no function can require it) and awaiting
|
|
37
|
-
* `pikku scopes prune`.
|
|
25
|
+
* The whole vocabulary a role can be composed from. `declared: false` marks a
|
|
26
|
+
* scope still in the store but no longer declared in code: inert, since no
|
|
27
|
+
* function can require it, and awaiting `pikku scopes prune`.
|
|
38
28
|
*/
|
|
39
29
|
listScopes(): Promise<Array<FlatScope & {
|
|
40
30
|
declared: boolean;
|
|
41
31
|
}>>;
|
|
32
|
+
/**
|
|
33
|
+
* Registers the roles declared with `defineSystemRole`. Additive on the same
|
|
34
|
+
* terms as {@link syncScopes}: a removed declaration leaves the row in place,
|
|
35
|
+
* marked `declared: false`, rather than revoking everyone's grant on deploy.
|
|
36
|
+
*
|
|
37
|
+
* A role's scope set *is* re-synced, because that is the declaration's whole
|
|
38
|
+
* content — editing `defineSystemRole` is how you change what a system role
|
|
39
|
+
* means, and the deploy is when it takes effect.
|
|
40
|
+
*
|
|
41
|
+
* Called once during startup with the generated role list.
|
|
42
|
+
*/
|
|
43
|
+
syncSystemRoles(roles: SystemRole[]): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates an admin-composed role.
|
|
46
|
+
*
|
|
47
|
+
* Must throw {@link SystemRoleShadowedError} when `role.name` matches a
|
|
48
|
+
* declared system role. Two rows answering to one name make "does this user
|
|
49
|
+
* hold `buyer`?" depend on which the store returns first.
|
|
50
|
+
*/
|
|
42
51
|
createRole(role: Role): Promise<void>;
|
|
52
|
+
/** Must throw {@link SystemRoleImmutableError} for a system role. */
|
|
43
53
|
deleteRole(name: string): Promise<void>;
|
|
54
|
+
/** Must throw {@link SystemRoleImmutableError} for a system role. */
|
|
44
55
|
setRoleScopes(name: string, scopes: string[]): Promise<void>;
|
|
45
56
|
listRoles(): Promise<Role[]>;
|
|
46
57
|
addUserToRole(userId: string, role: string, grantedBy?: string): Promise<void>;
|
|
47
58
|
removeUserFromRole(userId: string, role: string): Promise<void>;
|
|
48
59
|
listUserRoles(userId: string): Promise<string[]>;
|
|
49
|
-
/**
|
|
50
|
-
* Grants a scope directly to a user, outside of any role. Additive: the
|
|
51
|
-
* resolved set is the union of role-derived and directly-granted scopes.
|
|
52
|
-
*/
|
|
60
|
+
/** Grants outside of any role; additive with the user's role-derived scopes. */
|
|
53
61
|
addScopeToUser(userId: string, scope: string, grantedBy?: string): Promise<void>;
|
|
54
62
|
removeScopeFromUser(userId: string, scope: string): Promise<void>;
|
|
55
63
|
/** Only the scopes granted directly, not those inherited from roles. */
|
|
56
64
|
listUserScopes(userId: string): Promise<string[]>;
|
|
57
|
-
/**
|
|
58
|
-
* Scopes present in the store that are no longer declared in code, with the
|
|
59
|
-
* roles that would lose them. Powers `pikku scopes audit`.
|
|
60
|
-
*/
|
|
65
|
+
/** Undeclared scopes with the roles that would lose them; powers `pikku scopes audit`. */
|
|
61
66
|
findStaleScopes(): Promise<Array<{
|
|
62
67
|
scope: string;
|
|
63
68
|
roles: string[];
|
|
64
69
|
}>>;
|
|
65
70
|
/** Removes undeclared scopes, cascading them out of roles. */
|
|
66
71
|
pruneScopes(): Promise<string[]>;
|
|
72
|
+
/**
|
|
73
|
+
* System roles in the store whose declaration has gone, with the number of
|
|
74
|
+
* users still holding each. Powers `pikku roles audit`.
|
|
75
|
+
*/
|
|
76
|
+
findStaleSystemRoles(): Promise<Array<{
|
|
77
|
+
role: string;
|
|
78
|
+
users: number;
|
|
79
|
+
}>>;
|
|
80
|
+
/** Removes undeclared system roles, cascading them out of user grants. */
|
|
81
|
+
pruneSystemRoles(): Promise<string[]>;
|
|
67
82
|
}
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
* A read-only wrapper around SecretService that restricts access
|
|
4
|
-
* to only a defined set of allowed secret keys.
|
|
5
|
-
*/
|
|
1
|
+
import type { SecretValue } from '../secret-value.js';
|
|
2
|
+
import type { SecretService, SecretValues } from './secret-service.js';
|
|
6
3
|
export declare class ScopedSecretService implements SecretService {
|
|
7
4
|
private secrets;
|
|
8
5
|
private allowedKeys;
|
|
9
6
|
constructor(secrets: SecretService, allowedKeys: Set<string>);
|
|
10
7
|
private assertAllowed;
|
|
11
|
-
getSecret<T = string>(key: string): Promise<T
|
|
8
|
+
getSecret<T = string>(key: string): Promise<SecretValue<T>>;
|
|
12
9
|
hasSecret(key: string): Promise<boolean>;
|
|
13
10
|
setSecret(_key: string, _value: unknown): Promise<void>;
|
|
14
11
|
deleteSecret(_key: string): Promise<void>;
|
|
15
|
-
getSecrets<T extends Record<string, unknown> = Record<string, unknown>>(keys: (keyof T & string)[]): Promise<Partial<T
|
|
12
|
+
getSecrets<T extends Record<string, unknown> = Record<string, unknown>>(keys: (keyof T & string)[]): Promise<Partial<SecretValues<T>>>;
|
|
16
13
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SecretDefinitionsMeta } from '../wirings/secret/secret.types.js';
|
|
2
|
+
export declare class SecretHostNotAllowedError extends Error {
|
|
3
|
+
readonly secretId: string;
|
|
4
|
+
readonly host: string;
|
|
5
|
+
constructor(secretId: string, host: string, allowedHosts: string[] | undefined);
|
|
6
|
+
}
|
|
7
|
+
/** Refuses a secret/host pairing the declarations do not permit. */
|
|
8
|
+
export declare const assertSecretAllowedForHost: (secretId: string, url: string | URL, secretDefinitions: SecretDefinitionsMeta | undefined, requireAllowedHosts?: boolean) => void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export class SecretHostNotAllowedError extends Error {
|
|
2
|
+
secretId;
|
|
3
|
+
host;
|
|
4
|
+
constructor(secretId, host, allowedHosts) {
|
|
5
|
+
super(allowedHosts?.length
|
|
6
|
+
? `Secret '${secretId}' may not be sent to '${host}' — it is declared for ${allowedHosts.map((h) => `'${h}'`).join(', ')}. Add the host to allowedHosts on its defineSecret if this is intended.`
|
|
7
|
+
: `Secret '${secretId}' has no allowedHosts and this project requires one. Declare the hosts it may be sent to on its defineSecret.`);
|
|
8
|
+
this.secretId = secretId;
|
|
9
|
+
this.host = host;
|
|
10
|
+
this.name = 'SecretHostNotAllowedError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Exact match, or a single leading `*.` wildcard anchored on a dot. */
|
|
14
|
+
const hostMatches = (host, pattern) => {
|
|
15
|
+
const h = host.toLowerCase();
|
|
16
|
+
const p = pattern.toLowerCase();
|
|
17
|
+
if (p.startsWith('*.')) {
|
|
18
|
+
return h.endsWith(p.slice(1)) && h.length > p.length - 1;
|
|
19
|
+
}
|
|
20
|
+
return h === p;
|
|
21
|
+
};
|
|
22
|
+
/** Refuses a secret/host pairing the declarations do not permit. */
|
|
23
|
+
export const assertSecretAllowedForHost = (secretId, url, secretDefinitions, requireAllowedHosts = false) => {
|
|
24
|
+
const host = (typeof url === 'string' ? new URL(url) : url).hostname;
|
|
25
|
+
const definition = Object.values(secretDefinitions ?? {}).find((d) => d.secretId === secretId);
|
|
26
|
+
const allowedHosts = definition?.allowedHosts;
|
|
27
|
+
if (!allowedHosts?.length) {
|
|
28
|
+
if (requireAllowedHosts) {
|
|
29
|
+
throw new SecretHostNotAllowedError(secretId, host, allowedHosts);
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (!allowedHosts.some((pattern) => hostMatches(host, pattern))) {
|
|
34
|
+
throw new SecretHostNotAllowedError(secretId, host, allowedHosts);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -1,42 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { SecretValue } from '../secret-value.js';
|
|
2
|
+
/** A record of secrets, each still wrapped. */
|
|
3
|
+
export type SecretValues<T> = {
|
|
4
|
+
[K in keyof T]: SecretValue<T[K]>;
|
|
5
|
+
};
|
|
4
6
|
export interface SecretService {
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* @returns A promise that resolves to the secret value.
|
|
9
|
-
* @throws If the secret is not found.
|
|
10
|
-
*/
|
|
11
|
-
getSecret<T = string>(key: string): Promise<T>;
|
|
12
|
-
/**
|
|
13
|
-
* Checks if a secret exists without throwing.
|
|
14
|
-
* @param key - The key of the secret to check.
|
|
15
|
-
* @returns A promise that resolves to true if the secret exists, false otherwise.
|
|
16
|
-
*/
|
|
7
|
+
/** Throws if the secret is not found. Unwrap the result with `.reveal()`. */
|
|
8
|
+
getSecret<T = string>(key: string): Promise<SecretValue<T>>;
|
|
9
|
+
/** Answers for any key, including a disallowed one — it must not throw. */
|
|
17
10
|
hasSecret(key: string): Promise<boolean>;
|
|
18
|
-
/**
|
|
19
|
-
* Stores a secret value.
|
|
20
|
-
* @param key - The key to store the secret under.
|
|
21
|
-
* @param value - The value to store.
|
|
22
|
-
* @returns A promise that resolves when the secret is stored.
|
|
23
|
-
*/
|
|
24
11
|
setSecret(key: string, value: unknown): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* Deletes a secret by key.
|
|
27
|
-
* @param key - The key of the secret to delete.
|
|
28
|
-
* @returns A promise that resolves when the secret is deleted.
|
|
29
|
-
*/
|
|
30
12
|
deleteSecret(key: string): Promise<void>;
|
|
31
13
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* `Partial<T>` and callers must handle keys that may be absent at runtime.
|
|
36
|
-
*
|
|
37
|
-
* Pass a shape as `T` to get a typed result without casting, e.g.
|
|
38
|
-
* `await secrets.getSecrets<{ FOO: string; BAR: { id: string } }>(['FOO', 'BAR'])`.
|
|
39
|
-
* @param keys - The keys of the secrets to retrieve.
|
|
14
|
+
* Missing keys are omitted rather than throwing, hence `Partial<T>`: callers
|
|
15
|
+
* must handle keys absent at runtime. Pass a shape as `T` to avoid casting,
|
|
16
|
+
* e.g. `getSecrets<{ FOO: string; BAR: { id: string } }>(['FOO', 'BAR'])`.
|
|
40
17
|
*/
|
|
41
|
-
getSecrets<T extends Record<string, unknown> = Record<string, unknown>>(keys: (keyof T & string)[]): Promise<Partial<T
|
|
18
|
+
getSecrets<T extends Record<string, unknown> = Record<string, unknown>>(keys: (keyof T & string)[]): Promise<Partial<SecretValues<T>>>;
|
|
42
19
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SecretlessServices } from '../types/core.types.js';
|
|
2
|
+
export declare class SecretAccessDeniedError extends Error {
|
|
3
|
+
constructor(context: string);
|
|
4
|
+
}
|
|
5
|
+
/** Returns `services` with `secrets` replaced by a throwing accessor. */
|
|
6
|
+
export declare const withoutSecrets: <T extends object>(services: T, context: string) => SecretlessServices<T>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export class SecretAccessDeniedError extends Error {
|
|
2
|
+
constructor(context) {
|
|
3
|
+
super(`'secrets' is not available inside ${context}. SecretService is confined to pikkuServices, pikkuWireServices, addon service factories and middleware — give a service the secret when you construct it and ask that service here.`);
|
|
4
|
+
this.name = 'SecretAccessDeniedError';
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/** Returns `services` with `secrets` replaced by a throwing accessor. */
|
|
8
|
+
export const withoutSecrets = (services, context) => {
|
|
9
|
+
if (!('secrets' in services)) {
|
|
10
|
+
return services;
|
|
11
|
+
}
|
|
12
|
+
const stripped = { ...services };
|
|
13
|
+
Object.defineProperty(stripped, 'secrets', {
|
|
14
|
+
get() {
|
|
15
|
+
throw new SecretAccessDeniedError(context);
|
|
16
|
+
},
|
|
17
|
+
configurable: true,
|
|
18
|
+
enumerable: false,
|
|
19
|
+
});
|
|
20
|
+
return stripped;
|
|
21
|
+
};
|
|
@@ -4,10 +4,9 @@ export type StubCall = {
|
|
|
4
4
|
args: unknown[];
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Services never touched by an assertion stay lenient.
|
|
7
|
+
* Strict per service: once a scenario asserts any call on a service, every
|
|
8
|
+
* recorded call on it must be verified by the end of the scenario or the After
|
|
9
|
+
* hook fails. A service no assertion ever touched stays lenient.
|
|
11
10
|
*/
|
|
12
11
|
export declare class StubTracker {
|
|
13
12
|
private readonly calls;
|
|
@@ -21,23 +20,13 @@ export declare class StubTracker {
|
|
|
21
20
|
assertNoCalls(service: string, method?: string, predicate?: (args: unknown[]) => boolean, description?: string): void;
|
|
22
21
|
verify(): void;
|
|
23
22
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Creates a Proxy suitable for passing as `existingServices` to
|
|
26
|
-
* `createSingletonServices`. Every property returns `tracker.stub(prop)`
|
|
27
|
-
* EXCEPT `schema`, which returns `undefined` so the service factory creates
|
|
28
|
-
* a real schema service. Stubbing the schema makes validation a no-op —
|
|
29
|
-
* required fields pass silently and tests validate nothing.
|
|
30
|
-
*/
|
|
23
|
+
/** Pass as `existingServices` to `createSingletonServices`. */
|
|
31
24
|
export declare function createStubProxy(tracker: StubTracker): Record<string, unknown>;
|
|
32
|
-
/** The process-wide tracker
|
|
25
|
+
/** The process-wide tracker `stub()`/`spy()` record into; read by the console's getStubCalls/resetStubs RPCs. */
|
|
33
26
|
export declare const getStubTracker: () => StubTracker;
|
|
34
|
-
/** True when the server was started by `pikku dev --test
|
|
27
|
+
/** True when the server was started by `pikku dev --test`, which sets PIKKU_TEST_RUN. */
|
|
35
28
|
export declare const isTestRun: () => boolean;
|
|
36
|
-
/**
|
|
37
|
-
* Creates a recording fake for a service. Methods present on `impl` run and
|
|
38
|
-
* their result is returned; missing methods resolve `undefined`. Every call
|
|
39
|
-
* is recorded so scenarios can assert via workflow.expectService().
|
|
40
|
-
*/
|
|
29
|
+
/** Methods on `impl` run and return; every other method resolves `undefined`. */
|
|
41
30
|
export declare function stub<T = any>(service: string, impl?: Partial<T>): T;
|
|
42
31
|
/** Wraps a real service so every method call is recorded and passed through */
|
|
43
32
|
export declare function spy<T extends object>(service: string, real: T): T;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Services never touched by an assertion stay lenient.
|
|
2
|
+
* Strict per service: once a scenario asserts any call on a service, every
|
|
3
|
+
* recorded call on it must be verified by the end of the scenario or the After
|
|
4
|
+
* hook fails. A service no assertion ever touched stays lenient.
|
|
6
5
|
*/
|
|
7
6
|
export class StubTracker {
|
|
8
7
|
calls = new Map();
|
|
@@ -87,16 +86,11 @@ export class StubTracker {
|
|
|
87
86
|
}
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
|
-
/**
|
|
91
|
-
* Creates a Proxy suitable for passing as `existingServices` to
|
|
92
|
-
* `createSingletonServices`. Every property returns `tracker.stub(prop)`
|
|
93
|
-
* EXCEPT `schema`, which returns `undefined` so the service factory creates
|
|
94
|
-
* a real schema service. Stubbing the schema makes validation a no-op —
|
|
95
|
-
* required fields pass silently and tests validate nothing.
|
|
96
|
-
*/
|
|
89
|
+
/** Pass as `existingServices` to `createSingletonServices`. */
|
|
97
90
|
export function createStubProxy(tracker) {
|
|
98
91
|
return new Proxy({}, {
|
|
99
92
|
get(_, prop) {
|
|
93
|
+
// knowledge: decisions/internals/the-schema-service-is-never-stubbed.md
|
|
100
94
|
if (prop === 'schema')
|
|
101
95
|
return undefined;
|
|
102
96
|
return tracker.stub(prop);
|
|
@@ -104,16 +98,12 @@ export function createStubProxy(tracker) {
|
|
|
104
98
|
});
|
|
105
99
|
}
|
|
106
100
|
const defaultStubTracker = new StubTracker();
|
|
107
|
-
/** The process-wide tracker
|
|
101
|
+
/** The process-wide tracker `stub()`/`spy()` record into; read by the console's getStubCalls/resetStubs RPCs. */
|
|
108
102
|
export const getStubTracker = () => defaultStubTracker;
|
|
109
|
-
/** True when the server was started by `pikku dev --test
|
|
103
|
+
/** True when the server was started by `pikku dev --test`, which sets PIKKU_TEST_RUN. */
|
|
110
104
|
export const isTestRun = () => globalThis
|
|
111
105
|
.process?.env?.PIKKU_TEST_RUN === 'true';
|
|
112
|
-
/**
|
|
113
|
-
* Creates a recording fake for a service. Methods present on `impl` run and
|
|
114
|
-
* their result is returned; missing methods resolve `undefined`. Every call
|
|
115
|
-
* is recorded so scenarios can assert via workflow.expectService().
|
|
116
|
-
*/
|
|
106
|
+
/** Methods on `impl` run and return; every other method resolves `undefined`. */
|
|
117
107
|
export function stub(service, impl) {
|
|
118
108
|
return new Proxy((impl ?? {}), {
|
|
119
109
|
get(target, method) {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Role } from './scope-service.js';
|
|
2
|
+
/**
|
|
3
|
+
* The guards a {@link ScopeService} implementation must apply before mutating
|
|
4
|
+
* a role.
|
|
5
|
+
*
|
|
6
|
+
* Shared rather than left to each implementation because the rule is a
|
|
7
|
+
* contract, not a policy: a store that lets the console delete `buyer` makes
|
|
8
|
+
* every persona and scenario written against `buyer` silently stop testing
|
|
9
|
+
* what it claims to, and nothing fails at the point of the mistake. Two
|
|
10
|
+
* implementations disagreeing about that would be worse than either rule.
|
|
11
|
+
*
|
|
12
|
+
* `isSystemRole` is passed in rather than a role list, so an implementation can
|
|
13
|
+
* answer it from a column, a cached set, or a query, whichever is cheap.
|
|
14
|
+
*/
|
|
15
|
+
export type IsSystemRole = (name: string) => boolean | Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Refuses a destructive or re-scoping operation against a declared role.
|
|
18
|
+
*
|
|
19
|
+
* @param operation a verb phrase for the message, e.g. `'delete role'`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const assertRoleIsMutable: (name: string, isSystemRole: IsSystemRole, operation: string) => Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Refuses a new custom role that would shadow a declared one.
|
|
24
|
+
*/
|
|
25
|
+
export declare const assertRoleNameAvailable: (name: string, isSystemRole: IsSystemRole) => Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Why the console must render a role as locked, or `null` when it is editable.
|
|
28
|
+
*
|
|
29
|
+
* Returned rather than a boolean so the UI shows a reason instead of a
|
|
30
|
+
* disabled button with no explanation — the difference between a user filing a
|
|
31
|
+
* bug and a user editing the declaration.
|
|
32
|
+
*/
|
|
33
|
+
export declare const roleLockReason: (role: Role) => string | null;
|