@pikku/core 0.11.2 → 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.
Files changed (436) hide show
  1. package/CHANGELOG.md +57 -2
  2. package/dist/crypto-utils.d.ts +2 -0
  3. package/dist/crypto-utils.js +78 -0
  4. package/dist/errors/errors.d.ts +14 -0
  5. package/dist/errors/errors.js +26 -0
  6. package/dist/errors/index.d.ts +1 -1
  7. package/dist/errors/index.js +1 -1
  8. package/dist/function/function-runner.d.ts +10 -4
  9. package/dist/function/function-runner.js +126 -45
  10. package/dist/function/functions.types.d.ts +32 -87
  11. package/dist/function/functions.types.js +16 -46
  12. package/dist/function/index.d.ts +2 -2
  13. package/dist/function/index.js +1 -2
  14. package/dist/handle-error.d.ts +2 -2
  15. package/dist/handle-error.js +3 -12
  16. package/dist/index.d.ts +30 -26
  17. package/dist/index.js +19 -29
  18. package/dist/internal.d.ts +3 -0
  19. package/dist/internal.js +2 -0
  20. package/dist/middleware/auth-apikey.d.ts +2 -2
  21. package/dist/middleware/auth-apikey.js +3 -3
  22. package/dist/middleware/auth-bearer.d.ts +3 -3
  23. package/dist/middleware/auth-bearer.js +4 -7
  24. package/dist/middleware/auth-cookie.d.ts +4 -4
  25. package/dist/middleware/auth-cookie.js +7 -9
  26. package/dist/middleware/cors.d.ts +46 -0
  27. package/dist/middleware/cors.js +81 -0
  28. package/dist/middleware/index.d.ts +5 -3
  29. package/dist/middleware/index.js +5 -3
  30. package/dist/middleware/remote-auth.d.ts +5 -0
  31. package/dist/middleware/remote-auth.js +55 -0
  32. package/dist/middleware/timeout.d.ts +2 -2
  33. package/dist/middleware-runner.d.ts +1 -1
  34. package/dist/middleware-runner.js +8 -10
  35. package/dist/permissions.d.ts +2 -2
  36. package/dist/permissions.js +11 -15
  37. package/dist/pikku-state.d.ts +10 -8
  38. package/dist/pikku-state.js +48 -25
  39. package/dist/schema.d.ts +4 -4
  40. package/dist/schema.js +20 -15
  41. package/dist/services/ai-agent-runner-service.d.ts +43 -0
  42. package/dist/services/ai-agent-runner-service.js +1 -0
  43. package/dist/services/ai-run-state-service.d.ts +13 -0
  44. package/dist/services/ai-run-state-service.js +1 -0
  45. package/dist/services/ai-storage-service.d.ts +18 -0
  46. package/dist/services/ai-storage-service.js +1 -0
  47. package/dist/services/content-service.d.ts +6 -0
  48. package/dist/services/deployment-service.d.ts +19 -0
  49. package/dist/services/deployment-service.js +1 -0
  50. package/dist/services/gopass-secrets.d.ts +47 -0
  51. package/dist/services/gopass-secrets.js +97 -0
  52. package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
  53. package/dist/services/in-memory-ai-run-state-service.js +44 -0
  54. package/dist/services/in-memory-trigger-service.d.ts +22 -0
  55. package/dist/services/in-memory-trigger-service.js +48 -0
  56. package/dist/services/in-memory-workflow-service.d.ts +59 -0
  57. package/dist/services/in-memory-workflow-service.js +287 -0
  58. package/dist/services/index.d.ts +26 -11
  59. package/dist/services/index.js +11 -13
  60. package/dist/services/local-content.d.ts +2 -1
  61. package/dist/services/local-content.js +6 -1
  62. package/dist/services/local-secrets.d.ts +25 -2
  63. package/dist/services/local-secrets.js +45 -0
  64. package/dist/services/local-variables.d.ts +6 -1
  65. package/dist/services/local-variables.js +18 -0
  66. package/dist/services/logger-console.d.ts +2 -1
  67. package/dist/services/scheduler-service.d.ts +9 -1
  68. package/dist/services/scheduler-service.js +8 -0
  69. package/dist/services/schema-service.d.ts +6 -0
  70. package/dist/services/scoped-secret-service.d.ts +16 -0
  71. package/dist/services/scoped-secret-service.js +35 -0
  72. package/dist/services/secret-service.d.ts +25 -4
  73. package/dist/services/trigger-service.d.ts +16 -0
  74. package/dist/services/trigger-service.js +1 -0
  75. package/dist/services/typed-secret-service.d.ts +30 -0
  76. package/dist/services/typed-secret-service.js +40 -0
  77. package/dist/services/typed-variables-service.d.ts +27 -0
  78. package/dist/services/typed-variables-service.js +46 -0
  79. package/dist/services/user-session-service.d.ts +15 -2
  80. package/dist/services/user-session-service.js +17 -0
  81. package/dist/services/variables-service.d.ts +5 -0
  82. package/dist/services/workflow-service.d.ts +9 -5
  83. package/dist/types/core.types.d.ts +67 -25
  84. package/dist/types/core.types.js +8 -1
  85. package/dist/types/state.types.d.ts +53 -59
  86. package/dist/utils.d.ts +7 -6
  87. package/dist/utils.js +27 -12
  88. package/dist/version.d.ts +6 -0
  89. package/dist/version.js +19 -0
  90. package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
  91. package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +146 -0
  92. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
  93. package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
  94. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +29 -0
  95. package/dist/wirings/ai-agent/ai-agent-memory.js +199 -0
  96. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +9 -0
  97. package/dist/wirings/ai-agent/ai-agent-model-config.js +36 -0
  98. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +59 -0
  99. package/dist/wirings/ai-agent/ai-agent-prepare.js +348 -0
  100. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +15 -0
  101. package/dist/wirings/ai-agent/ai-agent-registry.js +47 -0
  102. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +3 -0
  103. package/dist/wirings/ai-agent/ai-agent-runner.js +195 -0
  104. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +12 -0
  105. package/dist/wirings/ai-agent/ai-agent-stream.js +662 -0
  106. package/dist/wirings/ai-agent/ai-agent.types.d.ts +313 -0
  107. package/dist/wirings/ai-agent/ai-agent.types.js +1 -0
  108. package/dist/wirings/ai-agent/index.d.ts +7 -0
  109. package/dist/wirings/ai-agent/index.js +6 -0
  110. package/dist/wirings/channel/channel-common.d.ts +8 -5
  111. package/dist/wirings/channel/channel-common.js +15 -8
  112. package/dist/wirings/channel/channel-handler.d.ts +3 -3
  113. package/dist/wirings/channel/channel-handler.js +15 -6
  114. package/dist/wirings/channel/channel-middleware-runner.d.ts +9 -0
  115. package/dist/wirings/channel/channel-middleware-runner.js +73 -0
  116. package/dist/wirings/channel/channel-runner.d.ts +5 -5
  117. package/dist/wirings/channel/channel-runner.js +10 -9
  118. package/dist/wirings/channel/channel-store.d.ts +1 -1
  119. package/dist/wirings/channel/channel.types.d.ts +9 -7
  120. package/dist/wirings/channel/define-channel-routes.d.ts +21 -0
  121. package/dist/wirings/channel/define-channel-routes.js +23 -0
  122. package/dist/wirings/channel/index.d.ts +10 -8
  123. package/dist/wirings/channel/index.js +7 -8
  124. package/dist/wirings/channel/local/index.d.ts +3 -3
  125. package/dist/wirings/channel/local/index.js +3 -3
  126. package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
  127. package/dist/wirings/channel/local/local-channel-runner.js +22 -9
  128. package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
  129. package/dist/wirings/channel/log-channels.d.ts +1 -1
  130. package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +1 -1
  131. package/dist/wirings/channel/serverless/index.d.ts +1 -1
  132. package/dist/wirings/channel/serverless/index.js +1 -1
  133. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +4 -4
  134. package/dist/wirings/channel/serverless/serverless-channel-runner.js +40 -23
  135. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
  136. package/dist/wirings/cli/channel/index.d.ts +1 -1
  137. package/dist/wirings/cli/channel/index.js +1 -1
  138. package/dist/wirings/cli/cli-runner.d.ts +3 -3
  139. package/dist/wirings/cli/cli-runner.js +12 -8
  140. package/dist/wirings/cli/cli.types.d.ts +9 -9
  141. package/dist/wirings/cli/command-parser.d.ts +1 -1
  142. package/dist/wirings/cli/define-cli-commands.d.ts +19 -0
  143. package/dist/wirings/cli/define-cli-commands.js +20 -0
  144. package/dist/wirings/cli/index.d.ts +2 -3
  145. package/dist/wirings/cli/index.js +1 -3
  146. package/dist/wirings/http/http-routes.d.ts +69 -0
  147. package/dist/wirings/http/http-routes.js +139 -0
  148. package/dist/wirings/http/http-runner.d.ts +9 -9
  149. package/dist/wirings/http/http-runner.js +79 -34
  150. package/dist/wirings/http/http.types.d.ts +77 -41
  151. package/dist/wirings/http/index.d.ts +5 -4
  152. package/dist/wirings/http/index.js +4 -3
  153. package/dist/wirings/http/log-http-routes.d.ts +1 -1
  154. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
  155. package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
  156. package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
  157. package/dist/wirings/http/routers/http-router.d.ts +1 -1
  158. package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
  159. package/dist/wirings/mcp/index.d.ts +4 -3
  160. package/dist/wirings/mcp/index.js +3 -3
  161. package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
  162. package/dist/wirings/mcp/mcp-runner.d.ts +1 -6
  163. package/dist/wirings/mcp/mcp-runner.js +28 -40
  164. package/dist/wirings/mcp/mcp.types.d.ts +5 -5
  165. package/dist/wirings/node/index.d.ts +2 -0
  166. package/dist/wirings/node/index.js +1 -0
  167. package/dist/wirings/node/node.types.d.ts +20 -0
  168. package/dist/wirings/node/node.types.js +1 -0
  169. package/dist/wirings/oauth2/index.d.ts +3 -0
  170. package/dist/wirings/oauth2/index.js +2 -0
  171. package/dist/wirings/oauth2/oauth2-client.d.ts +47 -0
  172. package/dist/wirings/oauth2/oauth2-client.js +267 -0
  173. package/dist/wirings/oauth2/oauth2.types.d.ts +65 -0
  174. package/dist/wirings/oauth2/oauth2.types.js +4 -0
  175. package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +20 -0
  176. package/dist/wirings/oauth2/wire-oauth2-credential.js +21 -0
  177. package/dist/wirings/queue/index.d.ts +1 -1
  178. package/dist/wirings/queue/queue-runner.d.ts +1 -5
  179. package/dist/wirings/queue/queue-runner.js +11 -8
  180. package/dist/wirings/queue/queue.types.d.ts +5 -5
  181. package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
  182. package/dist/wirings/queue/register-queue-helper.js +1 -1
  183. package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
  184. package/dist/wirings/rpc/index.d.ts +3 -1
  185. package/dist/wirings/rpc/index.js +2 -1
  186. package/dist/wirings/rpc/rpc-runner.d.ts +58 -8
  187. package/dist/wirings/rpc/rpc-runner.js +177 -31
  188. package/dist/wirings/rpc/rpc-types.d.ts +20 -4
  189. package/dist/wirings/rpc/wire-addon.d.ts +10 -0
  190. package/dist/wirings/rpc/wire-addon.js +9 -0
  191. package/dist/wirings/scheduler/index.d.ts +2 -2
  192. package/dist/wirings/scheduler/index.js +1 -2
  193. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
  194. package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -5
  195. package/dist/wirings/scheduler/scheduler-runner.js +11 -14
  196. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
  197. package/dist/wirings/secret/index.d.ts +3 -0
  198. package/dist/wirings/secret/index.js +2 -0
  199. package/dist/wirings/secret/secret.types.d.ts +27 -0
  200. package/dist/wirings/secret/secret.types.js +1 -0
  201. package/dist/wirings/secret/validate-secret-definitions.d.ts +6 -0
  202. package/dist/wirings/secret/validate-secret-definitions.js +55 -0
  203. package/dist/wirings/trigger/index.d.ts +3 -2
  204. package/dist/wirings/trigger/index.js +2 -2
  205. package/dist/wirings/trigger/pikku-trigger-service.d.ts +22 -0
  206. package/dist/wirings/trigger/pikku-trigger-service.js +70 -0
  207. package/dist/wirings/trigger/trigger-runner.d.ts +18 -9
  208. package/dist/wirings/trigger/trigger-runner.js +48 -19
  209. package/dist/wirings/trigger/trigger.types.d.ts +99 -11
  210. package/dist/wirings/trigger/trigger.types.js +40 -1
  211. package/dist/wirings/variable/index.d.ts +3 -0
  212. package/dist/wirings/variable/index.js +2 -0
  213. package/dist/wirings/variable/validate-variable-definitions.d.ts +6 -0
  214. package/dist/wirings/variable/validate-variable-definitions.js +45 -0
  215. package/dist/wirings/variable/variable.types.d.ts +18 -0
  216. package/dist/wirings/variable/variable.types.js +1 -0
  217. package/dist/wirings/workflow/dsl/index.d.ts +1 -1
  218. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +7 -1
  219. package/dist/wirings/workflow/dsl/workflow-runner.js +3 -2
  220. package/dist/wirings/workflow/graph/graph-node.d.ts +1 -6
  221. package/dist/wirings/workflow/graph/graph-runner.d.ts +5 -31
  222. package/dist/wirings/workflow/graph/graph-runner.js +384 -296
  223. package/dist/wirings/workflow/graph/index.d.ts +4 -3
  224. package/dist/wirings/workflow/graph/index.js +3 -3
  225. package/dist/wirings/workflow/graph/template.d.ts +15 -0
  226. package/dist/wirings/workflow/graph/template.js +27 -0
  227. package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +15 -0
  228. package/dist/wirings/workflow/graph/wire-workflow-graph.js +8 -0
  229. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -13
  230. package/dist/wirings/workflow/index.d.ts +6 -6
  231. package/dist/wirings/workflow/index.js +6 -4
  232. package/dist/wirings/workflow/pikku-workflow-service.d.ts +29 -19
  233. package/dist/wirings/workflow/pikku-workflow-service.js +217 -82
  234. package/dist/wirings/workflow/workflow-helpers.d.ts +36 -0
  235. package/dist/wirings/workflow/workflow-helpers.js +38 -0
  236. package/dist/wirings/workflow/workflow.types.d.ts +42 -95
  237. package/package.json +14 -15
  238. package/run-tests.sh +4 -1
  239. package/src/crypto-utils.test.ts +116 -0
  240. package/src/crypto-utils.ts +99 -0
  241. package/src/errors/error.test.ts +143 -2
  242. package/src/errors/errors.ts +27 -0
  243. package/src/errors/index.ts +1 -1
  244. package/src/factory-functions.test.ts +42 -2
  245. package/src/function/function-runner.test.ts +6 -13
  246. package/src/function/function-runner.ts +161 -53
  247. package/src/function/functions.types.ts +63 -132
  248. package/src/function/index.ts +5 -2
  249. package/src/handle-error.test.ts +361 -0
  250. package/src/handle-error.ts +6 -14
  251. package/src/index.ts +97 -30
  252. package/src/internal.ts +6 -0
  253. package/src/middleware/auth-apikey.test.ts +16 -13
  254. package/src/middleware/auth-apikey.ts +3 -3
  255. package/src/middleware/auth-bearer.test.ts +18 -15
  256. package/src/middleware/auth-bearer.ts +27 -32
  257. package/src/middleware/auth-cookie.test.ts +17 -14
  258. package/src/middleware/auth-cookie.ts +9 -13
  259. package/src/middleware/cors.test.ts +424 -0
  260. package/src/middleware/cors.ts +104 -0
  261. package/src/middleware/index.ts +5 -3
  262. package/src/middleware/remote-auth.test.ts +488 -0
  263. package/src/middleware/remote-auth.ts +68 -0
  264. package/src/middleware-runner.test.ts +123 -1
  265. package/src/middleware-runner.ts +13 -13
  266. package/src/permissions.test.ts +83 -9
  267. package/src/permissions.ts +17 -19
  268. package/src/pikku-state.test.ts +224 -0
  269. package/src/pikku-state.ts +59 -35
  270. package/src/run-tests-script.test.ts +49 -0
  271. package/src/schema.test.ts +198 -6
  272. package/src/schema.ts +28 -21
  273. package/src/services/ai-agent-runner-service.ts +41 -0
  274. package/src/services/ai-run-state-service.ts +20 -0
  275. package/src/services/ai-storage-service.ts +39 -0
  276. package/src/services/content-service.ts +7 -0
  277. package/src/services/deployment-service.ts +22 -0
  278. package/src/services/gopass-secrets.ts +98 -0
  279. package/src/services/in-memory-ai-run-state-service.ts +73 -0
  280. package/src/services/in-memory-trigger-service.ts +64 -0
  281. package/src/services/in-memory-workflow-service.test.ts +351 -0
  282. package/src/services/in-memory-workflow-service.ts +395 -0
  283. package/src/services/index.ts +50 -14
  284. package/src/services/local-content.ts +9 -3
  285. package/src/services/local-secrets.test.ts +80 -0
  286. package/src/services/local-secrets.ts +53 -2
  287. package/src/services/local-variables.test.ts +61 -0
  288. package/src/services/local-variables.ts +23 -1
  289. package/src/services/logger-console.test.ts +118 -0
  290. package/src/services/logger-console.ts +2 -1
  291. package/src/services/scheduler-service.ts +11 -1
  292. package/src/services/schema-service.ts +7 -0
  293. package/src/services/scoped-secret-service.test.ts +74 -0
  294. package/src/services/scoped-secret-service.ts +41 -0
  295. package/src/services/secret-service.ts +25 -4
  296. package/src/services/trigger-service.ts +17 -0
  297. package/src/services/typed-secret-service.test.ts +93 -0
  298. package/src/services/typed-secret-service.ts +70 -0
  299. package/src/services/typed-variables-service.test.ts +73 -0
  300. package/src/services/typed-variables-service.ts +81 -0
  301. package/src/services/user-session-service.test.ts +113 -0
  302. package/src/services/user-session-service.ts +25 -2
  303. package/src/services/variables-service.ts +5 -0
  304. package/src/services/workflow-service.ts +23 -13
  305. package/src/time-utils.test.ts +1 -1
  306. package/src/types/core.types.ts +95 -24
  307. package/src/types/state.types.ts +56 -73
  308. package/src/utils.test.ts +350 -0
  309. package/src/utils.ts +33 -18
  310. package/src/version.test.ts +80 -0
  311. package/src/version.ts +25 -0
  312. package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
  313. package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +214 -0
  314. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
  315. package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
  316. package/src/wirings/ai-agent/ai-agent-memory.ts +300 -0
  317. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
  318. package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
  319. package/src/wirings/ai-agent/ai-agent-prepare.ts +504 -0
  320. package/src/wirings/ai-agent/ai-agent-registry.test.ts +37 -0
  321. package/src/wirings/ai-agent/ai-agent-registry.ts +82 -0
  322. package/src/wirings/ai-agent/ai-agent-runner.test.ts +317 -0
  323. package/src/wirings/ai-agent/ai-agent-runner.ts +251 -0
  324. package/src/wirings/ai-agent/ai-agent-stream.test.ts +652 -0
  325. package/src/wirings/ai-agent/ai-agent-stream.ts +1049 -0
  326. package/src/wirings/ai-agent/ai-agent.types.ts +328 -0
  327. package/src/wirings/ai-agent/index.ts +39 -0
  328. package/src/wirings/channel/channel-common.ts +33 -20
  329. package/src/wirings/channel/channel-handler.ts +26 -9
  330. package/src/wirings/channel/channel-middleware-runner.ts +119 -0
  331. package/src/wirings/channel/channel-runner.ts +15 -16
  332. package/src/wirings/channel/channel-store.ts +1 -1
  333. package/src/wirings/channel/channel.types.ts +21 -9
  334. package/src/wirings/channel/define-channel-routes.ts +25 -0
  335. package/src/wirings/channel/index.ts +23 -8
  336. package/src/wirings/channel/local/index.ts +3 -3
  337. package/src/wirings/channel/local/local-channel-runner.test.ts +57 -7
  338. package/src/wirings/channel/local/local-channel-runner.ts +40 -19
  339. package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
  340. package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
  341. package/src/wirings/channel/log-channels.ts +1 -1
  342. package/src/wirings/channel/pikku-abstract-channel-handler.ts +1 -1
  343. package/src/wirings/channel/serverless/index.ts +5 -1
  344. package/src/wirings/channel/serverless/serverless-channel-runner.ts +57 -36
  345. package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
  346. package/src/wirings/cli/channel/index.ts +1 -1
  347. package/src/wirings/cli/cli-runner.test.ts +10 -10
  348. package/src/wirings/cli/cli-runner.ts +28 -14
  349. package/src/wirings/cli/cli.types.ts +14 -14
  350. package/src/wirings/cli/command-parser.test.ts +9 -9
  351. package/src/wirings/cli/command-parser.ts +1 -1
  352. package/src/wirings/cli/define-cli-commands.ts +24 -0
  353. package/src/wirings/cli/index.ts +10 -4
  354. package/src/wirings/http/http-routes.test.ts +322 -0
  355. package/src/wirings/http/http-routes.ts +198 -0
  356. package/src/wirings/http/http-runner.test.ts +12 -20
  357. package/src/wirings/http/http-runner.ts +101 -51
  358. package/src/wirings/http/http.types.ts +119 -48
  359. package/src/wirings/http/index.ts +16 -4
  360. package/src/wirings/http/log-http-routes.ts +1 -1
  361. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  362. package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
  363. package/src/wirings/http/routers/http-router.ts +1 -1
  364. package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
  365. package/src/wirings/http/routers/path-to-regex.ts +4 -3
  366. package/src/wirings/mcp/index.ts +27 -3
  367. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +3 -3
  368. package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
  369. package/src/wirings/mcp/mcp-runner.ts +48 -65
  370. package/src/wirings/mcp/mcp.types.ts +5 -5
  371. package/src/wirings/node/index.ts +2 -0
  372. package/src/wirings/node/node.types.ts +23 -0
  373. package/src/wirings/oauth2/index.ts +3 -0
  374. package/src/wirings/oauth2/oauth2-client.test.ts +929 -0
  375. package/src/wirings/oauth2/oauth2-client.ts +335 -0
  376. package/src/wirings/oauth2/oauth2.types.ts +69 -0
  377. package/src/wirings/oauth2/wire-oauth2-credential.ts +23 -0
  378. package/src/wirings/queue/index.ts +13 -2
  379. package/src/wirings/queue/queue-runner.test.ts +142 -73
  380. package/src/wirings/queue/queue-runner.ts +18 -14
  381. package/src/wirings/queue/queue.types.ts +5 -5
  382. package/src/wirings/queue/register-queue-helper.ts +3 -5
  383. package/src/wirings/queue/validate-worker-config.test.ts +108 -0
  384. package/src/wirings/queue/validate-worker-config.ts +4 -1
  385. package/src/wirings/rpc/index.ts +3 -1
  386. package/src/wirings/rpc/rpc-runner.ts +254 -41
  387. package/src/wirings/rpc/rpc-types.ts +28 -4
  388. package/src/wirings/rpc/wire-addon.ts +20 -0
  389. package/src/wirings/scheduler/index.ts +6 -4
  390. package/src/wirings/scheduler/log-schedulers.ts +1 -1
  391. package/src/wirings/scheduler/scheduler-runner.test.ts +78 -45
  392. package/src/wirings/scheduler/scheduler-runner.ts +20 -27
  393. package/src/wirings/scheduler/scheduler.types.ts +2 -2
  394. package/src/wirings/secret/index.ts +9 -0
  395. package/src/wirings/secret/secret.types.ts +32 -0
  396. package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
  397. package/src/wirings/secret/validate-secret-definitions.ts +82 -0
  398. package/src/wirings/trigger/index.ts +10 -2
  399. package/src/wirings/trigger/pikku-trigger-service.ts +112 -0
  400. package/src/wirings/trigger/trigger-runner.test.ts +79 -0
  401. package/src/wirings/trigger/trigger-runner.ts +80 -41
  402. package/src/wirings/trigger/trigger.types.ts +144 -22
  403. package/src/wirings/variable/index.ts +8 -0
  404. package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
  405. package/src/wirings/variable/validate-variable-definitions.ts +69 -0
  406. package/src/wirings/variable/variable.types.ts +22 -0
  407. package/src/wirings/workflow/dsl/index.ts +1 -0
  408. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +9 -1
  409. package/src/wirings/workflow/dsl/workflow-runner.ts +4 -3
  410. package/src/wirings/workflow/graph/graph-node.ts +1 -6
  411. package/src/wirings/workflow/graph/graph-runner.test.ts +487 -0
  412. package/src/wirings/workflow/graph/graph-runner.ts +496 -374
  413. package/src/wirings/workflow/graph/index.ts +14 -3
  414. package/src/wirings/workflow/graph/template.test.ts +49 -0
  415. package/src/wirings/workflow/graph/template.ts +42 -0
  416. package/src/wirings/workflow/graph/wire-workflow-graph.ts +29 -0
  417. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -22
  418. package/src/wirings/workflow/index.ts +21 -10
  419. package/src/wirings/workflow/pikku-workflow-service.test.ts +200 -0
  420. package/src/wirings/workflow/pikku-workflow-service.ts +308 -105
  421. package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
  422. package/src/wirings/workflow/workflow-helpers.ts +79 -0
  423. package/src/wirings/workflow/workflow.types.ts +47 -92
  424. package/tsconfig.tsbuildinfo +1 -1
  425. package/dist/wirings/forge-node/forge-node.types.d.ts +0 -120
  426. package/dist/wirings/forge-node/forge-node.types.js +0 -38
  427. package/dist/wirings/forge-node/index.d.ts +0 -1
  428. package/dist/wirings/forge-node/index.js +0 -1
  429. package/dist/wirings/workflow/wire-workflow.d.ts +0 -42
  430. package/dist/wirings/workflow/wire-workflow.js +0 -53
  431. package/dist/wirings/workflow/workflow-utils.d.ts +0 -23
  432. package/dist/wirings/workflow/workflow-utils.js +0 -66
  433. package/src/wirings/forge-node/forge-node.types.ts +0 -135
  434. package/src/wirings/forge-node/index.ts +0 -1
  435. package/src/wirings/workflow/wire-workflow.ts +0 -94
  436. package/src/wirings/workflow/workflow-utils.ts +0 -120
