@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
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { execFileSync } from 'child_process'
|
|
2
|
+
import { SecretService } from './secret-service.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Service for retrieving secrets from gopass.
|
|
6
|
+
* Requires gopass to be installed and configured on the system.
|
|
7
|
+
*/
|
|
8
|
+
export class GopassSecretService implements SecretService {
|
|
9
|
+
/**
|
|
10
|
+
* Creates an instance of GopassSecretService.
|
|
11
|
+
* @param prefix - Optional prefix for all secret keys (e.g., 'pikku/' will look up 'pikku/mykey' for key 'mykey')
|
|
12
|
+
*/
|
|
13
|
+
constructor(private prefix: string = '') {}
|
|
14
|
+
|
|
15
|
+
private getFullKey(key: string): string {
|
|
16
|
+
return this.prefix ? `${this.prefix}${key}` : key
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves a secret by key and parses it as JSON.
|
|
21
|
+
* @param key - The key of the secret to retrieve.
|
|
22
|
+
* @returns A promise that resolves to the parsed secret value.
|
|
23
|
+
* @throws {Error} If the secret is not found or gopass fails.
|
|
24
|
+
*/
|
|
25
|
+
public async getSecretJSON<R>(key: string): Promise<R> {
|
|
26
|
+
const value = await this.getSecret(key)
|
|
27
|
+
return JSON.parse(value)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Retrieves a secret by key as a string.
|
|
32
|
+
* @param key - The key of the secret to retrieve.
|
|
33
|
+
* @returns A promise that resolves to the secret value.
|
|
34
|
+
* @throws {Error} If the secret is not found or gopass fails.
|
|
35
|
+
*/
|
|
36
|
+
public async getSecret(key: string): Promise<string> {
|
|
37
|
+
const fullKey = this.getFullKey(key)
|
|
38
|
+
try {
|
|
39
|
+
return execFileSync('gopass', ['show', '-o', fullKey], {
|
|
40
|
+
encoding: 'utf8',
|
|
41
|
+
}).trim()
|
|
42
|
+
} catch (error: any) {
|
|
43
|
+
throw new Error(`Secret Not Found: ${key}`, { cause: error })
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Checks if a secret exists without throwing.
|
|
49
|
+
* @param key - The key of the secret to check.
|
|
50
|
+
* @returns A promise that resolves to true if the secret exists.
|
|
51
|
+
*/
|
|
52
|
+
public async hasSecret(key: string): Promise<boolean> {
|
|
53
|
+
const fullKey = this.getFullKey(key)
|
|
54
|
+
try {
|
|
55
|
+
execFileSync('gopass', ['show', '-o', fullKey], { encoding: 'utf8' })
|
|
56
|
+
return true
|
|
57
|
+
} catch {
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Stores a JSON value as a secret in gopass.
|
|
64
|
+
* @param key - The key to store the secret under.
|
|
65
|
+
* @param value - The JSON value to store.
|
|
66
|
+
* @returns A promise that resolves when the secret is stored.
|
|
67
|
+
*/
|
|
68
|
+
public async setSecretJSON(key: string, value: unknown): Promise<void> {
|
|
69
|
+
const fullKey = this.getFullKey(key)
|
|
70
|
+
const jsonValue = JSON.stringify(value)
|
|
71
|
+
try {
|
|
72
|
+
execFileSync('gopass', ['insert', '-f', fullKey], {
|
|
73
|
+
encoding: 'utf8',
|
|
74
|
+
input: jsonValue,
|
|
75
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
76
|
+
})
|
|
77
|
+
} catch (error: any) {
|
|
78
|
+
throw new Error(`Failed to set secret: ${key}`, { cause: error })
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Deletes a secret from gopass.
|
|
84
|
+
* @param key - The key of the secret to delete.
|
|
85
|
+
* @returns A promise that resolves when the secret is deleted.
|
|
86
|
+
*/
|
|
87
|
+
public async deleteSecret(key: string): Promise<void> {
|
|
88
|
+
const fullKey = this.getFullKey(key)
|
|
89
|
+
try {
|
|
90
|
+
execFileSync('gopass', ['rm', '-f', fullKey], { encoding: 'utf8' })
|
|
91
|
+
} catch {
|
|
92
|
+
// Ignore errors if secret doesn't exist
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { PikkuTriggerService } from '../wirings/trigger/pikku-trigger-service.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* In-memory TriggerService implementation.
|
|
5
|
+
*
|
|
6
|
+
* Reads both `wireTrigger` declarations and `wireTriggerSource` registrations
|
|
7
|
+
* from pikkuState. Only starts triggers that have both a declaration and a source.
|
|
8
|
+
* On fire, invokes target via `ContextAwareRPCService`.
|
|
9
|
+
*
|
|
10
|
+
* Single owner — one process runs triggers, no distributed claiming.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const triggerService = new InMemoryTriggerService()
|
|
15
|
+
* triggerService.setServices(singletonServices, createWireServices)
|
|
16
|
+
* await triggerService.start()
|
|
17
|
+
*
|
|
18
|
+
* // On shutdown
|
|
19
|
+
* await triggerService.stop()
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class InMemoryTriggerService extends PikkuTriggerService {
|
|
23
|
+
async start(): Promise<void> {
|
|
24
|
+
if (!this.singletonServices) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
'InMemoryTriggerService requires singletonServices to start triggers'
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const triggerTargets = this.getTriggerTargets()
|
|
31
|
+
const triggerSources = this.getTriggerSources()
|
|
32
|
+
|
|
33
|
+
for (const [name, source] of triggerSources) {
|
|
34
|
+
if (this.activeTriggers.has(name)) {
|
|
35
|
+
continue
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const targets = triggerTargets.get(name)
|
|
39
|
+
if (!targets || targets.length === 0) {
|
|
40
|
+
this.singletonServices.logger.info(
|
|
41
|
+
`Trigger source '${name}' has no targets, skipping`
|
|
42
|
+
)
|
|
43
|
+
continue
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const triggerInstance = await this.setupTriggerInstance(
|
|
48
|
+
name,
|
|
49
|
+
source.input,
|
|
50
|
+
(data) => this.onTriggerFire(name, targets, data)
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
this.activeTriggers.set(name, triggerInstance)
|
|
54
|
+
this.singletonServices.logger.info(`Started trigger: ${name}`)
|
|
55
|
+
} catch (error) {
|
|
56
|
+
this.singletonServices.logger.error(
|
|
57
|
+
`Failed to start trigger ${name}: ${error}`
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (this.activeTriggers.size === 0) {
|
|
63
|
+
this.singletonServices.logger.info(
|
|
64
|
+
'No triggers started (no matching sources and targets found)'
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto'
|
|
2
|
+
import { PikkuWorkflowService } from '../wirings/workflow/pikku-workflow-service.js'
|
|
3
|
+
import type { SerializedError } from '../types/core.types.js'
|
|
4
|
+
import type {
|
|
5
|
+
WorkflowRun,
|
|
6
|
+
WorkflowRunWire,
|
|
7
|
+
StepState,
|
|
8
|
+
WorkflowStatus,
|
|
9
|
+
WorkflowStepOptions,
|
|
10
|
+
} from '../wirings/workflow/workflow.types.js'
|
|
11
|
+
|
|
12
|
+
interface InternalStepData {
|
|
13
|
+
rpcName: string | null
|
|
14
|
+
data: any
|
|
15
|
+
stepName: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* In-memory implementation of WorkflowService for inline-only execution
|
|
20
|
+
*
|
|
21
|
+
* This is a lightweight workflow service that stores all state in memory.
|
|
22
|
+
* It only supports inline execution (no queue workers) and is ideal for:
|
|
23
|
+
* - CLI tools that need workflow-like step orchestration
|
|
24
|
+
* - Testing and development
|
|
25
|
+
* - Single-process applications without persistence requirements
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const workflowService = new InMemoryWorkflowService()
|
|
30
|
+
* await workflowService.startWorkflow('myWorkflow', input, { type: 'cli' }, rpc, { inline: true })
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class InMemoryWorkflowService extends PikkuWorkflowService {
|
|
34
|
+
private runs = new Map<string, WorkflowRun>()
|
|
35
|
+
private steps = new Map<string, StepState>() // keyed by `${runId}:${stepName}`
|
|
36
|
+
private stepData = new Map<string, InternalStepData>() // keyed by stepId
|
|
37
|
+
private stepHistory = new Map<
|
|
38
|
+
string,
|
|
39
|
+
Array<StepState & { stepName: string }>
|
|
40
|
+
>() // keyed by runId
|
|
41
|
+
private runState = new Map<string, Record<string, unknown>>() // keyed by runId
|
|
42
|
+
private branchKeys = new Map<string, string>() // keyed by stepId
|
|
43
|
+
private workflowVersions = new Map<string, { graph: any; source: string }>() // keyed by `${name}:${graphHash}`
|
|
44
|
+
|
|
45
|
+
async createRun(
|
|
46
|
+
workflowName: string,
|
|
47
|
+
input: any,
|
|
48
|
+
inline: boolean,
|
|
49
|
+
graphHash: string,
|
|
50
|
+
wire: WorkflowRunWire
|
|
51
|
+
): Promise<string> {
|
|
52
|
+
const runId = randomUUID()
|
|
53
|
+
const now = new Date()
|
|
54
|
+
|
|
55
|
+
const run: WorkflowRun = {
|
|
56
|
+
id: runId,
|
|
57
|
+
workflow: workflowName,
|
|
58
|
+
status: 'running',
|
|
59
|
+
input,
|
|
60
|
+
inline,
|
|
61
|
+
graphHash,
|
|
62
|
+
wire,
|
|
63
|
+
createdAt: now,
|
|
64
|
+
updatedAt: now,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this.runs.set(runId, run)
|
|
68
|
+
this.stepHistory.set(runId, [])
|
|
69
|
+
this.runState.set(runId, {})
|
|
70
|
+
|
|
71
|
+
if (inline) {
|
|
72
|
+
this.registerInlineRun(runId)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return runId
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async getRun(id: string): Promise<WorkflowRun | null> {
|
|
79
|
+
return this.runs.get(id) || null
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async getRunHistory(
|
|
83
|
+
runId: string
|
|
84
|
+
): Promise<Array<StepState & { stepName: string }>> {
|
|
85
|
+
return this.stepHistory.get(runId) || []
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async updateRunStatus(
|
|
89
|
+
id: string,
|
|
90
|
+
status: WorkflowStatus,
|
|
91
|
+
output?: any,
|
|
92
|
+
error?: SerializedError
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
const run = this.runs.get(id)
|
|
95
|
+
if (run) {
|
|
96
|
+
run.status = status
|
|
97
|
+
run.updatedAt = new Date()
|
|
98
|
+
if (output !== undefined) run.output = output
|
|
99
|
+
if (error !== undefined) run.error = error
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async insertStepState(
|
|
104
|
+
runId: string,
|
|
105
|
+
stepName: string,
|
|
106
|
+
rpcName: string | null,
|
|
107
|
+
data: any,
|
|
108
|
+
stepOptions?: WorkflowStepOptions
|
|
109
|
+
): Promise<StepState> {
|
|
110
|
+
const stepId = randomUUID()
|
|
111
|
+
const now = new Date()
|
|
112
|
+
|
|
113
|
+
const step: StepState = {
|
|
114
|
+
stepId,
|
|
115
|
+
status: 'pending',
|
|
116
|
+
attemptCount: 1,
|
|
117
|
+
retries: stepOptions?.retries,
|
|
118
|
+
retryDelay: stepOptions?.retryDelay,
|
|
119
|
+
createdAt: now,
|
|
120
|
+
updatedAt: now,
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const key = `${runId}:${stepName}`
|
|
124
|
+
this.steps.set(key, step)
|
|
125
|
+
this.stepData.set(stepId, { rpcName, data, stepName })
|
|
126
|
+
|
|
127
|
+
// Add to history
|
|
128
|
+
const history = this.stepHistory.get(runId) || []
|
|
129
|
+
history.push({ ...step, stepName })
|
|
130
|
+
this.stepHistory.set(runId, history)
|
|
131
|
+
|
|
132
|
+
return step
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async getStepState(runId: string, stepName: string): Promise<StepState> {
|
|
136
|
+
const key = `${runId}:${stepName}`
|
|
137
|
+
const step = this.steps.get(key)
|
|
138
|
+
if (!step) {
|
|
139
|
+
return {
|
|
140
|
+
stepId: '',
|
|
141
|
+
status: 'pending',
|
|
142
|
+
attemptCount: 0,
|
|
143
|
+
createdAt: new Date(),
|
|
144
|
+
updatedAt: new Date(),
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return step
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async setStepRunning(stepId: string): Promise<void> {
|
|
151
|
+
for (const step of this.steps.values()) {
|
|
152
|
+
if (step.stepId === stepId) {
|
|
153
|
+
step.status = 'running'
|
|
154
|
+
step.runningAt = new Date()
|
|
155
|
+
step.updatedAt = new Date()
|
|
156
|
+
break
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async setStepScheduled(stepId: string): Promise<void> {
|
|
162
|
+
for (const step of this.steps.values()) {
|
|
163
|
+
if (step.stepId === stepId) {
|
|
164
|
+
step.status = 'scheduled'
|
|
165
|
+
step.scheduledAt = new Date()
|
|
166
|
+
step.updatedAt = new Date()
|
|
167
|
+
break
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async setStepResult(stepId: string, result: any): Promise<void> {
|
|
173
|
+
for (const step of this.steps.values()) {
|
|
174
|
+
if (step.stepId === stepId) {
|
|
175
|
+
step.status = 'succeeded'
|
|
176
|
+
step.result = result
|
|
177
|
+
step.succeededAt = new Date()
|
|
178
|
+
step.updatedAt = new Date()
|
|
179
|
+
break
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async setStepError(stepId: string, error: Error): Promise<void> {
|
|
185
|
+
for (const step of this.steps.values()) {
|
|
186
|
+
if (step.stepId === stepId) {
|
|
187
|
+
step.status = 'failed'
|
|
188
|
+
step.error = {
|
|
189
|
+
name: error.name,
|
|
190
|
+
message: error.message,
|
|
191
|
+
stack: error.stack,
|
|
192
|
+
}
|
|
193
|
+
step.failedAt = new Date()
|
|
194
|
+
step.updatedAt = new Date()
|
|
195
|
+
break
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async createRetryAttempt(
|
|
201
|
+
failedStepId: string,
|
|
202
|
+
status: 'pending' | 'running'
|
|
203
|
+
): Promise<StepState> {
|
|
204
|
+
// Find the failed step
|
|
205
|
+
let failedStep: StepState | undefined
|
|
206
|
+
let runId: string | undefined
|
|
207
|
+
let stepName: string | undefined
|
|
208
|
+
|
|
209
|
+
for (const [key, step] of this.steps.entries()) {
|
|
210
|
+
if (step.stepId === failedStepId) {
|
|
211
|
+
failedStep = step
|
|
212
|
+
const parts = key.split(':')
|
|
213
|
+
runId = parts[0]
|
|
214
|
+
stepName = parts.slice(1).join(':')
|
|
215
|
+
break
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!failedStep || !runId || !stepName) {
|
|
220
|
+
throw new Error(`Step not found: ${failedStepId}`)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const failedStepData = this.stepData.get(failedStepId)
|
|
224
|
+
const newStepId = randomUUID()
|
|
225
|
+
const now = new Date()
|
|
226
|
+
|
|
227
|
+
const newStep: StepState = {
|
|
228
|
+
stepId: newStepId,
|
|
229
|
+
status,
|
|
230
|
+
attemptCount: failedStep.attemptCount + 1,
|
|
231
|
+
retries: failedStep.retries,
|
|
232
|
+
retryDelay: failedStep.retryDelay,
|
|
233
|
+
createdAt: now,
|
|
234
|
+
updatedAt: now,
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (status === 'running') {
|
|
238
|
+
newStep.runningAt = now
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const key = `${runId}:${stepName}`
|
|
242
|
+
this.steps.set(key, newStep)
|
|
243
|
+
|
|
244
|
+
// Copy step data to new step
|
|
245
|
+
if (failedStepData) {
|
|
246
|
+
this.stepData.set(newStepId, { ...failedStepData })
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Add to history
|
|
250
|
+
const history = this.stepHistory.get(runId) || []
|
|
251
|
+
history.push({ ...newStep, stepName })
|
|
252
|
+
this.stepHistory.set(runId, history)
|
|
253
|
+
|
|
254
|
+
return newStep
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async withRunLock<T>(_id: string, fn: () => Promise<T>): Promise<T> {
|
|
258
|
+
// In-memory service doesn't need locking for inline execution
|
|
259
|
+
return fn()
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async withStepLock<T>(
|
|
263
|
+
_runId: string,
|
|
264
|
+
_stepName: string,
|
|
265
|
+
fn: () => Promise<T>
|
|
266
|
+
): Promise<T> {
|
|
267
|
+
// In-memory service doesn't need locking for inline execution
|
|
268
|
+
return fn()
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async close(): Promise<void> {
|
|
272
|
+
// Clear all in-memory state
|
|
273
|
+
this.runs.clear()
|
|
274
|
+
this.steps.clear()
|
|
275
|
+
this.stepData.clear()
|
|
276
|
+
this.stepHistory.clear()
|
|
277
|
+
this.runState.clear()
|
|
278
|
+
this.branchKeys.clear()
|
|
279
|
+
this.workflowVersions.clear()
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Graph workflow methods
|
|
283
|
+
|
|
284
|
+
async getCompletedGraphState(runId: string): Promise<{
|
|
285
|
+
completedNodeIds: string[]
|
|
286
|
+
failedNodeIds: string[]
|
|
287
|
+
branchKeys: Record<string, string>
|
|
288
|
+
}> {
|
|
289
|
+
const completedNodeIds: string[] = []
|
|
290
|
+
const failedNodeIds: string[] = []
|
|
291
|
+
const prefix = `${runId}:`
|
|
292
|
+
for (const [key, step] of this.steps.entries()) {
|
|
293
|
+
if (!key.startsWith(prefix)) continue
|
|
294
|
+
const nodeId = key.substring(prefix.length)
|
|
295
|
+
if (step.status === 'succeeded') {
|
|
296
|
+
completedNodeIds.push(nodeId)
|
|
297
|
+
} else if (step.status === 'failed') {
|
|
298
|
+
const maxAttempts = (step.retries ?? 0) + 1
|
|
299
|
+
if (step.attemptCount >= maxAttempts) {
|
|
300
|
+
failedNodeIds.push(nodeId)
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const branchKeys: Record<string, string> = {}
|
|
306
|
+
for (const [stepId, branchKey] of this.branchKeys.entries()) {
|
|
307
|
+
const stepData = this.stepData.get(stepId)
|
|
308
|
+
if (stepData) {
|
|
309
|
+
branchKeys[stepData.stepName] = branchKey
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return { completedNodeIds, failedNodeIds, branchKeys }
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
async getNodesWithoutSteps(
|
|
317
|
+
runId: string,
|
|
318
|
+
nodeIds: string[]
|
|
319
|
+
): Promise<string[]> {
|
|
320
|
+
const existingSteps = new Set<string>()
|
|
321
|
+
const prefix = `${runId}:`
|
|
322
|
+
for (const [key] of this.steps.entries()) {
|
|
323
|
+
if (key.startsWith(prefix)) {
|
|
324
|
+
existingSteps.add(key.substring(prefix.length))
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return nodeIds.filter((id) => !existingSteps.has(id))
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async getNodeResults(
|
|
331
|
+
runId: string,
|
|
332
|
+
nodeIds: string[]
|
|
333
|
+
): Promise<Record<string, any>> {
|
|
334
|
+
const results: Record<string, any> = {}
|
|
335
|
+
for (const nodeId of nodeIds) {
|
|
336
|
+
const key = `${runId}:${nodeId}`
|
|
337
|
+
const step = this.steps.get(key)
|
|
338
|
+
if (step?.result !== undefined) {
|
|
339
|
+
results[nodeId] = step.result
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return results
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async setBranchKey(
|
|
346
|
+
runId: string,
|
|
347
|
+
nodeId: string,
|
|
348
|
+
branchKey: string
|
|
349
|
+
): Promise<void> {
|
|
350
|
+
const key = `${runId}:${nodeId}`
|
|
351
|
+
const step = this.steps.get(key)
|
|
352
|
+
if (step) {
|
|
353
|
+
this.branchKeys.set(step.stepId, branchKey)
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async setBranchTaken(stepId: string, branchKey: string): Promise<void> {
|
|
358
|
+
this.branchKeys.set(stepId, branchKey)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
async updateRunState(
|
|
362
|
+
runId: string,
|
|
363
|
+
name: string,
|
|
364
|
+
value: unknown
|
|
365
|
+
): Promise<void> {
|
|
366
|
+
const state = this.runState.get(runId) || {}
|
|
367
|
+
state[name] = value
|
|
368
|
+
this.runState.set(runId, state)
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
async getRunState(runId: string): Promise<Record<string, unknown>> {
|
|
372
|
+
return this.runState.get(runId) || {}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
async upsertWorkflowVersion(
|
|
376
|
+
name: string,
|
|
377
|
+
graphHash: string,
|
|
378
|
+
graph: any,
|
|
379
|
+
source: string
|
|
380
|
+
): Promise<void> {
|
|
381
|
+
this.workflowVersions.set(`${name}:${graphHash}`, {
|
|
382
|
+
graph,
|
|
383
|
+
source,
|
|
384
|
+
})
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async getWorkflowVersion(
|
|
388
|
+
name: string,
|
|
389
|
+
graphHash: string
|
|
390
|
+
): Promise<{ graph: any; source: string } | null> {
|
|
391
|
+
const version = this.workflowVersions.get(`${name}:${graphHash}`)
|
|
392
|
+
if (!version) return null
|
|
393
|
+
return { graph: version.graph, source: version.source }
|
|
394
|
+
}
|
|
395
|
+
}
|
package/src/services/index.ts
CHANGED
|
@@ -2,17 +2,52 @@
|
|
|
2
2
|
* @module @pikku/core
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export
|
|
17
|
-
export
|
|
18
|
-
export
|
|
5
|
+
export { LogLevel } from './logger.js'
|
|
6
|
+
export { ScopedSecretService } from './scoped-secret-service.js'
|
|
7
|
+
export {
|
|
8
|
+
PikkuSessionService,
|
|
9
|
+
createMiddlewareSessionWireProps,
|
|
10
|
+
createFunctionSessionWireProps,
|
|
11
|
+
} from './user-session-service.js'
|
|
12
|
+
export { TypedSecretService } from './typed-secret-service.js'
|
|
13
|
+
export { TypedVariablesService } from './typed-variables-service.js'
|
|
14
|
+
export { LocalSecretService } from './local-secrets.js'
|
|
15
|
+
export { LocalVariablesService } from './local-variables.js'
|
|
16
|
+
export { ConsoleLogger } from './logger-console.js'
|
|
17
|
+
export { InMemoryWorkflowService } from './in-memory-workflow-service.js'
|
|
18
|
+
export { InMemoryTriggerService } from './in-memory-trigger-service.js'
|
|
19
|
+
export type { ContentService } from './content-service.js'
|
|
20
|
+
export type { JWTService } from './jwt-service.js'
|
|
21
|
+
export type { Logger } from './logger.js'
|
|
22
|
+
export type { SecretService } from './secret-service.js'
|
|
23
|
+
export type { VariablesService } from './variables-service.js'
|
|
24
|
+
export type { SchemaService } from './schema-service.js'
|
|
25
|
+
export type { SessionService } from './user-session-service.js'
|
|
26
|
+
export type {
|
|
27
|
+
ScheduledTaskSummary,
|
|
28
|
+
ScheduledTaskInfo,
|
|
29
|
+
SchedulerRuntimeHandlers,
|
|
30
|
+
SchedulerService,
|
|
31
|
+
} from './scheduler-service.js'
|
|
32
|
+
export type { TriggerService } from './trigger-service.js'
|
|
33
|
+
export type {
|
|
34
|
+
DeploymentService,
|
|
35
|
+
DeploymentConfig,
|
|
36
|
+
DeploymentInfo,
|
|
37
|
+
DeploymentServiceConfig,
|
|
38
|
+
} from './deployment-service.js'
|
|
39
|
+
export type { AIStorageService } from './ai-storage-service.js'
|
|
40
|
+
export type {
|
|
41
|
+
AIAgentRunnerParams,
|
|
42
|
+
AIAgentRunnerResult,
|
|
43
|
+
AIAgentRunnerService,
|
|
44
|
+
} from './ai-agent-runner-service.js'
|
|
45
|
+
export type {
|
|
46
|
+
CreateRunInput,
|
|
47
|
+
AIRunStateService,
|
|
48
|
+
} from './ai-run-state-service.js'
|
|
49
|
+
export type {
|
|
50
|
+
CredentialStatus,
|
|
51
|
+
CredentialMeta,
|
|
52
|
+
} from './typed-secret-service.js'
|
|
53
|
+
export type { VariableStatus, VariableMeta } from './typed-variables-service.js'
|
|
@@ -4,8 +4,11 @@ import { VariablesService } from './variables-service.js'
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Service for retrieving secrets from environment variables.
|
|
7
|
+
* Supports storing secrets locally in memory for CLI operations.
|
|
7
8
|
*/
|
|
8
9
|
export class LocalSecretService implements SecretService {
|
|
10
|
+
private localSecrets: Map<string, string> = new Map()
|
|
11
|
+
|
|
9
12
|
/**
|
|
10
13
|
* Creates an instance of LocalSecretService.
|
|
11
14
|
*/
|
|
@@ -15,11 +18,19 @@ export class LocalSecretService implements SecretService {
|
|
|
15
18
|
|
|
16
19
|
/**
|
|
17
20
|
* Retrieves a secret by key.
|
|
21
|
+
* Checks local storage first, then falls back to environment variables.
|
|
18
22
|
* @param key - The key of the secret to retrieve.
|
|
19
23
|
* @returns A promise that resolves to the secret value.
|
|
20
24
|
* @throws {Error} If the secret is not found.
|
|
21
25
|
*/
|
|
22
26
|
public async getSecretJSON<R>(key: string): Promise<R> {
|
|
27
|
+
// Check local storage first
|
|
28
|
+
const localValue = this.localSecrets.get(key)
|
|
29
|
+
if (localValue) {
|
|
30
|
+
return JSON.parse(localValue)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Fall back to environment variables
|
|
23
34
|
const value = await this.variables.get(key)
|
|
24
35
|
if (value) {
|
|
25
36
|
return JSON.parse(value)
|
|
@@ -29,15 +40,55 @@ export class LocalSecretService implements SecretService {
|
|
|
29
40
|
|
|
30
41
|
/**
|
|
31
42
|
* Retrieves a secret by key.
|
|
43
|
+
* Checks local storage first, then falls back to environment variables.
|
|
32
44
|
* @param key - The key of the secret to retrieve.
|
|
33
45
|
* @returns A promise that resolves to the secret value.
|
|
34
46
|
* @throws {Error} If the secret is not found.
|
|
35
47
|
*/
|
|
36
48
|
public async getSecret(key: string): Promise<string> {
|
|
49
|
+
// Check local storage first
|
|
50
|
+
const localValue = this.localSecrets.get(key)
|
|
51
|
+
if (localValue) {
|
|
52
|
+
return localValue
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Fall back to environment variables
|
|
37
56
|
const value = await this.variables.get(key)
|
|
38
57
|
if (value) {
|
|
39
58
|
return value
|
|
40
59
|
}
|
|
41
60
|
throw new Error(`Secret Not Found: ${key}`)
|
|
42
61
|
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Stores a JSON value as a secret in local storage.
|
|
65
|
+
* @param key - The key to store the secret under.
|
|
66
|
+
* @param value - The JSON value to store.
|
|
67
|
+
* @returns A promise that resolves when the secret is stored.
|
|
68
|
+
*/
|
|
69
|
+
public async setSecretJSON(key: string, value: unknown): Promise<void> {
|
|
70
|
+
this.localSecrets.set(key, JSON.stringify(value))
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Checks if a secret exists without throwing.
|
|
75
|
+
* @param key - The key of the secret to check.
|
|
76
|
+
* @returns A promise that resolves to true if the secret exists.
|
|
77
|
+
*/
|
|
78
|
+
public async hasSecret(key: string): Promise<boolean> {
|
|
79
|
+
if (this.localSecrets.has(key)) {
|
|
80
|
+
return true
|
|
81
|
+
}
|
|
82
|
+
const value = await this.variables.get(key)
|
|
83
|
+
return value !== undefined && value !== null && value !== ''
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Deletes a secret from local storage.
|
|
88
|
+
* @param key - The key of the secret to delete.
|
|
89
|
+
* @returns A promise that resolves when the secret is deleted.
|
|
90
|
+
*/
|
|
91
|
+
public async deleteSecret(key: string): Promise<void> {
|
|
92
|
+
this.localSecrets.delete(key)
|
|
93
|
+
}
|
|
43
94
|
}
|