@pikku/core 0.12.0 → 0.12.2

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 (290) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/errors/errors.d.ts +6 -0
  3. package/dist/errors/errors.js +10 -0
  4. package/dist/errors/index.d.ts +1 -0
  5. package/dist/errors/index.js +1 -0
  6. package/dist/function/function-runner.d.ts +3 -3
  7. package/dist/function/function-runner.js +66 -44
  8. package/dist/function/functions.types.d.ts +1 -0
  9. package/dist/handle-error.d.ts +2 -2
  10. package/dist/handle-error.js +2 -2
  11. package/dist/index.d.ts +5 -3
  12. package/dist/index.js +2 -1
  13. package/dist/internal.d.ts +3 -0
  14. package/dist/internal.js +2 -0
  15. package/dist/middleware/auth-bearer.d.ts +1 -1
  16. package/dist/middleware/auth-bearer.js +1 -1
  17. package/dist/middleware/auth-cookie.d.ts +2 -2
  18. package/dist/middleware/auth-cookie.js +1 -1
  19. package/dist/middleware/cors.d.ts +2 -2
  20. package/dist/middleware/cors.js +45 -37
  21. package/dist/middleware-runner.d.ts +1 -1
  22. package/dist/middleware-runner.js +1 -0
  23. package/dist/permissions.d.ts +2 -2
  24. package/dist/permissions.js +1 -0
  25. package/dist/pikku-state.d.ts +9 -8
  26. package/dist/pikku-state.js +34 -17
  27. package/dist/schema.d.ts +4 -4
  28. package/dist/schema.js +9 -5
  29. package/dist/services/ai-agent-runner-service.d.ts +22 -3
  30. package/dist/services/ai-run-state-service.d.ts +1 -1
  31. package/dist/services/ai-storage-service.d.ts +1 -1
  32. package/dist/services/content-service.d.ts +6 -0
  33. package/dist/services/gateway-service.d.ts +19 -0
  34. package/dist/services/gopass-secrets.d.ts +1 -1
  35. package/dist/services/gopass-secrets.js +3 -0
  36. package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
  37. package/dist/services/in-memory-ai-run-state-service.js +44 -0
  38. package/dist/services/in-memory-trigger-service.d.ts +0 -1
  39. package/dist/services/in-memory-trigger-service.js +6 -8
  40. package/dist/services/index.d.ts +5 -2
  41. package/dist/services/index.js +2 -0
  42. package/dist/services/local-content.d.ts +2 -1
  43. package/dist/services/local-content.js +6 -1
  44. package/dist/services/local-gateway-service.d.ts +22 -0
  45. package/dist/services/local-gateway-service.js +51 -0
  46. package/dist/services/local-secrets.d.ts +2 -2
  47. package/dist/services/local-variables.d.ts +1 -1
  48. package/dist/services/logger-console.d.ts +2 -1
  49. package/dist/services/scheduler-service.d.ts +0 -12
  50. package/dist/services/scheduler-service.js +0 -6
  51. package/dist/services/scoped-secret-service.d.ts +1 -1
  52. package/dist/services/trigger-service.d.ts +0 -7
  53. package/dist/services/user-session-service.d.ts +3 -3
  54. package/dist/services/workflow-service.d.ts +2 -3
  55. package/dist/types/core.types.d.ts +27 -19
  56. package/dist/types/state.types.d.ts +22 -15
  57. package/dist/utils.d.ts +5 -5
  58. package/dist/utils.js +12 -9
  59. package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
  60. package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +168 -0
  61. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
  62. package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
  63. package/dist/wirings/ai-agent/ai-agent-memory.js +13 -2
  64. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +4 -5
  65. package/dist/wirings/ai-agent/ai-agent-prepare.js +80 -31
  66. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +1 -1
  67. package/dist/wirings/ai-agent/ai-agent-runner.js +107 -8
  68. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
  69. package/dist/wirings/ai-agent/ai-agent-stream.js +263 -89
  70. package/dist/wirings/ai-agent/ai-agent.types.d.ts +96 -4
  71. package/dist/wirings/ai-agent/index.d.ts +3 -1
  72. package/dist/wirings/ai-agent/index.js +2 -0
  73. package/dist/wirings/channel/channel-common.d.ts +2 -2
  74. package/dist/wirings/channel/channel-handler.d.ts +7 -4
  75. package/dist/wirings/channel/channel-handler.js +15 -5
  76. package/dist/wirings/channel/channel-middleware-runner.js +1 -0
  77. package/dist/wirings/channel/channel-runner.d.ts +5 -5
  78. package/dist/wirings/channel/channel-runner.js +3 -2
  79. package/dist/wirings/channel/channel-store.d.ts +1 -1
  80. package/dist/wirings/channel/channel.types.d.ts +10 -6
  81. package/dist/wirings/channel/index.d.ts +1 -1
  82. package/dist/wirings/channel/local/local-channel-handler.d.ts +7 -0
  83. package/dist/wirings/channel/local/local-channel-handler.js +17 -0
  84. package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
  85. package/dist/wirings/channel/local/local-channel-runner.js +18 -4
  86. package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
  87. package/dist/wirings/channel/log-channels.d.ts +1 -1
  88. package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +2 -1
  89. package/dist/wirings/channel/pikku-abstract-channel-handler.js +1 -0
  90. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +4 -4
  91. package/dist/wirings/channel/serverless/serverless-channel-runner.js +26 -20
  92. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
  93. package/dist/wirings/cli/cli-runner.d.ts +2 -2
  94. package/dist/wirings/cli/cli-runner.js +3 -0
  95. package/dist/wirings/cli/cli.types.d.ts +3 -3
  96. package/dist/wirings/cli/command-parser.d.ts +1 -1
  97. package/dist/wirings/gateway/gateway-runner.d.ts +24 -0
  98. package/dist/wirings/gateway/gateway-runner.js +325 -0
  99. package/dist/wirings/gateway/gateway.types.d.ts +127 -0
  100. package/dist/wirings/gateway/index.d.ts +2 -0
  101. package/dist/wirings/gateway/index.js +1 -0
  102. package/dist/wirings/http/http-runner.d.ts +9 -9
  103. package/dist/wirings/http/http-runner.js +36 -14
  104. package/dist/wirings/http/http.types.d.ts +2 -6
  105. package/dist/wirings/http/log-http-routes.d.ts +1 -1
  106. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
  107. package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
  108. package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
  109. package/dist/wirings/http/routers/http-router.d.ts +1 -1
  110. package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
  111. package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
  112. package/dist/wirings/mcp/mcp-runner.d.ts +0 -3
  113. package/dist/wirings/mcp/mcp-runner.js +4 -2
  114. package/dist/wirings/mcp/mcp.types.d.ts +2 -2
  115. package/dist/wirings/oauth2/oauth2-client.d.ts +3 -3
  116. package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +1 -1
  117. package/dist/wirings/queue/index.d.ts +1 -1
  118. package/dist/wirings/queue/index.js +1 -1
  119. package/dist/wirings/queue/queue-runner.d.ts +1 -12
  120. package/dist/wirings/queue/queue-runner.js +4 -12
  121. package/dist/wirings/queue/queue.types.d.ts +3 -9
  122. package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
  123. package/dist/wirings/queue/register-queue-helper.js +1 -1
  124. package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
  125. package/dist/wirings/rpc/index.d.ts +2 -0
  126. package/dist/wirings/rpc/index.js +1 -0
  127. package/dist/wirings/rpc/rpc-runner.d.ts +36 -14
  128. package/dist/wirings/rpc/rpc-runner.js +56 -28
  129. package/dist/wirings/rpc/rpc-types.d.ts +14 -2
  130. package/dist/wirings/rpc/wire-addon.d.ts +10 -0
  131. package/dist/wirings/rpc/wire-addon.js +9 -0
  132. package/dist/wirings/scheduler/index.d.ts +1 -1
  133. package/dist/wirings/scheduler/index.js +1 -1
  134. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
  135. package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -10
  136. package/dist/wirings/scheduler/scheduler-runner.js +4 -25
  137. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
  138. package/dist/wirings/trigger/pikku-trigger-service.d.ts +2 -6
  139. package/dist/wirings/trigger/pikku-trigger-service.js +11 -16
  140. package/dist/wirings/trigger/trigger-runner.d.ts +1 -5
  141. package/dist/wirings/trigger/trigger-runner.js +4 -3
  142. package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -6
  143. package/dist/wirings/workflow/pikku-workflow-service.js +20 -29
  144. package/dist/wirings/workflow/workflow.types.d.ts +2 -2
  145. package/package.json +4 -2
  146. package/src/crypto-utils.test.ts +116 -0
  147. package/src/errors/error.test.ts +143 -2
  148. package/src/errors/errors.ts +10 -0
  149. package/src/errors/index.ts +1 -0
  150. package/src/function/function-runner.test.ts +2 -2
  151. package/src/function/function-runner.ts +72 -49
  152. package/src/function/functions.types.ts +1 -0
  153. package/src/handle-error.test.ts +361 -0
  154. package/src/handle-error.ts +4 -4
  155. package/src/index.ts +3 -10
  156. package/src/internal.ts +6 -0
  157. package/src/middleware/auth-apikey.test.ts +1 -1
  158. package/src/middleware/auth-bearer.test.ts +1 -1
  159. package/src/middleware/auth-bearer.ts +2 -5
  160. package/src/middleware/auth-cookie.test.ts +1 -1
  161. package/src/middleware/auth-cookie.ts +3 -5
  162. package/src/middleware/cors.test.ts +424 -0
  163. package/src/middleware/cors.ts +14 -6
  164. package/src/middleware/remote-auth.test.ts +488 -0
  165. package/src/middleware-runner.test.ts +1 -1
  166. package/src/middleware-runner.ts +2 -1
  167. package/src/permissions.test.ts +2 -2
  168. package/src/permissions.ts +3 -2
  169. package/src/pikku-state.test.ts +224 -0
  170. package/src/pikku-state.ts +45 -28
  171. package/src/schema.test.ts +198 -6
  172. package/src/schema.ts +11 -7
  173. package/src/services/ai-agent-runner-service.ts +15 -3
  174. package/src/services/ai-run-state-service.ts +1 -1
  175. package/src/services/ai-storage-service.ts +1 -1
  176. package/src/services/content-service.ts +7 -0
  177. package/src/services/gateway-service.ts +20 -0
  178. package/src/services/gopass-secrets.ts +4 -1
  179. package/src/services/in-memory-ai-run-state-service.ts +73 -0
  180. package/src/services/in-memory-trigger-service.ts +6 -10
  181. package/src/services/in-memory-workflow-service.test.ts +351 -0
  182. package/src/services/index.ts +4 -1
  183. package/src/services/local-content.ts +9 -3
  184. package/src/services/local-gateway-service.ts +62 -0
  185. package/src/services/local-secrets.test.ts +80 -0
  186. package/src/services/local-secrets.ts +2 -2
  187. package/src/services/local-variables.test.ts +61 -0
  188. package/src/services/local-variables.ts +1 -1
  189. package/src/services/logger-console.test.ts +118 -0
  190. package/src/services/logger-console.ts +2 -1
  191. package/src/services/scheduler-service.ts +0 -18
  192. package/src/services/scoped-secret-service.test.ts +74 -0
  193. package/src/services/scoped-secret-service.ts +1 -1
  194. package/src/services/trigger-service.ts +0 -21
  195. package/src/services/typed-secret-service.test.ts +93 -0
  196. package/src/services/typed-variables-service.test.ts +73 -0
  197. package/src/services/user-session-service.test.ts +113 -0
  198. package/src/services/user-session-service.ts +3 -3
  199. package/src/services/workflow-service.ts +2 -12
  200. package/src/time-utils.test.ts +1 -1
  201. package/src/types/core.types.ts +28 -19
  202. package/src/types/state.types.ts +32 -15
  203. package/src/utils.test.ts +350 -0
  204. package/src/utils.ts +14 -13
  205. package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
  206. package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +238 -0
  207. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
  208. package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
  209. package/src/wirings/ai-agent/ai-agent-memory.ts +10 -1
  210. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
  211. package/src/wirings/ai-agent/ai-agent-prepare.ts +98 -46
  212. package/src/wirings/ai-agent/ai-agent-registry.ts +1 -1
  213. package/src/wirings/ai-agent/ai-agent-runner.test.ts +245 -3
  214. package/src/wirings/ai-agent/ai-agent-runner.ts +121 -7
  215. package/src/wirings/ai-agent/ai-agent-stream.test.ts +430 -24
  216. package/src/wirings/ai-agent/ai-agent-stream.ts +390 -104
  217. package/src/wirings/ai-agent/ai-agent.types.ts +91 -4
  218. package/src/wirings/ai-agent/index.ts +13 -0
  219. package/src/wirings/channel/channel-common.ts +2 -2
  220. package/src/wirings/channel/channel-handler.ts +43 -11
  221. package/src/wirings/channel/channel-middleware-runner.ts +1 -0
  222. package/src/wirings/channel/channel-runner.ts +6 -6
  223. package/src/wirings/channel/channel-store.ts +1 -1
  224. package/src/wirings/channel/channel.types.ts +15 -8
  225. package/src/wirings/channel/index.ts +1 -0
  226. package/src/wirings/channel/local/local-channel-handler.ts +26 -0
  227. package/src/wirings/channel/local/local-channel-runner.test.ts +19 -12
  228. package/src/wirings/channel/local/local-channel-runner.ts +33 -14
  229. package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
  230. package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
  231. package/src/wirings/channel/log-channels.ts +1 -1
  232. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +2 -0
  233. package/src/wirings/channel/pikku-abstract-channel-handler.ts +8 -1
  234. package/src/wirings/channel/serverless/serverless-channel-runner.ts +38 -33
  235. package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
  236. package/src/wirings/cli/cli-runner.test.ts +1 -1
  237. package/src/wirings/cli/cli-runner.ts +14 -4
  238. package/src/wirings/cli/cli.types.ts +3 -3
  239. package/src/wirings/cli/command-parser.test.ts +1 -1
  240. package/src/wirings/cli/command-parser.ts +1 -1
  241. package/src/wirings/gateway/gateway-runner.test.ts +474 -0
  242. package/src/wirings/gateway/gateway-runner.ts +411 -0
  243. package/src/wirings/gateway/gateway.types.ts +149 -0
  244. package/src/wirings/gateway/index.ts +13 -0
  245. package/src/wirings/http/http-routes.test.ts +1 -1
  246. package/src/wirings/http/http-runner.test.ts +9 -17
  247. package/src/wirings/http/http-runner.ts +46 -27
  248. package/src/wirings/http/http.types.ts +1 -14
  249. package/src/wirings/http/log-http-routes.ts +1 -1
  250. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  251. package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
  252. package/src/wirings/http/routers/http-router.ts +1 -1
  253. package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
  254. package/src/wirings/http/routers/path-to-regex.ts +4 -3
  255. package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
  256. package/src/wirings/mcp/mcp-runner.ts +9 -15
  257. package/src/wirings/mcp/mcp.types.ts +2 -2
  258. package/src/wirings/oauth2/oauth2-client.ts +3 -3
  259. package/src/wirings/oauth2/wire-oauth2-credential.ts +1 -1
  260. package/src/wirings/queue/index.ts +0 -1
  261. package/src/wirings/queue/queue-runner.test.ts +52 -25
  262. package/src/wirings/queue/queue-runner.ts +8 -30
  263. package/src/wirings/queue/queue.types.ts +3 -13
  264. package/src/wirings/queue/register-queue-helper.ts +3 -5
  265. package/src/wirings/queue/validate-worker-config.test.ts +108 -0
  266. package/src/wirings/queue/validate-worker-config.ts +4 -1
  267. package/src/wirings/rpc/index.ts +2 -0
  268. package/src/wirings/rpc/rpc-runner.ts +92 -49
  269. package/src/wirings/rpc/rpc-types.ts +17 -2
  270. package/src/wirings/rpc/wire-addon.ts +20 -0
  271. package/src/wirings/scheduler/index.ts +0 -1
  272. package/src/wirings/scheduler/log-schedulers.ts +1 -1
  273. package/src/wirings/scheduler/scheduler-runner.test.ts +49 -60
  274. package/src/wirings/scheduler/scheduler-runner.ts +9 -56
  275. package/src/wirings/scheduler/scheduler.types.ts +2 -2
  276. package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
  277. package/src/wirings/trigger/pikku-trigger-service.ts +17 -39
  278. package/src/wirings/trigger/trigger-runner.test.ts +79 -0
  279. package/src/wirings/trigger/trigger-runner.ts +8 -11
  280. package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
  281. package/src/wirings/workflow/graph/graph-runner.test.ts +14 -22
  282. package/src/wirings/workflow/graph/template.test.ts +49 -0
  283. package/src/wirings/workflow/pikku-workflow-service.test.ts +15 -27
  284. package/src/wirings/workflow/pikku-workflow-service.ts +29 -45
  285. package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
  286. package/src/wirings/workflow/workflow.types.ts +2 -2
  287. package/tsconfig.tsbuildinfo +1 -1
  288. package/src/wirings/workflow/workflow-utils.ts +0 -0
  289. /package/dist/{wirings/workflow/workflow-utils.d.ts → services/gateway-service.js} +0 -0
  290. /package/dist/wirings/{workflow/workflow-utils.js → gateway/gateway.types.js} +0 -0
