@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
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import type { OAuth2Token, OAuth2AppCredential } from './oauth2.types.js'
|
|
2
|
+
import type { OAuth2CredentialConfig } from '../secret/secret.types.js'
|
|
3
|
+
import type { SecretService } from '../../services/secret-service.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* OAuth2 client that acts as a service.
|
|
7
|
+
* Created once in createSingletonServices, handles token caching and refresh internally.
|
|
8
|
+
* Functions use it directly via oauth.request().
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // In services.ts
|
|
13
|
+
* export const createSingletonServices = async (config, { secrets }) => {
|
|
14
|
+
* return {
|
|
15
|
+
* slackOAuth: new OAuth2Client(
|
|
16
|
+
* { tokenSecretId: 'SLACK_TOKENS', authorizationUrl: '...', tokenUrl: '...', scopes: [] },
|
|
17
|
+
* 'SLACK_APP_CREDS',
|
|
18
|
+
* secrets
|
|
19
|
+
* ),
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* // In function
|
|
24
|
+
* export const postMessage = pikkuFunc(async ({ slackOAuth }, { channel, text }) => {
|
|
25
|
+
* const response = await slackOAuth.request('https://slack.com/api/chat.postMessage', {
|
|
26
|
+
* method: 'POST',
|
|
27
|
+
* body: JSON.stringify({ channel, text }),
|
|
28
|
+
* })
|
|
29
|
+
* return response.json()
|
|
30
|
+
* })
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
const DEFAULT_TIMEOUT_MS = 30000
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Helper to fetch with a timeout using AbortController.
|
|
37
|
+
*/
|
|
38
|
+
async function fetchWithTimeout(
|
|
39
|
+
url: string,
|
|
40
|
+
options: RequestInit,
|
|
41
|
+
timeoutMs: number = DEFAULT_TIMEOUT_MS
|
|
42
|
+
): Promise<Response> {
|
|
43
|
+
const controller = new AbortController()
|
|
44
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs)
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
return await fetch(url, {
|
|
48
|
+
...options,
|
|
49
|
+
signal: controller.signal,
|
|
50
|
+
})
|
|
51
|
+
} finally {
|
|
52
|
+
clearTimeout(timeoutId)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class OAuth2Client {
|
|
57
|
+
private cachedToken: OAuth2Token | null = null
|
|
58
|
+
private cachedAppCredential: OAuth2AppCredential | null = null
|
|
59
|
+
private refreshPromise: Promise<OAuth2Token> | null = null
|
|
60
|
+
|
|
61
|
+
constructor(
|
|
62
|
+
private oauth2Config: OAuth2CredentialConfig,
|
|
63
|
+
private appCredentialSecretId: string,
|
|
64
|
+
private secrets: SecretService
|
|
65
|
+
) {}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Make an authenticated request. Handles token caching and 401 refresh.
|
|
69
|
+
*/
|
|
70
|
+
async request(
|
|
71
|
+
url: string,
|
|
72
|
+
options?: RequestInit,
|
|
73
|
+
timeoutMs: number = DEFAULT_TIMEOUT_MS
|
|
74
|
+
): Promise<Response> {
|
|
75
|
+
const token = await this.getAccessToken()
|
|
76
|
+
|
|
77
|
+
const response = await fetchWithTimeout(
|
|
78
|
+
url,
|
|
79
|
+
{
|
|
80
|
+
...options,
|
|
81
|
+
headers: {
|
|
82
|
+
...options?.headers,
|
|
83
|
+
Authorization: `Bearer ${token}`,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
timeoutMs
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
// Auto-retry on 401 after refresh
|
|
90
|
+
if (response.status === 401) {
|
|
91
|
+
const newToken = await this.refreshAndGetToken()
|
|
92
|
+
return fetchWithTimeout(
|
|
93
|
+
url,
|
|
94
|
+
{
|
|
95
|
+
...options,
|
|
96
|
+
headers: {
|
|
97
|
+
...options?.headers,
|
|
98
|
+
Authorization: `Bearer ${newToken}`,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
timeoutMs
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return response
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get cached token or load from secrets.
|
|
110
|
+
*/
|
|
111
|
+
async getAccessToken(): Promise<string> {
|
|
112
|
+
// Return cached token if valid
|
|
113
|
+
if (this.cachedToken) {
|
|
114
|
+
if (this.isTokenValid(this.cachedToken)) {
|
|
115
|
+
return this.cachedToken.accessToken
|
|
116
|
+
}
|
|
117
|
+
// Token expired, try to refresh
|
|
118
|
+
if (this.cachedToken.refreshToken) {
|
|
119
|
+
return this.refreshAndGetToken()
|
|
120
|
+
}
|
|
121
|
+
// Token expired and no refresh token available
|
|
122
|
+
throw new Error('OAuth2 token expired and no refresh token available')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Load from secrets
|
|
126
|
+
const token = await this.secrets.getSecretJSON<OAuth2Token>(
|
|
127
|
+
this.oauth2Config.tokenSecretId
|
|
128
|
+
)
|
|
129
|
+
this.cachedToken = token
|
|
130
|
+
|
|
131
|
+
// Check if loaded token is expired and needs refresh
|
|
132
|
+
if (!this.isTokenValid(token)) {
|
|
133
|
+
if (token.refreshToken) {
|
|
134
|
+
return this.refreshAndGetToken()
|
|
135
|
+
}
|
|
136
|
+
// Token expired and no refresh token available
|
|
137
|
+
throw new Error('OAuth2 token expired and no refresh token available')
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return token.accessToken
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Refresh token and update cache.
|
|
145
|
+
* Uses a promise lock to prevent concurrent refresh attempts.
|
|
146
|
+
*/
|
|
147
|
+
private async refreshAndGetToken(): Promise<string> {
|
|
148
|
+
// If already refreshing, wait for that to complete
|
|
149
|
+
if (this.refreshPromise) {
|
|
150
|
+
const token = await this.refreshPromise
|
|
151
|
+
return token.accessToken
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Start refresh
|
|
155
|
+
this.refreshPromise = this.doRefreshToken()
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
const token = await this.refreshPromise
|
|
159
|
+
this.cachedToken = token
|
|
160
|
+
return token.accessToken
|
|
161
|
+
} finally {
|
|
162
|
+
this.refreshPromise = null
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Perform the actual token refresh.
|
|
168
|
+
*/
|
|
169
|
+
private async doRefreshToken(): Promise<OAuth2Token> {
|
|
170
|
+
if (!this.cachedToken?.refreshToken) {
|
|
171
|
+
throw new Error('No refresh token available')
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const appCredential = await this.getAppCredential()
|
|
175
|
+
|
|
176
|
+
const params = new URLSearchParams({
|
|
177
|
+
grant_type: 'refresh_token',
|
|
178
|
+
refresh_token: this.cachedToken.refreshToken,
|
|
179
|
+
client_id: appCredential.clientId,
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
if (appCredential.clientSecret) {
|
|
183
|
+
params.set('client_secret', appCredential.clientSecret)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const response = await fetchWithTimeout(this.oauth2Config.tokenUrl, {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
headers: {
|
|
189
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
190
|
+
},
|
|
191
|
+
body: params.toString(),
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
if (!response.ok) {
|
|
195
|
+
throw new Error(`Token refresh failed: ${response.status}`)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const data = await response.json()
|
|
199
|
+
|
|
200
|
+
if (!data.access_token || typeof data.access_token !== 'string') {
|
|
201
|
+
throw new Error('Invalid token response: missing access_token')
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const token: OAuth2Token = {
|
|
205
|
+
accessToken: data.access_token,
|
|
206
|
+
refreshToken: data.refresh_token || this.cachedToken.refreshToken,
|
|
207
|
+
expiresAt: data.expires_in
|
|
208
|
+
? Date.now() + data.expires_in * 1000
|
|
209
|
+
: undefined,
|
|
210
|
+
tokenType: data.token_type || 'Bearer',
|
|
211
|
+
scope: data.scope,
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Cache and persist the refreshed token
|
|
215
|
+
this.cachedToken = token
|
|
216
|
+
await this.secrets.setSecretJSON(this.oauth2Config.tokenSecretId, token)
|
|
217
|
+
|
|
218
|
+
return token
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Check if token is valid (not expired).
|
|
223
|
+
*/
|
|
224
|
+
private isTokenValid(token: OAuth2Token): boolean {
|
|
225
|
+
if (!token.expiresAt) {
|
|
226
|
+
return true // No expiry info, assume valid
|
|
227
|
+
}
|
|
228
|
+
// Add 60 second buffer to account for clock skew
|
|
229
|
+
return token.expiresAt > Date.now() + 60000
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Get app credentials (cached).
|
|
234
|
+
*/
|
|
235
|
+
private async getAppCredential(): Promise<OAuth2AppCredential> {
|
|
236
|
+
if (this.cachedAppCredential) {
|
|
237
|
+
return this.cachedAppCredential
|
|
238
|
+
}
|
|
239
|
+
this.cachedAppCredential =
|
|
240
|
+
await this.secrets.getSecretJSON<OAuth2AppCredential>(
|
|
241
|
+
this.appCredentialSecretId
|
|
242
|
+
)
|
|
243
|
+
return this.cachedAppCredential
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// ========================================
|
|
247
|
+
// CLI-only methods (for pikku oauth connect)
|
|
248
|
+
// ========================================
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Generate OAuth2 authorization URL.
|
|
252
|
+
* Used by CLI during `pikku oauth connect`.
|
|
253
|
+
*/
|
|
254
|
+
async getAuthorizationUrl(
|
|
255
|
+
state: string,
|
|
256
|
+
redirectUri: string
|
|
257
|
+
): Promise<string> {
|
|
258
|
+
const appCredential = await this.getAppCredential()
|
|
259
|
+
|
|
260
|
+
const params = new URLSearchParams({
|
|
261
|
+
response_type: 'code',
|
|
262
|
+
client_id: appCredential.clientId,
|
|
263
|
+
redirect_uri: redirectUri,
|
|
264
|
+
scope: this.oauth2Config.scopes.join(' '),
|
|
265
|
+
state,
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
// Add PKCE if enabled
|
|
269
|
+
// Note: code_verifier should be stored and passed to exchangeCode
|
|
270
|
+
// For now, PKCE implementation is simplified
|
|
271
|
+
|
|
272
|
+
// Add any additional params
|
|
273
|
+
if (this.oauth2Config.additionalParams) {
|
|
274
|
+
for (const [key, value] of Object.entries(
|
|
275
|
+
this.oauth2Config.additionalParams
|
|
276
|
+
)) {
|
|
277
|
+
params.set(key, value)
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return `${this.oauth2Config.authorizationUrl}?${params.toString()}`
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Exchange authorization code for tokens.
|
|
286
|
+
* Used by CLI during `pikku oauth connect`.
|
|
287
|
+
*/
|
|
288
|
+
async exchangeCode(code: string, redirectUri: string): Promise<OAuth2Token> {
|
|
289
|
+
const appCredential = await this.getAppCredential()
|
|
290
|
+
|
|
291
|
+
const params = new URLSearchParams({
|
|
292
|
+
grant_type: 'authorization_code',
|
|
293
|
+
code,
|
|
294
|
+
redirect_uri: redirectUri,
|
|
295
|
+
client_id: appCredential.clientId,
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
if (appCredential.clientSecret) {
|
|
299
|
+
params.set('client_secret', appCredential.clientSecret)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const response = await fetchWithTimeout(this.oauth2Config.tokenUrl, {
|
|
303
|
+
method: 'POST',
|
|
304
|
+
headers: {
|
|
305
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
306
|
+
},
|
|
307
|
+
body: params.toString(),
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
if (!response.ok) {
|
|
311
|
+
throw new Error(`Token exchange failed: ${response.status}`)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const data = await response.json()
|
|
315
|
+
|
|
316
|
+
if (!data.access_token || typeof data.access_token !== 'string') {
|
|
317
|
+
throw new Error('Invalid token response: missing access_token')
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const token: OAuth2Token = {
|
|
321
|
+
accessToken: data.access_token,
|
|
322
|
+
refreshToken: data.refresh_token,
|
|
323
|
+
expiresAt: data.expires_in
|
|
324
|
+
? Date.now() + data.expires_in * 1000
|
|
325
|
+
: undefined,
|
|
326
|
+
tokenType: data.token_type || 'Bearer',
|
|
327
|
+
scope: data.scope,
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Cache the token
|
|
331
|
+
this.cachedToken = token
|
|
332
|
+
|
|
333
|
+
return token
|
|
334
|
+
}
|
|
335
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2 credential and token types.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* App credentials for OAuth2 (client ID and secret).
|
|
7
|
+
* These are typically set once and stored in the secret service.
|
|
8
|
+
*/
|
|
9
|
+
export type OAuth2AppCredential = {
|
|
10
|
+
clientId: string
|
|
11
|
+
clientSecret?: string // Optional for PKCE flows
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* OAuth2 token data returned from token endpoint.
|
|
16
|
+
*/
|
|
17
|
+
export type OAuth2Token = {
|
|
18
|
+
accessToken: string
|
|
19
|
+
refreshToken?: string
|
|
20
|
+
expiresAt?: number // Unix timestamp
|
|
21
|
+
tokenType: string
|
|
22
|
+
scope?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* OAuth2-specific configuration that extends a credential.
|
|
27
|
+
* This is stored in SecretDefinitionMeta.oauth2 field.
|
|
28
|
+
*/
|
|
29
|
+
export type OAuth2Config = {
|
|
30
|
+
/** Where access/refresh tokens are stored */
|
|
31
|
+
tokenSecretId: string
|
|
32
|
+
/** OAuth2 authorization URL */
|
|
33
|
+
authorizationUrl: string
|
|
34
|
+
/** OAuth2 token exchange URL */
|
|
35
|
+
tokenUrl: string
|
|
36
|
+
/** Required scopes */
|
|
37
|
+
scopes: string[]
|
|
38
|
+
/** Use PKCE flow */
|
|
39
|
+
pkce?: boolean
|
|
40
|
+
/** Additional query parameters for authorization URL */
|
|
41
|
+
additionalParams?: Record<string, string>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Configuration for wireOAuth2Credential.
|
|
46
|
+
* Combines standard credential fields with OAuth2-specific config.
|
|
47
|
+
*/
|
|
48
|
+
export type CoreOAuth2Credential = {
|
|
49
|
+
/** Unique identifier for this credential */
|
|
50
|
+
name: string
|
|
51
|
+
/** Human-readable name for UI display */
|
|
52
|
+
displayName: string
|
|
53
|
+
/** Optional description for UI */
|
|
54
|
+
description?: string
|
|
55
|
+
/** Key used with SecretService to retrieve app credentials (clientId/clientSecret) */
|
|
56
|
+
secretId: string
|
|
57
|
+
/** Where access/refresh tokens are stored */
|
|
58
|
+
tokenSecretId: string
|
|
59
|
+
/** OAuth2 authorization URL */
|
|
60
|
+
authorizationUrl: string
|
|
61
|
+
/** OAuth2 token exchange URL */
|
|
62
|
+
tokenUrl: string
|
|
63
|
+
/** Required scopes */
|
|
64
|
+
scopes: string[]
|
|
65
|
+
/** Use PKCE flow */
|
|
66
|
+
pkce?: boolean
|
|
67
|
+
/** Additional query parameters for authorization URL */
|
|
68
|
+
additionalParams?: Record<string, string>
|
|
69
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CoreOAuth2Credential } from './oauth2.types.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* No-op function for declaring OAuth2 credentials.
|
|
5
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
6
|
+
* The CLI extracts metadata via AST parsing.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* wireOAuth2Credential({
|
|
11
|
+
* name: 'slackOAuth',
|
|
12
|
+
* displayName: 'Slack OAuth',
|
|
13
|
+
* secretId: 'SLACK_OAUTH_APP',
|
|
14
|
+
* tokenSecretId: 'SLACK_OAUTH_TOKENS',
|
|
15
|
+
* authorizationUrl: 'https://slack.com/oauth/v2/authorize',
|
|
16
|
+
* tokenUrl: 'https://slack.com/api/oauth.v2.access',
|
|
17
|
+
* scopes: ['chat:write', 'channels:read'],
|
|
18
|
+
* })
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export const wireOAuth2Credential = (_config: CoreOAuth2Credential): void => {
|
|
22
|
+
// No-op - metadata only, extracted by CLI via AST
|
|
23
|
+
}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export type {
|
|
2
|
+
ConfigValidationResult,
|
|
3
|
+
CoreQueueWorker,
|
|
4
|
+
JobOptions,
|
|
5
|
+
PikkuJobConfig,
|
|
6
|
+
PikkuWorkerConfig,
|
|
7
|
+
PikkuQueue,
|
|
8
|
+
QueueJob,
|
|
9
|
+
QueueJobStatus,
|
|
10
|
+
QueueService,
|
|
11
|
+
QueueWorkers,
|
|
12
|
+
QueueWorkersMeta,
|
|
13
|
+
} from './queue.types.js'
|
|
3
14
|
|
|
4
15
|
// Queue processor management
|
|
5
16
|
export {
|