@pikku/core 0.12.84 → 0.12.86
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 +424 -0
- package/dist/bootstrap-compat/root.d.ts +20 -0
- package/dist/classification/column-form.d.ts +32 -0
- package/dist/classification/column-form.js +42 -0
- package/dist/classification/data-classification.d.ts +64 -0
- package/dist/classification/index.d.ts +13 -0
- package/dist/classification/index.js +2 -0
- package/dist/classification/secret-value.d.ts +56 -0
- package/dist/classification/secret-value.js +46 -0
- package/dist/crypto-utils.d.ts +1 -1
- package/dist/ecosystem/agent-scorer.d.ts +1 -1
- package/dist/ecosystem/agent.d.ts +4 -1
- package/dist/ecosystem/channel/local.d.ts +2 -0
- package/dist/ecosystem/channel/local.js +2 -0
- package/dist/ecosystem/channel/serverless.d.ts +9 -0
- package/dist/ecosystem/channel/serverless.js +1 -0
- package/dist/ecosystem/channel.d.ts +3 -0
- package/dist/ecosystem/channel.js +1 -0
- package/dist/ecosystem/cli.d.ts +1 -1
- package/dist/ecosystem/cli.js +1 -1
- package/dist/ecosystem/credential.d.ts +1 -0
- package/dist/ecosystem/crypto-utils.d.ts +8 -0
- package/dist/ecosystem/crypto-utils.js +1 -0
- package/dist/ecosystem/dev.d.ts +1 -0
- package/dist/ecosystem/dev.js +1 -0
- package/{src/ecosystem/testing.ts → dist/ecosystem/errors.d.ts} +3 -3
- package/dist/ecosystem/errors.js +2 -0
- package/dist/ecosystem/function.d.ts +1 -1
- package/dist/ecosystem/function.js +1 -1
- package/dist/ecosystem/http.d.ts +3 -1
- package/dist/ecosystem/http.js +3 -1
- package/dist/ecosystem/mcp.d.ts +1 -1
- package/dist/ecosystem/mcp.js +1 -1
- package/dist/ecosystem/middleware.d.ts +2 -1
- package/dist/ecosystem/middleware.js +2 -1
- package/dist/ecosystem/persona.d.ts +4 -2
- package/dist/ecosystem/persona.js +2 -1
- package/dist/ecosystem/queue.d.ts +4 -2
- package/dist/ecosystem/queue.js +3 -1
- package/dist/ecosystem/role.d.ts +1 -0
- package/dist/ecosystem/rpc.d.ts +2 -0
- package/dist/ecosystem/rpc.js +1 -0
- package/dist/ecosystem/scenario.d.ts +8 -2
- package/dist/ecosystem/scenario.js +5 -1
- package/dist/ecosystem/scheduler.d.ts +2 -1
- package/dist/ecosystem/scheduler.js +2 -1
- package/dist/ecosystem/schema.d.ts +2 -1
- package/dist/ecosystem/schema.js +1 -1
- package/dist/ecosystem/scope.d.ts +2 -0
- package/dist/ecosystem/scope.js +1 -0
- package/dist/ecosystem/secret.d.ts +2 -0
- package/dist/ecosystem/secret.js +1 -0
- package/dist/ecosystem/services/local-content.d.ts +2 -1
- package/dist/ecosystem/services/local-content.js +1 -1
- package/dist/ecosystem/services/local-meta.d.ts +1 -0
- package/dist/ecosystem/services/local-meta.js +1 -0
- package/dist/ecosystem/services.d.ts +11 -3
- package/dist/ecosystem/services.js +7 -1
- package/dist/ecosystem/trigger.d.ts +1 -0
- package/dist/ecosystem/trigger.js +1 -1
- package/dist/ecosystem/types.d.ts +6 -3
- package/dist/ecosystem/types.js +3 -2
- package/dist/ecosystem/variable.d.ts +1 -0
- package/dist/ecosystem/virtual-user.d.ts +3 -0
- package/dist/ecosystem/virtual-user.js +3 -0
- package/dist/ecosystem/workflow.d.ts +2 -0
- package/dist/ecosystem/workflow.js +2 -0
- package/dist/errors/index.d.ts +8 -0
- package/dist/errors/index.js +1 -0
- package/dist/errors/serialized-error.d.ts +7 -0
- package/dist/function/function-meta.types.d.ts +139 -0
- package/dist/function/function-runner.d.ts +3 -2
- package/dist/function/function-runner.js +31 -11
- package/dist/function/functions.types.d.ts +10 -2
- package/dist/function/index.d.ts +8 -2
- package/dist/function/index.js +4 -1
- package/dist/function/pikku-request.d.ts +8 -0
- package/dist/function/pikku-request.js +15 -0
- package/dist/middleware/auth-apikey.d.ts +2 -10
- package/dist/middleware/auth-apikey.js +1 -1
- package/dist/middleware/auth-bearer.d.ts +2 -10
- package/dist/middleware/auth-bearer.js +1 -1
- package/dist/middleware/auth-cookie.d.ts +2 -10
- package/dist/middleware/auth-cookie.js +1 -1
- package/dist/middleware/cors.d.ts +5 -11
- package/dist/middleware/cors.js +13 -6
- package/dist/middleware/index.d.ts +3 -0
- package/dist/middleware/index.js +1 -0
- package/dist/middleware/middleware-factories.d.ts +9 -0
- package/dist/middleware/middleware-factories.js +19 -0
- package/dist/middleware/middleware.types.d.ts +27 -0
- package/dist/middleware/middleware.types.js +1 -0
- package/dist/middleware/remote-auth.d.ts +2 -2
- package/dist/middleware/remote-auth.js +1 -1
- package/dist/middleware/telemetry.d.ts +4 -20
- package/dist/middleware/telemetry.js +1 -1
- package/dist/middleware-runner.d.ts +2 -1
- package/dist/pikku-state.d.ts +2 -1
- package/dist/services/audit-service.d.ts +1 -1
- package/dist/services/credential-wire-service.js +1 -1
- package/dist/services/email-service.d.ts +1 -1
- package/dist/services/file-scenario-run-store.d.ts +58 -0
- package/dist/services/file-scenario-run-store.js +214 -0
- package/dist/services/in-memory-workflow-service.d.ts +1 -1
- package/dist/services/index.d.ts +5 -1
- package/dist/services/index.js +3 -0
- package/dist/services/local-secrets.d.ts +1 -1
- package/dist/services/local-secrets.js +1 -1
- package/dist/services/logger.d.ts +7 -7
- package/dist/services/meta-service.d.ts +2 -1
- package/dist/services/scoped-secret-service.d.ts +1 -1
- package/dist/services/secret-service.d.ts +1 -1
- package/dist/services/typed-secret-service.d.ts +16 -2
- package/dist/services/typed-secret-service.js +5 -0
- package/dist/services/webhook-service.d.ts +1 -1
- package/dist/services/workflow-service.d.ts +2 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +1 -0
- package/dist/types/core.types.d.ts +30 -180
- package/dist/types/core.types.js +1 -19
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +1 -0
- package/dist/types/state.types.d.ts +3 -1
- package/dist/utils.d.ts +13 -0
- package/dist/utils.js +2 -0
- package/dist/wirings/addon/addon-runner.d.ts +17 -0
- package/dist/wirings/addon/addon-runner.js +150 -0
- package/dist/wirings/addon/index.d.ts +6 -0
- package/dist/wirings/addon/index.js +3 -0
- package/dist/wirings/addon/remote-addon-auth.d.ts +16 -0
- package/dist/wirings/addon/remote-addon-auth.js +39 -0
- package/dist/wirings/addon/wire-addon.d.ts +80 -0
- package/dist/wirings/addon/wire-addon.js +120 -0
- package/dist/wirings/addon/wire-remote-addon.d.ts +22 -0
- package/dist/wirings/addon/wire-remote-addon.js +11 -0
- package/dist/wirings/agent/agent-prepare.d.ts +3 -3
- package/dist/wirings/agent/agent-prepare.js +1 -1
- package/dist/wirings/agent/agent-runner.js +2 -3
- package/dist/wirings/agent/agent-stream.js +2 -2
- package/dist/wirings/agent/agent-utils.d.ts +13 -0
- package/dist/wirings/agent/agent-utils.js +16 -0
- package/dist/wirings/agent/agent.types.d.ts +3 -2
- package/dist/wirings/agent/index.d.ts +1 -1
- package/dist/wirings/agent/voice-input.js +1 -1
- package/dist/wirings/agent/voice-output.js +1 -1
- package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +13 -0
- package/dist/wirings/agent-scorer/agent-scorer-judge.js +52 -0
- package/dist/wirings/agent-scorer/agent-scorer.d.ts +7 -1
- package/dist/wirings/agent-scorer/agent-scorer.js +1 -0
- package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +20 -0
- package/dist/wirings/agent-scorer/index.d.ts +1 -1
- package/dist/wirings/channel/channel-common.d.ts +2 -1
- package/dist/wirings/channel/channel-middleware-runner.d.ts +2 -1
- package/dist/wirings/channel/channel.types.d.ts +1 -1
- package/dist/wirings/channel/serverless/index.d.ts +1 -0
- package/dist/wirings/cli/channel/index.d.ts +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +2 -1
- package/dist/wirings/cli/cli-runner.js +4 -1
- package/dist/wirings/cli/cli.types.d.ts +21 -2
- package/dist/wirings/cli/command-parser.js +157 -23
- package/dist/wirings/gateway/gateway.types.d.ts +2 -1
- package/dist/wirings/http/http-runner.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +1 -1
- package/dist/wirings/http/http.types.d.ts +2 -2
- package/dist/wirings/http/index.d.ts +1 -0
- package/dist/wirings/http/index.js +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.js +1 -1
- package/dist/wirings/http/pikku-fetch-http-response.js +2 -2
- package/dist/wirings/mcp/mcp.types.d.ts +1 -1
- package/dist/wirings/persona/index.d.ts +1 -1
- package/dist/wirings/persona/index.js +1 -1
- package/dist/wirings/persona/persona.types.d.ts +14 -0
- package/dist/wirings/queue/queue.types.d.ts +1 -1
- package/dist/wirings/queue/signed-queue-service.d.ts +1 -1
- package/dist/wirings/rpc/index.d.ts +0 -6
- package/dist/wirings/rpc/index.js +0 -3
- package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -1
- package/dist/wirings/rpc/remote-addon-auth.js +1 -1
- package/dist/wirings/rpc/rpc-runner.js +2 -2
- package/dist/wirings/rpc/wire-addon.d.ts +1 -1
- package/dist/wirings/scheduler/scheduler.types.d.ts +2 -1
- package/dist/wirings/scope/index.d.ts +1 -0
- package/dist/wirings/scope/index.js +1 -0
- package/dist/wirings/secret/secret.types.d.ts +10 -0
- package/dist/wirings/secret/validate-secret-definitions.js +2 -0
- package/dist/wirings/variable/validate-variable-definitions.js +2 -0
- package/dist/wirings/variable/variable.types.d.ts +9 -0
- package/dist/wirings/virtual-user/index.d.ts +1 -1
- package/dist/wirings/virtual-user/index.js +1 -1
- package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +1 -1
- package/dist/wirings/virtual-user/virtual-user-derive.d.ts +1 -1
- package/dist/wirings/workflow/graph/graph-node.d.ts +9 -2
- package/dist/wirings/workflow/graph/graph-node.js +2 -0
- package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -0
- package/dist/wirings/workflow/graph/graph-runner.js +283 -31
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +16 -1
- package/dist/wirings/workflow/index.d.ts +2 -0
- package/dist/wirings/workflow/index.js +1 -0
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +14 -4
- package/dist/wirings/workflow/pikku-scenario-service.js +44 -16
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -1
- package/dist/wirings/workflow/pikku-workflow-service.js +3 -4
- package/dist/wirings/workflow/run-timeline.d.ts +1 -1
- package/dist/wirings/workflow/scenario-run.types.d.ts +171 -0
- package/dist/wirings/workflow/scenario-run.types.js +1 -0
- package/dist/wirings/workflow/scenario-step-guards.d.ts +1 -2
- package/dist/wirings/workflow/scenario-step-guards.js +0 -8
- package/dist/wirings/workflow/scenario-step.types.d.ts +27 -12
- package/dist/wirings/workflow/workflow-approval.js +2 -1
- package/dist/wirings/workflow/workflow-run-engine.types.d.ts +2 -1
- package/dist/wirings/workflow/workflow.types.d.ts +2 -1
- package/knowledge/decisions/index.md +2 -0
- package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +1 -1
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +1 -1
- package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +2 -2
- package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +6 -6
- package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +1 -1
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +1 -1
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +1 -1
- package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +1 -1
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +1 -1
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +1 -1
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +1 -1
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +1 -1
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +1 -1
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +1 -1
- package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +4 -4
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +1 -1
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +3 -3
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +2 -2
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +2 -2
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +1 -1
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +1 -1
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +3 -3
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +1 -1
- package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +4 -4
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +1 -1
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +1 -1
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +1 -1
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +1 -1
- package/knowledge/decisions/internals/index.md +4 -2
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +1 -1
- package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +1 -1
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +1 -1
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +1 -1
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +1 -1
- package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +2 -2
- package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +5 -5
- package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +1 -1
- package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +1 -1
- package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +43 -19
- package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +1 -1
- package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +1 -1
- package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +3 -3
- package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +1 -1
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +1 -1
- package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +1 -1
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +1 -1
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +1 -1
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +1 -1
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +1 -1
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +1 -1
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +1 -1
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +9 -5
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +2 -2
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +1 -1
- package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +1 -1
- package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +1 -1
- package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +2 -3
- package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +1 -1
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +1 -1
- package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +1 -1
- package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +3 -3
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +4 -3
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +1 -1
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +2 -2
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +1 -1
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +2 -2
- package/knowledge/decisions/security/index.md +2 -0
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +1 -1
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +3 -3
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +1 -1
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +2 -2
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +1 -1
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +2 -2
- package/knowledge/index.md +3 -1
- package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +1 -1
- package/knowledge/questions/index.md +2 -0
- package/package.json +14 -13
- package/run-tests.sh +0 -0
- package/scripts/generate-api-report.d.mts +1 -1
- package/scripts/generate-api-report.mjs +67 -60
- package/scripts/generate-api-report.mts +11 -45
- package/src/api-report.test.ts +70 -1
- package/src/app-alias-surface.test.ts +179 -0
- package/src/app-leaf-surface.test.ts +217 -0
- package/src/bootstrap-compat/root.ts +20 -0
- package/src/{column-form.test.ts → classification/column-form.test.ts} +2 -2
- package/src/{data-classification.ts → classification/data-classification.ts} +1 -5
- package/src/classification/index.ts +38 -0
- package/src/{secret-value.test.ts → classification/secret-value.test.ts} +2 -2
- package/src/{secret-value.ts → classification/secret-value.ts} +1 -6
- package/src/crypto-utils.ts +1 -1
- package/src/dev/reload-meta.test.ts +1 -1
- package/src/errors/index.ts +9 -0
- package/src/errors/serialized-error.ts +9 -0
- package/src/factory-functions.test.ts +4 -2
- package/src/function/function-meta.types.ts +151 -0
- package/src/function/function-runner.test.ts +4 -2
- package/src/function/function-runner.ts +47 -14
- package/src/function/functions.types.ts +11 -7
- package/src/function/index.ts +24 -5
- package/src/function/list.types.ts +1 -3
- package/src/middleware/auth-apikey.ts +4 -2
- package/src/middleware/auth-bearer.test.ts +1 -1
- package/src/middleware/auth-bearer.ts +4 -2
- package/src/middleware/auth-cookie.ts +4 -1
- package/src/middleware/cors.test.ts +126 -5
- package/src/middleware/cors.ts +19 -8
- package/src/middleware/index.ts +16 -0
- package/src/middleware/middleware-factories.ts +62 -0
- package/src/middleware/middleware.types.ts +61 -0
- package/src/middleware/remote-auth.test.ts +1 -1
- package/src/middleware/remote-auth.ts +1 -1
- package/src/middleware/telemetry.ts +4 -2
- package/src/middleware-runner.test.ts +2 -3
- package/src/middleware-runner.ts +2 -2
- package/src/no-root-barrel.test.ts +114 -0
- package/src/permissions.ts +2 -4
- package/src/pikku-state.ts +3 -1
- package/src/public-surface.json +56 -241
- package/src/public-surface.json.README +3 -3
- package/src/public-surface.test.ts +5 -5
- package/src/remote.test.ts +1 -1
- package/src/removed-legacy-exports.test.ts +5 -1
- package/src/services/audit-service.ts +1 -1
- package/src/services/credential-wire-service.ts +1 -1
- package/src/services/email-service.ts +2 -4
- package/src/services/file-scenario-run-store.test.ts +349 -0
- package/src/services/file-scenario-run-store.ts +282 -0
- package/src/services/in-memory-workflow-service.ts +1 -1
- package/src/services/index.ts +13 -1
- package/src/services/local-content-request-handler.ts +1 -2
- package/src/services/local-secrets.ts +1 -1
- package/src/services/logger.ts +7 -7
- package/src/services/meta-service.ts +2 -2
- package/src/services/queue-webhook-service.test.ts +1 -1
- package/src/services/scoped-secret-service.ts +1 -1
- package/src/services/secret-service.ts +1 -1
- package/src/services/typed-secret-service.test.ts +52 -0
- package/src/services/typed-secret-service.ts +26 -2
- package/src/services/webhook-service.ts +1 -1
- package/src/services/workflow-service.ts +2 -1
- package/src/template-alias-surface.test.ts +240 -0
- package/src/testing/index.ts +1 -0
- package/src/types/core.types.ts +33 -285
- package/src/types/index.ts +2 -0
- package/src/types/state.types.ts +6 -5
- package/src/types/typed-credentials.test.ts +72 -0
- package/src/utils.ts +34 -0
- package/src/wirings/{rpc → addon}/addon-scopes.test.ts +1 -1
- package/src/wirings/addon/index.ts +12 -0
- package/src/wirings/{rpc → addon}/remote-addon-auth.ts +4 -1
- package/src/wirings/{rpc → addon}/wire-addon.ts +37 -2
- package/src/wirings/agent/agent-prepare.ts +8 -5
- package/src/wirings/agent/agent-runner.ts +2 -3
- package/src/wirings/agent/agent-stream.ts +2 -3
- package/src/wirings/agent/agent-utils.ts +19 -0
- package/src/wirings/agent/agent.types.ts +3 -3
- package/src/wirings/agent/index.ts +1 -0
- package/src/wirings/agent/voice-input.ts +1 -1
- package/src/wirings/agent/voice-output.test.ts +2 -4
- package/src/wirings/agent/voice-output.ts +1 -1
- package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +145 -0
- package/src/wirings/agent-scorer/agent-scorer-judge.ts +60 -0
- package/src/wirings/agent-scorer/agent-scorer.ts +8 -0
- package/src/wirings/agent-scorer/agent-scorer.types.ts +21 -0
- package/src/wirings/agent-scorer/index.ts +1 -0
- package/src/wirings/channel/channel-common.ts +4 -2
- package/src/wirings/channel/channel-handler.ts +2 -5
- package/src/wirings/channel/channel-middleware-runner.ts +1 -1
- package/src/wirings/channel/channel-rpc.types.ts +1 -5
- package/src/wirings/channel/channel.types.ts +1 -2
- package/src/wirings/channel/local/local-channel-runner.test.ts +1 -2
- package/src/wirings/channel/serverless/index.ts +1 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +2 -2
- package/src/wirings/cli/channel/index.ts +1 -3
- package/src/wirings/cli/cli-runner.test.ts +1 -1
- package/src/wirings/cli/cli-runner.ts +11 -7
- package/src/wirings/cli/cli.types.ts +24 -3
- package/src/wirings/cli/command-parser.test.ts +388 -1
- package/src/wirings/cli/command-parser.ts +189 -29
- package/src/wirings/gateway/gateway-runner.test.ts +1 -2
- package/src/wirings/gateway/gateway-runner.ts +3 -6
- package/src/wirings/gateway/gateway.types.ts +5 -4
- package/src/wirings/http/http-routes.test.ts +1 -2
- package/src/wirings/http/http-runner-addon-ref.test.ts +238 -0
- package/src/wirings/http/http-runner.test.ts +3 -8
- package/src/wirings/http/http-runner.ts +9 -3
- package/src/wirings/http/http.types.ts +3 -12
- package/src/wirings/http/index.ts +1 -0
- package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +3 -2
- package/src/wirings/mcp/mcp-runner.test.ts +1 -1
- package/src/wirings/mcp/mcp.types.ts +1 -2
- package/src/wirings/persona/index.ts +1 -4
- package/src/wirings/persona/persona.types.ts +14 -0
- package/src/wirings/queue/queue-identity.test.ts +1 -1
- package/src/wirings/queue/queue.types.ts +2 -6
- package/src/wirings/queue/signed-queue-service.ts +1 -1
- package/src/wirings/rpc/index.ts +0 -12
- package/src/wirings/rpc/rpc-runner.test.ts +4 -4
- package/src/wirings/rpc/rpc-runner.ts +3 -3
- package/src/wirings/scheduler/scheduler.types.ts +2 -5
- package/src/wirings/scope/index.ts +1 -0
- package/src/wirings/secret/secret.types.ts +10 -0
- package/src/wirings/secret/validate-secret-definitions.test.ts +23 -0
- package/src/wirings/secret/validate-secret-definitions.ts +2 -0
- package/src/wirings/variable/validate-variable-definitions.test.ts +23 -0
- package/src/wirings/variable/validate-variable-definitions.ts +2 -0
- package/src/wirings/variable/variable.types.ts +9 -0
- package/src/wirings/virtual-user/index.ts +1 -4
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +1 -1
- package/src/wirings/virtual-user/virtual-user-derive.ts +1 -1
- package/src/wirings/virtual-user/virtual-user.types.ts +1 -5
- package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +569 -0
- package/src/wirings/workflow/graph/graph-foreach.test.ts +626 -0
- package/src/wirings/workflow/graph/graph-node.ts +16 -1
- package/src/wirings/workflow/graph/graph-runner.ts +387 -61
- package/src/wirings/workflow/graph/workflow-graph.types.ts +28 -3
- package/src/wirings/workflow/index.ts +8 -0
- package/src/wirings/workflow/pikku-scenario-service.ts +59 -19
- package/src/wirings/workflow/pikku-workflow-service.ts +6 -8
- package/src/wirings/workflow/run-timeline.ts +1 -1
- package/src/wirings/workflow/scenario-expectations.test.ts +28 -13
- package/src/wirings/workflow/scenario-run.types.ts +186 -0
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +32 -7
- package/src/wirings/workflow/scenario-step.types.ts +27 -12
- package/src/wirings/workflow/workflow-approval-policy.test.ts +117 -47
- package/src/wirings/workflow/workflow-approval.ts +2 -1
- package/src/wirings/workflow/workflow-run-engine.types.ts +2 -1
- package/src/wirings/workflow/workflow.types.ts +4 -12
- package/src/wirings-stay-decoupled.test.ts +6 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/tsconfig.type-tests.json +3 -2
- package/dist/ecosystem/ai-agent.d.ts +0 -18
- package/dist/ecosystem/ai-agent.js +0 -6
- package/dist/ecosystem/ai-scorer.d.ts +0 -12
- package/dist/ecosystem/ai-scorer.js +0 -5
- package/dist/services/ai-agent-runner-service.d.ts +0 -220
- package/dist/services/ai-run-state-service.d.ts +0 -29
- package/dist/services/ai-storage-service.d.ts +0 -18
- package/dist/services/in-memory-ai-run-state-service.d.ts +0 -19
- package/dist/services/in-memory-ai-run-state-service.js +0 -54
- package/dist/testing/service-tests/ai-storage-service-tests.d.ts +0 -3
- package/dist/testing/service-tests/ai-storage-service-tests.js +0 -302
- package/dist/wirings/ai-agent/agent-rpc.d.ts +0 -15
- package/dist/wirings/ai-agent/agent-rpc.js +0 -53
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -79
- package/dist/wirings/ai-agent/ai-agent-agui.js +0 -327
- package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +0 -58
- package/dist/wirings/ai-agent/ai-agent-finalize.js +0 -138
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +0 -35
- package/dist/wirings/ai-agent/ai-agent-helpers.js +0 -47
- package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +0 -153
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +0 -257
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +0 -42
- package/dist/wirings/ai-agent/ai-agent-memory.js +0 -333
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -16
- package/dist/wirings/ai-agent/ai-agent-model-config.js +0 -51
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +0 -117
- package/dist/wirings/ai-agent/ai-agent-prepare.js +0 -728
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +0 -16
- package/dist/wirings/ai-agent/ai-agent-registry.js +0 -51
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +0 -7
- package/dist/wirings/ai-agent/ai-agent-runner.js +0 -580
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +0 -41
- package/dist/wirings/ai-agent/ai-agent-stream.js +0 -1029
- package/dist/wirings/ai-agent/ai-agent-turn.d.ts +0 -57
- package/dist/wirings/ai-agent/ai-agent-turn.js +0 -82
- package/dist/wirings/ai-agent/ai-agent-utils.d.ts +0 -1
- package/dist/wirings/ai-agent/ai-agent-utils.js +0 -1
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +0 -625
- package/dist/wirings/ai-agent/index.d.ts +0 -12
- package/dist/wirings/ai-agent/index.js +0 -10
- package/dist/wirings/ai-agent/voice-input.d.ts +0 -69
- package/dist/wirings/ai-agent/voice-input.js +0 -150
- package/dist/wirings/ai-agent/voice-output.d.ts +0 -85
- package/dist/wirings/ai-agent/voice-output.js +0 -196
- package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +0 -26
- package/dist/wirings/ai-scorer/ai-scorer-grade.js +0 -33
- package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +0 -17
- package/dist/wirings/ai-scorer/ai-scorer-judge.js +0 -92
- package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +0 -15
- package/dist/wirings/ai-scorer/ai-scorer-live.js +0 -38
- package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +0 -18
- package/dist/wirings/ai-scorer/ai-scorer-registry.js +0 -46
- package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +0 -8
- package/dist/wirings/ai-scorer/ai-scorer-sampling.js +0 -31
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +0 -10
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +0 -40
- package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +0 -15
- package/dist/wirings/ai-scorer/ai-scorer-worker.js +0 -58
- package/dist/wirings/ai-scorer/ai-scorer.d.ts +0 -39
- package/dist/wirings/ai-scorer/ai-scorer.js +0 -40
- package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +0 -90
- package/dist/wirings/ai-scorer/ai-scorer.types.js +0 -4
- package/dist/wirings/ai-scorer/index.d.ts +0 -6
- package/dist/wirings/ai-scorer/index.js +0 -5
- package/src/ecosystem/agent-scorer.ts +0 -24
- package/src/ecosystem/agent.ts +0 -42
- package/src/ecosystem/channel/local.ts +0 -1
- package/src/ecosystem/channel.ts +0 -22
- package/src/ecosystem/cli/channel.ts +0 -25
- package/src/ecosystem/cli.ts +0 -21
- package/src/ecosystem/credential.ts +0 -10
- package/src/ecosystem/dev.ts +0 -12
- package/src/ecosystem/function.ts +0 -28
- package/src/ecosystem/gateway.ts +0 -4
- package/src/ecosystem/hmac.ts +0 -1
- package/src/ecosystem/http.ts +0 -22
- package/src/ecosystem/mcp.ts +0 -17
- package/src/ecosystem/middleware.ts +0 -27
- package/src/ecosystem/node-host-resolver.ts +0 -1
- package/src/ecosystem/node.ts +0 -5
- package/src/ecosystem/oauth2.ts +0 -4
- package/src/ecosystem/persona.ts +0 -30
- package/src/ecosystem/queue.ts +0 -23
- package/src/ecosystem/remote.ts +0 -9
- package/src/ecosystem/role.ts +0 -13
- package/src/ecosystem/rpc.ts +0 -7
- package/src/ecosystem/safe-fetch.ts +0 -8
- package/src/ecosystem/scenario.ts +0 -32
- package/src/ecosystem/scheduler.ts +0 -5
- package/src/ecosystem/schema.ts +0 -1
- package/src/ecosystem/scope.ts +0 -14
- package/src/ecosystem/secret.ts +0 -15
- package/src/ecosystem/services/istanbul-coverage.ts +0 -1
- package/src/ecosystem/services/local-content-request-handler.ts +0 -16
- package/src/ecosystem/services/local-content.ts +0 -1
- package/src/ecosystem/services/v8-coverage.ts +0 -1
- package/src/ecosystem/services.ts +0 -82
- package/src/ecosystem/trigger.ts +0 -7
- package/src/ecosystem/types.ts +0 -34
- package/src/ecosystem/variable.ts +0 -14
- package/src/ecosystem/virtual-user.ts +0 -48
- package/src/ecosystem/workflow.ts +0 -68
- package/src/ecosystem.ts +0 -40
- package/src/index.ts +0 -244
- /package/dist/{services/ai-agent-runner-service.js → bootstrap-compat/root.js} +0 -0
- /package/dist/{services/ai-run-state-service.js → classification/data-classification.js} +0 -0
- /package/dist/{services/ai-storage-service.js → errors/serialized-error.js} +0 -0
- /package/dist/{wirings/ai-agent/ai-agent.types.js → function/function-meta.types.js} +0 -0
- /package/src/{column-form.ts → classification/column-form.ts} +0 -0
- /package/src/{pikku-request.test.ts → function/pikku-request.test.ts} +0 -0
- /package/src/{pikku-request.ts → function/pikku-request.ts} +0 -0
- /package/src/wirings/{rpc → addon}/addon-auth-tags.test.ts +0 -0
- /package/src/wirings/{rpc → addon}/addon-runner.ts +0 -0
- /package/src/wirings/{rpc → addon}/addon-secrets.test.ts +0 -0
- /package/src/wirings/{rpc → addon}/wire-addon.test.ts +0 -0
- /package/src/wirings/{rpc → addon}/wire-remote-addon.ts +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { MiddlewareMetadata } from '../middleware/middleware.types.js'
|
|
2
|
+
import type { AuditDurability } from '../services/audit-service.js'
|
|
3
|
+
import type {
|
|
4
|
+
ScenarioStepKind,
|
|
5
|
+
ScenarioSurface,
|
|
6
|
+
} from '../wirings/workflow/scenario-step.types.js'
|
|
7
|
+
import type { CommonWireMeta } from '../types/core.types.js'
|
|
8
|
+
|
|
9
|
+
export interface FunctionServicesMeta {
|
|
10
|
+
optimized: boolean
|
|
11
|
+
services: string[]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface FunctionWiresMeta {
|
|
15
|
+
optimized: boolean
|
|
16
|
+
wires: string[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A reference to a permission function, resolved by name. Function-scoped
|
|
21
|
+
* only: there are no wire- or tag-level permission references.
|
|
22
|
+
*/
|
|
23
|
+
export type PermissionMetadata = {
|
|
24
|
+
type: 'wire'
|
|
25
|
+
name: string
|
|
26
|
+
inline?: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type FunctionRuntimeMeta = {
|
|
30
|
+
pikkuFuncId: string
|
|
31
|
+
inputSchemaName: string | null
|
|
32
|
+
outputSchemaName: string | null
|
|
33
|
+
/** Scopes the session must hold to run this function. All are required (AND). */
|
|
34
|
+
scopes?: string[]
|
|
35
|
+
expose?: boolean
|
|
36
|
+
/**
|
|
37
|
+
* A sessionless function's own `auth: true`. `sessionless` carries the
|
|
38
|
+
* baseline — a `pikkuFunc` always requires a session — and this carries the
|
|
39
|
+
* tightening a `pikkuSessionlessFunc` applies to itself. Both are needed to
|
|
40
|
+
* know whether a function is gated without running it.
|
|
41
|
+
*/
|
|
42
|
+
auth?: boolean
|
|
43
|
+
/**
|
|
44
|
+
* The author's declaration that this function's permission check lives in its
|
|
45
|
+
* own body. Carries no runtime effect — it records a gate codegen cannot see,
|
|
46
|
+
* so an audit is not left to guess whether a sessionless function is open.
|
|
47
|
+
* Refused unless `allow.permissionsInBody` is set in `pikku.config.json`.
|
|
48
|
+
*/
|
|
49
|
+
permissionsInBody?: boolean
|
|
50
|
+
remote?: boolean
|
|
51
|
+
/**
|
|
52
|
+
* A step RPC: invoked by name only from a scenario run and refused
|
|
53
|
+
* everywhere else, so it is never network-callable.
|
|
54
|
+
*/
|
|
55
|
+
scenarioStep?: boolean
|
|
56
|
+
/**
|
|
57
|
+
* The body of a `pikkuScenario(...)`. Only ever run by `pikku scenario run`,
|
|
58
|
+
* so it is held back from the app bootstrap and from every deployed unit.
|
|
59
|
+
*/
|
|
60
|
+
scenario?: boolean
|
|
61
|
+
mcp?: boolean
|
|
62
|
+
readonly?: boolean
|
|
63
|
+
deploy?: 'serverless' | 'server' | 'auto'
|
|
64
|
+
sessionless?: boolean
|
|
65
|
+
/** When true, workflow steps calling this function are dispatched via the queue. No queue service configured is a hard error. */
|
|
66
|
+
workflowQueued?: boolean
|
|
67
|
+
/** Retry count when this function is used as a workflow step. */
|
|
68
|
+
workflowRetries?: number
|
|
69
|
+
/** Timeout when this function is used as a workflow step (e.g. '30s', '5m'). */
|
|
70
|
+
workflowTimeout?: string
|
|
71
|
+
/**
|
|
72
|
+
* Scenario steps only: which surfaces this step declares a binding for.
|
|
73
|
+
*
|
|
74
|
+
* The reporter derives coverage from this — a `then` with no binding for the
|
|
75
|
+
* surface the run targeted was never actually witnessed there, which is a gap
|
|
76
|
+
* worth counting rather than excusing.
|
|
77
|
+
*/
|
|
78
|
+
scenarioStepSurfaces?: ScenarioSurface[]
|
|
79
|
+
/**
|
|
80
|
+
* Scenario steps only: this step runs as a persona, so every call site must
|
|
81
|
+
* pass one and the runner injects it as `wire.actor`.
|
|
82
|
+
*
|
|
83
|
+
* Declared by `actor: true`, or implied by a `browser` binding — a window is
|
|
84
|
+
* opened as somebody. Absent on a step with nobody to be: an assertion over
|
|
85
|
+
* what an earlier step returned, or one posting credentials precisely because
|
|
86
|
+
* it must not reuse an actor's session.
|
|
87
|
+
*/
|
|
88
|
+
scenarioStepRequiresActor?: boolean
|
|
89
|
+
/**
|
|
90
|
+
* Scenario steps only: who acts. Absent means `persona` — the ordinary step,
|
|
91
|
+
* and the only kind that existed before the other two.
|
|
92
|
+
*
|
|
93
|
+
* A `platform` or `addon` step is the app or a third-party system acting, and
|
|
94
|
+
* it must never reach a virtual user's catalogue. That is not tidiness: a
|
|
95
|
+
* virtual user that can invoke "Stripe's webhook arrives" can forge its own
|
|
96
|
+
* payment success, and every finding downstream of that is worthless.
|
|
97
|
+
*/
|
|
98
|
+
scenarioStepKind?: ScenarioStepKind
|
|
99
|
+
/** Addon steps only: the addon whose system acts — `wireAddon`'s `name`. */
|
|
100
|
+
scenarioStepAddon?: string
|
|
101
|
+
/** Scenario steps only: the prose a reporter renders, with `{placeholders}` filled from the step's recorded input. */
|
|
102
|
+
scenarioStepTemplate?: string
|
|
103
|
+
/**
|
|
104
|
+
* The function's `audit` config, resolved — `audit: true` reads as
|
|
105
|
+
* `{ durability: 'best-effort' }`. Absent means the function records nothing:
|
|
106
|
+
* `auditLog.write()` from an unmarked function is dropped with a warning, so
|
|
107
|
+
* this is the only place a reader can see which functions have a trail at all
|
|
108
|
+
* without running them.
|
|
109
|
+
*
|
|
110
|
+
* Informational. The runner resolves audit from the live function config, not
|
|
111
|
+
* from here, so meta and runtime cannot disagree about whether audit is on.
|
|
112
|
+
*/
|
|
113
|
+
audit?: {
|
|
114
|
+
durability: AuditDurability
|
|
115
|
+
}
|
|
116
|
+
version?: number
|
|
117
|
+
approvalRequired?: boolean
|
|
118
|
+
approvalDescription?: string
|
|
119
|
+
implementationHash?: string
|
|
120
|
+
contractHash?: string
|
|
121
|
+
inputHash?: string
|
|
122
|
+
outputHash?: string
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export type FunctionMeta = FunctionRuntimeMeta &
|
|
126
|
+
Partial<
|
|
127
|
+
{
|
|
128
|
+
name: string
|
|
129
|
+
/** `remote`: a contract with no local body, answered by a connected client. */
|
|
130
|
+
functionType: 'user' | 'inline' | 'helper' | 'remote'
|
|
131
|
+
funcWrapper: string
|
|
132
|
+
services: FunctionServicesMeta
|
|
133
|
+
wires: FunctionWiresMeta
|
|
134
|
+
inputs: string[] | null
|
|
135
|
+
outputs: string[] | null
|
|
136
|
+
middleware: MiddlewareMetadata[]
|
|
137
|
+
permissions: PermissionMetadata[]
|
|
138
|
+
isDirectFunction: boolean
|
|
139
|
+
sourceFile: string
|
|
140
|
+
exportedName: string
|
|
141
|
+
/** File containing the handler body when it differs from sourceFile (imported handlers) */
|
|
142
|
+
bodySourceFile?: string
|
|
143
|
+
/** 1-indexed first line of the handler body (verbose meta; coverage mapping) */
|
|
144
|
+
bodyStart: number
|
|
145
|
+
/** 1-indexed last line of the handler body (verbose meta; coverage mapping) */
|
|
146
|
+
bodyEnd: number
|
|
147
|
+
} & CommonWireMeta
|
|
148
|
+
>
|
|
149
|
+
|
|
150
|
+
export type FunctionsRuntimeMeta = Record<string, FunctionRuntimeMeta>
|
|
151
|
+
export type FunctionsMeta = Record<string, FunctionMeta>
|
|
@@ -6,10 +6,12 @@ import {
|
|
|
6
6
|
getFunctionNames,
|
|
7
7
|
runPikkuFunc,
|
|
8
8
|
} from './function-runner.js'
|
|
9
|
-
import { addGlobalPermission
|
|
9
|
+
import { addGlobalPermission } from '../permissions.js'
|
|
10
|
+
import { addTagMiddleware } from '../middleware-runner.js'
|
|
10
11
|
import { addSchema } from '../schema.js'
|
|
11
12
|
import { resetPikkuState, pikkuState } from '../pikku-state.js'
|
|
12
|
-
import type { CoreServices
|
|
13
|
+
import type { CoreServices } from '../types/core.types.js'
|
|
14
|
+
import type { CorePikkuMiddleware } from '../middleware/middleware.types.js'
|
|
13
15
|
import type { CorePermissionGroup } from './functions.types.js'
|
|
14
16
|
import { PikkuSessionService } from '../services/user-session-service.js'
|
|
15
17
|
import { MissingScopeError, ReadonlySessionError } from '../errors/errors.js'
|
|
@@ -14,14 +14,16 @@ import {
|
|
|
14
14
|
} from '../schema.js'
|
|
15
15
|
import type {
|
|
16
16
|
CoreUserSession,
|
|
17
|
-
CorePikkuMiddleware,
|
|
18
17
|
PikkuWiringTypes,
|
|
19
18
|
PikkuWire,
|
|
20
19
|
PikkuRawWire,
|
|
21
|
-
MiddlewareMetadata,
|
|
22
20
|
CoreSingletonServices,
|
|
23
21
|
CreateWireServices,
|
|
24
22
|
} from '../types/core.types.js'
|
|
23
|
+
import type {
|
|
24
|
+
CorePikkuMiddleware,
|
|
25
|
+
MiddlewareMetadata,
|
|
26
|
+
} from '../middleware/middleware.types.js'
|
|
25
27
|
import type { CorePikkuChannelMiddleware } from '../wirings/channel/channel.types.js'
|
|
26
28
|
import type { CorePikkuFunctionConfig } from './functions.types.js'
|
|
27
29
|
import { parseVersionedId } from '../version.js'
|
|
@@ -40,13 +42,14 @@ import {
|
|
|
40
42
|
type AuditLog,
|
|
41
43
|
} from '../services/audit-service.js'
|
|
42
44
|
import { rpcService } from '../wirings/rpc/rpc-runner.js'
|
|
43
|
-
import { getOrCreatePackageSingletonServices } from '../wirings/
|
|
45
|
+
import { getOrCreatePackageSingletonServices } from '../wirings/addon/addon-runner.js'
|
|
44
46
|
import {
|
|
45
47
|
resolveAddonAuth,
|
|
48
|
+
resolveAddonFunctionTarget,
|
|
46
49
|
resolveAddonScopes,
|
|
47
50
|
resolveAddonTagMiddleware,
|
|
48
|
-
} from '../wirings/
|
|
49
|
-
import type { AddonInstance } from '../wirings/
|
|
51
|
+
} from '../wirings/addon/wire-addon.js'
|
|
52
|
+
import type { AddonInstance } from '../wirings/addon/addon-runner.js'
|
|
50
53
|
import { closeWireServices } from '../utils.js'
|
|
51
54
|
|
|
52
55
|
async function resolveSession(
|
|
@@ -168,6 +171,32 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
168
171
|
}
|
|
169
172
|
}
|
|
170
173
|
|
|
174
|
+
/**
|
|
175
|
+
* The package the *function* belongs to, which is the wire's own until a
|
|
176
|
+
* `ref()` resolves the target into an addon. The wiring stays the consuming
|
|
177
|
+
* app's — that is what keeps the app's middleware running rather than the
|
|
178
|
+
* addon's — but everything the function is declared with lives in the addon's
|
|
179
|
+
* package state, so its schemas, services and permissions are read from here.
|
|
180
|
+
*/
|
|
181
|
+
let funcPackageName = packageName
|
|
182
|
+
|
|
183
|
+
if (!funcMeta) {
|
|
184
|
+
const addonTarget = resolveAddonFunctionTarget(funcName, packageName)
|
|
185
|
+
if (addonTarget) {
|
|
186
|
+
funcConfig =
|
|
187
|
+
funcConfig ||
|
|
188
|
+
pikkuState(addonTarget.packageName, 'function', 'functions').get(
|
|
189
|
+
addonTarget.localName
|
|
190
|
+
)
|
|
191
|
+
funcMeta = pikkuState(addonTarget.packageName, 'function', 'meta')[
|
|
192
|
+
addonTarget.localName
|
|
193
|
+
]
|
|
194
|
+
if (funcMeta) {
|
|
195
|
+
funcPackageName = addonTarget.packageName
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
171
200
|
if (!funcConfig) {
|
|
172
201
|
throw new Error(`Function not found: ${funcName}`)
|
|
173
202
|
}
|
|
@@ -177,17 +206,17 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
177
206
|
|
|
178
207
|
const resolvedFunctionId = funcMeta.pikkuFuncId ?? funcName
|
|
179
208
|
|
|
180
|
-
const resolvedSingletonServices =
|
|
209
|
+
const resolvedSingletonServices = funcPackageName
|
|
181
210
|
? await getOrCreatePackageSingletonServices(
|
|
182
|
-
|
|
211
|
+
funcPackageName,
|
|
183
212
|
singletonServices,
|
|
184
213
|
addonInstance
|
|
185
214
|
)
|
|
186
215
|
: singletonServices
|
|
187
216
|
|
|
188
217
|
let resolvedCreateWireServices = createWireServices
|
|
189
|
-
if (
|
|
190
|
-
const factories = pikkuState(
|
|
218
|
+
if (funcPackageName) {
|
|
219
|
+
const factories = pikkuState(funcPackageName, 'package', 'factories')
|
|
191
220
|
if (factories?.createWireServices) {
|
|
192
221
|
resolvedCreateWireServices = factories.createWireServices
|
|
193
222
|
}
|
|
@@ -345,17 +374,21 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
345
374
|
actualData = applyDefaultsFromSchema(
|
|
346
375
|
inputSchemaName,
|
|
347
376
|
actualData,
|
|
348
|
-
|
|
377
|
+
funcPackageName
|
|
349
378
|
)
|
|
350
379
|
if (coerceDataFromSchema) {
|
|
351
|
-
coerceTopLevelDataFromSchema(
|
|
380
|
+
coerceTopLevelDataFromSchema(
|
|
381
|
+
inputSchemaName,
|
|
382
|
+
actualData,
|
|
383
|
+
funcPackageName
|
|
384
|
+
)
|
|
352
385
|
}
|
|
353
386
|
await validateSchema(
|
|
354
387
|
resolvedSingletonServices.logger,
|
|
355
388
|
resolvedSingletonServices.schema,
|
|
356
389
|
inputSchemaName,
|
|
357
390
|
actualData,
|
|
358
|
-
|
|
391
|
+
funcPackageName
|
|
359
392
|
)
|
|
360
393
|
}
|
|
361
394
|
|
|
@@ -368,7 +401,7 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
368
401
|
// knowledge: decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md
|
|
369
402
|
wire: invocationWire as PermissionWire,
|
|
370
403
|
data: actualData,
|
|
371
|
-
packageName,
|
|
404
|
+
packageName: funcPackageName,
|
|
372
405
|
})
|
|
373
406
|
|
|
374
407
|
let wireServices: Record<string, unknown> | undefined
|
|
@@ -395,7 +428,7 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
395
428
|
)
|
|
396
429
|
services = { ...services, auditLog: invocationAuditLog }
|
|
397
430
|
}
|
|
398
|
-
const callerPackageName =
|
|
431
|
+
const callerPackageName = funcPackageName
|
|
399
432
|
Object.defineProperty(invocationWire, 'rpc', {
|
|
400
433
|
get() {
|
|
401
434
|
const rpc = rpcService.getContextRPCService(
|
|
@@ -2,17 +2,17 @@ import type {
|
|
|
2
2
|
CoreServices,
|
|
3
3
|
CoreSecretlessSingletonServices,
|
|
4
4
|
CoreUserSession,
|
|
5
|
-
CorePikkuMiddleware,
|
|
6
5
|
PikkuWire,
|
|
7
|
-
PickRequired,
|
|
8
6
|
SecretlessServices,
|
|
9
7
|
} from '../types/core.types.js'
|
|
8
|
+
import type { CorePikkuMiddleware } from '../middleware/middleware.types.js'
|
|
9
|
+
import type { PickRequired } from '../utils.js'
|
|
10
10
|
import type { PikkuRPC } from '../wirings/rpc/rpc-types.js'
|
|
11
11
|
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
|
12
12
|
import type { PikkuError } from '../errors/error-handler.js'
|
|
13
13
|
import type { CoreNodeConfig } from '../wirings/node/node.types.js'
|
|
14
14
|
import type { ScenarioSurface } from '../wirings/workflow/scenario-step.types.js'
|
|
15
|
-
import type { Safe } from '../secret-value.js'
|
|
15
|
+
import type { Safe } from '../classification/secret-value.js'
|
|
16
16
|
|
|
17
17
|
export type CorePikkuFunction<
|
|
18
18
|
In,
|
|
@@ -149,8 +149,7 @@ export const pikkuAuth = <
|
|
|
149
149
|
Session extends CoreUserSession = CoreUserSession,
|
|
150
150
|
>(
|
|
151
151
|
auth:
|
|
152
|
-
|
|
|
153
|
-
| CorePikkuAuthConfig<Services, Session>
|
|
152
|
+
CorePikkuAuth<Services, Session> | CorePikkuAuthConfig<Services, Session>
|
|
154
153
|
): CorePikkuPermission<any, Services, any> => {
|
|
155
154
|
const fn = typeof auth === 'function' ? auth : auth.func
|
|
156
155
|
const wrapper: CorePikkuPermission<any, Services, any> & AuthBranded = async (
|
|
@@ -167,8 +166,7 @@ export const pikkuAuth = <
|
|
|
167
166
|
}
|
|
168
167
|
|
|
169
168
|
export type CorePermissionGroup<PikkuPermission = CorePikkuPermission<any>> =
|
|
170
|
-
|
|
171
|
-
| undefined
|
|
169
|
+
Record<string, PikkuPermission | PikkuPermission[]> | undefined
|
|
172
170
|
|
|
173
171
|
/**
|
|
174
172
|
* A lifecycle hook: same call signature as the function it hangs off, return
|
|
@@ -232,6 +230,12 @@ export type CorePikkuFunctionConfig<
|
|
|
232
230
|
* and report how much of the flow each surface actually covers.
|
|
233
231
|
*/
|
|
234
232
|
surfaces?: ScenarioSurface[]
|
|
233
|
+
/**
|
|
234
|
+
* Scenario steps only: this step is driven by a persona, so the runner injects
|
|
235
|
+
* `wire.actor` and refuses to dispatch it without one. Set by the definer from
|
|
236
|
+
* a `browser` binding or an explicit `actor: true`, never written by hand.
|
|
237
|
+
*/
|
|
238
|
+
requiresActor?: boolean
|
|
235
239
|
audit?:
|
|
236
240
|
| boolean
|
|
237
241
|
| {
|
package/src/function/index.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {
|
|
2
|
+
addFunction,
|
|
3
|
+
getAllFunctionNames,
|
|
4
|
+
runPikkuFunc,
|
|
5
|
+
} from './function-runner.js'
|
|
2
6
|
export {
|
|
3
7
|
pikkuAuth,
|
|
4
8
|
pikkuPermission,
|
|
@@ -14,8 +18,23 @@ export type {
|
|
|
14
18
|
CorePikkuAuthConfig,
|
|
15
19
|
CorePikkuPermission,
|
|
16
20
|
} from './functions.types.js'
|
|
21
|
+
export type { ListInput, ListOutput, Filter } from './list.types.js'
|
|
22
|
+
export { AbandonedError } from './abort-scope.js'
|
|
23
|
+
export type { AbortScope } from './abort-scope.js'
|
|
24
|
+
export { checkAuthPermissions } from '../permissions.js'
|
|
25
|
+
export type {
|
|
26
|
+
CorePermissionGroup,
|
|
27
|
+
CorePikkuApprovalDescription,
|
|
28
|
+
CorePikkuPermissionConfig,
|
|
29
|
+
CorePikkuPermissionFactory,
|
|
30
|
+
} from './functions.types.js'
|
|
17
31
|
export type {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
32
|
+
FunctionMeta,
|
|
33
|
+
FunctionRuntimeMeta,
|
|
34
|
+
FunctionServicesMeta,
|
|
35
|
+
FunctionWiresMeta,
|
|
36
|
+
FunctionsMeta,
|
|
37
|
+
FunctionsRuntimeMeta,
|
|
38
|
+
PermissionMetadata,
|
|
39
|
+
} from './function-meta.types.js'
|
|
40
|
+
export { PikkuRequest } from './pikku-request.js'
|
|
@@ -66,6 +66,4 @@ export type LeafFilter<F extends Record<string, unknown>> = {
|
|
|
66
66
|
* evaluation time; a single-key object is a leaf predicate.
|
|
67
67
|
*/
|
|
68
68
|
export type Filter<F extends Record<string, unknown>> =
|
|
69
|
-
|
|
|
70
|
-
| Filter<F>[]
|
|
71
|
-
| { [label: string]: Filter<F> }
|
|
69
|
+
LeafFilter<F> | Filter<F>[] | { [label: string]: Filter<F> }
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
pikkuMiddleware,
|
|
3
|
+
pikkuMiddlewareFactory,
|
|
4
|
+
} from './middleware-factories.js'
|
|
3
5
|
export const authAPIKey = pikkuMiddlewareFactory<{
|
|
4
6
|
source: 'header' | 'query' | 'all'
|
|
5
7
|
}>(({ source }) =>
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
createMiddlewareSessionWireProps,
|
|
9
9
|
} from '../services/user-session-service.js'
|
|
10
10
|
import { InvalidSessionError } from '../errors/errors.js'
|
|
11
|
-
import { createSecretValue } from '../secret-value.js'
|
|
11
|
+
import { createSecretValue } from '../classification/secret-value.js'
|
|
12
12
|
|
|
13
13
|
beforeEach(() => {
|
|
14
14
|
resetPikkuState()
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { InvalidSessionError } from '../errors/errors.js'
|
|
2
2
|
import type { CoreUserSession } from '../types/core.types.js'
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
pikkuMiddleware,
|
|
5
|
+
pikkuMiddlewareFactory,
|
|
6
|
+
} from './middleware-factories.js'
|
|
5
7
|
const constantTimeEqual = (a: string, b: string): boolean => {
|
|
6
8
|
if (a.length !== b.length) return false
|
|
7
9
|
let result = 0
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { SerializeOptions } from 'cookie'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
pikkuMiddleware,
|
|
4
|
+
pikkuMiddlewareFactory,
|
|
5
|
+
} from './middleware-factories.js'
|
|
3
6
|
import type { RelativeTimeInput } from '../time-utils.js'
|
|
4
7
|
import { getRelativeTimeOffsetFromNow } from '../time-utils.js'
|
|
5
8
|
|
|
@@ -15,6 +15,21 @@ const createMockRequest = (method = 'get', origin?: string) => ({
|
|
|
15
15
|
},
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
+
const createMockServices = () => {
|
|
19
|
+
const debugMessages: string[] = []
|
|
20
|
+
return {
|
|
21
|
+
logger: {
|
|
22
|
+
debug: (message: string) => {
|
|
23
|
+
debugMessages.push(message)
|
|
24
|
+
},
|
|
25
|
+
info: () => {},
|
|
26
|
+
warn: () => {},
|
|
27
|
+
error: () => {},
|
|
28
|
+
},
|
|
29
|
+
_debugMessages: debugMessages,
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
18
33
|
const createMockResponse = () => {
|
|
19
34
|
const headers: Record<string, string> = {}
|
|
20
35
|
let statusCode: number | undefined
|
|
@@ -125,30 +140,113 @@ describe('cors', () => {
|
|
|
125
140
|
)
|
|
126
141
|
})
|
|
127
142
|
|
|
128
|
-
test('should
|
|
143
|
+
test('should omit Access-Control-Allow-Origin when request origin not in array', async () => {
|
|
129
144
|
const middleware = cors({ origin: ['https://a.com', 'https://b.com'] })
|
|
130
145
|
const request = createMockRequest('get', 'https://unknown.com')
|
|
131
146
|
const response = createMockResponse()
|
|
147
|
+
const services = createMockServices()
|
|
132
148
|
|
|
133
149
|
await middleware(
|
|
134
|
-
|
|
150
|
+
services as any,
|
|
135
151
|
{ http: { request, response } } as any,
|
|
136
152
|
async () => {}
|
|
137
153
|
)
|
|
138
154
|
|
|
139
155
|
assert.strictEqual(
|
|
140
156
|
response._headers['Access-Control-Allow-Origin'],
|
|
141
|
-
|
|
157
|
+
undefined
|
|
142
158
|
)
|
|
143
159
|
})
|
|
144
160
|
|
|
145
|
-
test('should
|
|
161
|
+
test('should log the rejected origin at debug level', async () => {
|
|
162
|
+
const middleware = cors({ origin: ['https://a.com', 'https://b.com'] })
|
|
163
|
+
const request = createMockRequest('get', 'https://unknown.com')
|
|
164
|
+
const response = createMockResponse()
|
|
165
|
+
const services = createMockServices()
|
|
166
|
+
|
|
167
|
+
await middleware(
|
|
168
|
+
services as any,
|
|
169
|
+
{ http: { request, response } } as any,
|
|
170
|
+
async () => {}
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
assert.strictEqual(services._debugMessages.length, 1)
|
|
174
|
+
assert.match(services._debugMessages[0]!, /https:\/\/unknown\.com/)
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
test('should omit Access-Control-Allow-Origin when no request origin header', async () => {
|
|
146
178
|
const middleware = cors({ origin: ['https://a.com', 'https://b.com'] })
|
|
147
179
|
const request = createMockRequest('get')
|
|
148
180
|
const response = createMockResponse()
|
|
181
|
+
const services = createMockServices()
|
|
149
182
|
|
|
150
183
|
await middleware(
|
|
151
|
-
|
|
184
|
+
services as any,
|
|
185
|
+
{ http: { request, response } } as any,
|
|
186
|
+
async () => {}
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
assert.strictEqual(
|
|
190
|
+
response._headers['Access-Control-Allow-Origin'],
|
|
191
|
+
undefined
|
|
192
|
+
)
|
|
193
|
+
assert.strictEqual(services._debugMessages.length, 0)
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
test('should still call next for a disallowed origin', async () => {
|
|
197
|
+
const middleware = cors({ origin: ['https://a.com'] })
|
|
198
|
+
const request = createMockRequest('get', 'https://unknown.com')
|
|
199
|
+
const response = createMockResponse()
|
|
200
|
+
const services = createMockServices()
|
|
201
|
+
let nextCalled = false
|
|
202
|
+
|
|
203
|
+
await middleware(
|
|
204
|
+
services as any,
|
|
205
|
+
{ http: { request, response } } as any,
|
|
206
|
+
async () => {
|
|
207
|
+
nextCalled = true
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
assert.strictEqual(nextCalled, true)
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
test('should omit Access-Control-Allow-Credentials for a disallowed origin', async () => {
|
|
215
|
+
const middleware = cors({
|
|
216
|
+
origin: ['https://a.com'],
|
|
217
|
+
credentials: true,
|
|
218
|
+
})
|
|
219
|
+
const request = createMockRequest('get', 'https://unknown.com')
|
|
220
|
+
const response = createMockResponse()
|
|
221
|
+
const services = createMockServices()
|
|
222
|
+
|
|
223
|
+
await middleware(
|
|
224
|
+
services as any,
|
|
225
|
+
{ http: { request, response } } as any,
|
|
226
|
+
async () => {}
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
assert.strictEqual(
|
|
230
|
+
response._headers['Access-Control-Allow-Origin'],
|
|
231
|
+
undefined
|
|
232
|
+
)
|
|
233
|
+
assert.strictEqual(
|
|
234
|
+
response._headers['Access-Control-Allow-Credentials'],
|
|
235
|
+
undefined
|
|
236
|
+
)
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
test('should set credentials header for an allowed array origin', async () => {
|
|
240
|
+
const middleware = cors({
|
|
241
|
+
origin: ['https://a.com'],
|
|
242
|
+
credentials: true,
|
|
243
|
+
})
|
|
244
|
+
const request = createMockRequest('get', 'https://a.com')
|
|
245
|
+
const response = createMockResponse()
|
|
246
|
+
const services = createMockServices()
|
|
247
|
+
|
|
248
|
+
await middleware(
|
|
249
|
+
services as any,
|
|
152
250
|
{ http: { request, response } } as any,
|
|
153
251
|
async () => {}
|
|
154
252
|
)
|
|
@@ -157,6 +255,29 @@ describe('cors', () => {
|
|
|
157
255
|
response._headers['Access-Control-Allow-Origin'],
|
|
158
256
|
'https://a.com'
|
|
159
257
|
)
|
|
258
|
+
assert.strictEqual(
|
|
259
|
+
response._headers['Access-Control-Allow-Credentials'],
|
|
260
|
+
'true'
|
|
261
|
+
)
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
test('should omit Access-Control-Allow-Origin on a disallowed preflight but still return 204', async () => {
|
|
265
|
+
const middleware = cors({ origin: ['https://a.com'] })
|
|
266
|
+
const request = createMockRequest('options', 'https://unknown.com')
|
|
267
|
+
const response = createMockResponse()
|
|
268
|
+
const services = createMockServices()
|
|
269
|
+
|
|
270
|
+
await middleware(
|
|
271
|
+
services as any,
|
|
272
|
+
{ http: { request, response } } as any,
|
|
273
|
+
async () => {}
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
assert.strictEqual(
|
|
277
|
+
response._headers['Access-Control-Allow-Origin'],
|
|
278
|
+
undefined
|
|
279
|
+
)
|
|
280
|
+
assert.strictEqual(response._getStatus(), 204)
|
|
160
281
|
})
|
|
161
282
|
|
|
162
283
|
test('should set Vary: Origin header when origin is array', async () => {
|
package/src/middleware/cors.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
pikkuMiddleware,
|
|
3
|
+
pikkuMiddlewareFactory,
|
|
4
|
+
} from './middleware-factories.js'
|
|
3
5
|
/**
|
|
4
6
|
* Sets CORS headers on every response and short-circuits OPTIONS preflight
|
|
5
7
|
* with a 204. `origin: true` reflects the request origin; an array reflects a
|
|
6
|
-
* matching origin and otherwise
|
|
8
|
+
* matching origin and otherwise sends no `Access-Control-Allow-Origin` at all,
|
|
9
|
+
* so the browser reports "origin not allowed" rather than an origin mismatch
|
|
10
|
+
* against whichever entry happened to be first.
|
|
7
11
|
*/
|
|
8
12
|
export const cors = pikkuMiddlewareFactory<{
|
|
9
13
|
origin?: string | string[] | true
|
|
@@ -29,7 +33,7 @@ export const cors = pikkuMiddlewareFactory<{
|
|
|
29
33
|
return pikkuMiddleware({
|
|
30
34
|
name: 'CORS',
|
|
31
35
|
description: 'Handles cross-origin requests including OPTIONS preflight',
|
|
32
|
-
func: async (
|
|
36
|
+
func: async (services, wires, next) => {
|
|
33
37
|
const request = wires.http?.request
|
|
34
38
|
const response = wires.http?.response
|
|
35
39
|
|
|
@@ -39,19 +43,26 @@ export const cors = pikkuMiddlewareFactory<{
|
|
|
39
43
|
|
|
40
44
|
const requestOrigin = request.header('origin')
|
|
41
45
|
|
|
42
|
-
let allowedOrigin: string
|
|
46
|
+
let allowedOrigin: string | undefined
|
|
43
47
|
if (origin === true) {
|
|
44
48
|
allowedOrigin = requestOrigin || '*'
|
|
45
49
|
} else if (Array.isArray(origin)) {
|
|
46
50
|
allowedOrigin =
|
|
47
51
|
requestOrigin && origin.includes(requestOrigin)
|
|
48
52
|
? requestOrigin
|
|
49
|
-
:
|
|
53
|
+
: undefined
|
|
54
|
+
if (requestOrigin && !allowedOrigin) {
|
|
55
|
+
services.logger.debug(
|
|
56
|
+
`CORS: origin '${requestOrigin}' is not in the allowed list, omitting Access-Control-Allow-Origin`
|
|
57
|
+
)
|
|
58
|
+
}
|
|
50
59
|
} else {
|
|
51
60
|
allowedOrigin = origin
|
|
52
61
|
}
|
|
53
62
|
|
|
54
|
-
|
|
63
|
+
if (allowedOrigin) {
|
|
64
|
+
response.header('Access-Control-Allow-Origin', allowedOrigin)
|
|
65
|
+
}
|
|
55
66
|
response.header('Access-Control-Allow-Methods', methods.join(', '))
|
|
56
67
|
response.header('Access-Control-Allow-Headers', headers.join(', '))
|
|
57
68
|
|
|
@@ -62,7 +73,7 @@ export const cors = pikkuMiddlewareFactory<{
|
|
|
62
73
|
)
|
|
63
74
|
}
|
|
64
75
|
|
|
65
|
-
if (credentials) {
|
|
76
|
+
if (credentials && allowedOrigin) {
|
|
66
77
|
response.header('Access-Control-Allow-Credentials', 'true')
|
|
67
78
|
}
|
|
68
79
|
|