@@ -4,11 +4,10 @@ import {
4
4
  wireScheduler,
5
5
  runScheduledTask,
6
6
  getScheduledTasks,
7
- createSchedulerRuntimeHandlers,
8
7
  } from './scheduler-runner.js'
9
8
  import { resetPikkuState, pikkuState } from '../../pikku-state.js'
10
- import { CoreScheduledTask } from './scheduler.types.js'
11
- import { CoreUserSession } from '../../types/core.types.js'
9
+ import type { CoreScheduledTask } from './scheduler.types.js'
10
+ import type { CoreUserSession } from '../../types/core.types.js'
12
11
 
13
12
  beforeEach(() => {
14
13
  resetPikkuState()
@@ -168,9 +167,11 @@ describe('runScheduledTask', () => {
168
167
  wireScheduler(mockTask)
169
168
 
170
169
  const mockLogger = createMockLogger()
170
+ pikkuState(null, 'package', 'singletonServices', {
171
+ logger: mockLogger,
172
+ } as any)
171
173
  await runScheduledTask({
172
174
  name: 'simple-task',
173
- singletonServices: { logger: mockLogger } as any,
174
175
  })
175
176
 
176
177
  assert.equal(taskExecuted, true)
@@ -208,12 +209,14 @@ describe('runScheduledTask', () => {
208
209
  wireScheduler(mockTask)
209
210
 
210
211
  const mockLogger = createMockLogger()
212
+ pikkuState(null, 'package', 'singletonServices', {
213
+ logger: mockLogger,
214
+ } as any)
211
215
  const session: CoreUserSession = { userId: 'user123' }
212
216
 
213
217
  await runScheduledTask({
214
218
  name: 'task-with-session',
215
219
  session,
216
- singletonServices: { logger: mockLogger } as any,
217
220
  })
218
221
 
219
222
  assert.deepEqual(receivedSession, session)
@@ -221,12 +224,14 @@ describe('runScheduledTask', () => {
221
224
 
222
225
  test('should throw ScheduledTaskNotFoundError when task not found', async () => {
223
226
  const mockLogger = createMockLogger()
227
+ pikkuState(null, 'package', 'singletonServices', {
228
+ logger: mockLogger,
229
+ } as any)
224
230
 
225
231
  await assert.rejects(
226
232
  async () => {
227
233
  await runScheduledTask({
228
234
  name: 'non-existent-task',
229
- singletonServices: { logger: mockLogger } as any,
230
235
  })
231
236
  },
232
237
  (error: any) => {
@@ -250,12 +255,14 @@ describe('runScheduledTask', () => {
250
255
  pikkuState(null, 'scheduler', 'tasks').set('task-without-meta', mockTask)
251
256
 
252
257
  const mockLogger = createMockLogger()
258
+ pikkuState(null, 'package', 'singletonServices', {
259
+ logger: mockLogger,
260
+ } as any)
253
261
 
254
262
  await assert.rejects(
255
263
  async () => {
256
264
  await runScheduledTask({
257
265
  name: 'task-without-meta',
258
- singletonServices: { logger: mockLogger } as any,
259
266
  })
260
267
  },
261
268
  (error: any) => {
@@ -290,12 +297,14 @@ describe('runScheduledTask', () => {
290
297
  wireScheduler(mockTask)
291
298
 
292
299
  const mockLogger = createMockLogger()
300
+ pikkuState(null, 'package', 'singletonServices', {
301
+ logger: mockLogger,
302
+ } as any)
293
303
 
294
304
  await assert.rejects(
295
305
  async () => {
296
306
  await runScheduledTask({
297
307
  name: 'skipped-task',
298
- singletonServices: { logger: mockLogger } as any,
299
308
  })
300
309
  },
301
310
  (error: any) => {
@@ -333,12 +342,14 @@ describe('runScheduledTask', () => {
333
342
  wireScheduler(mockTask)
334
343
 
335
344
  const mockLogger = createMockLogger()
345
+ pikkuState(null, 'package', 'singletonServices', {
346
+ logger: mockLogger,
347
+ } as any)
336
348
 
337
349
  await assert.rejects(
338
350
  async () => {
339
351
  await runScheduledTask({
340
352
  name: 'skipped-task-no-reason',
341
- singletonServices: { logger: mockLogger } as any,
342
353
  })
343
354
  },
344
355
  (error: any) => {
@@ -379,10 +390,12 @@ describe('runScheduledTask', () => {
379
390
  wireScheduler(mockTask)
380
391
 
381
392
  const mockLogger = createMockLogger()
393
+ pikkuState(null, 'package', 'singletonServices', {
394
+ logger: mockLogger,
395
+ } as any)
382
396
 
383
397
  await runScheduledTask({
384
398
  name: 'wire-task',
385
- singletonServices: { logger: mockLogger } as any,
386
399
  })
387
400
 
388
401
  assert.equal(capturedWire.scheduledTask.name, 'wire-task')
@@ -417,14 +430,18 @@ describe('runScheduledTask', () => {
417
430
  wireScheduler(mockTask)
418
431
 
419
432
  const mockLogger = createMockLogger()
420
-
421
- await runScheduledTask({
422
- name: 'session-services-task',
423
- singletonServices: { logger: mockLogger } as any,
433
+ pikkuState(null, 'package', 'singletonServices', {
434
+ logger: mockLogger,
435
+ } as any)
436
+ pikkuState(null, 'package', 'factories', {
424
437
  createWireServices: async () => {
425
438
  createWireServicesCalled = true
426
439
  return mockWireService as any
427
440
  },
441
+ } as any)
442
+
443
+ await runScheduledTask({
444
+ name: 'session-services-task',
428
445
  })
429
446
 
430
447
  assert.equal(createWireServicesCalled, true)
@@ -462,11 +479,15 @@ describe('runScheduledTask', () => {
462
479
  wireScheduler(mockTask)
463
480
 
464
481
  const mockLogger = createMockLogger()
482
+ pikkuState(null, 'package', 'singletonServices', {
483
+ logger: mockLogger,
484
+ } as any)
485
+ pikkuState(null, 'package', 'factories', {
486
+ createWireServices: async () => mockWireService as any,
487
+ } as any)
465
488
 
466
489
  await runScheduledTask({
467
490
  name: 'cleanup-task',
468
- singletonServices: { logger: mockLogger } as any,
469
- createWireServices: async () => mockWireService as any,
470
491
  })
471
492
 
472
493
  assert.equal(closeCalled, true)
@@ -506,12 +527,16 @@ describe('runScheduledTask', () => {
506
527
  wireScheduler(mockTask)
507
528
 
508
529
  const mockLogger = createMockLogger()
530
+ pikkuState(null, 'package', 'singletonServices', {
531
+ logger: mockLogger,
532
+ } as any)
533
+ pikkuState(null, 'package', 'factories', {
534
+ createWireServices: async () => mockWireService as any,
535
+ } as any)
509
536
 
510
537
  await assert.rejects(async () => {
511
538
  await runScheduledTask({
512
539
  name: 'error-cleanup-task',
513
- singletonServices: { logger: mockLogger } as any,
514
- createWireServices: async () => mockWireService as any,
515
540
  })
516
541
  })
517
542
 
@@ -543,11 +568,13 @@ describe('runScheduledTask', () => {
543
568
  wireScheduler(mockTask)
544
569
 
545
570
  const mockLogger = createMockLogger()
571
+ pikkuState(null, 'package', 'singletonServices', {
572
+ logger: mockLogger,
573
+ } as any)
546
574
 
547
575
  await assert.rejects(async () => {
548
576
  await runScheduledTask({
549
577
  name: 'error-task',
550
- singletonServices: { logger: mockLogger } as any,
551
578
  })
552
579
  })
553
580
 
@@ -590,10 +617,12 @@ describe('runScheduledTask', () => {
590
617
  wireScheduler(mockTask)
591
618
 
592
619
  const mockLogger = createMockLogger()
620
+ pikkuState(null, 'package', 'singletonServices', {
621
+ logger: mockLogger,
622
+ } as any)
593
623
 
594
624
  await runScheduledTask({
595
625
  name: 'middleware-task',
596
- singletonServices: { logger: mockLogger } as any,
597
626
  })
598
627
 
599
628
  assert.deepEqual(executionOrder, ['middleware', 'task'])
@@ -629,43 +658,3 @@ describe('getScheduledTasks', () => {
629
658
  assert.equal(tasks.size, 0)
630
659
  })
631
660
  })
632
-
633
- describe('createSchedulerRuntimeHandlers', () => {
634
- test('invokes RPC with optional session and runs scheduled task callback', async () => {
635
- const calls: Array<{ type: string; value: any }> = []
636
- const logger = createMockLogger()
637
- const singletonServices = { logger } as any
638
-
639
- const handlers = createSchedulerRuntimeHandlers({
640
- singletonServices,
641
- })
642
-
643
- const originalGetContextRPCService = (await import('../rpc/rpc-runner.js'))
644
- .rpcService.getContextRPCService
645
- ;(await import('../rpc/rpc-runner.js')).rpcService.getContextRPCService = ((
646
- _services: any,
647
- wire: any
648
- ) => {
649
- calls.push({ type: 'wire', value: wire })
650
- return {
651
- invoke: async (rpcName: string, data: any) => {
652
- calls.push({ type: 'invoke', value: { rpcName, data } })
653
- },
654
- } as any
655
- }) as any
656
-
657
- try {
658
- await handlers.invokeRPC('testRpc', { value: 1 }, { userId: 'u1' } as any)
659
- } finally {
660
- ;(await import('../rpc/rpc-runner.js')).rpcService.getContextRPCService =
661
- originalGetContextRPCService
662
- }
663
-
664
- assert.equal(calls[0]?.type, 'wire')
665
- assert.deepEqual(calls[0]?.value, { session: { userId: 'u1' } })
666
- assert.deepEqual(calls[1]?.value, {
667
- rpcName: 'testRpc',
668
- data: { value: 1 },
669
- })
670
- })
671
- })
@@ -1,36 +1,25 @@
1
- import {
2
- PikkuWire,
3
- type CoreServices,
4
- type CoreSingletonServices,
5
- type CoreUserSession,
6
- type CreateWireServices,
7
- } from '../../types/core.types.js'
1
+ import type { PikkuWire, CoreUserSession } from '../../types/core.types.js'
8
2
  import type { CoreScheduledTask } from './scheduler.types.js'
9
3
  import { getErrorResponse, PikkuError } from '../../errors/error-handler.js'
10
4
  import { PikkuMissingMetaError } from '../../errors/errors.js'
11
- import { closeWireServices } from '../../utils.js'
12
- import { pikkuState } from '../../pikku-state.js'
5
+ import {
6
+ getSingletonServices,
7
+ getCreateWireServices,
8
+ pikkuState,
9
+ } from '../../pikku-state.js'
13
10
  import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
14
11
  import {
15
12
  PikkuSessionService,
16
13
  createMiddlewareSessionWireProps,
17
14
  } from '../../services/user-session-service.js'
18
- import {
15
+ import type {
19
16
  CorePikkuFunctionConfig,
20
17
  CorePikkuFunctionSessionless,
21
18
  } from '../../function/functions.types.js'
22
- import { rpcService } from '../rpc/rpc-runner.js'
23
- import { SchedulerRuntimeHandlers } from '../../services/scheduler-service.js'
24
19
 
25
20
  export type RunScheduledTasksParams = {
26
21
  name: string
27
22
  session?: CoreUserSession
28
- singletonServices: CoreSingletonServices
29
- createWireServices?: CreateWireServices<
30
- CoreSingletonServices,
31
- CoreServices<CoreSingletonServices>,
32
- CoreUserSession
33
- >
34
23
  }
35
24
 
36
25
  export const wireScheduler = <
@@ -80,10 +69,9 @@ class ScheduledTaskSkippedError extends PikkuError {
80
69
  export async function runScheduledTask({
81
70
  name,
82
71
  session,
83
- singletonServices,
84
- createWireServices,
85
72
  }: RunScheduledTasksParams): Promise<void> {
86
- let wireServices: any
73
+ const singletonServices = getSingletonServices()
74
+ const createWireServices = getCreateWireServices()
87
75
  const task = pikkuState(null, 'scheduler', 'tasks').get(name)
88
76
  const meta = pikkuState(null, 'scheduler', 'meta')[name]
89
77
 
@@ -136,44 +124,9 @@ export async function runScheduledTask({
136
124
  singletonServices.logger.error(e)
137
125
  }
138
126
  throw e
139
- } finally {
140
- if (wireServices) {
141
- await closeWireServices(singletonServices.logger, wireServices)
142
- }
143
127
  }
144
128
  }
145
129
 
146
130
  export const getScheduledTasks = () => {
147
131
  return pikkuState(null, 'scheduler', 'tasks')
148
132
  }
149
-
150
- export const createSchedulerRuntimeHandlers = ({
151
- singletonServices,
152
- createWireServices,
153
- }: {
154
- singletonServices: CoreSingletonServices
155
- createWireServices?: CreateWireServices<
156
- CoreSingletonServices,
157
- CoreServices<CoreSingletonServices>,
158
- CoreUserSession
159
- >
160
- }): SchedulerRuntimeHandlers => {
161
- return {
162
- logger: singletonServices.logger,
163
- invokeRPC: async (
164
- rpcName: string,
165
- data?: any,
166
- session?: CoreUserSession
167
- ) => {
168
- const wire = session ? ({ session } as PikkuWire) : ({} as PikkuWire)
169
- const rpc = rpcService.getContextRPCService(singletonServices, wire)
170
- await rpc.invoke(rpcName, data)
171
- },
172
- runScheduledTask: async (name: string) =>
173
- runScheduledTask({
174
- name,
175
- singletonServices,
176
- createWireServices,
177
- }),
178
- }
179
- }
@@ -1,9 +1,9 @@
1
- import {
1
+ import type {
2
2
  CoreUserSession,
3
3
  CorePikkuMiddleware,
4
4
  CommonWireMeta,
5
5
  } from '../../types/core.types.js'
6
- import {
6
+ import type {
7
7
  CorePikkuFunctionConfig,
8
8
  CorePikkuFunctionSessionless,
9
9
  } from '../../function/functions.types.js'
@@ -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 { pikkuState } from '../../pikku-state.js'
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
- this.singletonServices!.logger.info(`Stopped trigger: ${name}`)
32
+ singletonServices.logger.info(`Stopped trigger: ${name}`)
52
33
  } catch (error) {
53
- this.singletonServices!.logger.error(
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 wireServices = await this.createWireServices?.(
106
- this.singletonServices!,
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
- this.singletonServices!.logger.info(
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
- this.singletonServices!.logger.info(
101
+ singletonServices.logger.info(
124
102
  `Trigger '${triggerName}' invoked RPC '${target.targetName}'`
125
103
  )
126
104
  }
127
105
  } catch (error) {
128
- this.singletonServices!.logger.error(
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
+ })