@pikku/core 0.12.2 → 0.12.4

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.
Files changed (282) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/crypto-utils.d.ts +10 -0
  3. package/dist/crypto-utils.js +62 -0
  4. package/dist/function/function-runner.js +4 -4
  5. package/dist/function/functions.types.d.ts +26 -1
  6. package/dist/function/functions.types.js +16 -0
  7. package/dist/handle-error.d.ts +1 -1
  8. package/dist/handle-error.js +7 -3
  9. package/dist/index.d.ts +14 -2
  10. package/dist/index.js +1 -1
  11. package/dist/pikku-state.js +3 -1
  12. package/dist/schema.js +1 -1
  13. package/dist/services/in-memory-workflow-service.d.ts +22 -3
  14. package/dist/services/in-memory-workflow-service.js +77 -1
  15. package/dist/services/workflow-service.d.ts +8 -2
  16. package/dist/testing/index.d.ts +2 -0
  17. package/dist/testing/index.js +1 -0
  18. package/dist/testing/service-tests.d.ts +31 -0
  19. package/dist/testing/service-tests.js +598 -0
  20. package/dist/types/core.types.d.ts +9 -1
  21. package/dist/types/state.types.d.ts +4 -2
  22. package/dist/utils/hash.d.ts +2 -0
  23. package/dist/utils/hash.js +23 -0
  24. package/dist/wirings/ai-agent/agent-dynamic-workflow.d.ts +6 -0
  25. package/dist/wirings/ai-agent/agent-dynamic-workflow.js +348 -0
  26. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +1 -1
  27. package/dist/wirings/ai-agent/ai-agent-memory.js +6 -5
  28. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -7
  29. package/dist/wirings/ai-agent/ai-agent-prepare.js +127 -47
  30. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +4 -0
  31. package/dist/wirings/ai-agent/ai-agent-runner.js +381 -27
  32. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +7 -2
  33. package/dist/wirings/ai-agent/ai-agent-stream.js +109 -46
  34. package/dist/wirings/ai-agent/ai-agent.types.d.ts +22 -1
  35. package/dist/wirings/ai-agent/index.d.ts +1 -2
  36. package/dist/wirings/ai-agent/index.js +1 -2
  37. package/dist/wirings/channel/channel-handler.js +5 -1
  38. package/dist/wirings/channel/channel.types.d.ts +1 -7
  39. package/dist/wirings/channel/local/local-channel-handler.d.ts +1 -1
  40. package/dist/wirings/channel/local/local-channel-handler.js +5 -3
  41. package/dist/wirings/channel/local/local-channel-runner.js +14 -4
  42. package/dist/wirings/channel/serverless/serverless-channel-runner.js +4 -1
  43. package/dist/wirings/cli/cli-runner.js +10 -2
  44. package/dist/wirings/cli/cli.types.d.ts +1 -0
  45. package/dist/wirings/http/http-routes.js +0 -1
  46. package/dist/wirings/http/http-runner.d.ts +1 -1
  47. package/dist/wirings/http/http-runner.js +25 -3
  48. package/dist/wirings/http/http.types.d.ts +3 -11
  49. package/dist/wirings/http/index.d.ts +2 -1
  50. package/dist/wirings/http/index.js +1 -0
  51. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
  52. package/dist/wirings/http/pikku-fetch-http-request.js +3 -0
  53. package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
  54. package/dist/wirings/http/pikku-fetch-http-response.js +4 -4
  55. package/dist/wirings/http/web-request.d.ts +12 -0
  56. package/dist/wirings/http/web-request.js +85 -0
  57. package/dist/wirings/mcp/mcp-endpoint-registry.js +1 -1
  58. package/dist/wirings/mcp/mcp-runner.js +13 -1
  59. package/dist/wirings/rpc/rpc-runner.d.ts +30 -6
  60. package/dist/wirings/rpc/rpc-runner.js +36 -14
  61. package/dist/wirings/rpc/rpc-types.d.ts +6 -1
  62. package/dist/wirings/rpc/wire-addon.d.ts +1 -0
  63. package/dist/wirings/rpc/wire-addon.js +1 -1
  64. package/dist/wirings/scheduler/scheduler-runner.js +1 -0
  65. package/dist/wirings/workflow/graph/graph-validation.d.ts +3 -0
  66. package/dist/wirings/workflow/graph/graph-validation.js +175 -0
  67. package/dist/wirings/workflow/graph/index.d.ts +1 -0
  68. package/dist/wirings/workflow/graph/index.js +1 -0
  69. package/dist/wirings/workflow/index.d.ts +1 -1
  70. package/dist/wirings/workflow/pikku-workflow-service.d.ts +8 -2
  71. package/dist/wirings/workflow/pikku-workflow-service.js +1 -2
  72. package/dist/wirings/workflow/workflow.types.d.ts +10 -1
  73. package/lcov.info +18891 -0
  74. package/package.json +4 -2
  75. package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +0 -5
  76. package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +0 -168
  77. package/src/crypto-utils.test.ts +0 -116
  78. package/src/crypto-utils.ts +0 -99
  79. package/src/errors/error-handler.ts +0 -62
  80. package/src/errors/error.test.ts +0 -195
  81. package/src/errors/errors.ts +0 -374
  82. package/src/errors/index.ts +0 -2
  83. package/src/factory-functions.test.ts +0 -109
  84. package/src/function/function-runner.test.ts +0 -536
  85. package/src/function/function-runner.ts +0 -365
  86. package/src/function/functions.types.ts +0 -267
  87. package/src/function/index.ts +0 -5
  88. package/src/handle-error.test.ts +0 -361
  89. package/src/handle-error.ts +0 -65
  90. package/src/index.ts +0 -104
  91. package/src/internal.ts +0 -6
  92. package/src/middleware/auth-apikey.test.ts +0 -363
  93. package/src/middleware/auth-apikey.ts +0 -47
  94. package/src/middleware/auth-bearer.test.ts +0 -450
  95. package/src/middleware/auth-bearer.ts +0 -72
  96. package/src/middleware/auth-cookie.test.ts +0 -528
  97. package/src/middleware/auth-cookie.ts +0 -80
  98. package/src/middleware/cors.test.ts +0 -424
  99. package/src/middleware/cors.ts +0 -104
  100. package/src/middleware/index.ts +0 -5
  101. package/src/middleware/remote-auth.test.ts +0 -488
  102. package/src/middleware/remote-auth.ts +0 -68
  103. package/src/middleware/timeout.ts +0 -15
  104. package/src/middleware-runner.test.ts +0 -418
  105. package/src/middleware-runner.ts +0 -234
  106. package/src/permissions.test.ts +0 -434
  107. package/src/permissions.ts +0 -319
  108. package/src/pikku-request.ts +0 -23
  109. package/src/pikku-response.ts +0 -5
  110. package/src/pikku-state.test.ts +0 -224
  111. package/src/pikku-state.ts +0 -214
  112. package/src/run-tests-script.test.ts +0 -49
  113. package/src/schema.test.ts +0 -249
  114. package/src/schema.ts +0 -151
  115. package/src/services/ai-agent-runner-service.ts +0 -41
  116. package/src/services/ai-run-state-service.ts +0 -20
  117. package/src/services/ai-storage-service.ts +0 -39
  118. package/src/services/content-service.ts +0 -76
  119. package/src/services/deployment-service.ts +0 -22
  120. package/src/services/gateway-service.ts +0 -20
  121. package/src/services/gopass-secrets.ts +0 -98
  122. package/src/services/in-memory-ai-run-state-service.ts +0 -73
  123. package/src/services/in-memory-trigger-service.ts +0 -64
  124. package/src/services/in-memory-workflow-service.test.ts +0 -351
  125. package/src/services/in-memory-workflow-service.ts +0 -395
  126. package/src/services/index.ts +0 -56
  127. package/src/services/jwt-service.ts +0 -30
  128. package/src/services/local-content.ts +0 -120
  129. package/src/services/local-gateway-service.ts +0 -62
  130. package/src/services/local-secrets.test.ts +0 -80
  131. package/src/services/local-secrets.ts +0 -94
  132. package/src/services/local-variables.test.ts +0 -61
  133. package/src/services/local-variables.ts +0 -39
  134. package/src/services/logger-console.test.ts +0 -118
  135. package/src/services/logger-console.ts +0 -98
  136. package/src/services/logger.ts +0 -57
  137. package/src/services/scheduler-service.ts +0 -86
  138. package/src/services/schema-service.ts +0 -33
  139. package/src/services/scoped-secret-service.test.ts +0 -74
  140. package/src/services/scoped-secret-service.ts +0 -41
  141. package/src/services/secret-service.ts +0 -38
  142. package/src/services/trigger-service.ts +0 -17
  143. package/src/services/typed-secret-service.test.ts +0 -93
  144. package/src/services/typed-secret-service.ts +0 -70
  145. package/src/services/typed-variables-service.test.ts +0 -73
  146. package/src/services/typed-variables-service.ts +0 -81
  147. package/src/services/user-session-service.test.ts +0 -113
  148. package/src/services/user-session-service.ts +0 -86
  149. package/src/services/variables-service.ts +0 -11
  150. package/src/services/workflow-service.ts +0 -84
  151. package/src/time-utils.test.ts +0 -56
  152. package/src/time-utils.ts +0 -107
  153. package/src/types/core.types.ts +0 -470
  154. package/src/types/state.types.ts +0 -186
  155. package/src/utils.test.ts +0 -350
  156. package/src/utils.ts +0 -129
  157. package/src/version.test.ts +0 -80
  158. package/src/version.ts +0 -25
  159. package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +0 -363
  160. package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +0 -238
  161. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +0 -152
  162. package/src/wirings/ai-agent/ai-agent-helpers.ts +0 -76
  163. package/src/wirings/ai-agent/ai-agent-memory.ts +0 -309
  164. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +0 -115
  165. package/src/wirings/ai-agent/ai-agent-model-config.ts +0 -43
  166. package/src/wirings/ai-agent/ai-agent-prepare.ts +0 -522
  167. package/src/wirings/ai-agent/ai-agent-registry.test.ts +0 -37
  168. package/src/wirings/ai-agent/ai-agent-registry.ts +0 -82
  169. package/src/wirings/ai-agent/ai-agent-runner.test.ts +0 -317
  170. package/src/wirings/ai-agent/ai-agent-runner.ts +0 -251
  171. package/src/wirings/ai-agent/ai-agent-stream.test.ts +0 -652
  172. package/src/wirings/ai-agent/ai-agent-stream.ts +0 -1060
  173. package/src/wirings/ai-agent/ai-agent.types.ts +0 -360
  174. package/src/wirings/ai-agent/index.ts +0 -41
  175. package/src/wirings/channel/channel-common.ts +0 -90
  176. package/src/wirings/channel/channel-handler.ts +0 -241
  177. package/src/wirings/channel/channel-middleware-runner.ts +0 -120
  178. package/src/wirings/channel/channel-runner.ts +0 -166
  179. package/src/wirings/channel/channel-store.ts +0 -29
  180. package/src/wirings/channel/channel.types.ts +0 -178
  181. package/src/wirings/channel/define-channel-routes.ts +0 -25
  182. package/src/wirings/channel/eventhub-service.ts +0 -34
  183. package/src/wirings/channel/eventhub-store.ts +0 -13
  184. package/src/wirings/channel/index.ts +0 -24
  185. package/src/wirings/channel/local/index.ts +0 -3
  186. package/src/wirings/channel/local/local-channel-handler.ts +0 -79
  187. package/src/wirings/channel/local/local-channel-runner.test.ts +0 -215
  188. package/src/wirings/channel/local/local-channel-runner.ts +0 -200
  189. package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -95
  190. package/src/wirings/channel/local/local-eventhub-service.ts +0 -101
  191. package/src/wirings/channel/log-channels.ts +0 -20
  192. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -54
  193. package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -45
  194. package/src/wirings/channel/serverless/index.ts +0 -5
  195. package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -286
  196. package/src/wirings/cli/channel/cli-channel-runner.ts +0 -136
  197. package/src/wirings/cli/channel/index.ts +0 -1
  198. package/src/wirings/cli/cli-runner.test.ts +0 -403
  199. package/src/wirings/cli/cli-runner.ts +0 -519
  200. package/src/wirings/cli/cli.types.ts +0 -357
  201. package/src/wirings/cli/command-parser.test.ts +0 -445
  202. package/src/wirings/cli/command-parser.ts +0 -504
  203. package/src/wirings/cli/define-cli-commands.ts +0 -24
  204. package/src/wirings/cli/index.ts +0 -19
  205. package/src/wirings/gateway/gateway-runner.test.ts +0 -474
  206. package/src/wirings/gateway/gateway-runner.ts +0 -411
  207. package/src/wirings/gateway/gateway.types.ts +0 -149
  208. package/src/wirings/gateway/index.ts +0 -13
  209. package/src/wirings/http/http-routes.test.ts +0 -322
  210. package/src/wirings/http/http-routes.ts +0 -198
  211. package/src/wirings/http/http-runner.test.ts +0 -144
  212. package/src/wirings/http/http-runner.ts +0 -563
  213. package/src/wirings/http/http.types.ts +0 -378
  214. package/src/wirings/http/index.ts +0 -25
  215. package/src/wirings/http/log-http-routes.ts +0 -22
  216. package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -237
  217. package/src/wirings/http/pikku-fetch-http-request.ts +0 -166
  218. package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -82
  219. package/src/wirings/http/pikku-fetch-http-response.ts +0 -147
  220. package/src/wirings/http/routers/http-router.ts +0 -13
  221. package/src/wirings/http/routers/path-to-regex.test.ts +0 -319
  222. package/src/wirings/http/routers/path-to-regex.ts +0 -126
  223. package/src/wirings/mcp/index.ts +0 -27
  224. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -389
  225. package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
  226. package/src/wirings/mcp/mcp-runner.ts +0 -305
  227. package/src/wirings/mcp/mcp.types.ts +0 -216
  228. package/src/wirings/node/index.ts +0 -2
  229. package/src/wirings/node/node.types.ts +0 -23
  230. package/src/wirings/oauth2/index.ts +0 -3
  231. package/src/wirings/oauth2/oauth2-client.test.ts +0 -929
  232. package/src/wirings/oauth2/oauth2-client.ts +0 -335
  233. package/src/wirings/oauth2/oauth2.types.ts +0 -69
  234. package/src/wirings/oauth2/wire-oauth2-credential.ts +0 -23
  235. package/src/wirings/queue/index.ts +0 -31
  236. package/src/wirings/queue/queue-runner.test.ts +0 -710
  237. package/src/wirings/queue/queue-runner.ts +0 -192
  238. package/src/wirings/queue/queue.types.ts +0 -189
  239. package/src/wirings/queue/register-queue-helper.ts +0 -60
  240. package/src/wirings/queue/validate-worker-config.test.ts +0 -108
  241. package/src/wirings/queue/validate-worker-config.ts +0 -116
  242. package/src/wirings/rpc/index.ts +0 -4
  243. package/src/wirings/rpc/rpc-runner.ts +0 -439
  244. package/src/wirings/rpc/rpc-types.ts +0 -51
  245. package/src/wirings/rpc/wire-addon.ts +0 -20
  246. package/src/wirings/scheduler/index.ts +0 -11
  247. package/src/wirings/scheduler/log-schedulers.ts +0 -20
  248. package/src/wirings/scheduler/scheduler-runner.test.ts +0 -660
  249. package/src/wirings/scheduler/scheduler-runner.ts +0 -132
  250. package/src/wirings/scheduler/scheduler.types.ts +0 -53
  251. package/src/wirings/secret/index.ts +0 -9
  252. package/src/wirings/secret/secret.types.ts +0 -32
  253. package/src/wirings/secret/validate-secret-definitions.test.ts +0 -140
  254. package/src/wirings/secret/validate-secret-definitions.ts +0 -82
  255. package/src/wirings/trigger/index.ts +0 -10
  256. package/src/wirings/trigger/pikku-trigger-service.ts +0 -112
  257. package/src/wirings/trigger/trigger-runner.test.ts +0 -79
  258. package/src/wirings/trigger/trigger-runner.ts +0 -135
  259. package/src/wirings/trigger/trigger.types.ts +0 -178
  260. package/src/wirings/variable/index.ts +0 -8
  261. package/src/wirings/variable/validate-variable-definitions.test.ts +0 -91
  262. package/src/wirings/variable/validate-variable-definitions.ts +0 -69
  263. package/src/wirings/variable/variable.types.ts +0 -22
  264. package/src/wirings/workflow/dsl/index.ts +0 -31
  265. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -320
  266. package/src/wirings/workflow/dsl/workflow-runner.ts +0 -28
  267. package/src/wirings/workflow/graph/graph-node.ts +0 -222
  268. package/src/wirings/workflow/graph/graph-runner.test.ts +0 -487
  269. package/src/wirings/workflow/graph/graph-runner.ts +0 -816
  270. package/src/wirings/workflow/graph/index.ts +0 -14
  271. package/src/wirings/workflow/graph/template.test.ts +0 -49
  272. package/src/wirings/workflow/graph/template.ts +0 -42
  273. package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -29
  274. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -104
  275. package/src/wirings/workflow/index.ts +0 -81
  276. package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -200
  277. package/src/wirings/workflow/pikku-workflow-service.ts +0 -1165
  278. package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
  279. package/src/wirings/workflow/workflow-helpers.ts +0 -79
  280. package/src/wirings/workflow/workflow.types.ts +0 -266
  281. package/tsconfig.json +0 -14
  282. package/tsconfig.tsbuildinfo +0 -1
