@pikku/core 0.11.2 → 0.12.0
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 +33 -2
- package/dist/crypto-utils.d.ts +2 -0
- package/dist/crypto-utils.js +78 -0
- package/dist/errors/errors.d.ts +8 -0
- package/dist/errors/errors.js +16 -0
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/function/function-runner.d.ts +7 -1
- package/dist/function/function-runner.js +82 -23
- package/dist/function/functions.types.d.ts +31 -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.js +1 -10
- package/dist/index.d.ts +28 -26
- package/dist/index.js +18 -29
- package/dist/middleware/auth-apikey.d.ts +2 -2
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.d.ts +2 -2
- package/dist/middleware/auth-bearer.js +3 -6
- package/dist/middleware/auth-cookie.d.ts +2 -2
- package/dist/middleware/auth-cookie.js +6 -8
- package/dist/middleware/cors.d.ts +46 -0
- package/dist/middleware/cors.js +73 -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.js +8 -10
- package/dist/permissions.js +11 -15
- package/dist/pikku-state.d.ts +1 -0
- package/dist/pikku-state.js +18 -8
- package/dist/schema.js +12 -11
- package/dist/services/ai-agent-runner-service.d.ts +24 -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/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 +94 -0
- package/dist/services/in-memory-trigger-service.d.ts +23 -0
- package/dist/services/in-memory-trigger-service.js +50 -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 +25 -11
- package/dist/services/index.js +10 -13
- package/dist/services/local-secrets.d.ts +23 -0
- package/dist/services/local-secrets.js +45 -0
- package/dist/services/local-variables.d.ts +5 -0
- package/dist/services/local-variables.js +18 -0
- package/dist/services/scheduler-service.d.ts +21 -1
- package/dist/services/scheduler-service.js +14 -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 +23 -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 +13 -0
- 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 -4
- package/dist/types/core.types.d.ts +48 -12
- package/dist/types/core.types.js +8 -1
- package/dist/types/state.types.d.ts +43 -51
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +15 -3
- package/dist/version.d.ts +6 -0
- package/dist/version.js +19 -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 +60 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +312 -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 +96 -0
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +11 -0
- package/dist/wirings/ai-agent/ai-agent-stream.js +503 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +254 -0
- package/dist/wirings/ai-agent/ai-agent.types.js +1 -0
- package/dist/wirings/ai-agent/index.d.ts +5 -0
- package/dist/wirings/ai-agent/index.js +4 -0
- package/dist/wirings/channel/channel-common.d.ts +7 -4
- package/dist/wirings/channel/channel-common.js +15 -8
- package/dist/wirings/channel/channel-handler.js +12 -3
- 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.js +7 -7
- package/dist/wirings/channel/channel.types.d.ts +5 -1
- 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.js +18 -6
- 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.js +15 -4
- 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 +1 -1
- package/dist/wirings/cli/cli-runner.js +12 -8
- package/dist/wirings/cli/cli.types.d.ts +6 -6
- 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.js +49 -23
- package/dist/wirings/http/http.types.d.ts +78 -38
- package/dist/wirings/http/index.d.ts +5 -4
- package/dist/wirings/http/index.js +4 -3
- package/dist/wirings/mcp/index.d.ts +4 -3
- package/dist/wirings/mcp/index.js +3 -3
- package/dist/wirings/mcp/mcp-runner.d.ts +1 -3
- package/dist/wirings/mcp/mcp-runner.js +25 -39
- package/dist/wirings/mcp/mcp.types.d.ts +3 -3
- 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 +2 -2
- package/dist/wirings/queue/index.js +1 -1
- package/dist/wirings/queue/queue-runner.d.ts +7 -0
- package/dist/wirings/queue/queue-runner.js +17 -6
- package/dist/wirings/queue/queue.types.d.ts +8 -2
- package/dist/wirings/rpc/index.d.ts +1 -1
- package/dist/wirings/rpc/index.js +1 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +33 -5
- package/dist/wirings/rpc/rpc-runner.js +134 -16
- package/dist/wirings/rpc/rpc-types.d.ts +8 -4
- package/dist/wirings/scheduler/index.d.ts +3 -3
- package/dist/wirings/scheduler/index.js +2 -3
- package/dist/wirings/scheduler/scheduler-runner.d.ts +5 -0
- package/dist/wirings/scheduler/scheduler-runner.js +23 -5
- 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 +26 -0
- package/dist/wirings/trigger/pikku-trigger-service.js +75 -0
- package/dist/wirings/trigger/trigger-runner.d.ts +21 -8
- package/dist/wirings/trigger/trigger-runner.js +46 -18
- 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 +28 -14
- package/dist/wirings/workflow/pikku-workflow-service.js +200 -56
- package/dist/wirings/workflow/workflow-helpers.d.ts +36 -0
- package/dist/wirings/workflow/workflow-helpers.js +38 -0
- package/dist/wirings/workflow/workflow-utils.d.ts +1 -23
- package/dist/wirings/workflow/workflow-utils.js +1 -66
- package/dist/wirings/workflow/workflow.types.d.ts +40 -93
- package/package.json +13 -15
- package/run-tests.sh +4 -1
- package/src/crypto-utils.ts +99 -0
- package/src/errors/errors.ts +17 -0
- package/src/errors/index.ts +0 -1
- package/src/factory-functions.test.ts +42 -2
- package/src/function/function-runner.test.ts +4 -11
- package/src/function/function-runner.ts +114 -29
- package/src/function/functions.types.ts +62 -132
- package/src/function/index.ts +5 -2
- package/src/handle-error.ts +2 -10
- package/src/index.ts +99 -25
- package/src/middleware/auth-apikey.test.ts +15 -12
- package/src/middleware/auth-apikey.ts +3 -3
- package/src/middleware/auth-bearer.test.ts +17 -14
- package/src/middleware/auth-bearer.ts +25 -27
- package/src/middleware/auth-cookie.test.ts +16 -13
- package/src/middleware/auth-cookie.ts +6 -8
- package/src/middleware/cors.ts +96 -0
- package/src/middleware/index.ts +5 -3
- package/src/middleware/remote-auth.ts +68 -0
- package/src/middleware-runner.test.ts +122 -0
- package/src/middleware-runner.ts +12 -12
- package/src/permissions.test.ts +81 -7
- package/src/permissions.ts +15 -17
- package/src/pikku-state.ts +20 -8
- package/src/run-tests-script.test.ts +49 -0
- package/src/schema.ts +18 -15
- package/src/services/ai-agent-runner-service.ts +29 -0
- package/src/services/ai-run-state-service.ts +20 -0
- package/src/services/ai-storage-service.ts +39 -0
- package/src/services/deployment-service.ts +22 -0
- package/src/services/gopass-secrets.ts +95 -0
- package/src/services/in-memory-trigger-service.ts +68 -0
- package/src/services/in-memory-workflow-service.ts +395 -0
- package/src/services/index.ts +49 -14
- package/src/services/local-secrets.ts +51 -0
- package/src/services/local-variables.ts +22 -0
- package/src/services/scheduler-service.ts +29 -1
- package/src/services/schema-service.ts +7 -0
- package/src/services/scoped-secret-service.ts +41 -0
- package/src/services/secret-service.ts +25 -4
- package/src/services/trigger-service.ts +38 -0
- package/src/services/typed-secret-service.ts +70 -0
- package/src/services/typed-variables-service.ts +81 -0
- package/src/services/user-session-service.ts +23 -0
- package/src/services/variables-service.ts +5 -0
- package/src/services/workflow-service.ts +22 -2
- package/src/types/core.types.ts +76 -11
- package/src/types/state.types.ts +37 -63
- package/src/utils.ts +20 -6
- package/src/version.test.ts +80 -0
- package/src/version.ts +25 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +300 -0
- package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +470 -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 +75 -0
- package/src/wirings/ai-agent/ai-agent-runner.ts +137 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +246 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +774 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +273 -0
- package/src/wirings/ai-agent/index.ts +28 -0
- package/src/wirings/channel/channel-common.ts +32 -19
- package/src/wirings/channel/channel-handler.ts +17 -4
- package/src/wirings/channel/channel-middleware-runner.ts +119 -0
- package/src/wirings/channel/channel-runner.ts +9 -10
- package/src/wirings/channel/channel.types.ts +17 -1
- 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 +44 -1
- package/src/wirings/channel/local/local-channel-runner.ts +22 -6
- package/src/wirings/channel/serverless/index.ts +5 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +20 -4
- package/src/wirings/cli/channel/index.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +9 -9
- package/src/wirings/cli/cli-runner.ts +17 -10
- package/src/wirings/cli/cli.types.ts +11 -11
- package/src/wirings/cli/command-parser.test.ts +8 -8
- 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 +3 -3
- package/src/wirings/http/http-runner.ts +63 -29
- package/src/wirings/http/http.types.ts +121 -37
- package/src/wirings/http/index.ts +16 -4
- package/src/wirings/mcp/index.ts +27 -3
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +3 -3
- package/src/wirings/mcp/mcp-runner.ts +39 -50
- package/src/wirings/mcp/mcp.types.ts +3 -3
- 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 +14 -2
- package/src/wirings/queue/queue-runner.test.ts +97 -55
- package/src/wirings/queue/queue-runner.ts +33 -7
- package/src/wirings/queue/queue.types.ts +12 -2
- package/src/wirings/rpc/index.ts +1 -1
- package/src/wirings/rpc/rpc-runner.ts +187 -17
- package/src/wirings/rpc/rpc-types.ts +13 -4
- package/src/wirings/scheduler/index.ts +7 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +70 -26
- package/src/wirings/scheduler/scheduler-runner.ts +45 -5
- package/src/wirings/secret/index.ts +9 -0
- package/src/wirings/secret/secret.types.ts +32 -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 +134 -0
- package/src/wirings/trigger/trigger-runner.ts +80 -38
- package/src/wirings/trigger/trigger.types.ts +144 -22
- package/src/wirings/variable/index.ts +8 -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 +495 -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.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 +212 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +285 -66
- package/src/wirings/workflow/workflow-helpers.ts +79 -0
- package/src/wirings/workflow/workflow-utils.ts +0 -120
- package/src/wirings/workflow/workflow.types.ts +45 -90
- 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/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/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
## 0.12.0
|
|
2
|
+
|
|
3
|
+
### New Features
|
|
4
|
+
|
|
5
|
+
- AI agents with `pikkuAIAgent()` — define agents with tools, sub-agents, memory, structured output, and streaming via SSE
|
|
6
|
+
- AI middleware hooks (`pikkuAIMiddleware`) for input, stream, and output transformation
|
|
7
|
+
- Tool approval flow — suspend agent execution pending human approval
|
|
8
|
+
- Channel middleware (`pikkuChannelMiddleware`) for intercepting and transforming channel events
|
|
9
|
+
- Remote RPC — call functions across servers with `rpc.remote()` and `DeploymentService`
|
|
10
|
+
- HTTP route groups with `wireHTTPRoutes` for shared basePath, tags, and auth
|
|
11
|
+
- Workflow graph engine with `createGraph()` type-safe builder
|
|
12
|
+
- Workflow HTTP helpers: `workflow()`, `workflowStart()`, `workflowStatus()`, `graphStart()`
|
|
13
|
+
- Workflow DSL with rich step types (branch, parallel, fanout, switch, filter)
|
|
14
|
+
- Trigger system with `wireTrigger()` and `wireTriggerSource()`
|
|
15
|
+
- OAuth2 support with `wireOAuth2Credential` and `OAuth2Client`
|
|
16
|
+
- Secret and variable declarations with `wireSecret()` and `wireVariable()`
|
|
17
|
+
- `TypedSecretService` and `TypedVariablesService` for compile-time validated access
|
|
18
|
+
- `defineCLICommands` and `defineChannelRoutes` for external composition
|
|
19
|
+
- Built-in CORS middleware
|
|
20
|
+
- `disabled: true` support on all wirings and functions
|
|
21
|
+
- `createWireServices` and `createConfig` are now optional
|
|
22
|
+
- `InMemoryWorkflowService` and `InMemoryTriggerService` for testing
|
|
23
|
+
|
|
24
|
+
### Breaking Changes
|
|
25
|
+
|
|
26
|
+
- `PikkuInteraction` → `PikkuWire`, `CreateSessionServices` → `CreateWireServices`
|
|
27
|
+
- `wireForgeCredential` → `wireCredential`
|
|
28
|
+
- `startWorkflowByWire` → `startWorkflowByHTTPWire`
|
|
29
|
+
- Renamed all `forge` → `node` naming
|
|
30
|
+
- Renamed `credential` → `secret` across core types
|
|
31
|
+
- `WorkflowService.createRun` signature changed (new `inline`, `graphHash` params)
|
|
32
|
+
- Auth enforced by default for `pikkuFunc`
|
|
33
|
+
|
|
1
34
|
## 0.11.0
|
|
2
35
|
|
|
3
36
|
## 0.11.2
|
|
@@ -6,8 +39,6 @@
|
|
|
6
39
|
|
|
7
40
|
- db9c7bf: Add workflow graph system with type-safe builder
|
|
8
41
|
|
|
9
|
-
## 0.11.2
|
|
10
|
-
|
|
11
42
|
### Features
|
|
12
43
|
|
|
13
44
|
- f35e89da: Add workflow graph system with type-safe builder
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const encoder = new TextEncoder();
|
|
2
|
+
const decoder = new TextDecoder();
|
|
3
|
+
const getSubtle = () => {
|
|
4
|
+
const crypto = globalThis.crypto;
|
|
5
|
+
if (!crypto?.subtle) {
|
|
6
|
+
throw new Error('WebCrypto not available');
|
|
7
|
+
}
|
|
8
|
+
return crypto.subtle;
|
|
9
|
+
};
|
|
10
|
+
const base64Encode = (bytes) => {
|
|
11
|
+
if (typeof Buffer !== 'undefined') {
|
|
12
|
+
return Buffer.from(bytes).toString('base64');
|
|
13
|
+
}
|
|
14
|
+
let binary = '';
|
|
15
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
16
|
+
binary += String.fromCharCode(bytes[i]);
|
|
17
|
+
}
|
|
18
|
+
return btoa(binary);
|
|
19
|
+
};
|
|
20
|
+
const base64Decode = (input) => {
|
|
21
|
+
if (typeof Buffer !== 'undefined') {
|
|
22
|
+
return new Uint8Array(Buffer.from(input, 'base64'));
|
|
23
|
+
}
|
|
24
|
+
const binary = atob(input);
|
|
25
|
+
const bytes = new Uint8Array(binary.length);
|
|
26
|
+
for (let i = 0; i < binary.length; i++) {
|
|
27
|
+
bytes[i] = binary.charCodeAt(i);
|
|
28
|
+
}
|
|
29
|
+
return bytes;
|
|
30
|
+
};
|
|
31
|
+
const toBase64Url = (bytes) => {
|
|
32
|
+
return base64Encode(bytes)
|
|
33
|
+
.replace(/\+/g, '-')
|
|
34
|
+
.replace(/\//g, '_')
|
|
35
|
+
.replace(/=+$/g, '');
|
|
36
|
+
};
|
|
37
|
+
const fromBase64Url = (input) => {
|
|
38
|
+
let base64 = input.replace(/-/g, '+').replace(/_/g, '/');
|
|
39
|
+
while (base64.length % 4 !== 0)
|
|
40
|
+
base64 += '=';
|
|
41
|
+
return base64Decode(base64);
|
|
42
|
+
};
|
|
43
|
+
const deriveKey = async (secret) => {
|
|
44
|
+
const subtle = getSubtle();
|
|
45
|
+
const hash = await subtle.digest('SHA-256', encoder.encode(secret));
|
|
46
|
+
return subtle.importKey('raw', hash, { name: 'AES-GCM' }, false, [
|
|
47
|
+
'encrypt',
|
|
48
|
+
'decrypt',
|
|
49
|
+
]);
|
|
50
|
+
};
|
|
51
|
+
export const encryptJSON = async (secret, value) => {
|
|
52
|
+
const crypto = globalThis.crypto;
|
|
53
|
+
if (!crypto?.getRandomValues) {
|
|
54
|
+
throw new Error('WebCrypto not available');
|
|
55
|
+
}
|
|
56
|
+
const subtle = getSubtle();
|
|
57
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
58
|
+
const key = await deriveKey(secret);
|
|
59
|
+
const plaintext = encoder.encode(JSON.stringify(value));
|
|
60
|
+
const encrypted = await subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);
|
|
61
|
+
const cipherBytes = new Uint8Array(encrypted);
|
|
62
|
+
const out = new Uint8Array(iv.length + cipherBytes.length);
|
|
63
|
+
out.set(iv, 0);
|
|
64
|
+
out.set(cipherBytes, iv.length);
|
|
65
|
+
return toBase64Url(out);
|
|
66
|
+
};
|
|
67
|
+
export const decryptJSON = async (secret, token) => {
|
|
68
|
+
const subtle = getSubtle();
|
|
69
|
+
const data = fromBase64Url(token);
|
|
70
|
+
if (data.length < 13) {
|
|
71
|
+
throw new Error('Invalid encrypted payload');
|
|
72
|
+
}
|
|
73
|
+
const iv = data.slice(0, 12);
|
|
74
|
+
const ciphertext = data.slice(12);
|
|
75
|
+
const key = await deriveKey(secret);
|
|
76
|
+
const decrypted = await subtle.decrypt({ name: 'AES-GCM', iv }, key, ciphertext);
|
|
77
|
+
return JSON.parse(decoder.decode(new Uint8Array(decrypted)));
|
|
78
|
+
};
|
package/dist/errors/errors.d.ts
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import { PikkuError } from './error-handler.js';
|
|
5
5
|
export declare class InvalidMiddlewareWireError extends PikkuError {
|
|
6
6
|
}
|
|
7
|
+
export declare class PikkuMissingMetaError extends PikkuError {
|
|
8
|
+
}
|
|
7
9
|
/**
|
|
8
10
|
* The server cannot or will not process the request due to client error (e.g., malformed request syntax).
|
|
9
11
|
* @group Error
|
|
@@ -190,3 +192,9 @@ export declare class HTTPVersionNotSupportedError extends PikkuError {
|
|
|
190
192
|
*/
|
|
191
193
|
export declare class MaxComputeTimeReachedError extends PikkuError {
|
|
192
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* A required schema was not found during validation.
|
|
197
|
+
* @group Error
|
|
198
|
+
*/
|
|
199
|
+
export declare class MissingSchemaError extends PikkuError {
|
|
200
|
+
}
|
package/dist/errors/errors.js
CHANGED
|
@@ -8,6 +8,12 @@ addError(InvalidMiddlewareWireError, {
|
|
|
8
8
|
status: 500,
|
|
9
9
|
message: 'The middleware wire is invalid for the current wiring type.',
|
|
10
10
|
});
|
|
11
|
+
export class PikkuMissingMetaError extends PikkuError {
|
|
12
|
+
}
|
|
13
|
+
addError(PikkuMissingMetaError, {
|
|
14
|
+
status: 500,
|
|
15
|
+
message: 'Required metadata is missing',
|
|
16
|
+
});
|
|
11
17
|
/**
|
|
12
18
|
* The server cannot or will not process the request due to client error (e.g., malformed request syntax).
|
|
13
19
|
* @group Error
|
|
@@ -321,3 +327,13 @@ addError(MaxComputeTimeReachedError, {
|
|
|
321
327
|
status: 524,
|
|
322
328
|
message: 'The server took too long to complete the request, reaching the maximum compute time allowed.',
|
|
323
329
|
});
|
|
330
|
+
/**
|
|
331
|
+
* A required schema was not found during validation.
|
|
332
|
+
* @group Error
|
|
333
|
+
*/
|
|
334
|
+
export class MissingSchemaError extends PikkuError {
|
|
335
|
+
}
|
|
336
|
+
addError(MissingSchemaError, {
|
|
337
|
+
status: 500,
|
|
338
|
+
message: 'A required schema was not found. Ensure schema generation has been run.',
|
|
339
|
+
});
|
package/dist/errors/index.d.ts
CHANGED
package/dist/errors/index.js
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import { CoreServices, CoreUserSession, CorePikkuMiddleware, PikkuWiringTypes, PikkuWire, MiddlewareMetadata, PermissionMetadata, CoreSingletonServices, CreateWireServices } from '../types/core.types.js';
|
|
2
|
+
import type { CorePikkuChannelMiddleware } from '../wirings/channel/channel.types.js';
|
|
2
3
|
import { CorePermissionGroup, CorePikkuFunctionConfig, CorePikkuPermission } from './functions.types.js';
|
|
3
4
|
import { SessionService } from '../services/user-session-service.js';
|
|
4
5
|
export declare const addFunction: (funcName: string, funcConfig: CorePikkuFunctionConfig<any, any>, packageName?: string | null) => void;
|
|
6
|
+
export declare const getFunctionNames: (packageName?: string | null) => string[];
|
|
7
|
+
export declare const getAllFunctionNames: () => string[];
|
|
5
8
|
export declare const runPikkuFuncDirectly: <In, Out>(funcName: string, allServices: CoreServices, wire: PikkuWire, data: In, userSession?: SessionService<CoreUserSession>, packageName?: string | null) => Promise<Out>;
|
|
6
|
-
export declare const runPikkuFunc: <In = any, Out = any>(wireType: PikkuWiringTypes, wireId: string, funcName: string, { singletonServices, createWireServices, data, auth: wiringAuth, inheritedMiddleware, wireMiddleware, inheritedPermissions, wirePermissions, coerceDataFromSchema, tags, wire, packageName, }: {
|
|
9
|
+
export declare const runPikkuFunc: <In = any, Out = any>(wireType: PikkuWiringTypes, wireId: string, funcName: string, { singletonServices, createWireServices, data, auth: wiringAuth, inheritedMiddleware, wireMiddleware, inheritedChannelMiddleware, wireChannelMiddleware, inheritedPermissions, wirePermissions, coerceDataFromSchema, tags, wire, sessionService, packageName, }: {
|
|
7
10
|
singletonServices: CoreSingletonServices;
|
|
8
11
|
createWireServices?: CreateWireServices;
|
|
9
12
|
data: () => Promise<In> | In;
|
|
10
13
|
auth?: boolean;
|
|
11
14
|
inheritedMiddleware?: MiddlewareMetadata[];
|
|
12
15
|
wireMiddleware?: CorePikkuMiddleware[];
|
|
16
|
+
inheritedChannelMiddleware?: MiddlewareMetadata[];
|
|
17
|
+
wireChannelMiddleware?: CorePikkuChannelMiddleware[];
|
|
13
18
|
inheritedPermissions?: PermissionMetadata[];
|
|
14
19
|
wirePermissions?: CorePermissionGroup | CorePikkuPermission[];
|
|
15
20
|
coerceDataFromSchema?: boolean;
|
|
16
21
|
tags?: string[];
|
|
17
22
|
wire: PikkuWire;
|
|
23
|
+
sessionService?: SessionService<CoreUserSession>;
|
|
18
24
|
packageName?: string | null;
|
|
19
25
|
}) => Promise<Out>;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { runMiddleware, combineMiddleware } from '../middleware-runner.js';
|
|
2
|
+
import { combineChannelMiddleware, wrapChannelWithMiddleware, } from '../wirings/channel/channel-middleware-runner.js';
|
|
2
3
|
import { runPermissions } from '../permissions.js';
|
|
3
4
|
import { pikkuState } from '../pikku-state.js';
|
|
4
5
|
import { coerceTopLevelDataFromSchema, validateSchema } from '../schema.js';
|
|
6
|
+
import { parseVersionedId } from '../version.js';
|
|
7
|
+
import { createFunctionSessionWireProps, } from '../services/user-session-service.js';
|
|
5
8
|
import { ForbiddenError } from '../errors/errors.js';
|
|
6
9
|
import { rpcService } from '../wirings/rpc/rpc-runner.js';
|
|
7
10
|
import { closeWireServices } from '../utils.js';
|
|
@@ -39,25 +42,57 @@ const getOrCreatePackageSingletonServices = async (packageName, parentServices)
|
|
|
39
42
|
export const addFunction = (funcName, funcConfig, packageName = null) => {
|
|
40
43
|
pikkuState(packageName, 'function', 'functions').set(funcName, funcConfig);
|
|
41
44
|
};
|
|
45
|
+
export const getFunctionNames = (packageName = null) => {
|
|
46
|
+
const functionsMeta = pikkuState(packageName, 'function', 'meta');
|
|
47
|
+
return Object.keys(functionsMeta);
|
|
48
|
+
};
|
|
49
|
+
export const getAllFunctionNames = () => {
|
|
50
|
+
const functions = [];
|
|
51
|
+
const mainFunctionsMeta = pikkuState(null, 'function', 'meta');
|
|
52
|
+
functions.push(...Object.keys(mainFunctionsMeta));
|
|
53
|
+
const externalPackages = pikkuState(null, 'rpc', 'externalPackages');
|
|
54
|
+
for (const [namespace, config] of externalPackages) {
|
|
55
|
+
const packageFunctionsMeta = pikkuState(config.package, 'function', 'meta');
|
|
56
|
+
for (const funcName of Object.keys(packageFunctionsMeta)) {
|
|
57
|
+
functions.push(`${namespace}:${funcName}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return functions;
|
|
61
|
+
};
|
|
42
62
|
export const runPikkuFuncDirectly = async (funcName, allServices, wire, data, userSession, packageName = null) => {
|
|
43
63
|
const funcConfig = pikkuState(packageName, 'function', 'functions').get(funcName);
|
|
44
64
|
if (!funcConfig) {
|
|
45
65
|
throw new Error(`Function not found: ${funcName}`);
|
|
46
66
|
}
|
|
47
|
-
// Inject session into wire
|
|
48
67
|
const wireWithSession = {
|
|
49
68
|
...wire,
|
|
50
|
-
|
|
69
|
+
...(userSession && createFunctionSessionWireProps(userSession)),
|
|
51
70
|
};
|
|
52
71
|
return (await funcConfig.func(allServices, data, wireWithSession));
|
|
53
72
|
};
|
|
54
|
-
export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServices, createWireServices, data, auth: wiringAuth, inheritedMiddleware, wireMiddleware, inheritedPermissions, wirePermissions, coerceDataFromSchema, tags = [], wire, packageName = null, }) => {
|
|
55
|
-
|
|
73
|
+
export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServices, createWireServices, data, auth: wiringAuth, inheritedMiddleware, wireMiddleware, inheritedChannelMiddleware, wireChannelMiddleware, inheritedPermissions, wirePermissions, coerceDataFromSchema, tags = [], wire, sessionService, packageName = null, }) => {
|
|
74
|
+
wire = {
|
|
75
|
+
...wire,
|
|
76
|
+
wireType: wire.wireType ?? wireType,
|
|
77
|
+
wireId: wire.wireId ?? wireId,
|
|
78
|
+
};
|
|
79
|
+
const funcMap = pikkuState(packageName, 'function', 'functions');
|
|
80
|
+
let funcConfig = funcMap.get(funcName);
|
|
81
|
+
const allMeta = pikkuState(packageName, 'function', 'meta');
|
|
82
|
+
let funcMeta = allMeta[funcName];
|
|
83
|
+
if (!funcConfig || !funcMeta) {
|
|
84
|
+
const { baseName, version } = parseVersionedId(funcName);
|
|
85
|
+
if (version !== null) {
|
|
86
|
+
funcConfig = funcConfig || funcMap.get(baseName);
|
|
87
|
+
funcMeta = funcMeta || allMeta[baseName];
|
|
88
|
+
if (funcConfig && funcMeta) {
|
|
89
|
+
singletonServices.logger.warn(`Version '${funcName}' not registered, resolved to '${baseName}'`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
56
93
|
if (!funcConfig) {
|
|
57
94
|
throw new Error(`Function not found: ${funcName}`);
|
|
58
95
|
}
|
|
59
|
-
const allMeta = pikkuState(packageName, 'function', 'meta');
|
|
60
|
-
const funcMeta = allMeta[funcName];
|
|
61
96
|
if (!funcMeta) {
|
|
62
97
|
throw new Error(`Function meta not found: ${funcName}`);
|
|
63
98
|
}
|
|
@@ -73,6 +108,14 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
|
|
|
73
108
|
resolvedCreateWireServices = factories.createWireServices;
|
|
74
109
|
}
|
|
75
110
|
}
|
|
111
|
+
const allChannelMiddleware = combineChannelMiddleware(wireType, wireId, {
|
|
112
|
+
wireInheritedChannelMiddleware: inheritedChannelMiddleware,
|
|
113
|
+
wireChannelMiddleware,
|
|
114
|
+
packageName,
|
|
115
|
+
});
|
|
116
|
+
const resolvedWire = allChannelMiddleware.length > 0 && wire.channel
|
|
117
|
+
? wrapChannelWithMiddleware(wire, resolvedSingletonServices, allChannelMiddleware)
|
|
118
|
+
: wire;
|
|
76
119
|
// Convert tags to PermissionMetadata and merge with inheritedPermissions
|
|
77
120
|
const mergedInheritedPermissions = [
|
|
78
121
|
...(inheritedPermissions || []),
|
|
@@ -80,22 +123,36 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
|
|
|
80
123
|
];
|
|
81
124
|
// Helper function to run permissions and execute the function
|
|
82
125
|
const executeFunction = async () => {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
126
|
+
const functionWireProps = sessionService
|
|
127
|
+
? createFunctionSessionWireProps(sessionService)
|
|
128
|
+
: undefined;
|
|
129
|
+
const wireWithSession = {
|
|
130
|
+
...resolvedWire,
|
|
131
|
+
...functionWireProps,
|
|
87
132
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (
|
|
133
|
+
const session = wireWithSession.session;
|
|
134
|
+
if (funcMeta.sessionless) {
|
|
135
|
+
if (wiringAuth === true || funcConfig.auth === true) {
|
|
136
|
+
if (!session) {
|
|
137
|
+
throw new ForbiddenError('Authentication required');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else if (funcMeta.sessionless === false) {
|
|
142
|
+
if (wiringAuth === false || funcConfig.auth === false) {
|
|
143
|
+
resolvedSingletonServices.logger.warn(`Function '${funcName}' requires a session but auth was explicitly disabled — use pikkuSessionlessFunc instead.`);
|
|
144
|
+
}
|
|
145
|
+
else if (!session) {
|
|
91
146
|
throw new ForbiddenError('Authentication required');
|
|
92
147
|
}
|
|
93
148
|
}
|
|
94
|
-
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
149
|
+
else {
|
|
150
|
+
// TODO: Remove after a couple of releases — backward compat for
|
|
151
|
+
// generated metadata that doesn't include the `sessionless` field yet.
|
|
152
|
+
if (wiringAuth === true || funcConfig.auth === true) {
|
|
153
|
+
if (!session) {
|
|
154
|
+
throw new ForbiddenError('Authentication required');
|
|
155
|
+
}
|
|
99
156
|
}
|
|
100
157
|
}
|
|
101
158
|
// Evaluate the data from the lazy function
|
|
@@ -116,16 +173,18 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
|
|
|
116
173
|
funcInheritedPermissions: funcMeta.permissions,
|
|
117
174
|
funcPermissions: funcConfig.permissions,
|
|
118
175
|
services: resolvedSingletonServices,
|
|
119
|
-
wire: { ...
|
|
176
|
+
wire: { ...wireWithSession, rpc: undefined },
|
|
120
177
|
data: actualData,
|
|
121
178
|
packageName,
|
|
122
179
|
});
|
|
123
|
-
const wireServices = await resolvedCreateWireServices?.(resolvedSingletonServices,
|
|
180
|
+
const wireServices = await resolvedCreateWireServices?.(resolvedSingletonServices, wireWithSession);
|
|
124
181
|
try {
|
|
125
182
|
const services = { ...resolvedSingletonServices, ...wireServices };
|
|
126
|
-
const rpc = rpcService.getContextRPCService(services,
|
|
183
|
+
const rpc = rpcService.getContextRPCService(services, wireWithSession, {
|
|
184
|
+
sessionService,
|
|
185
|
+
});
|
|
127
186
|
return await funcConfig.func(services, actualData, {
|
|
128
|
-
...
|
|
187
|
+
...wireWithSession,
|
|
129
188
|
rpc,
|
|
130
189
|
});
|
|
131
190
|
}
|
|
@@ -143,7 +202,7 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
|
|
|
143
202
|
packageName,
|
|
144
203
|
});
|
|
145
204
|
if (allMiddleware.length > 0) {
|
|
146
|
-
return (await runMiddleware(resolvedSingletonServices,
|
|
205
|
+
return (await runMiddleware(resolvedSingletonServices, resolvedWire, allMiddleware, executeFunction));
|
|
147
206
|
}
|
|
148
207
|
return (await executeFunction());
|
|
149
208
|
};
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { CoreServices, CoreSingletonServices, CoreUserSession, CorePikkuMiddleware, PikkuWire, PickRequired } from '../types/core.types.js';
|
|
2
|
-
import {
|
|
2
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
3
|
+
import type { CoreNodeConfig } from '../wirings/node/node.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated Use StandardSchemaV1 from @standard-schema/spec instead.
|
|
6
|
+
* This alias exists only for backward compatibility with generated code.
|
|
7
|
+
*/
|
|
8
|
+
export type ZodLike<T = any> = StandardSchemaV1<T, T>;
|
|
3
9
|
/**
|
|
4
10
|
* Represents a core API function that performs an operation using core services and a user session.
|
|
5
11
|
*
|
|
@@ -8,7 +14,7 @@ import { Session } from 'inspector';
|
|
|
8
14
|
* @template Services - The services type, defaults to `CoreServices`.
|
|
9
15
|
* @template Wire - The wire type, defaults to `PikkuWire<In, Out>`.
|
|
10
16
|
*/
|
|
11
|
-
export type CorePikkuFunction<In, Out, Services extends CoreSingletonServices = CoreServices, Wire extends PikkuWire<In, Out> = PikkuWire<In, Out, true, Session>> = (services: Services, data: In, wire: Wire) => Wire['channel'] extends null ? Promise<Out> : Promise<Out> | Promise<void>;
|
|
17
|
+
export type CorePikkuFunction<In, Out, Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession, Wire extends PikkuWire<In, Out> = PikkuWire<In, Out, true, Session>> = (services: Services, data: In, wire: Wire) => Wire['channel'] extends null ? Promise<Out> : Promise<Out> | Promise<void>;
|
|
12
18
|
/**
|
|
13
19
|
* Represents a core API function that can be used without a session.
|
|
14
20
|
*
|
|
@@ -17,7 +23,7 @@ export type CorePikkuFunction<In, Out, Services extends CoreSingletonServices =
|
|
|
17
23
|
* @template Services - The services type, defaults to `CoreServices`.
|
|
18
24
|
* @template Wire - The wire type, defaults to `PikkuWire<In, Out>`.
|
|
19
25
|
*/
|
|
20
|
-
export type CorePikkuFunctionSessionless<In, Out, Services extends CoreSingletonServices = CoreServices, Wire extends PikkuWire<In, Out, false,
|
|
26
|
+
export type CorePikkuFunctionSessionless<In, Out, Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession, Wire extends PikkuWire<In, Out, false, Session, any, any, any> = PikkuWire<In, Out, false, Session, any, any, any>> = (services: Services, data: In, wire: Wire) => Wire['channel'] extends null ? Promise<Out> : Promise<Out> | Promise<void>;
|
|
21
27
|
/**
|
|
22
28
|
* Represents a function that checks permissions for a given operation.
|
|
23
29
|
*
|
|
@@ -36,8 +42,8 @@ export type CorePikkuPermission<In = any, Services extends CoreSingletonServices
|
|
|
36
42
|
export type CorePikkuPermissionConfig<In = any, Services extends CoreSingletonServices = CoreServices, Wire extends PikkuWire<In, never, false, CoreUserSession> = PikkuWire<In, never, false, CoreUserSession>> = {
|
|
37
43
|
/** The permission function */
|
|
38
44
|
func: CorePikkuPermission<In, Services, Wire>;
|
|
39
|
-
/** Optional human-readable
|
|
40
|
-
|
|
45
|
+
/** Optional human-readable name for the permission */
|
|
46
|
+
name?: string;
|
|
41
47
|
/** Optional description of what the permission checks */
|
|
42
48
|
description?: string;
|
|
43
49
|
};
|
|
@@ -49,18 +55,18 @@ export type CorePikkuPermissionConfig<In = any, Services extends CoreSingletonSe
|
|
|
49
55
|
* ```typescript
|
|
50
56
|
* // Direct function syntax
|
|
51
57
|
* export const adminPermission = pikkuPermission(
|
|
52
|
-
* async ({ logger }, _data, {
|
|
53
|
-
* const currentSession = await
|
|
58
|
+
* async ({ logger }, _data, { getSession }) => {
|
|
59
|
+
* const currentSession = await getSession()
|
|
54
60
|
* return currentSession?.role === 'admin'
|
|
55
61
|
* }
|
|
56
62
|
* )
|
|
57
63
|
*
|
|
58
64
|
* // Configuration object syntax with metadata
|
|
59
65
|
* export const adminPermission = pikkuPermission({
|
|
60
|
-
*
|
|
66
|
+
* name: 'Admin Permission',
|
|
61
67
|
* description: 'Checks if user has admin role',
|
|
62
|
-
* func: async ({ logger }, _data, {
|
|
63
|
-
* const currentSession = await
|
|
68
|
+
* func: async ({ logger }, _data, { getSession }) => {
|
|
69
|
+
* const currentSession = await getSession()
|
|
64
70
|
* return currentSession?.role === 'admin'
|
|
65
71
|
* }
|
|
66
72
|
* })
|
|
@@ -85,8 +91,8 @@ export type CorePikkuPermissionFactory<In = any, Services extends CoreSingletonS
|
|
|
85
91
|
* export const requireRole = pikkuPermissionFactory<{ role: string }>(({
|
|
86
92
|
* role
|
|
87
93
|
* }) => {
|
|
88
|
-
* return pikkuPermission(async ({ logger }, data, {
|
|
89
|
-
* const currentSession = await
|
|
94
|
+
* return pikkuPermission(async ({ logger }, data, { getSession }) => {
|
|
95
|
+
* const currentSession = await getSession()
|
|
90
96
|
* if (!currentSession || currentSession.role !== role) {
|
|
91
97
|
* logger.warn(`Permission denied: required role '${role}'`)
|
|
92
98
|
* return false
|
|
@@ -97,93 +103,31 @@ export type CorePikkuPermissionFactory<In = any, Services extends CoreSingletonS
|
|
|
97
103
|
* ```
|
|
98
104
|
*/
|
|
99
105
|
export declare const pikkuPermissionFactory: <In = any>(factory: CorePikkuPermissionFactory<In>) => CorePikkuPermissionFactory<In>;
|
|
100
|
-
export type
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
export type ZodLike<T = any> = {
|
|
106
|
-
_input: T;
|
|
107
|
-
_output: T;
|
|
106
|
+
export type CorePikkuAuth<Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession> = (services: Services, session: Session) => Promise<boolean> | boolean;
|
|
107
|
+
export type CorePikkuAuthConfig<Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession> = {
|
|
108
|
+
func: CorePikkuAuth<Services, Session>;
|
|
109
|
+
name?: string;
|
|
110
|
+
description?: string;
|
|
108
111
|
};
|
|
109
|
-
export
|
|
112
|
+
export declare const pikkuAuth: <Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession>(auth: CorePikkuAuth<Services, Session> | CorePikkuAuthConfig<Services, Session>) => CorePikkuPermission<any, Services, any>;
|
|
113
|
+
export type CorePermissionGroup<PikkuPermission = CorePikkuPermission<any>> = Record<string, PikkuPermission | PikkuPermission[]> | undefined;
|
|
114
|
+
export type CorePikkuFunctionConfig<PikkuFunction extends CorePikkuFunction<any, any, any, any, any> | CorePikkuFunctionSessionless<any, any, any, any, any>, PikkuPermission extends CorePikkuPermission<any, any, any> = CorePikkuPermission<any>, PikkuMiddleware extends CorePikkuMiddleware<any, any> = CorePikkuMiddleware<any, any>, InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined> = {
|
|
110
115
|
/** Optional human-readable title for the function */
|
|
111
116
|
title?: string;
|
|
112
117
|
/** Optional description of what the function does */
|
|
113
118
|
description?: string;
|
|
114
119
|
override?: string;
|
|
120
|
+
version?: number;
|
|
115
121
|
tags?: string[];
|
|
116
122
|
expose?: boolean;
|
|
117
|
-
|
|
123
|
+
remote?: boolean;
|
|
124
|
+
mcp?: boolean;
|
|
125
|
+
requiresApproval?: boolean;
|
|
118
126
|
func: PikkuFunction;
|
|
119
127
|
auth?: boolean;
|
|
120
128
|
permissions?: CorePermissionGroup<PikkuPermission>;
|
|
121
129
|
middleware?: PikkuMiddleware[];
|
|
122
130
|
input?: InputSchema;
|
|
123
131
|
output?: OutputSchema;
|
|
132
|
+
node?: CoreNodeConfig;
|
|
124
133
|
};
|
|
125
|
-
/**
|
|
126
|
-
* A trigger function that sets up a subscription and returns a teardown function.
|
|
127
|
-
* The trigger is fired via wire.trigger.trigger(data).
|
|
128
|
-
*
|
|
129
|
-
* @template TConfig - Configuration type (hardcoded when wired)
|
|
130
|
-
* @template TOutput - Output type produced when trigger fires
|
|
131
|
-
* @template Services - Services available to the trigger
|
|
132
|
-
*/
|
|
133
|
-
export type CorePikkuTriggerFunction<TConfig = unknown, TOutput = unknown, Services extends CoreSingletonServices = CoreSingletonServices> = (services: Services, config: TConfig, wire: {
|
|
134
|
-
trigger: {
|
|
135
|
-
trigger: (data: TOutput) => void;
|
|
136
|
-
};
|
|
137
|
-
}) => Promise<() => void | Promise<void>>;
|
|
138
|
-
/**
|
|
139
|
-
* Configuration object for creating a trigger function with metadata
|
|
140
|
-
*/
|
|
141
|
-
export type CorePikkuTriggerFunctionConfig<TConfig = unknown, TOutput = unknown, Services extends CoreSingletonServices = CoreSingletonServices, ConfigSchema extends ZodLike | undefined = undefined, OutputSchema extends ZodLike | undefined = undefined> = {
|
|
142
|
-
/** Optional human-readable title for the trigger */
|
|
143
|
-
title?: string;
|
|
144
|
-
/** Optional description of what the trigger does */
|
|
145
|
-
description?: string;
|
|
146
|
-
/** Optional tags for categorization */
|
|
147
|
-
tags?: string[];
|
|
148
|
-
/** The trigger function */
|
|
149
|
-
func: CorePikkuTriggerFunction<TConfig, TOutput, Services>;
|
|
150
|
-
/** Optional Zod schema for config validation */
|
|
151
|
-
config?: ConfigSchema;
|
|
152
|
-
/** Optional Zod schema for output validation */
|
|
153
|
-
output?: OutputSchema;
|
|
154
|
-
};
|
|
155
|
-
/**
|
|
156
|
-
* Factory function for creating trigger functions
|
|
157
|
-
* Supports both direct function and configuration object syntax
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* ```typescript
|
|
161
|
-
* // Direct function syntax
|
|
162
|
-
* export const redisSubscribeTrigger = pikkuTriggerFunc<
|
|
163
|
-
* { channel: string },
|
|
164
|
-
* { message: string }
|
|
165
|
-
* >(async ({ redis }, { channel }, { trigger }) => {
|
|
166
|
-
* const subscriber = redis.duplicate()
|
|
167
|
-
* await subscriber.subscribe(channel, (msg) => {
|
|
168
|
-
* trigger.trigger({ message: msg })
|
|
169
|
-
* })
|
|
170
|
-
* return () => subscriber.unsubscribe()
|
|
171
|
-
* })
|
|
172
|
-
*
|
|
173
|
-
* // Configuration object syntax with metadata
|
|
174
|
-
* export const redisSubscribeTrigger = pikkuTriggerFunc({
|
|
175
|
-
* title: 'Redis Subscribe Trigger',
|
|
176
|
-
* description: 'Listens to Redis pub/sub channel',
|
|
177
|
-
* config: z.object({ channel: z.string() }),
|
|
178
|
-
* output: z.object({ message: z.string() }),
|
|
179
|
-
* func: async ({ redis }, { channel }, { trigger }) => {
|
|
180
|
-
* const subscriber = redis.duplicate()
|
|
181
|
-
* await subscriber.subscribe(channel, (msg) => {
|
|
182
|
-
* trigger.trigger({ message: msg })
|
|
183
|
-
* })
|
|
184
|
-
* return () => subscriber.unsubscribe()
|
|
185
|
-
* }
|
|
186
|
-
* })
|
|
187
|
-
* ```
|
|
188
|
-
*/
|
|
189
|
-
export declare const pikkuTriggerFunc: <TConfig = unknown, TOutput = unknown, Services extends CoreSingletonServices = CoreSingletonServices, ConfigSchema extends ZodLike | undefined = undefined, OutputSchema extends ZodLike | undefined = undefined>(triggerOrConfig: CorePikkuTriggerFunction<TConfig, TOutput, Services> | CorePikkuTriggerFunctionConfig<TConfig, TOutput, Services, ConfigSchema, OutputSchema>) => CorePikkuTriggerFunctionConfig<TConfig, TOutput, Services, ConfigSchema, OutputSchema>;
|
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
* ```typescript
|
|
7
7
|
* // Direct function syntax
|
|
8
8
|
* export const adminPermission = pikkuPermission(
|
|
9
|
-
* async ({ logger }, _data, {
|
|
10
|
-
* const currentSession = await
|
|
9
|
+
* async ({ logger }, _data, { getSession }) => {
|
|
10
|
+
* const currentSession = await getSession()
|
|
11
11
|
* return currentSession?.role === 'admin'
|
|
12
12
|
* }
|
|
13
13
|
* )
|
|
14
14
|
*
|
|
15
15
|
* // Configuration object syntax with metadata
|
|
16
16
|
* export const adminPermission = pikkuPermission({
|
|
17
|
-
*
|
|
17
|
+
* name: 'Admin Permission',
|
|
18
18
|
* description: 'Checks if user has admin role',
|
|
19
|
-
* func: async ({ logger }, _data, {
|
|
20
|
-
* const currentSession = await
|
|
19
|
+
* func: async ({ logger }, _data, { getSession }) => {
|
|
20
|
+
* const currentSession = await getSession()
|
|
21
21
|
* return currentSession?.role === 'admin'
|
|
22
22
|
* }
|
|
23
23
|
* })
|
|
@@ -35,8 +35,8 @@ export const pikkuPermission = (permission) => {
|
|
|
35
35
|
* export const requireRole = pikkuPermissionFactory<{ role: string }>(({
|
|
36
36
|
* role
|
|
37
37
|
* }) => {
|
|
38
|
-
* return pikkuPermission(async ({ logger }, data, {
|
|
39
|
-
* const currentSession = await
|
|
38
|
+
* return pikkuPermission(async ({ logger }, data, { getSession }) => {
|
|
39
|
+
* const currentSession = await getSession()
|
|
40
40
|
* if (!currentSession || currentSession.role !== role) {
|
|
41
41
|
* logger.warn(`Permission denied: required role '${role}'`)
|
|
42
42
|
* return false
|
|
@@ -49,43 +49,13 @@ export const pikkuPermission = (permission) => {
|
|
|
49
49
|
export const pikkuPermissionFactory = (factory) => {
|
|
50
50
|
return factory;
|
|
51
51
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
* { message: string }
|
|
62
|
-
* >(async ({ redis }, { channel }, { trigger }) => {
|
|
63
|
-
* const subscriber = redis.duplicate()
|
|
64
|
-
* await subscriber.subscribe(channel, (msg) => {
|
|
65
|
-
* trigger.trigger({ message: msg })
|
|
66
|
-
* })
|
|
67
|
-
* return () => subscriber.unsubscribe()
|
|
68
|
-
* })
|
|
69
|
-
*
|
|
70
|
-
* // Configuration object syntax with metadata
|
|
71
|
-
* export const redisSubscribeTrigger = pikkuTriggerFunc({
|
|
72
|
-
* title: 'Redis Subscribe Trigger',
|
|
73
|
-
* description: 'Listens to Redis pub/sub channel',
|
|
74
|
-
* config: z.object({ channel: z.string() }),
|
|
75
|
-
* output: z.object({ message: z.string() }),
|
|
76
|
-
* func: async ({ redis }, { channel }, { trigger }) => {
|
|
77
|
-
* const subscriber = redis.duplicate()
|
|
78
|
-
* await subscriber.subscribe(channel, (msg) => {
|
|
79
|
-
* trigger.trigger({ message: msg })
|
|
80
|
-
* })
|
|
81
|
-
* return () => subscriber.unsubscribe()
|
|
82
|
-
* }
|
|
83
|
-
* })
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
export const pikkuTriggerFunc = (triggerOrConfig) => {
|
|
87
|
-
if (typeof triggerOrConfig === 'function') {
|
|
88
|
-
return { func: triggerOrConfig };
|
|
89
|
-
}
|
|
90
|
-
return triggerOrConfig;
|
|
52
|
+
export const pikkuAuth = (auth) => {
|
|
53
|
+
const fn = typeof auth === 'function' ? auth : auth.func;
|
|
54
|
+
const wrapper = async (services, _data, wire) => {
|
|
55
|
+
const session = wire.session;
|
|
56
|
+
if (!session)
|
|
57
|
+
return false;
|
|
58
|
+
return fn(services, session);
|
|
59
|
+
};
|
|
60
|
+
return wrapper;
|
|
91
61
|
};
|