@pikku/core 0.11.1 → 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 +55 -0
- package/dist/crypto-utils.d.ts +2 -0
- package/dist/crypto-utils.js +78 -0
- package/dist/errors/error-handler.js +3 -3
- 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 +10 -3
- package/dist/function/function-runner.js +136 -31
- package/dist/function/functions.types.d.ts +35 -12
- package/dist/function/functions.types.js +16 -6
- 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 +30 -24
- package/dist/index.js +19 -27
- package/dist/middleware/auth-apikey.d.ts +1 -1
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.d.ts +1 -1
- package/dist/middleware/auth-bearer.js +3 -6
- package/dist/middleware/auth-cookie.d.ts +1 -1
- 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 +1 -1
- package/dist/middleware-runner.d.ts +3 -14
- package/dist/middleware-runner.js +14 -16
- package/dist/permissions.d.ts +3 -86
- package/dist/permissions.js +20 -80
- package/dist/pikku-state.d.ts +33 -104
- package/dist/pikku-state.js +150 -66
- package/dist/schema.d.ts +8 -6
- package/dist/schema.js +31 -18
- 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 +43 -0
- package/dist/services/workflow-service.js +1 -0
- package/dist/types/core.types.d.ts +54 -10
- package/dist/types/core.types.js +7 -0
- package/dist/types/state.types.d.ts +127 -0
- package/dist/types/state.types.js +1 -0
- package/dist/utils.d.ts +10 -1
- package/dist/utils.js +60 -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 +13 -4
- 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 +12 -12
- 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/log-channels.js +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.js +17 -6
- package/dist/wirings/cli/channel/cli-channel-runner.js +3 -2
- 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 +22 -18
- package/dist/wirings/cli/cli.types.d.ts +7 -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.d.ts +2 -2
- package/dist/wirings/http/http-runner.js +62 -27
- package/dist/wirings/http/http.types.d.ts +77 -24
- package/dist/wirings/http/index.d.ts +5 -4
- package/dist/wirings/http/index.js +4 -3
- package/dist/wirings/http/log-http-routes.js +1 -1
- package/dist/wirings/http/routers/path-to-regex.js +2 -2
- 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 +42 -56
- 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 +23 -12
- 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 +40 -13
- package/dist/wirings/rpc/rpc-runner.js +191 -25
- package/dist/wirings/rpc/rpc-types.d.ts +15 -4
- package/dist/wirings/scheduler/index.d.ts +3 -3
- package/dist/wirings/scheduler/index.js +2 -3
- package/dist/wirings/scheduler/log-schedulers.js +1 -1
- package/dist/wirings/scheduler/scheduler-runner.d.ts +5 -0
- package/dist/wirings/scheduler/scheduler-runner.js +28 -10
- 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 -0
- package/dist/wirings/trigger/index.js +2 -0
- 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 +42 -0
- package/dist/wirings/trigger/trigger-runner.js +85 -0
- package/dist/wirings/trigger/trigger.types.d.ts +130 -0
- package/dist/wirings/trigger/trigger.types.js +40 -0
- 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 +5 -0
- package/dist/wirings/workflow/dsl/index.js +4 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +292 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.js +5 -0
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +5 -0
- package/dist/wirings/workflow/dsl/workflow-runner.js +23 -0
- package/dist/wirings/workflow/graph/graph-node.d.ts +117 -0
- package/dist/wirings/workflow/graph/graph-node.js +58 -0
- package/dist/wirings/workflow/graph/graph-runner.d.ts +9 -0
- package/dist/wirings/workflow/graph/graph-runner.js +540 -0
- package/dist/wirings/workflow/graph/index.d.ts +4 -0
- package/dist/wirings/workflow/graph/index.js +3 -0
- 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 +82 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.js +15 -0
- package/dist/wirings/workflow/index.d.ts +7 -12
- package/dist/wirings/workflow/index.js +8 -11
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +114 -10
- package/dist/wirings/workflow/pikku-workflow-service.js +386 -115
- 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 -0
- package/dist/wirings/workflow/workflow-utils.js +1 -0
- package/dist/wirings/workflow/workflow.types.d.ts +83 -214
- package/package.json +13 -6
- package/run-tests.sh +4 -1
- package/src/crypto-utils.ts +99 -0
- package/src/errors/error-handler.ts +3 -3
- 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 +5 -12
- package/src/function/function-runner.ts +195 -40
- package/src/function/functions.types.ts +66 -14
- package/src/function/index.ts +5 -2
- package/src/handle-error.ts +2 -10
- package/src/index.ts +106 -27
- 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 +24 -17
- package/src/permissions.test.ts +102 -86
- package/src/permissions.ts +32 -93
- package/src/pikku-state.ts +168 -201
- package/src/run-tests-script.test.ts +49 -0
- package/src/schema.ts +50 -18
- 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 +94 -0
- package/src/types/core.types.ts +82 -8
- package/src/types/state.types.ts +169 -0
- package/src/utils.ts +74 -5
- 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 +18 -5
- package/src/wirings/channel/channel-middleware-runner.ts +119 -0
- package/src/wirings/channel/channel-runner.ts +14 -15
- 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 +47 -2
- package/src/wirings/channel/local/local-channel-runner.ts +22 -6
- package/src/wirings/channel/log-channels.ts +1 -1
- package/src/wirings/channel/serverless/index.ts +5 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +22 -6
- package/src/wirings/cli/channel/cli-channel-runner.ts +4 -3
- package/src/wirings/cli/channel/index.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +28 -28
- package/src/wirings/cli/cli-runner.ts +27 -19
- package/src/wirings/cli/cli.types.ts +12 -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 +5 -5
- package/src/wirings/http/http-runner.ts +80 -29
- package/src/wirings/http/http.types.ts +121 -23
- package/src/wirings/http/index.ts +16 -4
- package/src/wirings/http/log-http-routes.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.test.ts +30 -19
- package/src/wirings/http/routers/path-to-regex.ts +2 -2
- 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 +56 -67
- 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 +115 -73
- package/src/wirings/queue/queue-runner.ts +39 -13
- package/src/wirings/queue/queue.types.ts +12 -2
- package/src/wirings/rpc/index.ts +1 -1
- package/src/wirings/rpc/rpc-runner.ts +270 -34
- package/src/wirings/rpc/rpc-types.ts +21 -4
- package/src/wirings/scheduler/index.ts +7 -4
- package/src/wirings/scheduler/log-schedulers.ts +1 -1
- package/src/wirings/scheduler/scheduler-runner.test.ts +97 -53
- package/src/wirings/scheduler/scheduler-runner.ts +50 -10
- 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 -0
- package/src/wirings/trigger/pikku-trigger-service.ts +134 -0
- package/src/wirings/trigger/trigger-runner.ts +138 -0
- package/src/wirings/trigger/trigger.types.ts +178 -0
- 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 +31 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +320 -0
- package/src/wirings/workflow/dsl/workflow-runner.ts +28 -0
- package/src/wirings/workflow/graph/graph-node.ts +222 -0
- package/src/wirings/workflow/graph/graph-runner.test.ts +495 -0
- package/src/wirings/workflow/graph/graph-runner.ts +816 -0
- package/src/wirings/workflow/graph/index.ts +14 -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 +104 -0
- package/src/wirings/workflow/index.ts +64 -26
- package/src/wirings/workflow/pikku-workflow-service.test.ts +212 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +571 -136
- package/src/wirings/workflow/workflow-helpers.ts +79 -0
- package/src/wirings/workflow/workflow-utils.ts +0 -0
- package/src/wirings/workflow/workflow.types.ts +123 -279
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/workflow/workflow-runner.d.ts +0 -34
- package/dist/wirings/workflow/workflow-runner.js +0 -65
- package/src/function/function-runner.ts.bak +0 -188
- package/src/wirings/workflow/workflow-runner.ts +0 -72
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { test } from 'node:test'
|
|
2
2
|
import assert from 'node:assert'
|
|
3
3
|
import {
|
|
4
|
+
pikkuAuth,
|
|
4
5
|
pikkuPermission,
|
|
5
6
|
pikkuMiddleware,
|
|
6
7
|
pikkuPermissionFactory,
|
|
@@ -21,8 +22,8 @@ test('pikkuMiddleware returns the same function', async () => {
|
|
|
21
22
|
|
|
22
23
|
test('pikkuPermissionFactory creates a factory function', async () => {
|
|
23
24
|
const factory = pikkuPermissionFactory<{ role: string }>(({ role }) => {
|
|
24
|
-
return pikkuPermission(async ({ logger }, data, {
|
|
25
|
-
return (
|
|
25
|
+
return pikkuPermission(async ({ logger }, data, { session }) => {
|
|
26
|
+
return (session as any)?.role === role
|
|
26
27
|
})
|
|
27
28
|
})
|
|
28
29
|
|
|
@@ -67,3 +68,42 @@ test('pikkuMiddlewareFactory returns the same factory', async () => {
|
|
|
67
68
|
const wrappedFactory = pikkuMiddlewareFactory(originalFactory)
|
|
68
69
|
assert.strictEqual(wrappedFactory, originalFactory)
|
|
69
70
|
})
|
|
71
|
+
|
|
72
|
+
test('pikkuAuth returns a 3-arg wrapper function', async () => {
|
|
73
|
+
const authFn = async (_services, session) => !!session
|
|
74
|
+
const wrapped = pikkuAuth(authFn)
|
|
75
|
+
assert.strictEqual(typeof wrapped, 'function')
|
|
76
|
+
assert.strictEqual(wrapped.length, 3)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('pikkuAuth wrapper extracts session from wire and calls auth function', async () => {
|
|
80
|
+
let receivedSession = null
|
|
81
|
+
const authFn = async (_services, session) => {
|
|
82
|
+
receivedSession = session
|
|
83
|
+
return session.role === 'admin'
|
|
84
|
+
}
|
|
85
|
+
const wrapped = pikkuAuth(authFn)
|
|
86
|
+
const result = await wrapped({}, null, { session: { role: 'admin' } })
|
|
87
|
+
assert.strictEqual(result, true)
|
|
88
|
+
assert.deepStrictEqual(receivedSession, { role: 'admin' })
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
test('pikkuAuth wrapper returns false when no session', async () => {
|
|
92
|
+
const authFn = async (_services, session) => !!session
|
|
93
|
+
const wrapped = pikkuAuth(authFn)
|
|
94
|
+
const result = await wrapped({}, null, { session: null })
|
|
95
|
+
assert.strictEqual(result, false)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('pikkuAuth config object syntax works', async () => {
|
|
99
|
+
const authFn = async (_services, session) => !!session
|
|
100
|
+
const wrapped = pikkuAuth({
|
|
101
|
+
func: authFn,
|
|
102
|
+
name: 'Is Authenticated',
|
|
103
|
+
description: 'Checks if user has a session',
|
|
104
|
+
})
|
|
105
|
+
assert.strictEqual(typeof wrapped, 'function')
|
|
106
|
+
assert.strictEqual(wrapped.length, 3)
|
|
107
|
+
const result = await wrapped({}, null, { session: { id: '1' } })
|
|
108
|
+
assert.strictEqual(result, true)
|
|
109
|
+
})
|
|
@@ -21,8 +21,8 @@ const addTestFunction = (funcName: string, funcConfig: any) => {
|
|
|
21
21
|
const permissions = funcConfig.tags
|
|
22
22
|
? funcConfig.tags.map((tag: string) => ({ type: 'tag' as const, tag }))
|
|
23
23
|
: undefined
|
|
24
|
-
pikkuState('function', 'meta')[funcName] = {
|
|
25
|
-
|
|
24
|
+
pikkuState(null, 'function', 'meta')[funcName] = {
|
|
25
|
+
pikkuFuncId: funcName,
|
|
26
26
|
inputSchemaName: null,
|
|
27
27
|
outputSchemaName: null,
|
|
28
28
|
middleware,
|
|
@@ -152,14 +152,8 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
152
152
|
)
|
|
153
153
|
|
|
154
154
|
assert.equal(result, 'success')
|
|
155
|
-
// Order: wiringTags →
|
|
156
|
-
assert.deepEqual(executionOrder, [
|
|
157
|
-
'wiringTag',
|
|
158
|
-
'wiringPermission',
|
|
159
|
-
'funcTag',
|
|
160
|
-
'funcPermission',
|
|
161
|
-
'main',
|
|
162
|
-
])
|
|
155
|
+
// Order: wiringTags → main (short-circuit on first passing group)
|
|
156
|
+
assert.deepEqual(executionOrder, ['wiringTag', 'main'])
|
|
163
157
|
})
|
|
164
158
|
|
|
165
159
|
test('should throw specific error for wiring tag permission failures', async () => {
|
|
@@ -340,11 +334,10 @@ describe('runPikkuFunc - Integration Tests', () => {
|
|
|
340
334
|
)
|
|
341
335
|
|
|
342
336
|
assert.equal(result, 'success')
|
|
343
|
-
// Should execute tag permissions
|
|
337
|
+
// Should execute tag permissions and short-circuit before function permissions
|
|
344
338
|
assert.deepEqual(executionOrder, [
|
|
345
339
|
'arrayPermission1',
|
|
346
340
|
'arrayPermission2',
|
|
347
|
-
'objectPermission',
|
|
348
341
|
'main',
|
|
349
342
|
])
|
|
350
343
|
})
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { runMiddleware, combineMiddleware } from '../middleware-runner.js'
|
|
2
|
+
import {
|
|
3
|
+
combineChannelMiddleware,
|
|
4
|
+
wrapChannelWithMiddleware,
|
|
5
|
+
} from '../wirings/channel/channel-middleware-runner.js'
|
|
2
6
|
import { runPermissions } from '../permissions.js'
|
|
3
7
|
import { pikkuState } from '../pikku-state.js'
|
|
4
8
|
import { coerceTopLevelDataFromSchema, validateSchema } from '../schema.js'
|
|
@@ -12,22 +16,96 @@ import {
|
|
|
12
16
|
PermissionMetadata,
|
|
13
17
|
CoreSingletonServices,
|
|
14
18
|
CreateWireServices,
|
|
19
|
+
CoreConfig,
|
|
15
20
|
} from '../types/core.types.js'
|
|
21
|
+
import type { CorePikkuChannelMiddleware } from '../wirings/channel/channel.types.js'
|
|
16
22
|
import {
|
|
17
23
|
CorePermissionGroup,
|
|
18
24
|
CorePikkuFunctionConfig,
|
|
19
25
|
CorePikkuPermission,
|
|
20
26
|
} from './functions.types.js'
|
|
21
|
-
import {
|
|
27
|
+
import { parseVersionedId } from '../version.js'
|
|
28
|
+
import {
|
|
29
|
+
SessionService,
|
|
30
|
+
createFunctionSessionWireProps,
|
|
31
|
+
} from '../services/user-session-service.js'
|
|
22
32
|
import { ForbiddenError } from '../errors/errors.js'
|
|
23
33
|
import { rpcService } from '../wirings/rpc/rpc-runner.js'
|
|
24
34
|
import { closeWireServices } from '../utils.js'
|
|
25
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Get or create singleton services for an external package.
|
|
38
|
+
* Services are cached in pikkuState to avoid recreation on each call.
|
|
39
|
+
*
|
|
40
|
+
* @param packageName - The external package name
|
|
41
|
+
* @param parentServices - The parent/caller's singleton services (used as base)
|
|
42
|
+
* @returns The package's singleton services
|
|
43
|
+
*/
|
|
44
|
+
const getOrCreatePackageSingletonServices = async (
|
|
45
|
+
packageName: string,
|
|
46
|
+
parentServices: CoreSingletonServices
|
|
47
|
+
): Promise<CoreSingletonServices> => {
|
|
48
|
+
// Check if we already have cached singleton services for this package
|
|
49
|
+
const cachedServices = pikkuState(packageName, 'package', 'singletonServices')
|
|
50
|
+
if (cachedServices) {
|
|
51
|
+
return cachedServices
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Get the package's service factories
|
|
55
|
+
const factories = pikkuState(packageName, 'package', 'factories')
|
|
56
|
+
if (!factories || !factories.createSingletonServices) {
|
|
57
|
+
// No factories registered, use parent services
|
|
58
|
+
return parentServices
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Create config for the package (use parent config if no factory)
|
|
62
|
+
let config: CoreConfig = parentServices.config
|
|
63
|
+
if (factories.createConfig) {
|
|
64
|
+
config = await factories.createConfig(parentServices.variables)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Create singleton services for the package, passing parent services as existing
|
|
68
|
+
const packageServices = await factories.createSingletonServices(
|
|
69
|
+
config,
|
|
70
|
+
parentServices
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
// Cache the services
|
|
74
|
+
pikkuState(packageName, 'package', 'singletonServices', packageServices)
|
|
75
|
+
|
|
76
|
+
return packageServices
|
|
77
|
+
}
|
|
78
|
+
|
|
26
79
|
export const addFunction = (
|
|
27
80
|
funcName: string,
|
|
28
|
-
funcConfig: CorePikkuFunctionConfig<any, any
|
|
81
|
+
funcConfig: CorePikkuFunctionConfig<any, any>,
|
|
82
|
+
packageName: string | null = null
|
|
29
83
|
) => {
|
|
30
|
-
pikkuState('function', 'functions').set(funcName, funcConfig)
|
|
84
|
+
pikkuState(packageName, 'function', 'functions').set(funcName, funcConfig)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const getFunctionNames = (
|
|
88
|
+
packageName: string | null = null
|
|
89
|
+
): string[] => {
|
|
90
|
+
const functionsMeta = pikkuState(packageName, 'function', 'meta')
|
|
91
|
+
return Object.keys(functionsMeta)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const getAllFunctionNames = (): string[] => {
|
|
95
|
+
const functions: string[] = []
|
|
96
|
+
|
|
97
|
+
const mainFunctionsMeta = pikkuState(null, 'function', 'meta')
|
|
98
|
+
functions.push(...Object.keys(mainFunctionsMeta))
|
|
99
|
+
|
|
100
|
+
const externalPackages = pikkuState(null, 'rpc', 'externalPackages')
|
|
101
|
+
for (const [namespace, config] of externalPackages) {
|
|
102
|
+
const packageFunctionsMeta = pikkuState(config.package, 'function', 'meta')
|
|
103
|
+
for (const funcName of Object.keys(packageFunctionsMeta)) {
|
|
104
|
+
functions.push(`${namespace}:${funcName}`)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return functions
|
|
31
109
|
}
|
|
32
110
|
|
|
33
111
|
export const runPikkuFuncDirectly = async <In, Out>(
|
|
@@ -35,16 +113,18 @@ export const runPikkuFuncDirectly = async <In, Out>(
|
|
|
35
113
|
allServices: CoreServices,
|
|
36
114
|
wire: PikkuWire,
|
|
37
115
|
data: In,
|
|
38
|
-
userSession?: SessionService<CoreUserSession
|
|
116
|
+
userSession?: SessionService<CoreUserSession>,
|
|
117
|
+
packageName: string | null = null
|
|
39
118
|
) => {
|
|
40
|
-
const funcConfig = pikkuState('function', 'functions').get(
|
|
119
|
+
const funcConfig = pikkuState(packageName, 'function', 'functions').get(
|
|
120
|
+
funcName
|
|
121
|
+
)
|
|
41
122
|
if (!funcConfig) {
|
|
42
123
|
throw new Error(`Function not found: ${funcName}`)
|
|
43
124
|
}
|
|
44
|
-
// Inject session into wire
|
|
45
125
|
const wireWithSession = {
|
|
46
126
|
...wire,
|
|
47
|
-
|
|
127
|
+
...(userSession && createFunctionSessionWireProps(userSession)),
|
|
48
128
|
}
|
|
49
129
|
return (await funcConfig.func(allServices, data, wireWithSession)) as Out
|
|
50
130
|
}
|
|
@@ -60,11 +140,15 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
60
140
|
auth: wiringAuth,
|
|
61
141
|
inheritedMiddleware,
|
|
62
142
|
wireMiddleware,
|
|
143
|
+
inheritedChannelMiddleware,
|
|
144
|
+
wireChannelMiddleware,
|
|
63
145
|
inheritedPermissions,
|
|
64
146
|
wirePermissions,
|
|
65
147
|
coerceDataFromSchema,
|
|
66
148
|
tags = [],
|
|
67
149
|
wire,
|
|
150
|
+
sessionService,
|
|
151
|
+
packageName = null,
|
|
68
152
|
}: {
|
|
69
153
|
singletonServices: CoreSingletonServices
|
|
70
154
|
createWireServices?: CreateWireServices
|
|
@@ -72,22 +156,77 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
72
156
|
auth?: boolean
|
|
73
157
|
inheritedMiddleware?: MiddlewareMetadata[]
|
|
74
158
|
wireMiddleware?: CorePikkuMiddleware[]
|
|
159
|
+
inheritedChannelMiddleware?: MiddlewareMetadata[]
|
|
160
|
+
wireChannelMiddleware?: CorePikkuChannelMiddleware[]
|
|
75
161
|
inheritedPermissions?: PermissionMetadata[]
|
|
76
162
|
wirePermissions?: CorePermissionGroup | CorePikkuPermission[]
|
|
77
163
|
coerceDataFromSchema?: boolean
|
|
78
164
|
tags?: string[]
|
|
79
165
|
wire: PikkuWire
|
|
166
|
+
sessionService?: SessionService<CoreUserSession>
|
|
167
|
+
packageName?: string | null
|
|
80
168
|
}
|
|
81
169
|
): Promise<Out> => {
|
|
82
|
-
|
|
170
|
+
wire = {
|
|
171
|
+
...wire,
|
|
172
|
+
wireType: wire.wireType ?? wireType,
|
|
173
|
+
wireId: wire.wireId ?? wireId,
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const funcMap = pikkuState(packageName, 'function', 'functions')
|
|
177
|
+
let funcConfig = funcMap.get(funcName)
|
|
178
|
+
const allMeta = pikkuState(packageName, 'function', 'meta')
|
|
179
|
+
let funcMeta = allMeta[funcName]
|
|
180
|
+
|
|
181
|
+
if (!funcConfig || !funcMeta) {
|
|
182
|
+
const { baseName, version } = parseVersionedId(funcName)
|
|
183
|
+
if (version !== null) {
|
|
184
|
+
funcConfig = funcConfig || funcMap.get(baseName)
|
|
185
|
+
funcMeta = funcMeta || allMeta[baseName]
|
|
186
|
+
if (funcConfig && funcMeta) {
|
|
187
|
+
singletonServices.logger.warn(
|
|
188
|
+
`Version '${funcName}' not registered, resolved to '${baseName}'`
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
83
194
|
if (!funcConfig) {
|
|
84
195
|
throw new Error(`Function not found: ${funcName}`)
|
|
85
196
|
}
|
|
86
|
-
const funcMeta = pikkuState('function', 'meta')[funcName]
|
|
87
197
|
if (!funcMeta) {
|
|
88
198
|
throw new Error(`Function meta not found: ${funcName}`)
|
|
89
199
|
}
|
|
90
200
|
|
|
201
|
+
// For external packages, get or create their singleton services
|
|
202
|
+
const resolvedSingletonServices = packageName
|
|
203
|
+
? await getOrCreatePackageSingletonServices(packageName, singletonServices)
|
|
204
|
+
: singletonServices
|
|
205
|
+
|
|
206
|
+
// Get the package's createWireServices if available
|
|
207
|
+
let resolvedCreateWireServices = createWireServices
|
|
208
|
+
if (packageName) {
|
|
209
|
+
const factories = pikkuState(packageName, 'package', 'factories')
|
|
210
|
+
if (factories?.createWireServices) {
|
|
211
|
+
resolvedCreateWireServices = factories.createWireServices
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const allChannelMiddleware = combineChannelMiddleware(wireType, wireId, {
|
|
216
|
+
wireInheritedChannelMiddleware: inheritedChannelMiddleware,
|
|
217
|
+
wireChannelMiddleware,
|
|
218
|
+
packageName,
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
const resolvedWire =
|
|
222
|
+
allChannelMiddleware.length > 0 && wire.channel
|
|
223
|
+
? wrapChannelWithMiddleware(
|
|
224
|
+
wire,
|
|
225
|
+
resolvedSingletonServices,
|
|
226
|
+
allChannelMiddleware
|
|
227
|
+
)
|
|
228
|
+
: wire
|
|
229
|
+
|
|
91
230
|
// Convert tags to PermissionMetadata and merge with inheritedPermissions
|
|
92
231
|
const mergedInheritedPermissions: PermissionMetadata[] = [
|
|
93
232
|
...(inheritedPermissions || []),
|
|
@@ -96,24 +235,38 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
96
235
|
|
|
97
236
|
// Helper function to run permissions and execute the function
|
|
98
237
|
const executeFunction = async () => {
|
|
99
|
-
const
|
|
238
|
+
const functionWireProps = sessionService
|
|
239
|
+
? createFunctionSessionWireProps(sessionService)
|
|
240
|
+
: undefined
|
|
100
241
|
|
|
101
|
-
const
|
|
102
|
-
...
|
|
103
|
-
|
|
242
|
+
const wireWithSession: PikkuWire = {
|
|
243
|
+
...resolvedWire,
|
|
244
|
+
...functionWireProps,
|
|
104
245
|
}
|
|
105
246
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
247
|
+
const session = wireWithSession.session
|
|
248
|
+
|
|
249
|
+
if (funcMeta.sessionless) {
|
|
250
|
+
if (wiringAuth === true || funcConfig.auth === true) {
|
|
251
|
+
if (!session) {
|
|
252
|
+
throw new ForbiddenError('Authentication required')
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
} else if (funcMeta.sessionless === false) {
|
|
256
|
+
if (wiringAuth === false || funcConfig.auth === false) {
|
|
257
|
+
resolvedSingletonServices.logger.warn(
|
|
258
|
+
`Function '${funcName}' requires a session but auth was explicitly disabled — use pikkuSessionlessFunc instead.`
|
|
259
|
+
)
|
|
260
|
+
} else if (!session) {
|
|
109
261
|
throw new ForbiddenError('Authentication required')
|
|
110
262
|
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
//
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
|
|
263
|
+
} else {
|
|
264
|
+
// TODO: Remove after a couple of releases — backward compat for
|
|
265
|
+
// generated metadata that doesn't include the `sessionless` field yet.
|
|
266
|
+
if (wiringAuth === true || funcConfig.auth === true) {
|
|
267
|
+
if (!session) {
|
|
268
|
+
throw new ForbiddenError('Authentication required')
|
|
269
|
+
}
|
|
117
270
|
}
|
|
118
271
|
}
|
|
119
272
|
|
|
@@ -125,14 +278,15 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
125
278
|
if (inputSchemaName) {
|
|
126
279
|
// Validate request data against the defined schema, if any
|
|
127
280
|
await validateSchema(
|
|
128
|
-
|
|
129
|
-
|
|
281
|
+
resolvedSingletonServices.logger,
|
|
282
|
+
resolvedSingletonServices.schema,
|
|
130
283
|
inputSchemaName,
|
|
131
|
-
actualData
|
|
284
|
+
actualData,
|
|
285
|
+
packageName
|
|
132
286
|
)
|
|
133
287
|
// Coerce (top level) query string parameters or date objects if specified by the schema
|
|
134
288
|
if (coerceDataFromSchema) {
|
|
135
|
-
coerceTopLevelDataFromSchema(inputSchemaName, actualData)
|
|
289
|
+
coerceTopLevelDataFromSchema(inputSchemaName, actualData, packageName)
|
|
136
290
|
}
|
|
137
291
|
}
|
|
138
292
|
|
|
@@ -141,28 +295,28 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
141
295
|
wirePermissions: wirePermissions,
|
|
142
296
|
funcInheritedPermissions: funcMeta.permissions,
|
|
143
297
|
funcPermissions: funcConfig.permissions,
|
|
144
|
-
services:
|
|
145
|
-
wire: { ...
|
|
298
|
+
services: resolvedSingletonServices,
|
|
299
|
+
wire: { ...wireWithSession, rpc: undefined } as any,
|
|
146
300
|
data: actualData,
|
|
301
|
+
packageName,
|
|
147
302
|
})
|
|
148
303
|
|
|
149
|
-
const wireServices = await
|
|
150
|
-
|
|
151
|
-
|
|
304
|
+
const wireServices = await resolvedCreateWireServices?.(
|
|
305
|
+
resolvedSingletonServices,
|
|
306
|
+
wireWithSession
|
|
152
307
|
)
|
|
153
308
|
try {
|
|
154
|
-
const services = { ...
|
|
155
|
-
const rpc = rpcService.getContextRPCService(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
)
|
|
309
|
+
const services = { ...resolvedSingletonServices, ...wireServices }
|
|
310
|
+
const rpc = rpcService.getContextRPCService(services, wireWithSession, {
|
|
311
|
+
sessionService,
|
|
312
|
+
})
|
|
159
313
|
return await funcConfig.func(services, actualData, {
|
|
160
|
-
...
|
|
314
|
+
...wireWithSession,
|
|
161
315
|
rpc,
|
|
162
316
|
})
|
|
163
317
|
} finally {
|
|
164
318
|
if (wireServices) {
|
|
165
|
-
await closeWireServices(
|
|
319
|
+
await closeWireServices(resolvedSingletonServices.logger, wireServices)
|
|
166
320
|
}
|
|
167
321
|
}
|
|
168
322
|
}
|
|
@@ -172,12 +326,13 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
172
326
|
wireMiddleware,
|
|
173
327
|
funcInheritedMiddleware: funcMeta.middleware,
|
|
174
328
|
funcMiddleware: funcConfig.middleware,
|
|
329
|
+
packageName,
|
|
175
330
|
})
|
|
176
331
|
|
|
177
332
|
if (allMiddleware.length > 0) {
|
|
178
333
|
return (await runMiddleware<CorePikkuMiddleware>(
|
|
179
|
-
|
|
180
|
-
|
|
334
|
+
resolvedSingletonServices,
|
|
335
|
+
resolvedWire,
|
|
181
336
|
allMiddleware,
|
|
182
337
|
executeFunction
|
|
183
338
|
)) as Out
|
|
@@ -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,
|
|
@@ -108,8 +117,8 @@ 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
|
* )
|
|
@@ -118,8 +127,8 @@ export type CorePikkuPermissionConfig<
|
|
|
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,14 +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
232
|
export type CorePikkuFunctionConfig<
|
|
193
233
|
PikkuFunction extends
|
|
194
|
-
| CorePikkuFunction<any, any, any, any>
|
|
195
|
-
| CorePikkuFunctionSessionless<any, any, any, any>,
|
|
234
|
+
| CorePikkuFunction<any, any, any, any, any>
|
|
235
|
+
| CorePikkuFunctionSessionless<any, any, any, any, any>,
|
|
196
236
|
PikkuPermission extends CorePikkuPermission<
|
|
197
237
|
any,
|
|
198
238
|
any,
|
|
@@ -202,13 +242,25 @@ export type CorePikkuFunctionConfig<
|
|
|
202
242
|
any,
|
|
203
243
|
any
|
|
204
244
|
>,
|
|
245
|
+
InputSchema extends StandardSchemaV1 | undefined = undefined,
|
|
246
|
+
OutputSchema extends StandardSchemaV1 | undefined = undefined,
|
|
205
247
|
> = {
|
|
206
|
-
|
|
248
|
+
/** Optional human-readable title for the function */
|
|
249
|
+
title?: string
|
|
250
|
+
/** Optional description of what the function does */
|
|
251
|
+
description?: string
|
|
252
|
+
override?: string
|
|
253
|
+
version?: number
|
|
207
254
|
tags?: string[]
|
|
208
255
|
expose?: boolean
|
|
209
|
-
|
|
256
|
+
remote?: boolean
|
|
257
|
+
mcp?: boolean
|
|
258
|
+
requiresApproval?: boolean
|
|
210
259
|
func: PikkuFunction
|
|
211
260
|
auth?: boolean
|
|
212
261
|
permissions?: CorePermissionGroup<PikkuPermission>
|
|
213
262
|
middleware?: PikkuMiddleware[]
|
|
263
|
+
input?: InputSchema
|
|
264
|
+
output?: OutputSchema
|
|
265
|
+
node?: CoreNodeConfig
|
|
214
266
|
}
|
package/src/function/index.ts
CHANGED
package/src/handle-error.ts
CHANGED
|
@@ -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
|
}
|