@pikku/core 0.11.2 → 0.12.1
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 +57 -2
- package/dist/crypto-utils.d.ts +2 -0
- package/dist/crypto-utils.js +78 -0
- package/dist/errors/errors.d.ts +14 -0
- package/dist/errors/errors.js +26 -0
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/function/function-runner.d.ts +10 -4
- package/dist/function/function-runner.js +126 -45
- package/dist/function/functions.types.d.ts +32 -87
- package/dist/function/functions.types.js +16 -46
- package/dist/function/index.d.ts +2 -2
- package/dist/function/index.js +1 -2
- package/dist/handle-error.d.ts +2 -2
- package/dist/handle-error.js +3 -12
- package/dist/index.d.ts +30 -26
- package/dist/index.js +19 -29
- package/dist/internal.d.ts +3 -0
- package/dist/internal.js +2 -0
- package/dist/middleware/auth-apikey.d.ts +2 -2
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.d.ts +3 -3
- package/dist/middleware/auth-bearer.js +4 -7
- package/dist/middleware/auth-cookie.d.ts +4 -4
- package/dist/middleware/auth-cookie.js +7 -9
- package/dist/middleware/cors.d.ts +46 -0
- package/dist/middleware/cors.js +81 -0
- package/dist/middleware/index.d.ts +5 -3
- package/dist/middleware/index.js +5 -3
- package/dist/middleware/remote-auth.d.ts +5 -0
- package/dist/middleware/remote-auth.js +55 -0
- package/dist/middleware/timeout.d.ts +2 -2
- package/dist/middleware-runner.d.ts +1 -1
- package/dist/middleware-runner.js +8 -10
- package/dist/permissions.d.ts +2 -2
- package/dist/permissions.js +11 -15
- package/dist/pikku-state.d.ts +10 -8
- package/dist/pikku-state.js +48 -25
- package/dist/schema.d.ts +4 -4
- package/dist/schema.js +20 -15
- package/dist/services/ai-agent-runner-service.d.ts +43 -0
- package/dist/services/ai-agent-runner-service.js +1 -0
- package/dist/services/ai-run-state-service.d.ts +13 -0
- package/dist/services/ai-run-state-service.js +1 -0
- package/dist/services/ai-storage-service.d.ts +18 -0
- package/dist/services/ai-storage-service.js +1 -0
- package/dist/services/content-service.d.ts +6 -0
- package/dist/services/deployment-service.d.ts +19 -0
- package/dist/services/deployment-service.js +1 -0
- package/dist/services/gopass-secrets.d.ts +47 -0
- package/dist/services/gopass-secrets.js +97 -0
- package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
- package/dist/services/in-memory-ai-run-state-service.js +44 -0
- package/dist/services/in-memory-trigger-service.d.ts +22 -0
- package/dist/services/in-memory-trigger-service.js +48 -0
- package/dist/services/in-memory-workflow-service.d.ts +59 -0
- package/dist/services/in-memory-workflow-service.js +287 -0
- package/dist/services/index.d.ts +26 -11
- package/dist/services/index.js +11 -13
- package/dist/services/local-content.d.ts +2 -1
- package/dist/services/local-content.js +6 -1
- package/dist/services/local-secrets.d.ts +25 -2
- package/dist/services/local-secrets.js +45 -0
- package/dist/services/local-variables.d.ts +6 -1
- package/dist/services/local-variables.js +18 -0
- package/dist/services/logger-console.d.ts +2 -1
- package/dist/services/scheduler-service.d.ts +9 -1
- package/dist/services/scheduler-service.js +8 -0
- package/dist/services/schema-service.d.ts +6 -0
- package/dist/services/scoped-secret-service.d.ts +16 -0
- package/dist/services/scoped-secret-service.js +35 -0
- package/dist/services/secret-service.d.ts +25 -4
- package/dist/services/trigger-service.d.ts +16 -0
- package/dist/services/trigger-service.js +1 -0
- package/dist/services/typed-secret-service.d.ts +30 -0
- package/dist/services/typed-secret-service.js +40 -0
- package/dist/services/typed-variables-service.d.ts +27 -0
- package/dist/services/typed-variables-service.js +46 -0
- package/dist/services/user-session-service.d.ts +15 -2
- package/dist/services/user-session-service.js +17 -0
- package/dist/services/variables-service.d.ts +5 -0
- package/dist/services/workflow-service.d.ts +9 -5
- package/dist/types/core.types.d.ts +67 -25
- package/dist/types/core.types.js +8 -1
- package/dist/types/state.types.d.ts +53 -59
- package/dist/utils.d.ts +7 -6
- package/dist/utils.js +27 -12
- package/dist/version.d.ts +6 -0
- package/dist/version.js +19 -0
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +146 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +29 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +199 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +9 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.js +36 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +59 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +348 -0
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +15 -0
- package/dist/wirings/ai-agent/ai-agent-registry.js +47 -0
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +3 -0
- package/dist/wirings/ai-agent/ai-agent-runner.js +195 -0
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +12 -0
- package/dist/wirings/ai-agent/ai-agent-stream.js +662 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +313 -0
- package/dist/wirings/ai-agent/ai-agent.types.js +1 -0
- package/dist/wirings/ai-agent/index.d.ts +7 -0
- package/dist/wirings/ai-agent/index.js +6 -0
- package/dist/wirings/channel/channel-common.d.ts +8 -5
- package/dist/wirings/channel/channel-common.js +15 -8
- package/dist/wirings/channel/channel-handler.d.ts +3 -3
- package/dist/wirings/channel/channel-handler.js +15 -6
- package/dist/wirings/channel/channel-middleware-runner.d.ts +9 -0
- package/dist/wirings/channel/channel-middleware-runner.js +73 -0
- package/dist/wirings/channel/channel-runner.d.ts +5 -5
- package/dist/wirings/channel/channel-runner.js +10 -9
- package/dist/wirings/channel/channel-store.d.ts +1 -1
- package/dist/wirings/channel/channel.types.d.ts +9 -7
- package/dist/wirings/channel/define-channel-routes.d.ts +21 -0
- package/dist/wirings/channel/define-channel-routes.js +23 -0
- package/dist/wirings/channel/index.d.ts +10 -8
- package/dist/wirings/channel/index.js +7 -8
- package/dist/wirings/channel/local/index.d.ts +3 -3
- package/dist/wirings/channel/local/index.js +3 -3
- package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
- package/dist/wirings/channel/local/local-channel-runner.js +22 -9
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
- package/dist/wirings/channel/log-channels.d.ts +1 -1
- package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +1 -1
- package/dist/wirings/channel/serverless/index.d.ts +1 -1
- package/dist/wirings/channel/serverless/index.js +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +4 -4
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +40 -23
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
- package/dist/wirings/cli/channel/index.d.ts +1 -1
- package/dist/wirings/cli/channel/index.js +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +3 -3
- package/dist/wirings/cli/cli-runner.js +12 -8
- package/dist/wirings/cli/cli.types.d.ts +9 -9
- package/dist/wirings/cli/command-parser.d.ts +1 -1
- package/dist/wirings/cli/define-cli-commands.d.ts +19 -0
- package/dist/wirings/cli/define-cli-commands.js +20 -0
- package/dist/wirings/cli/index.d.ts +2 -3
- package/dist/wirings/cli/index.js +1 -3
- package/dist/wirings/http/http-routes.d.ts +69 -0
- package/dist/wirings/http/http-routes.js +139 -0
- package/dist/wirings/http/http-runner.d.ts +9 -9
- package/dist/wirings/http/http-runner.js +79 -34
- package/dist/wirings/http/http.types.d.ts +77 -41
- package/dist/wirings/http/index.d.ts +5 -4
- package/dist/wirings/http/index.js +4 -3
- package/dist/wirings/http/log-http-routes.d.ts +1 -1
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
- package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
- package/dist/wirings/http/routers/http-router.d.ts +1 -1
- package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
- package/dist/wirings/mcp/index.d.ts +4 -3
- package/dist/wirings/mcp/index.js +3 -3
- package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
- package/dist/wirings/mcp/mcp-runner.d.ts +1 -6
- package/dist/wirings/mcp/mcp-runner.js +28 -40
- package/dist/wirings/mcp/mcp.types.d.ts +5 -5
- package/dist/wirings/node/index.d.ts +2 -0
- package/dist/wirings/node/index.js +1 -0
- package/dist/wirings/node/node.types.d.ts +20 -0
- package/dist/wirings/node/node.types.js +1 -0
- package/dist/wirings/oauth2/index.d.ts +3 -0
- package/dist/wirings/oauth2/index.js +2 -0
- package/dist/wirings/oauth2/oauth2-client.d.ts +47 -0
- package/dist/wirings/oauth2/oauth2-client.js +267 -0
- package/dist/wirings/oauth2/oauth2.types.d.ts +65 -0
- package/dist/wirings/oauth2/oauth2.types.js +4 -0
- package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +20 -0
- package/dist/wirings/oauth2/wire-oauth2-credential.js +21 -0
- package/dist/wirings/queue/index.d.ts +1 -1
- package/dist/wirings/queue/queue-runner.d.ts +1 -5
- package/dist/wirings/queue/queue-runner.js +11 -8
- package/dist/wirings/queue/queue.types.d.ts +5 -5
- package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
- package/dist/wirings/queue/register-queue-helper.js +1 -1
- package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
- package/dist/wirings/rpc/index.d.ts +3 -1
- package/dist/wirings/rpc/index.js +2 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +58 -8
- package/dist/wirings/rpc/rpc-runner.js +177 -31
- package/dist/wirings/rpc/rpc-types.d.ts +20 -4
- package/dist/wirings/rpc/wire-addon.d.ts +10 -0
- package/dist/wirings/rpc/wire-addon.js +9 -0
- package/dist/wirings/scheduler/index.d.ts +2 -2
- package/dist/wirings/scheduler/index.js +1 -2
- package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -5
- package/dist/wirings/scheduler/scheduler-runner.js +11 -14
- package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
- package/dist/wirings/secret/index.d.ts +3 -0
- package/dist/wirings/secret/index.js +2 -0
- package/dist/wirings/secret/secret.types.d.ts +27 -0
- package/dist/wirings/secret/secret.types.js +1 -0
- package/dist/wirings/secret/validate-secret-definitions.d.ts +6 -0
- package/dist/wirings/secret/validate-secret-definitions.js +55 -0
- package/dist/wirings/trigger/index.d.ts +3 -2
- package/dist/wirings/trigger/index.js +2 -2
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +22 -0
- package/dist/wirings/trigger/pikku-trigger-service.js +70 -0
- package/dist/wirings/trigger/trigger-runner.d.ts +18 -9
- package/dist/wirings/trigger/trigger-runner.js +48 -19
- package/dist/wirings/trigger/trigger.types.d.ts +99 -11
- package/dist/wirings/trigger/trigger.types.js +40 -1
- package/dist/wirings/variable/index.d.ts +3 -0
- package/dist/wirings/variable/index.js +2 -0
- package/dist/wirings/variable/validate-variable-definitions.d.ts +6 -0
- package/dist/wirings/variable/validate-variable-definitions.js +45 -0
- package/dist/wirings/variable/variable.types.d.ts +18 -0
- package/dist/wirings/variable/variable.types.js +1 -0
- package/dist/wirings/workflow/dsl/index.d.ts +1 -1
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +7 -1
- package/dist/wirings/workflow/dsl/workflow-runner.js +3 -2
- package/dist/wirings/workflow/graph/graph-node.d.ts +1 -6
- package/dist/wirings/workflow/graph/graph-runner.d.ts +5 -31
- package/dist/wirings/workflow/graph/graph-runner.js +384 -296
- package/dist/wirings/workflow/graph/index.d.ts +4 -3
- package/dist/wirings/workflow/graph/index.js +3 -3
- package/dist/wirings/workflow/graph/template.d.ts +15 -0
- package/dist/wirings/workflow/graph/template.js +27 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +15 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.js +8 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -13
- package/dist/wirings/workflow/index.d.ts +6 -6
- package/dist/wirings/workflow/index.js +6 -4
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +29 -19
- package/dist/wirings/workflow/pikku-workflow-service.js +217 -82
- package/dist/wirings/workflow/workflow-helpers.d.ts +36 -0
- package/dist/wirings/workflow/workflow-helpers.js +38 -0
- package/dist/wirings/workflow/workflow.types.d.ts +42 -95
- package/package.json +14 -15
- package/run-tests.sh +4 -1
- package/src/crypto-utils.test.ts +116 -0
- package/src/crypto-utils.ts +99 -0
- package/src/errors/error.test.ts +143 -2
- package/src/errors/errors.ts +27 -0
- package/src/errors/index.ts +1 -1
- package/src/factory-functions.test.ts +42 -2
- package/src/function/function-runner.test.ts +6 -13
- package/src/function/function-runner.ts +161 -53
- package/src/function/functions.types.ts +63 -132
- package/src/function/index.ts +5 -2
- package/src/handle-error.test.ts +361 -0
- package/src/handle-error.ts +6 -14
- package/src/index.ts +97 -30
- package/src/internal.ts +6 -0
- package/src/middleware/auth-apikey.test.ts +16 -13
- package/src/middleware/auth-apikey.ts +3 -3
- package/src/middleware/auth-bearer.test.ts +18 -15
- package/src/middleware/auth-bearer.ts +27 -32
- package/src/middleware/auth-cookie.test.ts +17 -14
- package/src/middleware/auth-cookie.ts +9 -13
- package/src/middleware/cors.test.ts +424 -0
- package/src/middleware/cors.ts +104 -0
- package/src/middleware/index.ts +5 -3
- package/src/middleware/remote-auth.test.ts +488 -0
- package/src/middleware/remote-auth.ts +68 -0
- package/src/middleware-runner.test.ts +123 -1
- package/src/middleware-runner.ts +13 -13
- package/src/permissions.test.ts +83 -9
- package/src/permissions.ts +17 -19
- package/src/pikku-state.test.ts +224 -0
- package/src/pikku-state.ts +59 -35
- package/src/run-tests-script.test.ts +49 -0
- package/src/schema.test.ts +198 -6
- package/src/schema.ts +28 -21
- package/src/services/ai-agent-runner-service.ts +41 -0
- package/src/services/ai-run-state-service.ts +20 -0
- package/src/services/ai-storage-service.ts +39 -0
- package/src/services/content-service.ts +7 -0
- package/src/services/deployment-service.ts +22 -0
- package/src/services/gopass-secrets.ts +98 -0
- package/src/services/in-memory-ai-run-state-service.ts +73 -0
- package/src/services/in-memory-trigger-service.ts +64 -0
- package/src/services/in-memory-workflow-service.test.ts +351 -0
- package/src/services/in-memory-workflow-service.ts +395 -0
- package/src/services/index.ts +50 -14
- package/src/services/local-content.ts +9 -3
- package/src/services/local-secrets.test.ts +80 -0
- package/src/services/local-secrets.ts +53 -2
- package/src/services/local-variables.test.ts +61 -0
- package/src/services/local-variables.ts +23 -1
- package/src/services/logger-console.test.ts +118 -0
- package/src/services/logger-console.ts +2 -1
- package/src/services/scheduler-service.ts +11 -1
- package/src/services/schema-service.ts +7 -0
- package/src/services/scoped-secret-service.test.ts +74 -0
- package/src/services/scoped-secret-service.ts +41 -0
- package/src/services/secret-service.ts +25 -4
- package/src/services/trigger-service.ts +17 -0
- package/src/services/typed-secret-service.test.ts +93 -0
- package/src/services/typed-secret-service.ts +70 -0
- package/src/services/typed-variables-service.test.ts +73 -0
- package/src/services/typed-variables-service.ts +81 -0
- package/src/services/user-session-service.test.ts +113 -0
- package/src/services/user-session-service.ts +25 -2
- package/src/services/variables-service.ts +5 -0
- package/src/services/workflow-service.ts +23 -13
- package/src/time-utils.test.ts +1 -1
- package/src/types/core.types.ts +95 -24
- package/src/types/state.types.ts +56 -73
- package/src/utils.test.ts +350 -0
- package/src/utils.ts +33 -18
- package/src/version.test.ts +80 -0
- package/src/version.ts +25 -0
- package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
- package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +214 -0
- package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
- package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +300 -0
- package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
- package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +504 -0
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +37 -0
- package/src/wirings/ai-agent/ai-agent-registry.ts +82 -0
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +317 -0
- package/src/wirings/ai-agent/ai-agent-runner.ts +251 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +652 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +1049 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +328 -0
- package/src/wirings/ai-agent/index.ts +39 -0
- package/src/wirings/channel/channel-common.ts +33 -20
- package/src/wirings/channel/channel-handler.ts +26 -9
- package/src/wirings/channel/channel-middleware-runner.ts +119 -0
- package/src/wirings/channel/channel-runner.ts +15 -16
- package/src/wirings/channel/channel-store.ts +1 -1
- package/src/wirings/channel/channel.types.ts +21 -9
- package/src/wirings/channel/define-channel-routes.ts +25 -0
- package/src/wirings/channel/index.ts +23 -8
- package/src/wirings/channel/local/index.ts +3 -3
- package/src/wirings/channel/local/local-channel-runner.test.ts +57 -7
- package/src/wirings/channel/local/local-channel-runner.ts +40 -19
- package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
- package/src/wirings/channel/log-channels.ts +1 -1
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +1 -1
- package/src/wirings/channel/serverless/index.ts +5 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +57 -36
- package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
- package/src/wirings/cli/channel/index.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +10 -10
- package/src/wirings/cli/cli-runner.ts +28 -14
- package/src/wirings/cli/cli.types.ts +14 -14
- package/src/wirings/cli/command-parser.test.ts +9 -9
- package/src/wirings/cli/command-parser.ts +1 -1
- package/src/wirings/cli/define-cli-commands.ts +24 -0
- package/src/wirings/cli/index.ts +10 -4
- package/src/wirings/http/http-routes.test.ts +322 -0
- package/src/wirings/http/http-routes.ts +198 -0
- package/src/wirings/http/http-runner.test.ts +12 -20
- package/src/wirings/http/http-runner.ts +101 -51
- package/src/wirings/http/http.types.ts +119 -48
- package/src/wirings/http/index.ts +16 -4
- package/src/wirings/http/log-http-routes.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
- package/src/wirings/http/routers/http-router.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.ts +4 -3
- package/src/wirings/mcp/index.ts +27 -3
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +3 -3
- package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
- package/src/wirings/mcp/mcp-runner.ts +48 -65
- package/src/wirings/mcp/mcp.types.ts +5 -5
- package/src/wirings/node/index.ts +2 -0
- package/src/wirings/node/node.types.ts +23 -0
- package/src/wirings/oauth2/index.ts +3 -0
- package/src/wirings/oauth2/oauth2-client.test.ts +929 -0
- package/src/wirings/oauth2/oauth2-client.ts +335 -0
- package/src/wirings/oauth2/oauth2.types.ts +69 -0
- package/src/wirings/oauth2/wire-oauth2-credential.ts +23 -0
- package/src/wirings/queue/index.ts +13 -2
- package/src/wirings/queue/queue-runner.test.ts +142 -73
- package/src/wirings/queue/queue-runner.ts +18 -14
- package/src/wirings/queue/queue.types.ts +5 -5
- package/src/wirings/queue/register-queue-helper.ts +3 -5
- package/src/wirings/queue/validate-worker-config.test.ts +108 -0
- package/src/wirings/queue/validate-worker-config.ts +4 -1
- package/src/wirings/rpc/index.ts +3 -1
- package/src/wirings/rpc/rpc-runner.ts +254 -41
- package/src/wirings/rpc/rpc-types.ts +28 -4
- package/src/wirings/rpc/wire-addon.ts +20 -0
- package/src/wirings/scheduler/index.ts +6 -4
- package/src/wirings/scheduler/log-schedulers.ts +1 -1
- package/src/wirings/scheduler/scheduler-runner.test.ts +78 -45
- package/src/wirings/scheduler/scheduler-runner.ts +20 -27
- package/src/wirings/scheduler/scheduler.types.ts +2 -2
- package/src/wirings/secret/index.ts +9 -0
- package/src/wirings/secret/secret.types.ts +32 -0
- package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
- package/src/wirings/secret/validate-secret-definitions.ts +82 -0
- package/src/wirings/trigger/index.ts +10 -2
- package/src/wirings/trigger/pikku-trigger-service.ts +112 -0
- package/src/wirings/trigger/trigger-runner.test.ts +79 -0
- package/src/wirings/trigger/trigger-runner.ts +80 -41
- package/src/wirings/trigger/trigger.types.ts +144 -22
- package/src/wirings/variable/index.ts +8 -0
- package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
- package/src/wirings/variable/validate-variable-definitions.ts +69 -0
- package/src/wirings/variable/variable.types.ts +22 -0
- package/src/wirings/workflow/dsl/index.ts +1 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +9 -1
- package/src/wirings/workflow/dsl/workflow-runner.ts +4 -3
- package/src/wirings/workflow/graph/graph-node.ts +1 -6
- package/src/wirings/workflow/graph/graph-runner.test.ts +487 -0
- package/src/wirings/workflow/graph/graph-runner.ts +496 -374
- package/src/wirings/workflow/graph/index.ts +14 -3
- package/src/wirings/workflow/graph/template.test.ts +49 -0
- package/src/wirings/workflow/graph/template.ts +42 -0
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +29 -0
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -22
- package/src/wirings/workflow/index.ts +21 -10
- package/src/wirings/workflow/pikku-workflow-service.test.ts +200 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +308 -105
- package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
- package/src/wirings/workflow/workflow-helpers.ts +79 -0
- package/src/wirings/workflow/workflow.types.ts +47 -92
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/forge-node/forge-node.types.d.ts +0 -120
- package/dist/wirings/forge-node/forge-node.types.js +0 -38
- package/dist/wirings/forge-node/index.d.ts +0 -1
- package/dist/wirings/forge-node/index.js +0 -1
- package/dist/wirings/workflow/wire-workflow.d.ts +0 -42
- package/dist/wirings/workflow/wire-workflow.js +0 -53
- package/dist/wirings/workflow/workflow-utils.d.ts +0 -23
- package/dist/wirings/workflow/workflow-utils.js +0 -66
- package/src/wirings/forge-node/forge-node.types.ts +0 -135
- package/src/wirings/forge-node/index.ts +0 -1
- package/src/wirings/workflow/wire-workflow.ts +0 -94
- package/src/wirings/workflow/workflow-utils.ts +0 -120
|
@@ -6,7 +6,14 @@ import type {
|
|
|
6
6
|
PikkuWire,
|
|
7
7
|
PickRequired,
|
|
8
8
|
} from '../types/core.types.js'
|
|
9
|
-
import {
|
|
9
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
|
10
|
+
import type { CoreNodeConfig } from '../wirings/node/node.types.js'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated Use StandardSchemaV1 from @standard-schema/spec instead.
|
|
14
|
+
* This alias exists only for backward compatibility with generated code.
|
|
15
|
+
*/
|
|
16
|
+
export type ZodLike<T = any> = StandardSchemaV1<T, T>
|
|
10
17
|
|
|
11
18
|
/**
|
|
12
19
|
* Represents a core API function that performs an operation using core services and a user session.
|
|
@@ -20,6 +27,7 @@ export type CorePikkuFunction<
|
|
|
20
27
|
In,
|
|
21
28
|
Out,
|
|
22
29
|
Services extends CoreSingletonServices = CoreServices,
|
|
30
|
+
Session extends CoreUserSession = CoreUserSession,
|
|
23
31
|
Wire extends PikkuWire<In, Out> = PikkuWire<In, Out, true, Session>,
|
|
24
32
|
> = (
|
|
25
33
|
services: Services,
|
|
@@ -39,15 +47,16 @@ export type CorePikkuFunctionSessionless<
|
|
|
39
47
|
In,
|
|
40
48
|
Out,
|
|
41
49
|
Services extends CoreSingletonServices = CoreServices,
|
|
42
|
-
|
|
50
|
+
Session extends CoreUserSession = CoreUserSession,
|
|
51
|
+
Wire extends PikkuWire<In, Out, false, Session, any, any, any> = PikkuWire<
|
|
43
52
|
In,
|
|
44
53
|
Out,
|
|
45
54
|
false,
|
|
46
|
-
|
|
55
|
+
Session,
|
|
47
56
|
any,
|
|
48
57
|
any,
|
|
49
58
|
any
|
|
50
|
-
|
|
59
|
+
>,
|
|
51
60
|
> = (
|
|
52
61
|
services: Services,
|
|
53
62
|
data: In,
|
|
@@ -94,8 +103,8 @@ export type CorePikkuPermissionConfig<
|
|
|
94
103
|
> = {
|
|
95
104
|
/** The permission function */
|
|
96
105
|
func: CorePikkuPermission<In, Services, Wire>
|
|
97
|
-
/** Optional human-readable
|
|
98
|
-
|
|
106
|
+
/** Optional human-readable name for the permission */
|
|
107
|
+
name?: string
|
|
99
108
|
/** Optional description of what the permission checks */
|
|
100
109
|
description?: string
|
|
101
110
|
}
|
|
@@ -108,18 +117,18 @@ export type CorePikkuPermissionConfig<
|
|
|
108
117
|
* ```typescript
|
|
109
118
|
* // Direct function syntax
|
|
110
119
|
* export const adminPermission = pikkuPermission(
|
|
111
|
-
* async ({ logger }, _data, {
|
|
112
|
-
* const currentSession = await
|
|
120
|
+
* async ({ logger }, _data, { getSession }) => {
|
|
121
|
+
* const currentSession = await getSession()
|
|
113
122
|
* return currentSession?.role === 'admin'
|
|
114
123
|
* }
|
|
115
124
|
* )
|
|
116
125
|
*
|
|
117
126
|
* // Configuration object syntax with metadata
|
|
118
127
|
* export const adminPermission = pikkuPermission({
|
|
119
|
-
*
|
|
128
|
+
* name: 'Admin Permission',
|
|
120
129
|
* description: 'Checks if user has admin role',
|
|
121
|
-
* func: async ({ logger }, _data, {
|
|
122
|
-
* const currentSession = await
|
|
130
|
+
* func: async ({ logger }, _data, { getSession }) => {
|
|
131
|
+
* const currentSession = await getSession()
|
|
123
132
|
* return currentSession?.role === 'admin'
|
|
124
133
|
* }
|
|
125
134
|
* })
|
|
@@ -168,8 +177,8 @@ export type CorePikkuPermissionFactory<
|
|
|
168
177
|
* export const requireRole = pikkuPermissionFactory<{ role: string }>(({
|
|
169
178
|
* role
|
|
170
179
|
* }) => {
|
|
171
|
-
* return pikkuPermission(async ({ logger }, data, {
|
|
172
|
-
* const currentSession = await
|
|
180
|
+
* return pikkuPermission(async ({ logger }, data, { getSession }) => {
|
|
181
|
+
* const currentSession = await getSession()
|
|
173
182
|
* if (!currentSession || currentSession.role !== role) {
|
|
174
183
|
* logger.warn(`Permission denied: required role '${role}'`)
|
|
175
184
|
* return false
|
|
@@ -185,23 +194,45 @@ export const pikkuPermissionFactory = <In = any>(
|
|
|
185
194
|
return factory
|
|
186
195
|
}
|
|
187
196
|
|
|
197
|
+
export type CorePikkuAuth<
|
|
198
|
+
Services extends CoreSingletonServices = CoreServices,
|
|
199
|
+
Session extends CoreUserSession = CoreUserSession,
|
|
200
|
+
> = (services: Services, session: Session) => Promise<boolean> | boolean
|
|
201
|
+
|
|
202
|
+
export type CorePikkuAuthConfig<
|
|
203
|
+
Services extends CoreSingletonServices = CoreServices,
|
|
204
|
+
Session extends CoreUserSession = CoreUserSession,
|
|
205
|
+
> = {
|
|
206
|
+
func: CorePikkuAuth<Services, Session>
|
|
207
|
+
name?: string
|
|
208
|
+
description?: string
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export const pikkuAuth = <
|
|
212
|
+
Services extends CoreSingletonServices = CoreServices,
|
|
213
|
+
Session extends CoreUserSession = CoreUserSession,
|
|
214
|
+
>(
|
|
215
|
+
auth:
|
|
216
|
+
| CorePikkuAuth<Services, Session>
|
|
217
|
+
| CorePikkuAuthConfig<Services, Session>
|
|
218
|
+
): CorePikkuPermission<any, Services, any> => {
|
|
219
|
+
const fn = typeof auth === 'function' ? auth : auth.func
|
|
220
|
+
const wrapper = async (services: Services, _data: any, wire: any) => {
|
|
221
|
+
const session = wire.session
|
|
222
|
+
if (!session) return false
|
|
223
|
+
return fn(services, session as Session)
|
|
224
|
+
}
|
|
225
|
+
return wrapper as any
|
|
226
|
+
}
|
|
227
|
+
|
|
188
228
|
export type CorePermissionGroup<PikkuPermission = CorePikkuPermission<any>> =
|
|
189
229
|
| Record<string, PikkuPermission | PikkuPermission[]>
|
|
190
230
|
| undefined
|
|
191
231
|
|
|
192
|
-
/**
|
|
193
|
-
* Zod schema type - matches z.ZodType shape for type inference
|
|
194
|
-
* This avoids requiring zod as a dependency while allowing schema inference
|
|
195
|
-
*/
|
|
196
|
-
export type ZodLike<T = any> = {
|
|
197
|
-
_input: T
|
|
198
|
-
_output: T
|
|
199
|
-
}
|
|
200
|
-
|
|
201
232
|
export type CorePikkuFunctionConfig<
|
|
202
233
|
PikkuFunction extends
|
|
203
|
-
| CorePikkuFunction<any, any, any, any>
|
|
204
|
-
| CorePikkuFunctionSessionless<any, any, any, any>,
|
|
234
|
+
| CorePikkuFunction<any, any, any, any, any>
|
|
235
|
+
| CorePikkuFunctionSessionless<any, any, any, any, any>,
|
|
205
236
|
PikkuPermission extends CorePikkuPermission<
|
|
206
237
|
any,
|
|
207
238
|
any,
|
|
@@ -211,126 +242,26 @@ export type CorePikkuFunctionConfig<
|
|
|
211
242
|
any,
|
|
212
243
|
any
|
|
213
244
|
>,
|
|
214
|
-
InputSchema extends
|
|
215
|
-
OutputSchema extends
|
|
245
|
+
InputSchema extends StandardSchemaV1 | undefined = undefined,
|
|
246
|
+
OutputSchema extends StandardSchemaV1 | undefined = undefined,
|
|
216
247
|
> = {
|
|
217
248
|
/** Optional human-readable title for the function */
|
|
218
249
|
title?: string
|
|
219
250
|
/** Optional description of what the function does */
|
|
220
251
|
description?: string
|
|
221
252
|
override?: string
|
|
253
|
+
version?: number
|
|
222
254
|
tags?: string[]
|
|
223
255
|
expose?: boolean
|
|
224
|
-
|
|
256
|
+
remote?: boolean
|
|
257
|
+
mcp?: boolean
|
|
258
|
+
readonly?: boolean
|
|
259
|
+
requiresApproval?: boolean
|
|
225
260
|
func: PikkuFunction
|
|
226
261
|
auth?: boolean
|
|
227
262
|
permissions?: CorePermissionGroup<PikkuPermission>
|
|
228
263
|
middleware?: PikkuMiddleware[]
|
|
229
264
|
input?: InputSchema
|
|
230
265
|
output?: OutputSchema
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* A trigger function that sets up a subscription and returns a teardown function.
|
|
235
|
-
* The trigger is fired via wire.trigger.trigger(data).
|
|
236
|
-
*
|
|
237
|
-
* @template TConfig - Configuration type (hardcoded when wired)
|
|
238
|
-
* @template TOutput - Output type produced when trigger fires
|
|
239
|
-
* @template Services - Services available to the trigger
|
|
240
|
-
*/
|
|
241
|
-
export type CorePikkuTriggerFunction<
|
|
242
|
-
TConfig = unknown,
|
|
243
|
-
TOutput = unknown,
|
|
244
|
-
Services extends CoreSingletonServices = CoreSingletonServices,
|
|
245
|
-
> = (
|
|
246
|
-
services: Services,
|
|
247
|
-
config: TConfig,
|
|
248
|
-
wire: { trigger: { trigger: (data: TOutput) => void } }
|
|
249
|
-
) => Promise<() => void | Promise<void>>
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Configuration object for creating a trigger function with metadata
|
|
253
|
-
*/
|
|
254
|
-
export type CorePikkuTriggerFunctionConfig<
|
|
255
|
-
TConfig = unknown,
|
|
256
|
-
TOutput = unknown,
|
|
257
|
-
Services extends CoreSingletonServices = CoreSingletonServices,
|
|
258
|
-
ConfigSchema extends ZodLike | undefined = undefined,
|
|
259
|
-
OutputSchema extends ZodLike | undefined = undefined,
|
|
260
|
-
> = {
|
|
261
|
-
/** Optional human-readable title for the trigger */
|
|
262
|
-
title?: string
|
|
263
|
-
/** Optional description of what the trigger does */
|
|
264
|
-
description?: string
|
|
265
|
-
/** Optional tags for categorization */
|
|
266
|
-
tags?: string[]
|
|
267
|
-
/** The trigger function */
|
|
268
|
-
func: CorePikkuTriggerFunction<TConfig, TOutput, Services>
|
|
269
|
-
/** Optional Zod schema for config validation */
|
|
270
|
-
config?: ConfigSchema
|
|
271
|
-
/** Optional Zod schema for output validation */
|
|
272
|
-
output?: OutputSchema
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Factory function for creating trigger functions
|
|
277
|
-
* Supports both direct function and configuration object syntax
|
|
278
|
-
*
|
|
279
|
-
* @example
|
|
280
|
-
* ```typescript
|
|
281
|
-
* // Direct function syntax
|
|
282
|
-
* export const redisSubscribeTrigger = pikkuTriggerFunc<
|
|
283
|
-
* { channel: string },
|
|
284
|
-
* { message: string }
|
|
285
|
-
* >(async ({ redis }, { channel }, { trigger }) => {
|
|
286
|
-
* const subscriber = redis.duplicate()
|
|
287
|
-
* await subscriber.subscribe(channel, (msg) => {
|
|
288
|
-
* trigger.trigger({ message: msg })
|
|
289
|
-
* })
|
|
290
|
-
* return () => subscriber.unsubscribe()
|
|
291
|
-
* })
|
|
292
|
-
*
|
|
293
|
-
* // Configuration object syntax with metadata
|
|
294
|
-
* export const redisSubscribeTrigger = pikkuTriggerFunc({
|
|
295
|
-
* title: 'Redis Subscribe Trigger',
|
|
296
|
-
* description: 'Listens to Redis pub/sub channel',
|
|
297
|
-
* config: z.object({ channel: z.string() }),
|
|
298
|
-
* output: z.object({ message: z.string() }),
|
|
299
|
-
* func: async ({ redis }, { channel }, { trigger }) => {
|
|
300
|
-
* const subscriber = redis.duplicate()
|
|
301
|
-
* await subscriber.subscribe(channel, (msg) => {
|
|
302
|
-
* trigger.trigger({ message: msg })
|
|
303
|
-
* })
|
|
304
|
-
* return () => subscriber.unsubscribe()
|
|
305
|
-
* }
|
|
306
|
-
* })
|
|
307
|
-
* ```
|
|
308
|
-
*/
|
|
309
|
-
export const pikkuTriggerFunc = <
|
|
310
|
-
TConfig = unknown,
|
|
311
|
-
TOutput = unknown,
|
|
312
|
-
Services extends CoreSingletonServices = CoreSingletonServices,
|
|
313
|
-
ConfigSchema extends ZodLike | undefined = undefined,
|
|
314
|
-
OutputSchema extends ZodLike | undefined = undefined,
|
|
315
|
-
>(
|
|
316
|
-
triggerOrConfig:
|
|
317
|
-
| CorePikkuTriggerFunction<TConfig, TOutput, Services>
|
|
318
|
-
| CorePikkuTriggerFunctionConfig<
|
|
319
|
-
TConfig,
|
|
320
|
-
TOutput,
|
|
321
|
-
Services,
|
|
322
|
-
ConfigSchema,
|
|
323
|
-
OutputSchema
|
|
324
|
-
>
|
|
325
|
-
): CorePikkuTriggerFunctionConfig<
|
|
326
|
-
TConfig,
|
|
327
|
-
TOutput,
|
|
328
|
-
Services,
|
|
329
|
-
ConfigSchema,
|
|
330
|
-
OutputSchema
|
|
331
|
-
> => {
|
|
332
|
-
if (typeof triggerOrConfig === 'function') {
|
|
333
|
-
return { func: triggerOrConfig }
|
|
334
|
-
}
|
|
335
|
-
return triggerOrConfig
|
|
266
|
+
node?: CoreNodeConfig
|
|
336
267
|
}
|
package/src/function/index.ts
CHANGED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { describe, test, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { handleHTTPError } from './handle-error.js'
|
|
4
|
+
import { addError } from './errors/error-handler.js'
|
|
5
|
+
import {
|
|
6
|
+
NotFoundError,
|
|
7
|
+
BadRequestError,
|
|
8
|
+
ForbiddenError,
|
|
9
|
+
} from './errors/errors.js'
|
|
10
|
+
import { resetPikkuState } from './pikku-state.js'
|
|
11
|
+
|
|
12
|
+
const createMockLogger = () => {
|
|
13
|
+
const logs: { level: string; args: any[] }[] = []
|
|
14
|
+
return {
|
|
15
|
+
info: (...args: any[]) => logs.push({ level: 'info', args }),
|
|
16
|
+
warn: (...args: any[]) => logs.push({ level: 'warn', args }),
|
|
17
|
+
error: (...args: any[]) => logs.push({ level: 'error', args }),
|
|
18
|
+
debug: (...args: any[]) => logs.push({ level: 'debug', args }),
|
|
19
|
+
_logs: logs,
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const createMockHTTP = () => {
|
|
24
|
+
const state = {
|
|
25
|
+
statusCode: undefined as number | undefined,
|
|
26
|
+
jsonBody: undefined as any,
|
|
27
|
+
closed: false,
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
request: {},
|
|
31
|
+
response: {
|
|
32
|
+
status: (code: number) => {
|
|
33
|
+
state.statusCode = code
|
|
34
|
+
return {
|
|
35
|
+
json: (body: any) => {
|
|
36
|
+
state.jsonBody = body
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
json: (body: any) => {
|
|
41
|
+
state.jsonBody = body
|
|
42
|
+
},
|
|
43
|
+
close: () => {
|
|
44
|
+
state.closed = true
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
_state: state,
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
resetPikkuState()
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
describe('handleHTTPError', () => {
|
|
56
|
+
test('should skip NotFoundError when respondWith404 is false', () => {
|
|
57
|
+
const logger = createMockLogger()
|
|
58
|
+
const http = createMockHTTP()
|
|
59
|
+
const error = new NotFoundError()
|
|
60
|
+
|
|
61
|
+
handleHTTPError(
|
|
62
|
+
error,
|
|
63
|
+
http as any,
|
|
64
|
+
'tracker-1',
|
|
65
|
+
logger as any,
|
|
66
|
+
[],
|
|
67
|
+
false,
|
|
68
|
+
false
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
assert.strictEqual(http._state.statusCode, undefined)
|
|
72
|
+
assert.strictEqual(http._state.jsonBody, undefined)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('should handle NotFoundError when respondWith404 is true', () => {
|
|
76
|
+
const logger = createMockLogger()
|
|
77
|
+
const http = createMockHTTP()
|
|
78
|
+
const error = new NotFoundError()
|
|
79
|
+
|
|
80
|
+
handleHTTPError(
|
|
81
|
+
error,
|
|
82
|
+
http as any,
|
|
83
|
+
'tracker-1',
|
|
84
|
+
logger as any,
|
|
85
|
+
[],
|
|
86
|
+
true,
|
|
87
|
+
false
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
assert.strictEqual(http._state.statusCode, 404)
|
|
91
|
+
assert.deepStrictEqual(http._state.jsonBody, {
|
|
92
|
+
message: 'The server cannot find the requested resource.',
|
|
93
|
+
payload: undefined,
|
|
94
|
+
traceId: 'tracker-1',
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('should set correct status and message for known errors', () => {
|
|
99
|
+
const logger = createMockLogger()
|
|
100
|
+
const http = createMockHTTP()
|
|
101
|
+
const error = new BadRequestError('Invalid input')
|
|
102
|
+
|
|
103
|
+
handleHTTPError(
|
|
104
|
+
error,
|
|
105
|
+
http as any,
|
|
106
|
+
'tracker-2',
|
|
107
|
+
logger as any,
|
|
108
|
+
[],
|
|
109
|
+
true,
|
|
110
|
+
false
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
assert.strictEqual(http._state.statusCode, 400)
|
|
114
|
+
assert.ok(http._state.jsonBody.message.includes('client error'))
|
|
115
|
+
assert.strictEqual(http._state.jsonBody.traceId, 'tracker-2')
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
test('should set status 403 for ForbiddenError', () => {
|
|
119
|
+
const logger = createMockLogger()
|
|
120
|
+
const http = createMockHTTP()
|
|
121
|
+
const error = new ForbiddenError()
|
|
122
|
+
|
|
123
|
+
handleHTTPError(
|
|
124
|
+
error,
|
|
125
|
+
http as any,
|
|
126
|
+
'tracker-3',
|
|
127
|
+
logger as any,
|
|
128
|
+
[],
|
|
129
|
+
true,
|
|
130
|
+
false
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
assert.strictEqual(http._state.statusCode, 403)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
test('should log warning when status code is in logWarningsForStatusCodes', () => {
|
|
137
|
+
const logger = createMockLogger()
|
|
138
|
+
const http = createMockHTTP()
|
|
139
|
+
const error = new BadRequestError('bad')
|
|
140
|
+
|
|
141
|
+
handleHTTPError(
|
|
142
|
+
error,
|
|
143
|
+
http as any,
|
|
144
|
+
'tracker-4',
|
|
145
|
+
logger as any,
|
|
146
|
+
[400],
|
|
147
|
+
true,
|
|
148
|
+
false
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
const warns = logger._logs.filter((l) => l.level === 'warn')
|
|
152
|
+
assert.ok(warns.length >= 1)
|
|
153
|
+
assert.ok(warns.some((w) => w.args[0].includes('tracker-4')))
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
test('should not log warning when status code is not in logWarningsForStatusCodes', () => {
|
|
157
|
+
const logger = createMockLogger()
|
|
158
|
+
const http = createMockHTTP()
|
|
159
|
+
const error = new BadRequestError('bad')
|
|
160
|
+
|
|
161
|
+
handleHTTPError(
|
|
162
|
+
error,
|
|
163
|
+
http as any,
|
|
164
|
+
'tracker-5',
|
|
165
|
+
logger as any,
|
|
166
|
+
[500],
|
|
167
|
+
true,
|
|
168
|
+
false
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
const warns = logger._logs.filter((l) => l.level === 'warn')
|
|
172
|
+
assert.strictEqual(warns.length, 0)
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
test('should handle unknown errors with 500 status', () => {
|
|
176
|
+
const logger = createMockLogger()
|
|
177
|
+
const http = createMockHTTP()
|
|
178
|
+
const error = new Error('something unexpected')
|
|
179
|
+
|
|
180
|
+
handleHTTPError(
|
|
181
|
+
error,
|
|
182
|
+
http as any,
|
|
183
|
+
'tracker-6',
|
|
184
|
+
logger as any,
|
|
185
|
+
[],
|
|
186
|
+
true,
|
|
187
|
+
false
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
assert.strictEqual(http._state.statusCode, 500)
|
|
191
|
+
assert.deepStrictEqual(http._state.jsonBody, { errorId: 'tracker-6' })
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
test('should log unknown errors with error level', () => {
|
|
195
|
+
const logger = createMockLogger()
|
|
196
|
+
const http = createMockHTTP()
|
|
197
|
+
const error = new Error('unexpected')
|
|
198
|
+
|
|
199
|
+
handleHTTPError(
|
|
200
|
+
error,
|
|
201
|
+
http as any,
|
|
202
|
+
undefined,
|
|
203
|
+
logger as any,
|
|
204
|
+
[],
|
|
205
|
+
true,
|
|
206
|
+
false
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
const errors = logger._logs.filter((l) => l.level === 'error')
|
|
210
|
+
assert.ok(errors.length >= 1)
|
|
211
|
+
assert.ok(errors.some((e) => e.args[0] === 'unexpected'))
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
test('should not include errorId in response when trackerId is undefined for unknown errors', () => {
|
|
215
|
+
const logger = createMockLogger()
|
|
216
|
+
const http = createMockHTTP()
|
|
217
|
+
const error = new Error('unexpected')
|
|
218
|
+
|
|
219
|
+
handleHTTPError(
|
|
220
|
+
error,
|
|
221
|
+
http as any,
|
|
222
|
+
undefined,
|
|
223
|
+
logger as any,
|
|
224
|
+
[],
|
|
225
|
+
true,
|
|
226
|
+
false
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
assert.strictEqual(http._state.statusCode, 500)
|
|
230
|
+
assert.strictEqual(http._state.jsonBody, undefined)
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
test('should bubble error when bubbleError is true', () => {
|
|
234
|
+
const logger = createMockLogger()
|
|
235
|
+
const http = createMockHTTP()
|
|
236
|
+
const error = new BadRequestError('bad')
|
|
237
|
+
|
|
238
|
+
assert.throws(
|
|
239
|
+
() =>
|
|
240
|
+
handleHTTPError(
|
|
241
|
+
error,
|
|
242
|
+
http as any,
|
|
243
|
+
'tracker',
|
|
244
|
+
logger as any,
|
|
245
|
+
[],
|
|
246
|
+
true,
|
|
247
|
+
true
|
|
248
|
+
),
|
|
249
|
+
(e: any) => e === error
|
|
250
|
+
)
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
test('should not bubble error when bubbleError is false', () => {
|
|
254
|
+
const logger = createMockLogger()
|
|
255
|
+
const http = createMockHTTP()
|
|
256
|
+
const error = new BadRequestError('bad')
|
|
257
|
+
|
|
258
|
+
handleHTTPError(
|
|
259
|
+
error,
|
|
260
|
+
http as any,
|
|
261
|
+
'tracker',
|
|
262
|
+
logger as any,
|
|
263
|
+
[],
|
|
264
|
+
true,
|
|
265
|
+
false
|
|
266
|
+
)
|
|
267
|
+
// Should not throw
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
test('should call response.close when available', () => {
|
|
271
|
+
const logger = createMockLogger()
|
|
272
|
+
const http = createMockHTTP()
|
|
273
|
+
const error = new BadRequestError('bad')
|
|
274
|
+
|
|
275
|
+
handleHTTPError(
|
|
276
|
+
error,
|
|
277
|
+
http as any,
|
|
278
|
+
'tracker',
|
|
279
|
+
logger as any,
|
|
280
|
+
[],
|
|
281
|
+
true,
|
|
282
|
+
false
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
assert.strictEqual(http._state.closed, true)
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
test('should handle undefined http gracefully', () => {
|
|
289
|
+
const logger = createMockLogger()
|
|
290
|
+
const error = new BadRequestError('bad')
|
|
291
|
+
|
|
292
|
+
handleHTTPError(error, undefined, 'tracker', logger as any, [], true, false)
|
|
293
|
+
// Should not throw
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
test('should include payload from error in known error response', () => {
|
|
297
|
+
const logger = createMockLogger()
|
|
298
|
+
const http = createMockHTTP()
|
|
299
|
+
const error = new BadRequestError('bad') as any
|
|
300
|
+
error.payload = { field: 'email', reason: 'invalid' }
|
|
301
|
+
|
|
302
|
+
handleHTTPError(
|
|
303
|
+
error,
|
|
304
|
+
http as any,
|
|
305
|
+
'tracker',
|
|
306
|
+
logger as any,
|
|
307
|
+
[],
|
|
308
|
+
true,
|
|
309
|
+
false
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
assert.deepStrictEqual(http._state.jsonBody.payload, {
|
|
313
|
+
field: 'email',
|
|
314
|
+
reason: 'invalid',
|
|
315
|
+
})
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
test('should handle non-Error objects as errors', () => {
|
|
319
|
+
const logger = createMockLogger()
|
|
320
|
+
const http = createMockHTTP()
|
|
321
|
+
const error = 'just a string error'
|
|
322
|
+
|
|
323
|
+
handleHTTPError(
|
|
324
|
+
error,
|
|
325
|
+
http as any,
|
|
326
|
+
'tracker',
|
|
327
|
+
logger as any,
|
|
328
|
+
[],
|
|
329
|
+
true,
|
|
330
|
+
false
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
assert.strictEqual(http._state.statusCode, 500)
|
|
334
|
+
const errors = logger._logs.filter((l) => l.level === 'error')
|
|
335
|
+
assert.ok(errors.some((e) => e.args[0] === 'just a string error'))
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
test('should handle warning log without trackerId', () => {
|
|
339
|
+
const logger = createMockLogger()
|
|
340
|
+
const http = createMockHTTP()
|
|
341
|
+
const error = new BadRequestError('bad')
|
|
342
|
+
|
|
343
|
+
handleHTTPError(
|
|
344
|
+
error,
|
|
345
|
+
http as any,
|
|
346
|
+
undefined,
|
|
347
|
+
logger as any,
|
|
348
|
+
[400],
|
|
349
|
+
true,
|
|
350
|
+
false
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
const warns = logger._logs.filter((l) => l.level === 'warn')
|
|
354
|
+
assert.ok(warns.length >= 1)
|
|
355
|
+
assert.ok(
|
|
356
|
+
!warns.some(
|
|
357
|
+
(w) => typeof w.args[0] === 'string' && w.args[0].includes('Warning id')
|
|
358
|
+
)
|
|
359
|
+
)
|
|
360
|
+
})
|
|
361
|
+
})
|
package/src/handle-error.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getErrorResponse } from './errors/error-handler.js'
|
|
2
2
|
import { NotFoundError } from './errors/errors.js'
|
|
3
|
-
import { Logger } from './services/logger.js'
|
|
4
|
-
import { PikkuHTTP } from './wirings/http/http.types.js'
|
|
3
|
+
import type { Logger } from './services/logger.js'
|
|
4
|
+
import type { PikkuHTTP } from './wirings/http/http.types.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Handle errors that occur during route processing
|
|
@@ -44,11 +44,11 @@ export const handleHTTPError = (
|
|
|
44
44
|
if (trackerId) {
|
|
45
45
|
logger.warn(`Warning id: ${trackerId}`)
|
|
46
46
|
}
|
|
47
|
-
logger.warn(e)
|
|
47
|
+
logger.warn(e instanceof Error ? e.message : e)
|
|
48
48
|
}
|
|
49
49
|
} else {
|
|
50
50
|
// Handle unexpected errors
|
|
51
|
-
logger.error(e)
|
|
51
|
+
logger.error(e instanceof Error ? e.message : e)
|
|
52
52
|
http?.response?.status(500)
|
|
53
53
|
|
|
54
54
|
if (trackerId) {
|
|
@@ -57,17 +57,9 @@ export const handleHTTPError = (
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
// Handle 404 errors specifically
|
|
61
|
-
if (e instanceof NotFoundError) {
|
|
62
|
-
// TODO
|
|
63
|
-
// http?.response?.end()
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Either bubble up or end the response
|
|
67
60
|
if (bubbleError) {
|
|
68
61
|
throw e
|
|
69
|
-
} else {
|
|
70
|
-
// TODO
|
|
71
|
-
// http?.response?.end()
|
|
72
62
|
}
|
|
63
|
+
|
|
64
|
+
http?.response?.close?.()
|
|
73
65
|
}
|