@@ -1,74 +0,0 @@
1
- import { describe, test } from 'node:test'
2
- import assert from 'node:assert'
3
- import { ScopedSecretService } from './scoped-secret-service.js'
4
-
5
- const createMockSecrets = () => ({
6
- getSecret: async (key: string) => `value-of-${key}`,
7
- getSecretJSON: async (key: string) => ({ key }),
8
- hasSecret: async () => true,
9
- setSecretJSON: async () => {},
10
- deleteSecret: async () => {},
11
- })
12
-
13
- describe('ScopedSecretService', () => {
14
- test('should allow access to allowed keys', async () => {
15
- const mock = createMockSecrets()
16
- const scoped = new ScopedSecretService(mock, new Set(['KEY1', 'KEY2']))
17
- const result = await scoped.getSecret('KEY1')
18
- assert.strictEqual(result, 'value-of-KEY1')
19
- })
20
-
21
- test('should deny access to non-allowed keys', async () => {
22
- const mock = createMockSecrets()
23
- const scoped = new ScopedSecretService(mock, new Set(['KEY1']))
24
- await assert.rejects(() => scoped.getSecret('KEY2'), {
25
- message: 'Access denied to secret key: KEY2',
26
- })
27
- })
28
-
29
- test('should allow getSecretJSON for allowed keys', async () => {
30
- const mock = createMockSecrets()
31
- const scoped = new ScopedSecretService(mock, new Set(['KEY1']))
32
- const result = await scoped.getSecretJSON('KEY1')
33
- assert.deepStrictEqual(result, { key: 'KEY1' })
34
- })
35
-
36
- test('should deny getSecretJSON for non-allowed keys', async () => {
37
- const mock = createMockSecrets()
38
- const scoped = new ScopedSecretService(mock, new Set(['KEY1']))
39
- await assert.rejects(() => scoped.getSecretJSON('FORBIDDEN'), {
40
- message: 'Access denied to secret key: FORBIDDEN',
41
- })
42
- })
43
-
44
- test('should allow hasSecret for allowed keys', async () => {
45
- const mock = createMockSecrets()
46
- const scoped = new ScopedSecretService(mock, new Set(['KEY1']))
47
- const result = await scoped.hasSecret('KEY1')
48
- assert.strictEqual(result, true)
49
- })
50
-
51
- test('should deny hasSecret for non-allowed keys', async () => {
52
- const mock = createMockSecrets()
53
- const scoped = new ScopedSecretService(mock, new Set(['KEY1']))
54
- await assert.rejects(() => scoped.hasSecret('KEY2'), {
55
- message: 'Access denied to secret key: KEY2',
56
- })
57
- })
58
-
59
- test('should always throw on setSecretJSON', async () => {
60
- const mock = createMockSecrets()
61
- const scoped = new ScopedSecretService(mock, new Set(['KEY1']))
62
- await assert.rejects(() => scoped.setSecretJSON('KEY1', 'val'), {
63
- message: 'setSecretJSON is not allowed in scoped secret service',
64
- })
65
- })
66
-
67
- test('should always throw on deleteSecret', async () => {
68
- const mock = createMockSecrets()
69
- const scoped = new ScopedSecretService(mock, new Set(['KEY1']))
70
- await assert.rejects(() => scoped.deleteSecret('KEY1'), {
71
- message: 'deleteSecret is not allowed in scoped secret service',
72
- })
73
- })
74
- })
@@ -1,41 +0,0 @@
1
- import type { SecretService } from './secret-service.js'
2
-
3
- /**
4
- * A read-only wrapper around SecretService that restricts access
5
- * to only a defined set of allowed secret keys.
6
- */
7
- export class ScopedSecretService implements SecretService {
8
- constructor(
9
- private secrets: SecretService,
10
- private allowedKeys: Set<string>
11
- ) {}
12
-
13
- private assertAllowed(key: string): void {
14
- if (!this.allowedKeys.has(key)) {
15
- throw new Error(`Access denied to secret key: ${key}`)
16
- }
17
- }
18
-
19
- async getSecret(key: string): Promise<string> {
20
- this.assertAllowed(key)
21
- return this.secrets.getSecret(key)
22
- }
23
-
24
- async getSecretJSON<T = {}>(key: string): Promise<T> {
25
- this.assertAllowed(key)
26
- return this.secrets.getSecretJSON<T>(key)
27
- }
28
-
29
- async hasSecret(key: string): Promise<boolean> {
30
- this.assertAllowed(key)
31
- return this.secrets.hasSecret(key)
32
- }
33
-
34
- async setSecretJSON(_key: string, _value: unknown): Promise<void> {
35
- throw new Error('setSecretJSON is not allowed in scoped secret service')
36
- }
37
-
38
- async deleteSecret(_key: string): Promise<void> {
39
- throw new Error('deleteSecret is not allowed in scoped secret service')
40
- }
41
- }
@@ -1,38 +0,0 @@
1
- /**
2
- * Interface for retrieving and managing secrets.
3
- */
4
- export interface SecretService {
5
- /**
6
- * Retrieves a secret by key and parses it as JSON.
7
- * @param key - The key of the secret to retrieve.
8
- * @returns A promise that resolves to the parsed secret value.
9
- * @throws If the secret is not found.
10
- */
11
- getSecretJSON<Return = {}>(key: string): Promise<Return>
12
- /**
13
- * Retrieves a secret by key as a string.
14
- * @param key - The key of the secret to retrieve.
15
- * @returns A promise that resolves to the secret value.
16
- * @throws If the secret is not found.
17
- */
18
- getSecret(key: string): Promise<string>
19
- /**
20
- * Checks if a secret exists without throwing.
21
- * @param key - The key of the secret to check.
22
- * @returns A promise that resolves to true if the secret exists, false otherwise.
23
- */
24
- hasSecret(key: string): Promise<boolean>
25
- /**
26
- * Stores a JSON value as a secret.
27
- * @param key - The key to store the secret under.
28
- * @param value - The JSON value to store.
29
- * @returns A promise that resolves when the secret is stored.
30
- */
31
- setSecretJSON(key: string, value: unknown): Promise<void>
32
- /**
33
- * Deletes a secret by key.
34
- * @param key - The key of the secret to delete.
35
- * @returns A promise that resolves when the secret is deleted.
36
- */
37
- deleteSecret(key: string): Promise<void>
38
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * Abstract TriggerService interface.
3
- *
4
- * Implementations manage trigger subscriptions — listening to external events
5
- * and dispatching to RPC targets or workflow starts.
6
- */
7
- export interface TriggerService {
8
- /**
9
- * Start all triggers
10
- */
11
- start(): Promise<void>
12
-
13
- /**
14
- * Stop all triggers
15
- */
16
- stop(): Promise<void>
17
- }
@@ -1,93 +0,0 @@
1
- import { describe, test } from 'node:test'
2
- import assert from 'node:assert'
3
- import { TypedSecretService } from './typed-secret-service.js'
4
-
5
- const createMockSecrets = (store: Map<string, string> = new Map()) => ({
6
- getSecret: async (key: string) => {
7
- const val = store.get(key)
8
- if (!val) throw new Error(`Not found: ${key}`)
9
- return val
10
- },
11
- getSecretJSON: async (key: string) => {
12
- const val = store.get(key)
13
- if (!val) throw new Error(`Not found: ${key}`)
14
- return JSON.parse(val)
15
- },
16
- hasSecret: async (key: string) => store.has(key),
17
- setSecretJSON: async (key: string, value: unknown) => {
18
- store.set(key, JSON.stringify(value))
19
- },
20
- deleteSecret: async (key: string) => {
21
- store.delete(key)
22
- },
23
- })
24
-
25
- describe('TypedSecretService', () => {
26
- test('should delegate getSecret to underlying service', async () => {
27
- const store = new Map([['API_KEY', 'sk-123']])
28
- const service = new TypedSecretService(createMockSecrets(store), {})
29
- const result = await service.getSecret('API_KEY')
30
- assert.strictEqual(result, 'sk-123')
31
- })
32
-
33
- test('should delegate getSecretJSON to underlying service', async () => {
34
- const store = new Map([['CONFIG', '{"port":3000}']])
35
- const service = new TypedSecretService(createMockSecrets(store), {})
36
- const result = await service.getSecretJSON('CONFIG')
37
- assert.deepStrictEqual(result, { port: 3000 })
38
- })
39
-
40
- test('should delegate hasSecret to underlying service', async () => {
41
- const store = new Map([['EXISTS', 'val']])
42
- const service = new TypedSecretService(createMockSecrets(store), {})
43
- assert.strictEqual(await service.hasSecret('EXISTS'), true)
44
- assert.strictEqual(await service.hasSecret('MISSING'), false)
45
- })
46
-
47
- test('should delegate setSecretJSON to underlying service', async () => {
48
- const store = new Map<string, string>()
49
- const service = new TypedSecretService(createMockSecrets(store), {})
50
- await service.setSecretJSON('NEW_KEY', { data: 'val' })
51
- assert.strictEqual(store.get('NEW_KEY'), '{"data":"val"}')
52
- })
53
-
54
- test('should delegate deleteSecret to underlying service', async () => {
55
- const store = new Map([['KEY', 'val']])
56
- const service = new TypedSecretService(createMockSecrets(store), {})
57
- await service.deleteSecret('KEY')
58
- assert.strictEqual(store.has('KEY'), false)
59
- })
60
-
61
- test('should get all status for credentials', async () => {
62
- const store = new Map([['STRIPE_KEY', 'sk-123']])
63
- const meta = {
64
- STRIPE_KEY: { name: 'stripe', displayName: 'Stripe' },
65
- GITHUB_TOKEN: {
66
- name: 'github',
67
- displayName: 'GitHub',
68
- oauth2: { tokenSecretId: 'GH_TOKEN' },
69
- },
70
- }
71
- const service = new TypedSecretService(createMockSecrets(store), meta)
72
- const status = await service.getAllStatus()
73
- assert.strictEqual(status.length, 2)
74
- const stripeStatus = status.find((s) => s.secretId === 'STRIPE_KEY')!
75
- assert.strictEqual(stripeStatus.isConfigured, true)
76
- assert.strictEqual(stripeStatus.displayName, 'Stripe')
77
- const ghStatus = status.find((s) => s.secretId === 'GITHUB_TOKEN')!
78
- assert.strictEqual(ghStatus.isConfigured, false)
79
- assert.deepStrictEqual(ghStatus.oauth2, { tokenSecretId: 'GH_TOKEN' })
80
- })
81
-
82
- test('should get missing credentials', async () => {
83
- const store = new Map([['STRIPE_KEY', 'sk-123']])
84
- const meta = {
85
- STRIPE_KEY: { name: 'stripe', displayName: 'Stripe' },
86
- GITHUB_TOKEN: { name: 'github', displayName: 'GitHub' },
87
- }
88
- const service = new TypedSecretService(createMockSecrets(store), meta)
89
- const missing = await service.getMissing()
90
- assert.strictEqual(missing.length, 1)
91
- assert.strictEqual(missing[0].secretId, 'GITHUB_TOKEN')
92
- })
93
- })
@@ -1,70 +0,0 @@
1
- import type { SecretService } from './secret-service.js'
2
-
3
- export interface CredentialStatus {
4
- secretId: string
5
- name: string
6
- displayName: string
7
- isConfigured: boolean
8
- oauth2?: { tokenSecretId: string }
9
- }
10
-
11
- export type CredentialMeta = {
12
- name: string
13
- displayName: string
14
- oauth2?: { tokenSecretId: string }
15
- }
16
-
17
- export class TypedSecretService<TMap = Record<string, unknown>>
18
- implements SecretService
19
- {
20
- constructor(
21
- private secrets: SecretService,
22
- private credentialsMeta: Record<string, CredentialMeta>
23
- ) {}
24
-
25
- async getSecretJSON<K extends keyof TMap & string>(key: K): Promise<TMap[K]>
26
- async getSecretJSON<T = unknown>(key: string): Promise<T>
27
- async getSecretJSON(key: string): Promise<unknown> {
28
- return this.secrets.getSecretJSON(key)
29
- }
30
-
31
- async getSecret(key: string): Promise<string> {
32
- return this.secrets.getSecret(key)
33
- }
34
-
35
- async hasSecret(key: string): Promise<boolean> {
36
- return this.secrets.hasSecret(key)
37
- }
38
-
39
- async setSecretJSON<K extends string>(
40
- key: K,
41
- value: K extends keyof TMap ? TMap[K] : unknown
42
- ): Promise<void> {
43
- return this.secrets.setSecretJSON(key, value)
44
- }
45
-
46
- async deleteSecret(key: string): Promise<void> {
47
- return this.secrets.deleteSecret(key)
48
- }
49
-
50
- async getAllStatus(): Promise<CredentialStatus[]> {
51
- const results: CredentialStatus[] = []
52
-
53
- for (const [secretId, meta] of Object.entries(this.credentialsMeta)) {
54
- results.push({
55
- secretId,
56
- name: meta.name,
57
- displayName: meta.displayName,
58
- isConfigured: await this.secrets.hasSecret(secretId),
59
- oauth2: meta.oauth2,
60
- })
61
- }
62
-
63
- return results
64
- }
65
-
66
- async getMissing(): Promise<CredentialStatus[]> {
67
- const all = await this.getAllStatus()
68
- return all.filter((c) => !c.isConfigured)
69
- }
70
- }
@@ -1,73 +0,0 @@
1
- import { describe, test } from 'node:test'
2
- import assert from 'node:assert'
3
- import { TypedVariablesService } from './typed-variables-service.js'
4
- import { LocalVariablesService } from './local-variables.js'
5
-
6
- describe('TypedVariablesService', () => {
7
- const createService = (vars: Record<string, string | undefined> = {}) => {
8
- const underlying = new LocalVariablesService(vars)
9
- const meta = {
10
- DB_URL: { name: 'DB_URL', displayName: 'Database URL' },
11
- API_KEY: { name: 'API_KEY', displayName: 'API Key' },
12
- }
13
- return new TypedVariablesService(underlying, meta)
14
- }
15
-
16
- test('should delegate get to underlying service', () => {
17
- const service = createService({ DB_URL: 'postgres://...' })
18
- assert.strictEqual(service.get('DB_URL'), 'postgres://...')
19
- })
20
-
21
- test('should delegate set to underlying service', () => {
22
- const service = createService()
23
- service.set('DB_URL', 'new-value')
24
- assert.strictEqual(service.get('DB_URL'), 'new-value')
25
- })
26
-
27
- test('should delegate has to underlying service', () => {
28
- const service = createService({ DB_URL: 'val' })
29
- assert.strictEqual(service.has('DB_URL'), true)
30
- assert.strictEqual(service.has('MISSING'), false)
31
- })
32
-
33
- test('should delegate delete to underlying service', () => {
34
- const service = createService({ DB_URL: 'val' })
35
- service.delete('DB_URL')
36
- assert.strictEqual(service.has('DB_URL'), false)
37
- })
38
-
39
- test('should delegate getJSON to underlying service', () => {
40
- const service = createService({ DATA: '{"key":"val"}' })
41
- assert.deepStrictEqual(service.getJSON('DATA'), { key: 'val' })
42
- })
43
-
44
- test('should delegate setJSON to underlying service', () => {
45
- const service = createService()
46
- service.setJSON('DATA', { key: 'val' })
47
- assert.strictEqual(service.get('DATA'), '{"key":"val"}')
48
- })
49
-
50
- test('should get all status for configured variables', async () => {
51
- const service = createService({ DB_URL: 'postgres://...' })
52
- const status = await service.getAllStatus()
53
- assert.strictEqual(status.length, 2)
54
- const dbStatus = status.find((s) => s.variableId === 'DB_URL')!
55
- assert.strictEqual(dbStatus.isConfigured, true)
56
- assert.strictEqual(dbStatus.displayName, 'Database URL')
57
- const apiStatus = status.find((s) => s.variableId === 'API_KEY')!
58
- assert.strictEqual(apiStatus.isConfigured, false)
59
- })
60
-
61
- test('should get missing variables', async () => {
62
- const service = createService({ DB_URL: 'val' })
63
- const missing = await service.getMissing()
64
- assert.strictEqual(missing.length, 1)
65
- assert.strictEqual(missing[0].variableId, 'API_KEY')
66
- })
67
-
68
- test('should return empty missing when all configured', async () => {
69
- const service = createService({ DB_URL: 'val', API_KEY: 'key' })
70
- const missing = await service.getMissing()
71
- assert.strictEqual(missing.length, 0)
72
- })
73
- })
@@ -1,81 +0,0 @@
1
- import type { VariablesService } from './variables-service.js'
2
-
3
- export interface VariableStatus {
4
- variableId: string
5
- name: string
6
- displayName: string
7
- isConfigured: boolean
8
- }
9
-
10
- export type VariableMeta = {
11
- name: string
12
- displayName: string
13
- }
14
-
15
- export class TypedVariablesService<TMap = Record<string, unknown>>
16
- implements VariablesService
17
- {
18
- constructor(
19
- private variables: VariablesService,
20
- private variablesMeta: Record<string, VariableMeta>
21
- ) {}
22
-
23
- get(
24
- name: keyof TMap & string
25
- ): Promise<string | undefined> | string | undefined
26
- get(name: string): Promise<string | undefined> | string | undefined
27
- get(name: string): Promise<string | undefined> | string | undefined {
28
- return this.variables.get(name)
29
- }
30
-
31
- getJSON<K extends keyof TMap & string>(
32
- name: K
33
- ): Promise<TMap[K] | undefined> | TMap[K] | undefined
34
- getJSON<T = unknown>(name: string): Promise<T | undefined> | T | undefined
35
- getJSON(name: string): Promise<unknown> | unknown {
36
- return this.variables.getJSON(name)
37
- }
38
-
39
- getAll():
40
- | Promise<Record<string, string | undefined>>
41
- | Record<string, string | undefined> {
42
- return this.variables.getAll()
43
- }
44
-
45
- set(name: string, value: string): Promise<void> | void {
46
- return this.variables.set(name, value)
47
- }
48
-
49
- setJSON(name: string, value: unknown): Promise<void> | void {
50
- return this.variables.setJSON(name, value)
51
- }
52
-
53
- has(name: string): Promise<boolean> | boolean {
54
- return this.variables.has(name)
55
- }
56
-
57
- delete(name: string): Promise<void> | void {
58
- return this.variables.delete(name)
59
- }
60
-
61
- async getAllStatus(): Promise<VariableStatus[]> {
62
- const results: VariableStatus[] = []
63
- const all = await this.variables.getAll()
64
-
65
- for (const [variableId, meta] of Object.entries(this.variablesMeta)) {
66
- results.push({
67
- variableId,
68
- name: meta.name,
69
- displayName: meta.displayName,
70
- isConfigured: all[variableId] !== undefined,
71
- })
72
- }
73
-
74
- return results
75
- }
76
-
77
- async getMissing(): Promise<VariableStatus[]> {
78
- const all = await this.getAllStatus()
79
- return all.filter((v) => !v.isConfigured)
80
- }
81
- }
@@ -1,113 +0,0 @@
1
- import { describe, test } from 'node:test'
2
- import assert from 'node:assert'
3
- import {
4
- PikkuSessionService,
5
- createMiddlewareSessionWireProps,
6
- createFunctionSessionWireProps,
7
- } from './user-session-service.js'
8
-
9
- describe('PikkuSessionService', () => {
10
- test('should set and get session', () => {
11
- const service = new PikkuSessionService()
12
- service.setInitial({ userId: 'user-1' })
13
- const session = service.get()
14
- assert.deepStrictEqual(session, { userId: 'user-1' })
15
- })
16
-
17
- test('should return undefined when no session set', () => {
18
- const service = new PikkuSessionService()
19
- assert.strictEqual(service.get(), undefined)
20
- })
21
-
22
- test('should mark sessionChanged when set is called', () => {
23
- const service = new PikkuSessionService()
24
- assert.strictEqual(service.sessionChanged, false)
25
- service.set({ userId: 'user-1' })
26
- assert.strictEqual(service.sessionChanged, true)
27
- })
28
-
29
- test('should clear session', () => {
30
- const service = new PikkuSessionService()
31
- service.setInitial({ userId: 'user-1' })
32
- service.clear()
33
- assert.strictEqual(service.get(), undefined)
34
- assert.strictEqual(service.sessionChanged, true)
35
- })
36
-
37
- test('should freeze initial session', () => {
38
- const service = new PikkuSessionService()
39
- service.setInitial({ userId: 'user-1' })
40
- const frozen = service.freezeInitial()
41
- assert.deepStrictEqual(frozen, { userId: 'user-1' })
42
- })
43
-
44
- test('should only freeze initial once', () => {
45
- const service = new PikkuSessionService()
46
- service.setInitial({ userId: 'user-1' })
47
- service.freezeInitial()
48
- service.set({ userId: 'user-2' })
49
- const frozen2 = service.freezeInitial()
50
- assert.deepStrictEqual(frozen2, { userId: 'user-1' })
51
- })
52
-
53
- test('should throw when channelStore provided without channelId', () => {
54
- assert.throws(() => new PikkuSessionService({} as any), {
55
- message: 'Channel ID is required when using channel store',
56
- })
57
- })
58
-
59
- test('should use channelStore when provided', async () => {
60
- let storedSession: any
61
- const store = {
62
- setUserSession: (id: string, session: any) => {
63
- storedSession = session
64
- },
65
- getChannelAndSession: (id: string) => ({ session: { userId: 'stored' } }),
66
- }
67
- const service = new PikkuSessionService(store as any, 'ch-1')
68
- service.set({ userId: 'new' })
69
- assert.deepStrictEqual(storedSession, { userId: 'new' })
70
-
71
- const session = service.get()
72
- assert.deepStrictEqual(session, { userId: 'stored' })
73
- })
74
- })
75
-
76
- describe('createMiddlewareSessionWireProps', () => {
77
- test('should return session wire props', () => {
78
- const service = new PikkuSessionService()
79
- service.setInitial({ userId: 'user-1' })
80
- const props = createMiddlewareSessionWireProps(service)
81
- assert.ok('session' in props)
82
- assert.ok('setSession' in props)
83
- assert.ok('getSession' in props)
84
- assert.ok('hasSessionChanged' in props)
85
- })
86
-
87
- test('setSession should call setInitial', () => {
88
- const service = new PikkuSessionService()
89
- const props = createMiddlewareSessionWireProps(service)
90
- props.setSession({ userId: 'user-2' })
91
- assert.deepStrictEqual(service.get(), { userId: 'user-2' })
92
- })
93
- })
94
-
95
- describe('createFunctionSessionWireProps', () => {
96
- test('should return function session wire props', () => {
97
- const service = new PikkuSessionService()
98
- service.setInitial({ userId: 'user-1' })
99
- const props = createFunctionSessionWireProps(service)
100
- assert.ok('session' in props)
101
- assert.ok('setSession' in props)
102
- assert.ok('clearSession' in props)
103
- assert.ok('getSession' in props)
104
- assert.ok('hasSessionChanged' in props)
105
- })
106
-
107
- test('session should be frozen initial', () => {
108
- const service = new PikkuSessionService()
109
- service.setInitial({ userId: 'user-1' })
110
- const props = createFunctionSessionWireProps(service)
111
- assert.deepStrictEqual(props.session, { userId: 'user-1' })
112
- })
113
- })
@@ -1,86 +0,0 @@
1
- import type { ChannelStore } from '../wirings/channel/channel-store.js'
2
- import type { CoreUserSession } from '../types/core.types.js'
3
-
4
- export interface SessionService<UserSession extends CoreUserSession> {
5
- sessionChanged: boolean
6
- initial: UserSession | undefined
7
- setInitial(session: UserSession): void
8
- freezeInitial(): UserSession | undefined
9
- set(session: UserSession): Promise<void> | void
10
- clear(): Promise<void> | void
11
- get(): Promise<UserSession> | UserSession | undefined
12
- }
13
-
14
- export class PikkuSessionService<UserSession extends CoreUserSession>
15
- implements SessionService<UserSession>
16
- {
17
- public sessionChanged = false
18
- public initial: UserSession | undefined
19
- private session: UserSession | undefined
20
- constructor(
21
- private channelStore?: ChannelStore<unknown, unknown, UserSession>,
22
- private channelId?: string
23
- ) {
24
- if (channelStore && !channelId) {
25
- throw new Error('Channel ID is required when using channel store')
26
- }
27
- }
28
-
29
- public setInitial(session: UserSession) {
30
- this.session = session
31
- }
32
-
33
- public freezeInitial() {
34
- if (this.initial === undefined) {
35
- this.initial = this.session
36
- }
37
- return this.initial
38
- }
39
-
40
- public set(session: UserSession) {
41
- this.sessionChanged = true
42
- this.session = session
43
- return this.channelStore?.setUserSession(this.channelId!, session)
44
- }
45
-
46
- public clear() {
47
- this.sessionChanged = true
48
- this.session = undefined
49
- return this.channelStore?.setUserSession(this.channelId!, null)
50
- }
51
-
52
- public get(): Promise<UserSession> | UserSession | undefined {
53
- if (this.channelStore) {
54
- const channel = this.channelStore.getChannelAndSession(this.channelId!)
55
- if (channel instanceof Promise) {
56
- return channel.then(({ session }) => session)
57
- } else {
58
- return channel.session
59
- }
60
- }
61
- return this.session
62
- }
63
- }
64
-
65
- export function createMiddlewareSessionWireProps<
66
- UserSession extends CoreUserSession,
67
- >(session: SessionService<UserSession>) {
68
- return {
69
- session: session.get() as UserSession | undefined,
70
- setSession: (s: UserSession) => session.setInitial(s),
71
- getSession: () => session.get(),
72
- hasSessionChanged: () => session.sessionChanged,
73
- }
74
- }
75
-
76
- export function createFunctionSessionWireProps<
77
- UserSession extends CoreUserSession,
78
- >(session: SessionService<UserSession>) {
79
- return {
80
- session: session.freezeInitial(),
81
- setSession: (s: UserSession) => session.set(s),
82
- clearSession: () => session.clear(),
83
- getSession: () => session.get(),
84
- hasSessionChanged: () => session.sessionChanged,
85
- }
86
- }