@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
package/src/services/logger.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { Safe } from '../secret-value.js'
|
|
1
|
+
import type { Safe } from '../classification/secret-value.js'
|
|
2
2
|
|
|
3
3
|
export enum LogLevel {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
trace,
|
|
5
|
+
debug,
|
|
6
|
+
info,
|
|
7
|
+
warn,
|
|
8
|
+
error,
|
|
9
|
+
critical,
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -27,9 +27,9 @@ import type { VariableDefinitionsMeta } from '../wirings/variable/variable.types
|
|
|
27
27
|
import type {
|
|
28
28
|
FunctionMeta,
|
|
29
29
|
FunctionsMeta,
|
|
30
|
-
MiddlewareMetadata,
|
|
31
30
|
PermissionMetadata,
|
|
32
|
-
} from '../
|
|
31
|
+
} from '../function/function-meta.types.js'
|
|
32
|
+
import type { MiddlewareMetadata } from '../middleware/middleware.types.js'
|
|
33
33
|
import type { AgentsMeta } from '../wirings/agent/agent.types.js'
|
|
34
34
|
import type { GatewaysMeta } from '../wirings/gateway/gateway.types.js'
|
|
35
35
|
|
|
@@ -14,7 +14,7 @@ import { InMemoryQueueService } from './in-memory-queue-service.js'
|
|
|
14
14
|
import { wireQueueWorker } from '../wirings/queue/queue-runner.js'
|
|
15
15
|
import { resetPikkuState, pikkuState } from '../pikku-state.js'
|
|
16
16
|
import type { JobOptions } from '../wirings/queue/queue.types.js'
|
|
17
|
-
import { createSecretValue } from '../secret-value.js'
|
|
17
|
+
import { createSecretValue } from '../classification/secret-value.js'
|
|
18
18
|
|
|
19
19
|
const noopLogger = { error() {}, info() {}, warn() {}, debug() {} }
|
|
20
20
|
|
|
@@ -124,4 +124,56 @@ describe('TypedSecretService', () => {
|
|
|
124
124
|
assert.strictEqual(missing.length, 1)
|
|
125
125
|
assert.strictEqual(missing[0].secretId, 'GITHUB_TOKEN')
|
|
126
126
|
})
|
|
127
|
+
|
|
128
|
+
test('an optional secret that is missing resolves undefined instead of throwing', async () => {
|
|
129
|
+
// getSecret throws for a missing secret, which is right for a required one:
|
|
130
|
+
// the app cannot run without it. An optional secret's absence is a supported
|
|
131
|
+
// state, so throwing forces every caller into a `.catch(() => null)` that
|
|
132
|
+
// also swallows a real vault failure.
|
|
133
|
+
const service = new TypedSecretService(createMockSecrets(), {
|
|
134
|
+
SCENARIO_ACTOR_SECRET: {
|
|
135
|
+
name: 'scenarioActor',
|
|
136
|
+
displayName: 'Scenario Actor Secret',
|
|
137
|
+
optional: true,
|
|
138
|
+
},
|
|
139
|
+
})
|
|
140
|
+
assert.strictEqual(await service.getSecret('SCENARIO_ACTOR_SECRET'), undefined)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
test('an optional secret that IS set resolves its value', async () => {
|
|
144
|
+
const store = new Map([['SCENARIO_ACTOR_SECRET', '"shh"']])
|
|
145
|
+
const service = new TypedSecretService(createMockSecrets(store), {
|
|
146
|
+
SCENARIO_ACTOR_SECRET: {
|
|
147
|
+
name: 'scenarioActor',
|
|
148
|
+
displayName: 'Scenario Actor Secret',
|
|
149
|
+
optional: true,
|
|
150
|
+
},
|
|
151
|
+
})
|
|
152
|
+
assert.strictEqual(await service.getSecret('SCENARIO_ACTOR_SECRET'), 'shh')
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
test('a missing secret still throws unless it declared itself optional', async () => {
|
|
156
|
+
const service = new TypedSecretService(createMockSecrets(), {
|
|
157
|
+
STRIPE_KEY: { name: 'stripe', displayName: 'Stripe' },
|
|
158
|
+
})
|
|
159
|
+
await assert.rejects(() => service.getSecret('STRIPE_KEY'))
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
test('an optional secret does not re-hit the store once resolved', async () => {
|
|
163
|
+
let reads = 0
|
|
164
|
+
const base = createMockSecrets()
|
|
165
|
+
const service = new TypedSecretService(
|
|
166
|
+
{
|
|
167
|
+
...base,
|
|
168
|
+
hasSecret: async (key: string) => {
|
|
169
|
+
reads++
|
|
170
|
+
return base.hasSecret(key)
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
{ OPTIONAL: { name: 'opt', displayName: 'Optional', optional: true } }
|
|
174
|
+
)
|
|
175
|
+
await service.getSecret('OPTIONAL')
|
|
176
|
+
await service.getSecret('OPTIONAL')
|
|
177
|
+
assert.strictEqual(reads, 1)
|
|
178
|
+
})
|
|
127
179
|
})
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import type { SecretValue } from '../secret-value.js'
|
|
1
|
+
import type { SecretValue } from '../classification/secret-value.js'
|
|
2
2
|
import type { SecretService, SecretValues } from './secret-service.js'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* The wrapper, or `undefined` when the generated map declares the key as an
|
|
6
|
+
* optional property. The `undefined` has to be lifted OUT of `SecretValue` —
|
|
7
|
+
* a missing optional secret resolves to `undefined` itself, not to a wrapper
|
|
8
|
+
* around it, so `SecretValue<T | undefined>` would type a value that never
|
|
9
|
+
* exists and hide the `undefined` behind a `.reveal()` the caller never reaches.
|
|
10
|
+
*/
|
|
11
|
+
export type SecretResult<T> = undefined extends T
|
|
12
|
+
? SecretValue<Exclude<T, undefined>> | undefined
|
|
13
|
+
: SecretValue<T>
|
|
14
|
+
|
|
4
15
|
export interface CredentialStatus {
|
|
5
16
|
secretId: string
|
|
6
17
|
name: string
|
|
@@ -12,6 +23,12 @@ export interface CredentialStatus {
|
|
|
12
23
|
export type CredentialMeta = {
|
|
13
24
|
name: string
|
|
14
25
|
displayName: string
|
|
26
|
+
/**
|
|
27
|
+
* Declared `optional: true`, so absence is a supported state rather than a
|
|
28
|
+
* misconfiguration. The generated map types the key as an optional property,
|
|
29
|
+
* which is what puts `undefined` in `getSecret`'s return type.
|
|
30
|
+
*/
|
|
31
|
+
optional?: boolean
|
|
15
32
|
oauth2?: { tokenSecretId: string }
|
|
16
33
|
}
|
|
17
34
|
|
|
@@ -28,12 +45,19 @@ export class TypedSecretService<
|
|
|
28
45
|
|
|
29
46
|
async getSecret<K extends keyof TMap & string>(
|
|
30
47
|
key: K
|
|
31
|
-
): Promise<
|
|
48
|
+
): Promise<SecretResult<TMap[K]>>
|
|
32
49
|
async getSecret<T = string>(key: string): Promise<SecretValue<T>>
|
|
33
50
|
async getSecret(key: string): Promise<unknown> {
|
|
34
51
|
if (this.cache.has(key)) {
|
|
35
52
|
return this.cache.get(key)
|
|
36
53
|
}
|
|
54
|
+
if (
|
|
55
|
+
this.credentialsMeta[key]?.optional &&
|
|
56
|
+
!(await this.secrets.hasSecret(key))
|
|
57
|
+
) {
|
|
58
|
+
this.cache.set(key, undefined)
|
|
59
|
+
return undefined
|
|
60
|
+
}
|
|
37
61
|
const value = await this.secrets.getSecret(key)
|
|
38
62
|
this.cache.set(key, value)
|
|
39
63
|
return value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NotImplementedError } from '../errors/errors.js'
|
|
2
2
|
import { hmacSha256Hex, timingSafeStringEqual } from '../utils/hmac.js'
|
|
3
|
-
import type { Safe } from '../secret-value.js'
|
|
3
|
+
import type { Safe } from '../classification/secret-value.js'
|
|
4
4
|
|
|
5
5
|
export interface SendWebhookInput {
|
|
6
6
|
url: string
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { test, describe } from 'node:test'
|
|
2
|
+
import * as assert from 'assert'
|
|
3
|
+
import ts from 'typescript'
|
|
4
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs'
|
|
5
|
+
import { dirname, join, relative } from 'node:path'
|
|
6
|
+
import { fileURLToPath } from 'node:url'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Templates are the one tree that is copied verbatim into a user's project, so
|
|
10
|
+
* whatever they import is what every new Pikku app starts life importing. The
|
|
11
|
+
* app-developer surface is the generated `#pikku` alias; a relative path into
|
|
12
|
+
* `.pikku` reaches the same file but teaches the wrong habit, and it breaks the
|
|
13
|
+
* moment `create-pikku` moves the directory — which it does for StackBlitz,
|
|
14
|
+
* where `.pikku` becomes `pikku-gen`.
|
|
15
|
+
*/
|
|
16
|
+
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), '../../..')
|
|
17
|
+
const templatesDir = join(repoRoot, 'templates')
|
|
18
|
+
const skipped = new Set(['node_modules', 'dist', '.pikku', '.next', 'build'])
|
|
19
|
+
|
|
20
|
+
const walk = (dir: string, out: string[] = []): string[] => {
|
|
21
|
+
for (const entry of readdirSync(dir)) {
|
|
22
|
+
if (skipped.has(entry)) continue
|
|
23
|
+
const path = join(dir, entry)
|
|
24
|
+
if (statSync(path).isDirectory()) walk(path, out)
|
|
25
|
+
else if (path.endsWith('.ts') || path.endsWith('.tsx')) out.push(path)
|
|
26
|
+
}
|
|
27
|
+
return out
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* `.gen.*` and `.d.ts` files are CLI output rather than template source: what
|
|
32
|
+
* they import is decided by the codegen serializers, not by the template.
|
|
33
|
+
*/
|
|
34
|
+
const isGenerated = (path: string) =>
|
|
35
|
+
path.includes('.gen.') || path.endsWith('.d.ts')
|
|
36
|
+
|
|
37
|
+
const templateNames = () =>
|
|
38
|
+
readdirSync(templatesDir).filter((name) =>
|
|
39
|
+
existsSync(join(templatesDir, name, 'package.json'))
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const templateSourceFiles = (template: string) => {
|
|
43
|
+
const dir = join(templatesDir, template)
|
|
44
|
+
return walk(dir).filter((file) => !isGenerated(file))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Parsed rather than grepped, so a `.pikku` path quoted inside a string
|
|
49
|
+
* literal — a config default, a doc comment, a codegen fixture — is not
|
|
50
|
+
* mistaken for an import the template actually makes.
|
|
51
|
+
*/
|
|
52
|
+
const generatedImports = (file: string) => {
|
|
53
|
+
const source = ts.createSourceFile(
|
|
54
|
+
file,
|
|
55
|
+
readFileSync(file, 'utf8'),
|
|
56
|
+
ts.ScriptTarget.Latest,
|
|
57
|
+
true
|
|
58
|
+
)
|
|
59
|
+
const found: { specifier: string; line: number }[] = []
|
|
60
|
+
for (const statement of source.statements) {
|
|
61
|
+
if (
|
|
62
|
+
!ts.isImportDeclaration(statement) &&
|
|
63
|
+
!ts.isExportDeclaration(statement)
|
|
64
|
+
) {
|
|
65
|
+
continue
|
|
66
|
+
}
|
|
67
|
+
const moduleSpecifier = statement.moduleSpecifier
|
|
68
|
+
if (!moduleSpecifier || !ts.isStringLiteral(moduleSpecifier)) continue
|
|
69
|
+
const specifier = moduleSpecifier.text
|
|
70
|
+
if (!specifier.startsWith('.')) continue
|
|
71
|
+
if (!/(^|\/)\.pikku\//.test(specifier)) continue
|
|
72
|
+
const { line } = source.getLineAndCharacterOfPosition(
|
|
73
|
+
statement.getStart(source)
|
|
74
|
+
)
|
|
75
|
+
found.push({ specifier, line: line + 1 })
|
|
76
|
+
}
|
|
77
|
+
return found
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Bun resolves a '#'-prefixed specifier as a Node subpath import and does not
|
|
82
|
+
* apply tsconfig `paths` to it, so neither half of the alias reaches the
|
|
83
|
+
* functions template next door: Node rejects the '../' imports target, and
|
|
84
|
+
* `paths` is never consulted. Until the bun template takes a workspace
|
|
85
|
+
* dependency on the functions template — which makes a bare specifier a legal
|
|
86
|
+
* imports target — it has no alias mechanism and keeps the relative path.
|
|
87
|
+
*/
|
|
88
|
+
const withoutAlias = new Set(['bun'])
|
|
89
|
+
|
|
90
|
+
describe('templates ship the #pikku alias', () => {
|
|
91
|
+
test('no template reaches generated output through a relative path', () => {
|
|
92
|
+
const offenders: string[] = []
|
|
93
|
+
|
|
94
|
+
for (const template of templateNames()) {
|
|
95
|
+
if (withoutAlias.has(template)) continue
|
|
96
|
+
for (const file of templateSourceFiles(template)) {
|
|
97
|
+
for (const { specifier, line } of generatedImports(file)) {
|
|
98
|
+
offenders.push(`${relative(repoRoot, file)}:${line} ${specifier}`)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
assert.deepStrictEqual(
|
|
104
|
+
offenders,
|
|
105
|
+
[],
|
|
106
|
+
`Templates must reach generated output through the '#pikku' alias.\n` +
|
|
107
|
+
`A relative path into '.pikku' is the specifier every scaffolded app ` +
|
|
108
|
+
`would inherit, and it breaks when create-pikku relocates the ` +
|
|
109
|
+
`directory.\n\n` +
|
|
110
|
+
offenders.join('\n')
|
|
111
|
+
)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* `paths` is what actually resolves the alias in a runtime template: it
|
|
116
|
+
* points at the functions template next door, and tsx, tsc and the
|
|
117
|
+
* inspector all consult it. The inspector in particular builds its own
|
|
118
|
+
* program and inherits only baseUrl, paths, rootDirs and pathsBasePath —
|
|
119
|
+
* it never sees an imports map.
|
|
120
|
+
*/
|
|
121
|
+
test('every template using #pikku declares it in tsconfig paths', () => {
|
|
122
|
+
const offenders: string[] = []
|
|
123
|
+
|
|
124
|
+
for (const template of templateNames()) {
|
|
125
|
+
const usesAlias = templateSourceFiles(template).some((file) =>
|
|
126
|
+
/['"]#pikku\//.test(readFileSync(file, 'utf8'))
|
|
127
|
+
)
|
|
128
|
+
if (!usesAlias) continue
|
|
129
|
+
|
|
130
|
+
const tsconfigPath = join(templatesDir, template, 'tsconfig.json')
|
|
131
|
+
if (!existsSync(tsconfigPath)) {
|
|
132
|
+
offenders.push(`templates/${template}/tsconfig.json missing`)
|
|
133
|
+
continue
|
|
134
|
+
}
|
|
135
|
+
const tsconfig = JSON.parse(readFileSync(tsconfigPath, 'utf8'))
|
|
136
|
+
if (!tsconfig.compilerOptions?.paths?.['#pikku/*']) {
|
|
137
|
+
offenders.push(`templates/${template}/tsconfig.json missing paths`)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
assert.deepStrictEqual(
|
|
142
|
+
offenders,
|
|
143
|
+
[],
|
|
144
|
+
`A template that imports '#pikku/…' has to declare it in tsconfig ` +
|
|
145
|
+
`'paths', which is what resolves it.\n\n` +
|
|
146
|
+
offenders.join('\n')
|
|
147
|
+
)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Every `#pikku/…` pattern shares the prefix `#pikku/`, and TypeScript picks
|
|
152
|
+
* the matching pattern with the longest prefix, ignoring the suffix and
|
|
153
|
+
* breaking the tie in favour of the first key. So a suffix-specific pattern
|
|
154
|
+
* such as `#pikku/*.json` only ever wins by being listed before the bare one
|
|
155
|
+
* — an ordering that does not survive `create-pikku` deep-merging the runtime
|
|
156
|
+
* template's tsconfig with the functions template's.
|
|
157
|
+
*
|
|
158
|
+
* The bare pattern therefore has to resolve a file as well as a directory
|
|
159
|
+
* index, which a target list does: `#pikku/mcp/mcp.gen.json` misses
|
|
160
|
+
* `.pikku/mcp/mcp.gen.json/index.ts` and lands on the file behind it.
|
|
161
|
+
*/
|
|
162
|
+
test('the bare #pikku pattern resolves a file, not only a directory index', () => {
|
|
163
|
+
const offenders: string[] = []
|
|
164
|
+
|
|
165
|
+
for (const template of templateNames()) {
|
|
166
|
+
const declare = (
|
|
167
|
+
source: string,
|
|
168
|
+
targets: string | string[] | undefined
|
|
169
|
+
) => {
|
|
170
|
+
if (targets === undefined) return
|
|
171
|
+
const list = Array.isArray(targets) ? targets : [targets]
|
|
172
|
+
// A directory-index target ends in the index file; anything else names
|
|
173
|
+
// whatever the alias was pointed at, which is what a file needs.
|
|
174
|
+
if (list.every((target) => /\/index\.[cm]?[jt]s$/.test(target))) {
|
|
175
|
+
offenders.push(`${source} ${list.join(', ')}`)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const tsconfigPath = join(templatesDir, template, 'tsconfig.json')
|
|
180
|
+
if (existsSync(tsconfigPath)) {
|
|
181
|
+
const tsconfig = JSON.parse(readFileSync(tsconfigPath, 'utf8'))
|
|
182
|
+
declare(
|
|
183
|
+
`templates/${template}/tsconfig.json`,
|
|
184
|
+
tsconfig.compilerOptions?.paths?.['#pikku/*']
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const pkg = JSON.parse(
|
|
189
|
+
readFileSync(join(templatesDir, template, 'package.json'), 'utf8')
|
|
190
|
+
)
|
|
191
|
+
declare(
|
|
192
|
+
`templates/${template}/package.json`,
|
|
193
|
+
pkg.imports?.['#pikku/*'] as string | string[] | undefined
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
assert.deepStrictEqual(
|
|
198
|
+
offenders,
|
|
199
|
+
[],
|
|
200
|
+
`The bare '#pikku/*' pattern must list a file target alongside the ` +
|
|
201
|
+
`directory index, because a suffix-specific pattern like ` +
|
|
202
|
+
`'#pikku/*.json' loses to it whenever it is not listed first — and ` +
|
|
203
|
+
`create-pikku's merge decides that order.\n\n` +
|
|
204
|
+
offenders.join('\n')
|
|
205
|
+
)
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Node rejects an internal-imports target that is not './'-relative or a
|
|
210
|
+
* bare package specifier, so a '../' target throws ERR_INVALID_PACKAGE_TARGET
|
|
211
|
+
* rather than resolving. A runtime template reaching the functions template
|
|
212
|
+
* next door cannot express that as an imports map at all — it resolves
|
|
213
|
+
* through `paths`, and declaring the map anyway only looks like it works,
|
|
214
|
+
* because `paths` answers first.
|
|
215
|
+
*/
|
|
216
|
+
test('no template declares an imports target Node will reject', () => {
|
|
217
|
+
const offenders: string[] = []
|
|
218
|
+
|
|
219
|
+
for (const template of templateNames()) {
|
|
220
|
+
const pkg = JSON.parse(
|
|
221
|
+
readFileSync(join(templatesDir, template, 'package.json'), 'utf8')
|
|
222
|
+
)
|
|
223
|
+
for (const [specifier, target] of Object.entries(pkg.imports ?? {})) {
|
|
224
|
+
if (typeof target === 'string' && target.startsWith('../')) {
|
|
225
|
+
offenders.push(
|
|
226
|
+
`templates/${template}/package.json ${specifier} -> ${target}`
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
assert.deepStrictEqual(
|
|
233
|
+
offenders,
|
|
234
|
+
[],
|
|
235
|
+
`An 'imports' target must start with './' or be a bare package ` +
|
|
236
|
+
`specifier; '../' throws ERR_INVALID_PACKAGE_TARGET.\n\n` +
|
|
237
|
+
offenders.join('\n')
|
|
238
|
+
)
|
|
239
|
+
})
|
|
240
|
+
})
|
package/src/testing/index.ts
CHANGED