@pikku/core 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/errors/errors.d.ts +6 -0
- package/dist/errors/errors.js +10 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/function/function-runner.d.ts +3 -3
- package/dist/function/function-runner.js +66 -44
- package/dist/function/functions.types.d.ts +1 -0
- package/dist/handle-error.d.ts +2 -2
- package/dist/handle-error.js +2 -2
- package/dist/index.d.ts +5 -3
- package/dist/index.js +2 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.js +2 -0
- package/dist/middleware/auth-bearer.d.ts +1 -1
- package/dist/middleware/auth-bearer.js +1 -1
- package/dist/middleware/auth-cookie.d.ts +2 -2
- package/dist/middleware/auth-cookie.js +1 -1
- package/dist/middleware/cors.d.ts +2 -2
- package/dist/middleware/cors.js +45 -37
- package/dist/middleware-runner.d.ts +1 -1
- package/dist/permissions.d.ts +2 -2
- package/dist/pikku-state.d.ts +9 -8
- package/dist/pikku-state.js +30 -17
- package/dist/schema.d.ts +4 -4
- package/dist/schema.js +9 -5
- package/dist/services/ai-agent-runner-service.d.ts +22 -3
- package/dist/services/ai-run-state-service.d.ts +1 -1
- package/dist/services/ai-storage-service.d.ts +1 -1
- package/dist/services/content-service.d.ts +6 -0
- package/dist/services/gopass-secrets.d.ts +1 -1
- package/dist/services/gopass-secrets.js +3 -0
- package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
- package/dist/services/in-memory-ai-run-state-service.js +44 -0
- package/dist/services/in-memory-trigger-service.d.ts +0 -1
- package/dist/services/in-memory-trigger-service.js +6 -8
- package/dist/services/index.d.ts +3 -2
- package/dist/services/index.js +1 -0
- package/dist/services/local-content.d.ts +2 -1
- package/dist/services/local-content.js +6 -1
- package/dist/services/local-secrets.d.ts +2 -2
- package/dist/services/local-variables.d.ts +1 -1
- package/dist/services/logger-console.d.ts +2 -1
- package/dist/services/scheduler-service.d.ts +0 -12
- package/dist/services/scheduler-service.js +0 -6
- package/dist/services/scoped-secret-service.d.ts +1 -1
- package/dist/services/trigger-service.d.ts +0 -7
- package/dist/services/user-session-service.d.ts +3 -3
- package/dist/services/workflow-service.d.ts +2 -3
- package/dist/types/core.types.d.ts +24 -18
- package/dist/types/state.types.d.ts +17 -15
- package/dist/utils.d.ts +5 -5
- package/dist/utils.js +12 -9
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +146 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +4 -5
- package/dist/wirings/ai-agent/ai-agent-prepare.js +66 -30
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +1 -1
- package/dist/wirings/ai-agent/ai-agent-runner.js +107 -8
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-stream.js +246 -87
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +61 -2
- package/dist/wirings/ai-agent/index.d.ts +3 -1
- package/dist/wirings/ai-agent/index.js +2 -0
- package/dist/wirings/channel/channel-common.d.ts +2 -2
- package/dist/wirings/channel/channel-handler.d.ts +3 -3
- package/dist/wirings/channel/channel-handler.js +4 -4
- package/dist/wirings/channel/channel-runner.d.ts +5 -5
- package/dist/wirings/channel/channel-runner.js +3 -2
- package/dist/wirings/channel/channel-store.d.ts +1 -1
- package/dist/wirings/channel/channel.types.d.ts +4 -6
- package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
- package/dist/wirings/channel/local/local-channel-runner.js +4 -3
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
- package/dist/wirings/channel/log-channels.d.ts +1 -1
- package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +4 -4
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +25 -19
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +2 -2
- package/dist/wirings/cli/cli.types.d.ts +3 -3
- package/dist/wirings/cli/command-parser.d.ts +1 -1
- package/dist/wirings/http/http-runner.d.ts +9 -9
- package/dist/wirings/http/http-runner.js +33 -14
- package/dist/wirings/http/http.types.d.ts +2 -6
- package/dist/wirings/http/log-http-routes.d.ts +1 -1
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
- package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
- package/dist/wirings/http/routers/http-router.d.ts +1 -1
- package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
- package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
- package/dist/wirings/mcp/mcp-runner.d.ts +0 -3
- package/dist/wirings/mcp/mcp-runner.js +4 -2
- package/dist/wirings/mcp/mcp.types.d.ts +2 -2
- package/dist/wirings/oauth2/oauth2-client.d.ts +3 -3
- package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +1 -1
- package/dist/wirings/queue/index.d.ts +1 -1
- package/dist/wirings/queue/index.js +1 -1
- package/dist/wirings/queue/queue-runner.d.ts +1 -12
- package/dist/wirings/queue/queue-runner.js +4 -12
- package/dist/wirings/queue/queue.types.d.ts +3 -9
- package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
- package/dist/wirings/queue/register-queue-helper.js +1 -1
- package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
- package/dist/wirings/rpc/index.d.ts +2 -0
- package/dist/wirings/rpc/index.js +1 -0
- package/dist/wirings/rpc/rpc-runner.d.ts +36 -14
- package/dist/wirings/rpc/rpc-runner.js +56 -28
- package/dist/wirings/rpc/rpc-types.d.ts +14 -2
- package/dist/wirings/rpc/wire-addon.d.ts +10 -0
- package/dist/wirings/rpc/wire-addon.js +9 -0
- package/dist/wirings/scheduler/index.d.ts +1 -1
- package/dist/wirings/scheduler/index.js +1 -1
- package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -10
- package/dist/wirings/scheduler/scheduler-runner.js +4 -25
- package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +2 -6
- package/dist/wirings/trigger/pikku-trigger-service.js +11 -16
- package/dist/wirings/trigger/trigger-runner.d.ts +1 -5
- package/dist/wirings/trigger/trigger-runner.js +4 -3
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -6
- package/dist/wirings/workflow/pikku-workflow-service.js +20 -29
- package/dist/wirings/workflow/workflow.types.d.ts +2 -2
- package/package.json +2 -1
- package/src/crypto-utils.test.ts +116 -0
- package/src/errors/error.test.ts +143 -2
- package/src/errors/errors.ts +10 -0
- package/src/errors/index.ts +1 -0
- package/src/function/function-runner.test.ts +2 -2
- package/src/function/function-runner.ts +72 -49
- package/src/function/functions.types.ts +1 -0
- package/src/handle-error.test.ts +361 -0
- package/src/handle-error.ts +4 -4
- package/src/index.ts +3 -10
- package/src/internal.ts +6 -0
- package/src/middleware/auth-apikey.test.ts +1 -1
- package/src/middleware/auth-bearer.test.ts +1 -1
- package/src/middleware/auth-bearer.ts +2 -5
- package/src/middleware/auth-cookie.test.ts +1 -1
- package/src/middleware/auth-cookie.ts +3 -5
- package/src/middleware/cors.test.ts +424 -0
- package/src/middleware/cors.ts +14 -6
- package/src/middleware/remote-auth.test.ts +488 -0
- package/src/middleware-runner.test.ts +1 -1
- package/src/middleware-runner.ts +1 -1
- package/src/permissions.test.ts +2 -2
- package/src/permissions.ts +2 -2
- package/src/pikku-state.test.ts +224 -0
- package/src/pikku-state.ts +40 -28
- package/src/schema.test.ts +198 -6
- package/src/schema.ts +11 -7
- package/src/services/ai-agent-runner-service.ts +15 -3
- package/src/services/ai-run-state-service.ts +1 -1
- package/src/services/ai-storage-service.ts +1 -1
- package/src/services/content-service.ts +7 -0
- package/src/services/gopass-secrets.ts +4 -1
- package/src/services/in-memory-ai-run-state-service.ts +73 -0
- package/src/services/in-memory-trigger-service.ts +6 -10
- package/src/services/in-memory-workflow-service.test.ts +351 -0
- package/src/services/index.ts +2 -1
- package/src/services/local-content.ts +9 -3
- package/src/services/local-secrets.test.ts +80 -0
- package/src/services/local-secrets.ts +2 -2
- package/src/services/local-variables.test.ts +61 -0
- package/src/services/local-variables.ts +1 -1
- package/src/services/logger-console.test.ts +118 -0
- package/src/services/logger-console.ts +2 -1
- package/src/services/scheduler-service.ts +0 -18
- package/src/services/scoped-secret-service.test.ts +74 -0
- package/src/services/scoped-secret-service.ts +1 -1
- package/src/services/trigger-service.ts +0 -21
- package/src/services/typed-secret-service.test.ts +93 -0
- package/src/services/typed-variables-service.test.ts +73 -0
- package/src/services/user-session-service.test.ts +113 -0
- package/src/services/user-session-service.ts +3 -3
- package/src/services/workflow-service.ts +2 -12
- package/src/time-utils.test.ts +1 -1
- package/src/types/core.types.ts +25 -19
- package/src/types/state.types.ts +24 -15
- package/src/utils.test.ts +350 -0
- package/src/utils.ts +14 -13
- package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
- package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +214 -0
- package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
- package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
- package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +79 -45
- package/src/wirings/ai-agent/ai-agent-registry.ts +1 -1
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +245 -3
- package/src/wirings/ai-agent/ai-agent-runner.ts +121 -7
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +430 -24
- package/src/wirings/ai-agent/ai-agent-stream.ts +377 -102
- package/src/wirings/ai-agent/ai-agent.types.ts +57 -2
- package/src/wirings/ai-agent/index.ts +11 -0
- package/src/wirings/channel/channel-common.ts +2 -2
- package/src/wirings/channel/channel-handler.ts +13 -9
- package/src/wirings/channel/channel-runner.ts +6 -6
- package/src/wirings/channel/channel-store.ts +1 -1
- package/src/wirings/channel/channel.types.ts +4 -8
- package/src/wirings/channel/local/local-channel-runner.test.ts +19 -12
- package/src/wirings/channel/local/local-channel-runner.ts +18 -13
- package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
- package/src/wirings/channel/log-channels.ts +1 -1
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +1 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +37 -32
- package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +1 -1
- package/src/wirings/cli/cli-runner.ts +11 -4
- package/src/wirings/cli/cli.types.ts +3 -3
- package/src/wirings/cli/command-parser.test.ts +1 -1
- package/src/wirings/cli/command-parser.ts +1 -1
- package/src/wirings/http/http-routes.test.ts +1 -1
- package/src/wirings/http/http-runner.test.ts +9 -17
- package/src/wirings/http/http-runner.ts +43 -27
- package/src/wirings/http/http.types.ts +1 -14
- package/src/wirings/http/log-http-routes.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
- package/src/wirings/http/routers/http-router.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.ts +4 -3
- package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
- package/src/wirings/mcp/mcp-runner.ts +9 -15
- package/src/wirings/mcp/mcp.types.ts +2 -2
- package/src/wirings/oauth2/oauth2-client.ts +3 -3
- package/src/wirings/oauth2/wire-oauth2-credential.ts +1 -1
- package/src/wirings/queue/index.ts +0 -1
- package/src/wirings/queue/queue-runner.test.ts +52 -25
- package/src/wirings/queue/queue-runner.ts +8 -30
- package/src/wirings/queue/queue.types.ts +3 -13
- package/src/wirings/queue/register-queue-helper.ts +3 -5
- package/src/wirings/queue/validate-worker-config.test.ts +108 -0
- package/src/wirings/queue/validate-worker-config.ts +4 -1
- package/src/wirings/rpc/index.ts +2 -0
- package/src/wirings/rpc/rpc-runner.ts +92 -49
- package/src/wirings/rpc/rpc-types.ts +17 -2
- package/src/wirings/rpc/wire-addon.ts +20 -0
- package/src/wirings/scheduler/index.ts +0 -1
- package/src/wirings/scheduler/log-schedulers.ts +1 -1
- package/src/wirings/scheduler/scheduler-runner.test.ts +49 -60
- package/src/wirings/scheduler/scheduler-runner.ts +9 -56
- package/src/wirings/scheduler/scheduler.types.ts +2 -2
- package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
- package/src/wirings/trigger/pikku-trigger-service.ts +17 -39
- package/src/wirings/trigger/trigger-runner.test.ts +79 -0
- package/src/wirings/trigger/trigger-runner.ts +8 -11
- package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
- package/src/wirings/workflow/graph/graph-runner.test.ts +14 -22
- package/src/wirings/workflow/graph/template.test.ts +49 -0
- package/src/wirings/workflow/pikku-workflow-service.test.ts +15 -27
- package/src/wirings/workflow/pikku-workflow-service.ts +29 -45
- package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
- package/src/wirings/workflow/workflow.types.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/workflow/workflow-utils.d.ts +0 -1
- package/dist/wirings/workflow/workflow-utils.js +0 -1
- package/src/wirings/workflow/workflow-utils.ts +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { describe, test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { validateAndBuildSecretDefinitionsMeta } from './validate-secret-definitions.js'
|
|
4
|
+
|
|
5
|
+
describe('validateAndBuildSecretDefinitionsMeta', () => {
|
|
6
|
+
test('should build meta from single definition', () => {
|
|
7
|
+
const definitions = [
|
|
8
|
+
{
|
|
9
|
+
name: 'stripe',
|
|
10
|
+
displayName: 'Stripe',
|
|
11
|
+
description: 'API key',
|
|
12
|
+
secretId: 'STRIPE_KEY',
|
|
13
|
+
sourceFile: 'a.ts',
|
|
14
|
+
},
|
|
15
|
+
]
|
|
16
|
+
const result = validateAndBuildSecretDefinitionsMeta(
|
|
17
|
+
definitions as any,
|
|
18
|
+
new Map()
|
|
19
|
+
)
|
|
20
|
+
assert.ok(result['stripe'])
|
|
21
|
+
assert.strictEqual(result['stripe'].secretId, 'STRIPE_KEY')
|
|
22
|
+
assert.strictEqual(result['stripe'].displayName, 'Stripe')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('should allow duplicate secretId with same schema', () => {
|
|
26
|
+
const schemaLookup = new Map([
|
|
27
|
+
['schema1', { variableName: 'Schema', sourceFile: 'types.ts' }],
|
|
28
|
+
])
|
|
29
|
+
const definitions = [
|
|
30
|
+
{
|
|
31
|
+
name: 'cred1',
|
|
32
|
+
displayName: 'Cred 1',
|
|
33
|
+
description: 'd',
|
|
34
|
+
secretId: 'SHARED',
|
|
35
|
+
schema: 'schema1',
|
|
36
|
+
sourceFile: 'a.ts',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'cred2',
|
|
40
|
+
displayName: 'Cred 2',
|
|
41
|
+
description: 'd',
|
|
42
|
+
secretId: 'SHARED',
|
|
43
|
+
schema: 'schema1',
|
|
44
|
+
sourceFile: 'b.ts',
|
|
45
|
+
},
|
|
46
|
+
]
|
|
47
|
+
const result = validateAndBuildSecretDefinitionsMeta(
|
|
48
|
+
definitions as any,
|
|
49
|
+
schemaLookup
|
|
50
|
+
)
|
|
51
|
+
assert.ok(result['cred1'])
|
|
52
|
+
assert.ok(result['cred2'])
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test('should throw when duplicate secretId has different schemas', () => {
|
|
56
|
+
const schemaLookup = new Map([
|
|
57
|
+
['schema1', { variableName: 'SchemaA', sourceFile: 'types.ts' }],
|
|
58
|
+
['schema2', { variableName: 'SchemaB', sourceFile: 'types2.ts' }],
|
|
59
|
+
])
|
|
60
|
+
const definitions = [
|
|
61
|
+
{
|
|
62
|
+
name: 'cred1',
|
|
63
|
+
displayName: 'Cred 1',
|
|
64
|
+
description: 'd',
|
|
65
|
+
secretId: 'SHARED',
|
|
66
|
+
schema: 'schema1',
|
|
67
|
+
sourceFile: 'a.ts',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'cred2',
|
|
71
|
+
displayName: 'Cred 2',
|
|
72
|
+
description: 'd',
|
|
73
|
+
secretId: 'SHARED',
|
|
74
|
+
schema: 'schema2',
|
|
75
|
+
sourceFile: 'b.ts',
|
|
76
|
+
},
|
|
77
|
+
]
|
|
78
|
+
assert.throws(
|
|
79
|
+
() =>
|
|
80
|
+
validateAndBuildSecretDefinitionsMeta(definitions as any, schemaLookup),
|
|
81
|
+
(err: any) => err.message.includes('different schemas')
|
|
82
|
+
)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('should throw when duplicate secretId has different oauth2 configs', () => {
|
|
86
|
+
const definitions = [
|
|
87
|
+
{
|
|
88
|
+
name: 'cred1',
|
|
89
|
+
displayName: 'C1',
|
|
90
|
+
description: 'd',
|
|
91
|
+
secretId: 'OAUTH',
|
|
92
|
+
oauth2: { provider: 'google' },
|
|
93
|
+
sourceFile: 'a.ts',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'cred2',
|
|
97
|
+
displayName: 'C2',
|
|
98
|
+
description: 'd',
|
|
99
|
+
secretId: 'OAUTH',
|
|
100
|
+
oauth2: { provider: 'github' },
|
|
101
|
+
sourceFile: 'b.ts',
|
|
102
|
+
},
|
|
103
|
+
]
|
|
104
|
+
assert.throws(
|
|
105
|
+
() =>
|
|
106
|
+
validateAndBuildSecretDefinitionsMeta(definitions as any, new Map()),
|
|
107
|
+
(err: any) => err.message.includes('different configurations')
|
|
108
|
+
)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
test('should handle empty definitions', () => {
|
|
112
|
+
const result = validateAndBuildSecretDefinitionsMeta([], new Map())
|
|
113
|
+
assert.deepStrictEqual(result, {})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test('should not duplicate names in meta', () => {
|
|
117
|
+
const definitions = [
|
|
118
|
+
{
|
|
119
|
+
name: 'same',
|
|
120
|
+
displayName: 'Same',
|
|
121
|
+
description: 'd',
|
|
122
|
+
secretId: 'KEY1',
|
|
123
|
+
sourceFile: 'a.ts',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: 'same',
|
|
127
|
+
displayName: 'Same',
|
|
128
|
+
description: 'd',
|
|
129
|
+
secretId: 'KEY2',
|
|
130
|
+
sourceFile: 'b.ts',
|
|
131
|
+
},
|
|
132
|
+
]
|
|
133
|
+
const result = validateAndBuildSecretDefinitionsMeta(
|
|
134
|
+
definitions as any,
|
|
135
|
+
new Map()
|
|
136
|
+
)
|
|
137
|
+
assert.ok(result['same'])
|
|
138
|
+
assert.strictEqual(result['same'].secretId, 'KEY1')
|
|
139
|
+
})
|
|
140
|
+
})
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CoreSingletonServices,
|
|
3
|
-
CreateWireServices,
|
|
4
|
-
CoreServices,
|
|
5
|
-
CoreUserSession,
|
|
6
|
-
} from '../../types/core.types.js'
|
|
7
1
|
import { rpcService } from '../rpc/rpc-runner.js'
|
|
8
2
|
import { setupTrigger } from './trigger-runner.js'
|
|
9
|
-
import { TriggerInstance } from './trigger.types.js'
|
|
10
|
-
import { TriggerService } from '../../services/trigger-service.js'
|
|
11
|
-
import {
|
|
3
|
+
import type { TriggerInstance } from './trigger.types.js'
|
|
4
|
+
import type { TriggerService } from '../../services/trigger-service.js'
|
|
5
|
+
import {
|
|
6
|
+
getSingletonServices,
|
|
7
|
+
getCreateWireServices,
|
|
8
|
+
pikkuState,
|
|
9
|
+
} from '../../pikku-state.js'
|
|
12
10
|
|
|
13
11
|
export type TriggerTarget = {
|
|
14
12
|
targetType: 'rpc' | 'workflow'
|
|
@@ -23,34 +21,17 @@ export type TriggerSourceInfo = {
|
|
|
23
21
|
|
|
24
22
|
export abstract class PikkuTriggerService implements TriggerService {
|
|
25
23
|
protected activeTriggers = new Map<string, TriggerInstance>()
|
|
26
|
-
protected singletonServices?: CoreSingletonServices
|
|
27
|
-
protected createWireServices?: CreateWireServices<
|
|
28
|
-
CoreSingletonServices,
|
|
29
|
-
CoreServices,
|
|
30
|
-
CoreUserSession
|
|
31
|
-
>
|
|
32
|
-
|
|
33
|
-
setServices(
|
|
34
|
-
singletonServices: CoreSingletonServices,
|
|
35
|
-
createWireServices?: CreateWireServices<
|
|
36
|
-
CoreSingletonServices,
|
|
37
|
-
CoreServices,
|
|
38
|
-
CoreUserSession
|
|
39
|
-
>
|
|
40
|
-
): void {
|
|
41
|
-
this.singletonServices = singletonServices
|
|
42
|
-
this.createWireServices = createWireServices
|
|
43
|
-
}
|
|
44
24
|
|
|
45
25
|
abstract start(): Promise<void>
|
|
46
26
|
|
|
47
27
|
async stop(): Promise<void> {
|
|
28
|
+
const singletonServices = getSingletonServices()
|
|
48
29
|
for (const [name, instance] of this.activeTriggers) {
|
|
49
30
|
try {
|
|
50
31
|
await instance.teardown()
|
|
51
|
-
|
|
32
|
+
singletonServices.logger.info(`Stopped trigger: ${name}`)
|
|
52
33
|
} catch (error) {
|
|
53
|
-
|
|
34
|
+
singletonServices.logger.error(
|
|
54
35
|
`Error stopping trigger ${name}: ${error}`
|
|
55
36
|
)
|
|
56
37
|
}
|
|
@@ -90,8 +71,6 @@ export abstract class PikkuTriggerService implements TriggerService {
|
|
|
90
71
|
): Promise<TriggerInstance> {
|
|
91
72
|
return setupTrigger({
|
|
92
73
|
name,
|
|
93
|
-
singletonServices: this.singletonServices!,
|
|
94
|
-
createWireServices: this.createWireServices as any,
|
|
95
74
|
input,
|
|
96
75
|
onTrigger,
|
|
97
76
|
})
|
|
@@ -102,11 +81,10 @@ export abstract class PikkuTriggerService implements TriggerService {
|
|
|
102
81
|
targets: TriggerTarget[],
|
|
103
82
|
data: unknown
|
|
104
83
|
): Promise<void> {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const services = { ...this.singletonServices!, ...wireServices }
|
|
84
|
+
const singletonServices = getSingletonServices()
|
|
85
|
+
const createWireServices = getCreateWireServices()
|
|
86
|
+
const wireServices = await createWireServices?.(singletonServices, {})
|
|
87
|
+
const services = { ...singletonServices, ...wireServices }
|
|
110
88
|
const rpc = rpcService.getContextRPCService(services, {}, false)
|
|
111
89
|
|
|
112
90
|
for (const target of targets) {
|
|
@@ -115,17 +93,17 @@ export abstract class PikkuTriggerService implements TriggerService {
|
|
|
115
93
|
await rpc.startWorkflow(target.targetName, data, {
|
|
116
94
|
startNode: target.startNode,
|
|
117
95
|
})
|
|
118
|
-
|
|
96
|
+
singletonServices.logger.info(
|
|
119
97
|
`Trigger '${triggerName}' started workflow '${target.targetName}'`
|
|
120
98
|
)
|
|
121
99
|
} else {
|
|
122
100
|
await rpc.invoke(target.targetName, data)
|
|
123
|
-
|
|
101
|
+
singletonServices.logger.info(
|
|
124
102
|
`Trigger '${triggerName}' invoked RPC '${target.targetName}'`
|
|
125
103
|
)
|
|
126
104
|
}
|
|
127
105
|
} catch (error) {
|
|
128
|
-
|
|
106
|
+
singletonServices.logger.error(
|
|
129
107
|
`Error invoking ${target.targetType} '${target.targetName}' from trigger '${triggerName}': ${error}`
|
|
130
108
|
)
|
|
131
109
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { describe, test, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import {
|
|
4
|
+
wireTrigger,
|
|
5
|
+
wireTriggerSource,
|
|
6
|
+
getRegisteredTriggers,
|
|
7
|
+
getTriggerMeta,
|
|
8
|
+
} from './trigger-runner.js'
|
|
9
|
+
import { resetPikkuState, pikkuState } from '../../pikku-state.js'
|
|
10
|
+
import { PikkuMissingMetaError } from '../../errors/errors.js'
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
resetPikkuState()
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
describe('wireTrigger', () => {
|
|
17
|
+
test('should register a trigger when meta exists', () => {
|
|
18
|
+
const meta = pikkuState(null, 'trigger', 'meta')
|
|
19
|
+
;(meta as any)['myTrigger'] = { pikkuFuncId: 'triggerFunc' }
|
|
20
|
+
|
|
21
|
+
wireTrigger({ name: 'myTrigger', func: async () => {} } as any)
|
|
22
|
+
|
|
23
|
+
const triggers = getRegisteredTriggers()
|
|
24
|
+
assert.ok(triggers.has('myTrigger'))
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('should throw PikkuMissingMetaError when meta is missing', () => {
|
|
28
|
+
assert.throws(
|
|
29
|
+
() => wireTrigger({ name: 'noMeta', func: async () => {} } as any),
|
|
30
|
+
(err: any) => err instanceof PikkuMissingMetaError
|
|
31
|
+
)
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
describe('wireTriggerSource', () => {
|
|
36
|
+
test('should register a trigger source when meta exists', () => {
|
|
37
|
+
const sourceMeta = pikkuState(null, 'trigger', 'sourceMeta')
|
|
38
|
+
;(sourceMeta as any)['mySource'] = { pikkuFuncId: 'sourceFunc' }
|
|
39
|
+
|
|
40
|
+
wireTriggerSource({ name: 'mySource', func: async () => {} } as any)
|
|
41
|
+
|
|
42
|
+
const sources = pikkuState(null, 'trigger', 'triggerSources')
|
|
43
|
+
assert.ok(sources.has('mySource'))
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('should throw PikkuMissingMetaError when source meta is missing', () => {
|
|
47
|
+
assert.throws(
|
|
48
|
+
() => wireTriggerSource({ name: 'noMeta', func: async () => {} } as any),
|
|
49
|
+
(err: any) => err instanceof PikkuMissingMetaError
|
|
50
|
+
)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('should throw when trigger source already exists', () => {
|
|
54
|
+
const sourceMeta = pikkuState(null, 'trigger', 'sourceMeta')
|
|
55
|
+
;(sourceMeta as any)['dupSource'] = { pikkuFuncId: 'sourceFunc' }
|
|
56
|
+
|
|
57
|
+
wireTriggerSource({ name: 'dupSource', func: async () => {} } as any)
|
|
58
|
+
|
|
59
|
+
assert.throws(
|
|
60
|
+
() =>
|
|
61
|
+
wireTriggerSource({ name: 'dupSource', func: async () => {} } as any),
|
|
62
|
+
{ message: 'Trigger source already exists: dupSource' }
|
|
63
|
+
)
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
describe('getRegisteredTriggers', () => {
|
|
68
|
+
test('should return the triggers Map', () => {
|
|
69
|
+
const triggers = getRegisteredTriggers()
|
|
70
|
+
assert.ok(triggers instanceof Map)
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('getTriggerMeta', () => {
|
|
75
|
+
test('should return the trigger meta object', () => {
|
|
76
|
+
const meta = getTriggerMeta()
|
|
77
|
+
assert.ok(typeof meta === 'object')
|
|
78
|
+
})
|
|
79
|
+
})
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PikkuWire,
|
|
3
|
-
CreateWireServices,
|
|
4
|
-
type CoreSingletonServices,
|
|
5
|
-
} from '../../types/core.types.js'
|
|
1
|
+
import type { PikkuWire } from '../../types/core.types.js'
|
|
6
2
|
import type {
|
|
7
3
|
CoreTrigger,
|
|
8
4
|
CoreTriggerSource,
|
|
9
5
|
TriggerInstance,
|
|
10
6
|
} from './trigger.types.js'
|
|
11
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
pikkuState,
|
|
9
|
+
getSingletonServices,
|
|
10
|
+
getCreateWireServices,
|
|
11
|
+
} from '../../pikku-state.js'
|
|
12
12
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
|
|
13
13
|
import { PikkuMissingMetaError } from '../../errors/errors.js'
|
|
14
14
|
|
|
@@ -66,8 +66,6 @@ export const wireTriggerSource = <TInput = unknown, TOutput = unknown>(
|
|
|
66
66
|
*/
|
|
67
67
|
export type SetupTriggerParams<TInput = unknown, TOutput = unknown> = {
|
|
68
68
|
name: string
|
|
69
|
-
singletonServices: CoreSingletonServices
|
|
70
|
-
createWireServices?: CreateWireServices
|
|
71
69
|
input?: TInput
|
|
72
70
|
onTrigger: (data: TOutput) => void | Promise<void>
|
|
73
71
|
}
|
|
@@ -77,17 +75,16 @@ export type SetupTriggerParams<TInput = unknown, TOutput = unknown> = {
|
|
|
77
75
|
* Returns a TriggerInstance with a teardown function.
|
|
78
76
|
*
|
|
79
77
|
* @param name - The trigger name (must be registered via wireTrigger)
|
|
80
|
-
* @param singletonServices - The singleton services
|
|
81
78
|
* @param input - The input to pass to the trigger function
|
|
82
79
|
* @param onTrigger - Callback invoked when the trigger fires
|
|
83
80
|
*/
|
|
84
81
|
export async function setupTrigger<TInput = unknown, TOutput = unknown>({
|
|
85
82
|
name,
|
|
86
|
-
singletonServices,
|
|
87
|
-
createWireServices,
|
|
88
83
|
input,
|
|
89
84
|
onTrigger,
|
|
90
85
|
}: SetupTriggerParams<TInput, TOutput>): Promise<TriggerInstance> {
|
|
86
|
+
const singletonServices = getSingletonServices()
|
|
87
|
+
const createWireServices = getCreateWireServices()
|
|
91
88
|
const source = pikkuState(null, 'trigger', 'triggerSources').get(name)
|
|
92
89
|
const sourceMeta = pikkuState(null, 'trigger', 'sourceMeta')[name]
|
|
93
90
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { describe, test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { validateAndBuildVariableDefinitionsMeta } from './validate-variable-definitions.js'
|
|
4
|
+
|
|
5
|
+
describe('validateAndBuildVariableDefinitionsMeta', () => {
|
|
6
|
+
test('should build meta from single definition', () => {
|
|
7
|
+
const definitions = [
|
|
8
|
+
{
|
|
9
|
+
name: 'dbUrl',
|
|
10
|
+
displayName: 'Database URL',
|
|
11
|
+
description: 'Connection string',
|
|
12
|
+
variableId: 'DB_URL',
|
|
13
|
+
sourceFile: 'a.ts',
|
|
14
|
+
},
|
|
15
|
+
]
|
|
16
|
+
const result = validateAndBuildVariableDefinitionsMeta(
|
|
17
|
+
definitions as any,
|
|
18
|
+
new Map()
|
|
19
|
+
)
|
|
20
|
+
assert.ok(result['dbUrl'])
|
|
21
|
+
assert.strictEqual(result['dbUrl'].variableId, 'DB_URL')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('should allow duplicate variableId with same schema', () => {
|
|
25
|
+
const schemaLookup = new Map([
|
|
26
|
+
['schema1', { variableName: 'Schema', sourceFile: 'types.ts' }],
|
|
27
|
+
])
|
|
28
|
+
const definitions = [
|
|
29
|
+
{
|
|
30
|
+
name: 'var1',
|
|
31
|
+
displayName: 'Var 1',
|
|
32
|
+
description: 'd',
|
|
33
|
+
variableId: 'SHARED',
|
|
34
|
+
schema: 'schema1',
|
|
35
|
+
sourceFile: 'a.ts',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'var2',
|
|
39
|
+
displayName: 'Var 2',
|
|
40
|
+
description: 'd',
|
|
41
|
+
variableId: 'SHARED',
|
|
42
|
+
schema: 'schema1',
|
|
43
|
+
sourceFile: 'b.ts',
|
|
44
|
+
},
|
|
45
|
+
]
|
|
46
|
+
const result = validateAndBuildVariableDefinitionsMeta(
|
|
47
|
+
definitions as any,
|
|
48
|
+
schemaLookup
|
|
49
|
+
)
|
|
50
|
+
assert.ok(result['var1'])
|
|
51
|
+
assert.ok(result['var2'])
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('should throw when duplicate variableId has different schemas', () => {
|
|
55
|
+
const schemaLookup = new Map([
|
|
56
|
+
['schema1', { variableName: 'SchemaA', sourceFile: 'types.ts' }],
|
|
57
|
+
['schema2', { variableName: 'SchemaB', sourceFile: 'types2.ts' }],
|
|
58
|
+
])
|
|
59
|
+
const definitions = [
|
|
60
|
+
{
|
|
61
|
+
name: 'var1',
|
|
62
|
+
displayName: 'Var 1',
|
|
63
|
+
description: 'd',
|
|
64
|
+
variableId: 'SHARED',
|
|
65
|
+
schema: 'schema1',
|
|
66
|
+
sourceFile: 'a.ts',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'var2',
|
|
70
|
+
displayName: 'Var 2',
|
|
71
|
+
description: 'd',
|
|
72
|
+
variableId: 'SHARED',
|
|
73
|
+
schema: 'schema2',
|
|
74
|
+
sourceFile: 'b.ts',
|
|
75
|
+
},
|
|
76
|
+
]
|
|
77
|
+
assert.throws(
|
|
78
|
+
() =>
|
|
79
|
+
validateAndBuildVariableDefinitionsMeta(
|
|
80
|
+
definitions as any,
|
|
81
|
+
schemaLookup
|
|
82
|
+
),
|
|
83
|
+
(err: any) => err.message.includes('different schemas')
|
|
84
|
+
)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('should handle empty definitions', () => {
|
|
88
|
+
const result = validateAndBuildVariableDefinitionsMeta([], new Map())
|
|
89
|
+
assert.deepStrictEqual(result, {})
|
|
90
|
+
})
|
|
91
|
+
})
|
|
@@ -196,19 +196,15 @@ describe('graph-runner bugs', () => {
|
|
|
196
196
|
const ws = new InMemoryWorkflowService()
|
|
197
197
|
const queuedNodes: string[] = []
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
{
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
},
|
|
199
|
+
pikkuState(null, 'package', 'singletonServices', {
|
|
200
|
+
queueService: {
|
|
201
|
+
add: async (_queueName: string, data: any) => {
|
|
202
|
+
if (data?.stepName) {
|
|
203
|
+
queuedNodes.push(data.stepName)
|
|
204
|
+
}
|
|
207
205
|
},
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
{} as any
|
|
211
|
-
)
|
|
206
|
+
},
|
|
207
|
+
} as any)
|
|
212
208
|
|
|
213
209
|
const meta: WorkflowRuntimeMeta = {
|
|
214
210
|
name: 'testConvergingNextNode',
|
|
@@ -322,7 +318,7 @@ describe('graph-runner bugs', () => {
|
|
|
322
318
|
true
|
|
323
319
|
)
|
|
324
320
|
runId = result.runId
|
|
325
|
-
} catch
|
|
321
|
+
} catch {
|
|
326
322
|
const runs = (ws as any).runs as Map<string, any>
|
|
327
323
|
for (const [id] of runs) {
|
|
328
324
|
runId = id
|
|
@@ -344,15 +340,11 @@ describe('graph-runner bugs', () => {
|
|
|
344
340
|
test('executeGraphStep should throw after queueing onError nodes', async () => {
|
|
345
341
|
const ws = new InMemoryWorkflowService()
|
|
346
342
|
|
|
347
|
-
|
|
348
|
-
{
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
} as any,
|
|
353
|
-
(() => ({})) as any,
|
|
354
|
-
{} as any
|
|
355
|
-
)
|
|
343
|
+
pikkuState(null, 'package', 'singletonServices', {
|
|
344
|
+
queueService: {
|
|
345
|
+
add: async () => {},
|
|
346
|
+
},
|
|
347
|
+
} as any)
|
|
356
348
|
|
|
357
349
|
const metaState = pikkuState(null, 'workflows', 'meta')
|
|
358
350
|
metaState['testQueuedOnErrorThrow'] = {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { describe, test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { template } from './template.js'
|
|
4
|
+
|
|
5
|
+
describe('template', () => {
|
|
6
|
+
test('should parse a simple template with one placeholder', () => {
|
|
7
|
+
const result = template('Hello $0!', [{ $ref: 'greeting' }])
|
|
8
|
+
assert.deepStrictEqual(result.$template.parts, ['Hello ', '!'])
|
|
9
|
+
assert.deepStrictEqual(result.$template.expressions, [{ $ref: 'greeting' }])
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
test('should parse template with multiple placeholders', () => {
|
|
13
|
+
const result = template('$0 and $1', [{ $ref: 'a' }, { $ref: 'b' }])
|
|
14
|
+
assert.deepStrictEqual(result.$template.parts, ['', ' and ', ''])
|
|
15
|
+
assert.strictEqual(result.$template.expressions.length, 2)
|
|
16
|
+
assert.strictEqual(result.$template.expressions[0].$ref, 'a')
|
|
17
|
+
assert.strictEqual(result.$template.expressions[1].$ref, 'b')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('should preserve path in references', () => {
|
|
21
|
+
const result = template('Value: $0', [{ $ref: 'node1', path: 'data.name' }])
|
|
22
|
+
assert.deepStrictEqual(result.$template.expressions[0], {
|
|
23
|
+
$ref: 'node1',
|
|
24
|
+
path: 'data.name',
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('should handle template with no placeholders', () => {
|
|
29
|
+
const result = template('No placeholders here', [])
|
|
30
|
+
assert.deepStrictEqual(result.$template.parts, ['No placeholders here'])
|
|
31
|
+
assert.deepStrictEqual(result.$template.expressions, [])
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('should handle out-of-range ref index as unknown', () => {
|
|
35
|
+
const result = template('$5', [{ $ref: 'a' }])
|
|
36
|
+
assert.deepStrictEqual(result.$template.expressions[0], { $ref: 'unknown' })
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('should handle adjacent placeholders', () => {
|
|
40
|
+
const result = template('$0$1', [{ $ref: 'a' }, { $ref: 'b' }])
|
|
41
|
+
assert.deepStrictEqual(result.$template.parts, ['', '', ''])
|
|
42
|
+
assert.strictEqual(result.$template.expressions.length, 2)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('should omit path when not provided', () => {
|
|
46
|
+
const result = template('$0', [{ $ref: 'node' }])
|
|
47
|
+
assert.strictEqual(result.$template.expressions[0].path, undefined)
|
|
48
|
+
})
|
|
49
|
+
})
|
|
@@ -16,15 +16,11 @@ describe('pikku-workflow-service version mismatch fallback', () => {
|
|
|
16
16
|
const oldHash = 'old-hash'
|
|
17
17
|
const newHash = 'new-hash'
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} as any,
|
|
25
|
-
(() => ({})) as any,
|
|
26
|
-
{} as any
|
|
27
|
-
)
|
|
19
|
+
pikkuState(null, 'package', 'singletonServices', {
|
|
20
|
+
queueService: {
|
|
21
|
+
add: async () => {},
|
|
22
|
+
},
|
|
23
|
+
} as any)
|
|
28
24
|
|
|
29
25
|
const metaState = pikkuState(null, 'workflows', 'meta')
|
|
30
26
|
metaState[workflowName] = {
|
|
@@ -111,15 +107,11 @@ describe('pikku-workflow-service version mismatch fallback', () => {
|
|
|
111
107
|
describe('pikku-workflow-service executeWorkflowStep', () => {
|
|
112
108
|
test('should set pending step to running before succeeding', async () => {
|
|
113
109
|
const ws = new InMemoryWorkflowService()
|
|
114
|
-
|
|
115
|
-
{
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
} as any,
|
|
120
|
-
(() => ({})) as any,
|
|
121
|
-
{} as any
|
|
122
|
-
)
|
|
110
|
+
pikkuState(null, 'package', 'singletonServices', {
|
|
111
|
+
queueService: {
|
|
112
|
+
add: async () => {},
|
|
113
|
+
},
|
|
114
|
+
} as any)
|
|
123
115
|
|
|
124
116
|
const runId = await ws.createRun(
|
|
125
117
|
'pending-step-running',
|
|
@@ -149,15 +141,11 @@ describe('pikku-workflow-service executeWorkflowStep', () => {
|
|
|
149
141
|
describe('pikku-workflow-service suspend', () => {
|
|
150
142
|
test('should set run status to suspended when workflow.suspend is called', async () => {
|
|
151
143
|
const ws = new InMemoryWorkflowService()
|
|
152
|
-
|
|
153
|
-
{
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
} as any,
|
|
158
|
-
(() => ({})) as any,
|
|
159
|
-
{} as any
|
|
160
|
-
)
|
|
144
|
+
pikkuState(null, 'package', 'singletonServices', {
|
|
145
|
+
queueService: {
|
|
146
|
+
add: async () => {},
|
|
147
|
+
},
|
|
148
|
+
} as any)
|
|
161
149
|
|
|
162
150
|
const workflowName = 'testSuspendWorkflow'
|
|
163
151
|
const graphHash = 'suspend-hash'
|