@@ -6,7 +6,14 @@ import type {
6
6
  PikkuWire,
7
7
  PickRequired,
8
8
  } from '../types/core.types.js'
9
- import { Session } from 'inspector'
9
+ import type { StandardSchemaV1 } from '@standard-schema/spec'
10
+ import type { CoreNodeConfig } from '../wirings/node/node.types.js'
11
+
12
+ /**
13
+ * @deprecated Use StandardSchemaV1 from @standard-schema/spec instead.
14
+ * This alias exists only for backward compatibility with generated code.
15
+ */
16
+ export type ZodLike<T = any> = StandardSchemaV1<T, T>
10
17
 
11
18
  /**
12
19
  * Represents a core API function that performs an operation using core services and a user session.
@@ -20,6 +27,7 @@ export type CorePikkuFunction<
20
27
  In,
21
28
  Out,
22
29
  Services extends CoreSingletonServices = CoreServices,
30
+ Session extends CoreUserSession = CoreUserSession,
23
31
  Wire extends PikkuWire<In, Out> = PikkuWire<In, Out, true, Session>,
24
32
  > = (
25
33
  services: Services,
@@ -39,15 +47,16 @@ export type CorePikkuFunctionSessionless<
39
47
  In,
40
48
  Out,
41
49
  Services extends CoreSingletonServices = CoreServices,
42
- Wire extends PikkuWire<
50
+ Session extends CoreUserSession = CoreUserSession,
51
+ Wire extends PikkuWire<In, Out, false, Session, any, any, any> = PikkuWire<
43
52
  In,
44
53
  Out,
45
54
  false,
46
- CoreUserSession,
55
+ Session,
47
56
  any,
48
57
  any,
49
58
  any
50
- > = PikkuWire<In, Out, false, CoreUserSession, any, any, any>,
59
+ >,
51
60
  > = (
52
61
  services: Services,
53
62
  data: In,
@@ -94,8 +103,8 @@ export type CorePikkuPermissionConfig<
94
103
  > = {
95
104
  /** The permission function */
96
105
  func: CorePikkuPermission<In, Services, Wire>
97
- /** Optional human-readable title for the permission */
98
- title?: string
106
+ /** Optional human-readable name for the permission */
107
+ name?: string
99
108
  /** Optional description of what the permission checks */
100
109
  description?: string
101
110
  }
@@ -108,18 +117,18 @@ export type CorePikkuPermissionConfig<
108
117
  * ```typescript
109
118
  * // Direct function syntax
110
119
  * export const adminPermission = pikkuPermission(
111
- * async ({ logger }, _data, { session }) => {
112
- * const currentSession = await session.get()
120
+ * async ({ logger }, _data, { getSession }) => {
121
+ * const currentSession = await getSession()
113
122
  * return currentSession?.role === 'admin'
114
123
  * }
115
124
  * )
116
125
  *
117
126
  * // Configuration object syntax with metadata
118
127
  * export const adminPermission = pikkuPermission({
119
- * title: 'Admin Permission',
128
+ * name: 'Admin Permission',
120
129
  * description: 'Checks if user has admin role',
121
- * func: async ({ logger }, _data, { session }) => {
122
- * const currentSession = await session.get()
130
+ * func: async ({ logger }, _data, { getSession }) => {
131
+ * const currentSession = await getSession()
123
132
  * return currentSession?.role === 'admin'
124
133
  * }
125
134
  * })
@@ -168,8 +177,8 @@ export type CorePikkuPermissionFactory<
168
177
  * export const requireRole = pikkuPermissionFactory<{ role: string }>(({
169
178
  * role
170
179
  * }) => {
171
- * return pikkuPermission(async ({ logger }, data, { session }) => {
172
- * const currentSession = await session.get()
180
+ * return pikkuPermission(async ({ logger }, data, { getSession }) => {
181
+ * const currentSession = await getSession()
173
182
  * if (!currentSession || currentSession.role !== role) {
174
183
  * logger.warn(`Permission denied: required role '${role}'`)
175
184
  * return false
@@ -185,23 +194,45 @@ export const pikkuPermissionFactory = <In = any>(
185
194
  return factory
186
195
  }
187
196
 
197
+ export type CorePikkuAuth<
198
+ Services extends CoreSingletonServices = CoreServices,
199
+ Session extends CoreUserSession = CoreUserSession,
200
+ > = (services: Services, session: Session) => Promise<boolean> | boolean
201
+
202
+ export type CorePikkuAuthConfig<
203
+ Services extends CoreSingletonServices = CoreServices,
204
+ Session extends CoreUserSession = CoreUserSession,
205
+ > = {
206
+ func: CorePikkuAuth<Services, Session>
207
+ name?: string
208
+ description?: string
209
+ }
210
+
211
+ export const pikkuAuth = <
212
+ Services extends CoreSingletonServices = CoreServices,
213
+ Session extends CoreUserSession = CoreUserSession,
214
+ >(
215
+ auth:
216
+ | CorePikkuAuth<Services, Session>
217
+ | CorePikkuAuthConfig<Services, Session>
218
+ ): CorePikkuPermission<any, Services, any> => {
219
+ const fn = typeof auth === 'function' ? auth : auth.func
220
+ const wrapper = async (services: Services, _data: any, wire: any) => {
221
+ const session = wire.session
222
+ if (!session) return false
223
+ return fn(services, session as Session)
224
+ }
225
+ return wrapper as any
226
+ }
227
+
188
228
  export type CorePermissionGroup<PikkuPermission = CorePikkuPermission<any>> =
189
229
  | Record<string, PikkuPermission | PikkuPermission[]>
190
230
  | undefined
191
231
 
192
- /**
193
- * Zod schema type - matches z.ZodType shape for type inference
194
- * This avoids requiring zod as a dependency while allowing schema inference
195
- */
196
- export type ZodLike<T = any> = {
197
- _input: T
198
- _output: T
199
- }
200
-
201
232
  export type CorePikkuFunctionConfig<
202
233
  PikkuFunction extends
203
- | CorePikkuFunction<any, any, any, any>
204
- | CorePikkuFunctionSessionless<any, any, any, any>,
234
+ | CorePikkuFunction<any, any, any, any, any>
235
+ | CorePikkuFunctionSessionless<any, any, any, any, any>,
205
236
  PikkuPermission extends CorePikkuPermission<
206
237
  any,
207
238
  any,
@@ -211,126 +242,26 @@ export type CorePikkuFunctionConfig<
211
242
  any,
212
243
  any
213
244
  >,
214
- InputSchema extends ZodLike | undefined = undefined,
215
- OutputSchema extends ZodLike | undefined = undefined,
245
+ InputSchema extends StandardSchemaV1 | undefined = undefined,
246
+ OutputSchema extends StandardSchemaV1 | undefined = undefined,
216
247
  > = {
217
248
  /** Optional human-readable title for the function */
218
249
  title?: string
219
250
  /** Optional description of what the function does */
220
251
  description?: string
221
252
  override?: string
253
+ version?: number
222
254
  tags?: string[]
223
255
  expose?: boolean
224
- internal?: boolean
256
+ remote?: boolean
257
+ mcp?: boolean
258
+ readonly?: boolean
259
+ requiresApproval?: boolean
225
260
  func: PikkuFunction
226
261
  auth?: boolean
227
262
  permissions?: CorePermissionGroup<PikkuPermission>
228
263
  middleware?: PikkuMiddleware[]
229
264
  input?: InputSchema
230
265
  output?: OutputSchema
231
- }
232
-
233
- /**
234
- * A trigger function that sets up a subscription and returns a teardown function.
235
- * The trigger is fired via wire.trigger.trigger(data).
236
- *
237
- * @template TConfig - Configuration type (hardcoded when wired)
238
- * @template TOutput - Output type produced when trigger fires
239
- * @template Services - Services available to the trigger
240
- */
241
- export type CorePikkuTriggerFunction<
242
- TConfig = unknown,
243
- TOutput = unknown,
244
- Services extends CoreSingletonServices = CoreSingletonServices,
245
- > = (
246
- services: Services,
247
- config: TConfig,
248
- wire: { trigger: { trigger: (data: TOutput) => void } }
249
- ) => Promise<() => void | Promise<void>>
250
-
251
- /**
252
- * Configuration object for creating a trigger function with metadata
253
- */
254
- export type CorePikkuTriggerFunctionConfig<
255
- TConfig = unknown,
256
- TOutput = unknown,
257
- Services extends CoreSingletonServices = CoreSingletonServices,
258
- ConfigSchema extends ZodLike | undefined = undefined,
259
- OutputSchema extends ZodLike | undefined = undefined,
260
- > = {
261
- /** Optional human-readable title for the trigger */
262
- title?: string
263
- /** Optional description of what the trigger does */
264
- description?: string
265
- /** Optional tags for categorization */
266
- tags?: string[]
267
- /** The trigger function */
268
- func: CorePikkuTriggerFunction<TConfig, TOutput, Services>
269
- /** Optional Zod schema for config validation */
270
- config?: ConfigSchema
271
- /** Optional Zod schema for output validation */
272
- output?: OutputSchema
273
- }
274
-
275
- /**
276
- * Factory function for creating trigger functions
277
- * Supports both direct function and configuration object syntax
278
- *
279
- * @example
280
- * ```typescript
281
- * // Direct function syntax
282
- * export const redisSubscribeTrigger = pikkuTriggerFunc<
283
- * { channel: string },
284
- * { message: string }
285
- * >(async ({ redis }, { channel }, { trigger }) => {
286
- * const subscriber = redis.duplicate()
287
- * await subscriber.subscribe(channel, (msg) => {
288
- * trigger.trigger({ message: msg })
289
- * })
290
- * return () => subscriber.unsubscribe()
291
- * })
292
- *
293
- * // Configuration object syntax with metadata
294
- * export const redisSubscribeTrigger = pikkuTriggerFunc({
295
- * title: 'Redis Subscribe Trigger',
296
- * description: 'Listens to Redis pub/sub channel',
297
- * config: z.object({ channel: z.string() }),
298
- * output: z.object({ message: z.string() }),
299
- * func: async ({ redis }, { channel }, { trigger }) => {
300
- * const subscriber = redis.duplicate()
301
- * await subscriber.subscribe(channel, (msg) => {
302
- * trigger.trigger({ message: msg })
303
- * })
304
- * return () => subscriber.unsubscribe()
305
- * }
306
- * })
307
- * ```
308
- */
309
- export const pikkuTriggerFunc = <
310
- TConfig = unknown,
311
- TOutput = unknown,
312
- Services extends CoreSingletonServices = CoreSingletonServices,
313
- ConfigSchema extends ZodLike | undefined = undefined,
314
- OutputSchema extends ZodLike | undefined = undefined,
315
- >(
316
- triggerOrConfig:
317
- | CorePikkuTriggerFunction<TConfig, TOutput, Services>
318
- | CorePikkuTriggerFunctionConfig<
319
- TConfig,
320
- TOutput,
321
- Services,
322
- ConfigSchema,
323
- OutputSchema
324
- >
325
- ): CorePikkuTriggerFunctionConfig<
326
- TConfig,
327
- TOutput,
328
- Services,
329
- ConfigSchema,
330
- OutputSchema
331
- > => {
332
- if (typeof triggerOrConfig === 'function') {
333
- return { func: triggerOrConfig }
334
- }
335
- return triggerOrConfig
266
+ node?: CoreNodeConfig
336
267
  }
@@ -1,2 +1,5 @@
1
- export * from './function-runner.js'
2
- export * from './functions.types.js'
1
+ export { addFunction, getAllFunctionNames } from './function-runner.js'
2
+ export type {
3
+ CorePikkuFunction,
4
+ CorePikkuFunctionSessionless,
5
+ } from './functions.types.js'
@@ -0,0 +1,361 @@
1
+ import { describe, test, beforeEach } from 'node:test'
2
+ import assert from 'node:assert'
3
+ import { handleHTTPError } from './handle-error.js'
4
+ import { addError } from './errors/error-handler.js'
5
+ import {
6
+ NotFoundError,
7
+ BadRequestError,
8
+ ForbiddenError,
9
+ } from './errors/errors.js'
10
+ import { resetPikkuState } from './pikku-state.js'
11
+
12
+ const createMockLogger = () => {
13
+ const logs: { level: string; args: any[] }[] = []
14
+ return {
15
+ info: (...args: any[]) => logs.push({ level: 'info', args }),
16
+ warn: (...args: any[]) => logs.push({ level: 'warn', args }),
17
+ error: (...args: any[]) => logs.push({ level: 'error', args }),
18
+ debug: (...args: any[]) => logs.push({ level: 'debug', args }),
19
+ _logs: logs,
20
+ }
21
+ }
22
+
23
+ const createMockHTTP = () => {
24
+ const state = {
25
+ statusCode: undefined as number | undefined,
26
+ jsonBody: undefined as any,
27
+ closed: false,
28
+ }
29
+ return {
30
+ request: {},
31
+ response: {
32
+ status: (code: number) => {
33
+ state.statusCode = code
34
+ return {
35
+ json: (body: any) => {
36
+ state.jsonBody = body
37
+ },
38
+ }
39
+ },
40
+ json: (body: any) => {
41
+ state.jsonBody = body
42
+ },
43
+ close: () => {
44
+ state.closed = true
45
+ },
46
+ },
47
+ _state: state,
48
+ }
49
+ }
50
+
51
+ beforeEach(() => {
52
+ resetPikkuState()
53
+ })
54
+
55
+ describe('handleHTTPError', () => {
56
+ test('should skip NotFoundError when respondWith404 is false', () => {
57
+ const logger = createMockLogger()
58
+ const http = createMockHTTP()
59
+ const error = new NotFoundError()
60
+
61
+ handleHTTPError(
62
+ error,
63
+ http as any,
64
+ 'tracker-1',
65
+ logger as any,
66
+ [],
67
+ false,
68
+ false
69
+ )
70
+
71
+ assert.strictEqual(http._state.statusCode, undefined)
72
+ assert.strictEqual(http._state.jsonBody, undefined)
73
+ })
74
+
75
+ test('should handle NotFoundError when respondWith404 is true', () => {
76
+ const logger = createMockLogger()
77
+ const http = createMockHTTP()
78
+ const error = new NotFoundError()
79
+
80
+ handleHTTPError(
81
+ error,
82
+ http as any,
83
+ 'tracker-1',
84
+ logger as any,
85
+ [],
86
+ true,
87
+ false
88
+ )
89
+
90
+ assert.strictEqual(http._state.statusCode, 404)
91
+ assert.deepStrictEqual(http._state.jsonBody, {
92
+ message: 'The server cannot find the requested resource.',
93
+ payload: undefined,
94
+ traceId: 'tracker-1',
95
+ })
96
+ })
97
+
98
+ test('should set correct status and message for known errors', () => {
99
+ const logger = createMockLogger()
100
+ const http = createMockHTTP()
101
+ const error = new BadRequestError('Invalid input')
102
+
103
+ handleHTTPError(
104
+ error,
105
+ http as any,
106
+ 'tracker-2',
107
+ logger as any,
108
+ [],
109
+ true,
110
+ false
111
+ )
112
+
113
+ assert.strictEqual(http._state.statusCode, 400)
114
+ assert.ok(http._state.jsonBody.message.includes('client error'))
115
+ assert.strictEqual(http._state.jsonBody.traceId, 'tracker-2')
116
+ })
117
+
118
+ test('should set status 403 for ForbiddenError', () => {
119
+ const logger = createMockLogger()
120
+ const http = createMockHTTP()
121
+ const error = new ForbiddenError()
122
+
123
+ handleHTTPError(
124
+ error,
125
+ http as any,
126
+ 'tracker-3',
127
+ logger as any,
128
+ [],
129
+ true,
130
+ false
131
+ )
132
+
133
+ assert.strictEqual(http._state.statusCode, 403)
134
+ })
135
+
136
+ test('should log warning when status code is in logWarningsForStatusCodes', () => {
137
+ const logger = createMockLogger()
138
+ const http = createMockHTTP()
139
+ const error = new BadRequestError('bad')
140
+
141
+ handleHTTPError(
142
+ error,
143
+ http as any,
144
+ 'tracker-4',
145
+ logger as any,
146
+ [400],
147
+ true,
148
+ false
149
+ )
150
+
151
+ const warns = logger._logs.filter((l) => l.level === 'warn')
152
+ assert.ok(warns.length >= 1)
153
+ assert.ok(warns.some((w) => w.args[0].includes('tracker-4')))
154
+ })
155
+
156
+ test('should not log warning when status code is not in logWarningsForStatusCodes', () => {
157
+ const logger = createMockLogger()
158
+ const http = createMockHTTP()
159
+ const error = new BadRequestError('bad')
160
+
161
+ handleHTTPError(
162
+ error,
163
+ http as any,
164
+ 'tracker-5',
165
+ logger as any,
166
+ [500],
167
+ true,
168
+ false
169
+ )
170
+
171
+ const warns = logger._logs.filter((l) => l.level === 'warn')
172
+ assert.strictEqual(warns.length, 0)
173
+ })
174
+
175
+ test('should handle unknown errors with 500 status', () => {
176
+ const logger = createMockLogger()
177
+ const http = createMockHTTP()
178
+ const error = new Error('something unexpected')
179
+
180
+ handleHTTPError(
181
+ error,
182
+ http as any,
183
+ 'tracker-6',
184
+ logger as any,
185
+ [],
186
+ true,
187
+ false
188
+ )
189
+
190
+ assert.strictEqual(http._state.statusCode, 500)
191
+ assert.deepStrictEqual(http._state.jsonBody, { errorId: 'tracker-6' })
192
+ })
193
+
194
+ test('should log unknown errors with error level', () => {
195
+ const logger = createMockLogger()
196
+ const http = createMockHTTP()
197
+ const error = new Error('unexpected')
198
+
199
+ handleHTTPError(
200
+ error,
201
+ http as any,
202
+ undefined,
203
+ logger as any,
204
+ [],
205
+ true,
206
+ false
207
+ )
208
+
209
+ const errors = logger._logs.filter((l) => l.level === 'error')
210
+ assert.ok(errors.length >= 1)
211
+ assert.ok(errors.some((e) => e.args[0] === 'unexpected'))
212
+ })
213
+
214
+ test('should not include errorId in response when trackerId is undefined for unknown errors', () => {
215
+ const logger = createMockLogger()
216
+ const http = createMockHTTP()
217
+ const error = new Error('unexpected')
218
+
219
+ handleHTTPError(
220
+ error,
221
+ http as any,
222
+ undefined,
223
+ logger as any,
224
+ [],
225
+ true,
226
+ false
227
+ )
228
+
229
+ assert.strictEqual(http._state.statusCode, 500)
230
+ assert.strictEqual(http._state.jsonBody, undefined)
231
+ })
232
+
233
+ test('should bubble error when bubbleError is true', () => {
234
+ const logger = createMockLogger()
235
+ const http = createMockHTTP()
236
+ const error = new BadRequestError('bad')
237
+
238
+ assert.throws(
239
+ () =>
240
+ handleHTTPError(
241
+ error,
242
+ http as any,
243
+ 'tracker',
244
+ logger as any,
245
+ [],
246
+ true,
247
+ true
248
+ ),
249
+ (e: any) => e === error
250
+ )
251
+ })
252
+
253
+ test('should not bubble error when bubbleError is false', () => {
254
+ const logger = createMockLogger()
255
+ const http = createMockHTTP()
256
+ const error = new BadRequestError('bad')
257
+
258
+ handleHTTPError(
259
+ error,
260
+ http as any,
261
+ 'tracker',
262
+ logger as any,
263
+ [],
264
+ true,
265
+ false
266
+ )
267
+ // Should not throw
268
+ })
269
+
270
+ test('should call response.close when available', () => {
271
+ const logger = createMockLogger()
272
+ const http = createMockHTTP()
273
+ const error = new BadRequestError('bad')
274
+
275
+ handleHTTPError(
276
+ error,
277
+ http as any,
278
+ 'tracker',
279
+ logger as any,
280
+ [],
281
+ true,
282
+ false
283
+ )
284
+
285
+ assert.strictEqual(http._state.closed, true)
286
+ })
287
+
288
+ test('should handle undefined http gracefully', () => {
289
+ const logger = createMockLogger()
290
+ const error = new BadRequestError('bad')
291
+
292
+ handleHTTPError(error, undefined, 'tracker', logger as any, [], true, false)
293
+ // Should not throw
294
+ })
295
+
296
+ test('should include payload from error in known error response', () => {
297
+ const logger = createMockLogger()
298
+ const http = createMockHTTP()
299
+ const error = new BadRequestError('bad') as any
300
+ error.payload = { field: 'email', reason: 'invalid' }
301
+
302
+ handleHTTPError(
303
+ error,
304
+ http as any,
305
+ 'tracker',
306
+ logger as any,
307
+ [],
308
+ true,
309
+ false
310
+ )
311
+
312
+ assert.deepStrictEqual(http._state.jsonBody.payload, {
313
+ field: 'email',
314
+ reason: 'invalid',
315
+ })
316
+ })
317
+
318
+ test('should handle non-Error objects as errors', () => {
319
+ const logger = createMockLogger()
320
+ const http = createMockHTTP()
321
+ const error = 'just a string error'
322
+
323
+ handleHTTPError(
324
+ error,
325
+ http as any,
326
+ 'tracker',
327
+ logger as any,
328
+ [],
329
+ true,
330
+ false
331
+ )
332
+
333
+ assert.strictEqual(http._state.statusCode, 500)
334
+ const errors = logger._logs.filter((l) => l.level === 'error')
335
+ assert.ok(errors.some((e) => e.args[0] === 'just a string error'))
336
+ })
337
+
338
+ test('should handle warning log without trackerId', () => {
339
+ const logger = createMockLogger()
340
+ const http = createMockHTTP()
341
+ const error = new BadRequestError('bad')
342
+
343
+ handleHTTPError(
344
+ error,
345
+ http as any,
346
+ undefined,
347
+ logger as any,
348
+ [400],
349
+ true,
350
+ false
351
+ )
352
+
353
+ const warns = logger._logs.filter((l) => l.level === 'warn')
354
+ assert.ok(warns.length >= 1)
355
+ assert.ok(
356
+ !warns.some(
357
+ (w) => typeof w.args[0] === 'string' && w.args[0].includes('Warning id')
358
+ )
359
+ )
360
+ })
361
+ })
@@ -1,7 +1,7 @@
1
1
  import { getErrorResponse } from './errors/error-handler.js'
2
2
  import { NotFoundError } from './errors/errors.js'
3
- import { Logger } from './services/logger.js'
4
- import { PikkuHTTP } from './wirings/http/http.types.js'
3
+ import type { Logger } from './services/logger.js'
4
+ import type { PikkuHTTP } from './wirings/http/http.types.js'
5
5
 
6
6
  /**
7
7
  * Handle errors that occur during route processing
@@ -44,11 +44,11 @@ export const handleHTTPError = (
44
44
  if (trackerId) {
45
45
  logger.warn(`Warning id: ${trackerId}`)
46
46
  }
47
- logger.warn(e)
47
+ logger.warn(e instanceof Error ? e.message : e)
48
48
  }
49
49
  } else {
50
50
  // Handle unexpected errors
51
- logger.error(e)
51
+ logger.error(e instanceof Error ? e.message : e)
52
52
  http?.response?.status(500)
53
53
 
54
54
  if (trackerId) {
@@ -57,17 +57,9 @@ export const handleHTTPError = (
57
57
  }
58
58
  }
59
59
 
60
- // Handle 404 errors specifically
61
- if (e instanceof NotFoundError) {
62
- // TODO
63
- // http?.response?.end()
64
- }
65
-
66
- // Either bubble up or end the response
67
60
  if (bubbleError) {
68
61
  throw e
69
- } else {
70
- // TODO
71
- // http?.response?.end()
72
62
  }
63
+
64
+ http?.response?.close?.()
73
65
  }