@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
@@ -1,20 +1,19 @@
1
- import {
1
+ import type {
2
2
  CoreHTTPFunctionWiring,
3
3
  RunHTTPWiringOptions,
4
- RunHTTPWiringParams,
5
4
  PikkuHTTP,
6
5
  PikkuHTTPRequest,
7
6
  PikkuHTTPResponse,
8
7
  HTTPWiringMeta,
9
8
  HTTPMethod,
10
9
  } from './http.types.js'
11
- import {
10
+ import type {
12
11
  CorePikkuFunction,
13
12
  CorePikkuFunctionSessionless,
14
13
  CorePikkuPermission,
15
14
  CorePermissionGroup,
16
15
  } from '../../function/functions.types.js'
17
- import {
16
+ import type {
18
17
  CoreUserSession,
19
18
  CorePikkuMiddleware,
20
19
  CorePikkuMiddlewareGroup,
@@ -29,17 +28,19 @@ import {
29
28
  isSerializable,
30
29
  } from '../../utils.js'
31
30
  import {
32
- PikkuSessionService,
33
- createMiddlewareSessionWireProps,
34
- } from '../../services/user-session-service.js'
31
+ getSingletonServices,
32
+ getCreateWireServices,
33
+ } from '../../pikku-state.js'
34
+ import { PikkuSessionService } from '../../services/user-session-service.js'
35
35
  import { handleHTTPError } from '../../handle-error.js'
36
36
  import { pikkuState } from '../../pikku-state.js'
37
37
  import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js'
38
38
  import { PikkuFetchHTTPRequest } from './pikku-fetch-http-request.js'
39
- import { PikkuChannel } from '../channel/channel.types.js'
39
+ import type { PikkuChannel } from '../channel/channel.types.js'
40
40
  import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
41
41
  import { httpRouter } from './routers/http-router.js'
42
42
  import { validateSchema } from '../../schema.js'
43
+ import { runMiddleware } from '../../middleware-runner.js'
43
44
 
44
45
  /**
45
46
  * Extract headers from a PikkuHTTPRequest based on the schema keys
@@ -358,6 +359,9 @@ const executeRoute = async (
358
359
  send: (data: any) => {
359
360
  response.arrayBuffer(isSerializable(data) ? JSON.stringify(data) : data)
360
361
  },
362
+ sendBinary: (data) => {
363
+ response.arrayBuffer(data)
364
+ },
361
365
  close: () => {
362
366
  channel!.state = 'closed'
363
367
  response.close?.()
@@ -369,7 +373,10 @@ const executeRoute = async (
369
373
  const wire: PikkuWire = {
370
374
  http,
371
375
  channel,
372
- ...createMiddlewareSessionWireProps(userSession),
376
+ session: userSession.get() as CoreUserSession | undefined,
377
+ setSession: (s: any) => userSession.setInitial(s),
378
+ getSession: () => userSession.get(),
379
+ hasSessionChanged: () => userSession.sessionChanged,
373
380
  }
374
381
 
375
382
  result = await runPikkuFunc(
@@ -417,12 +424,12 @@ const executeRoute = async (
417
424
  * @template In Expected input data type.
418
425
  * @template Out Expected output data type.
419
426
  * @param {Request} request - The native Fetch API Request object.
420
- * @param {RunHTTPWiringOptions & RunHTTPWiringParams} params - Additional options including services and session management.
427
+ * @param {RunHTTPWiringOptions} params - Additional options including services and session management.
421
428
  * @returns {Promise<Response>} A promise that resolves to a Fetch API Response object.
422
429
  */
423
430
  export const fetch = async <In, Out>(
424
431
  request: Request,
425
- params: RunHTTPWiringOptions & RunHTTPWiringParams
432
+ params: RunHTTPWiringOptions = {}
426
433
  ): Promise<Response> => {
427
434
  const pikkuResponse = new PikkuFetchHTTPResponse()
428
435
  await fetchData<In, Out>(request, pikkuResponse, params)
@@ -438,12 +445,12 @@ export const fetch = async <In, Out>(
438
445
  * @template In Expected input data type.
439
446
  * @template Out Expected output data type.
440
447
  * @param {Request | PikkuHTTPRequest} request - The request object.
441
- * @param {RunHTTPWiringOptions & RunHTTPWiringParams} params - Execution options including services and session configuration.
448
+ * @param {RunHTTPWiringOptions} params - Execution options including services and session configuration.
442
449
  * @returns {Promise<PikkuFetchHTTPResponse>} A promise that resolves to a PikkuFetchHTTPResponse object.
443
450
  */
444
451
  export const pikkuFetch = async <In, Out>(
445
452
  request: Request | PikkuHTTPRequest,
446
- params: RunHTTPWiringOptions & RunHTTPWiringParams
453
+ params: RunHTTPWiringOptions = {}
447
454
  ): Promise<PikkuFetchHTTPResponse> => {
448
455
  const pikkuResponse = new PikkuFetchHTTPResponse()
449
456
  await fetchData<In, Out>(request, pikkuResponse, params)
@@ -465,43 +472,56 @@ export const pikkuFetch = async <In, Out>(
465
472
  * @template Out Expected output data type.
466
473
  * @param {Request | PikkuHTTPRequest} request - The incoming HTTP request.
467
474
  * @param {PikkuHTTPResponse} response - The response object to be populated.
468
- * @param {RunHTTPWiringOptions & RunHTTPWiringParams} options - Options such as singleton services, session handling, and error configuration.
475
+ * @param {RunHTTPWiringOptions} options - Options such as singleton services, session handling, and error configuration.
469
476
  * @returns {Promise<Out | void>} The output from the route handler or void if an error occurred.
470
477
  */
471
478
  export const fetchData = async <In, Out>(
472
479
  request: Request | PikkuHTTPRequest,
473
480
  response: PikkuHTTPResponse,
474
481
  {
475
- singletonServices,
476
- createWireServices,
477
482
  skipUserSession = false,
478
483
  respondWith404 = true,
479
484
  logWarningsForStatusCodes = [],
480
485
  coerceDataFromSchema = true,
481
486
  bubbleErrors = false,
482
487
  generateRequestId,
483
- }: RunHTTPWiringOptions & RunHTTPWiringParams
488
+ }: RunHTTPWiringOptions = {}
484
489
  ): Promise<Out | void> => {
485
- const requestId =
486
- (request as any).getHeader?.('x-request-id') ||
487
- generateRequestId?.() ||
488
- createWeakUID()
490
+ const singletonServices = getSingletonServices()
491
+ const createWireServices = getCreateWireServices()
489
492
  let wireServices: WireServices<typeof singletonServices> | undefined
490
493
  let result: Out
491
494
 
492
495
  // Combine the request and response into one wire object
493
- const http = createHTTPWire(
494
- request instanceof Request ? new PikkuFetchHTTPRequest(request) : request,
495
- response
496
- )
496
+ const pikkuRequest =
497
+ request instanceof Request ? new PikkuFetchHTTPRequest(request) : request
498
+ let requestId: string | null = null
499
+ try {
500
+ requestId = pikkuRequest.header('x-request-id')
501
+ } catch {}
502
+ requestId = requestId || generateRequestId?.() || createWeakUID()
503
+ const http = createHTTPWire(pikkuRequest, response)
497
504
  const apiType = http!.request!.method()
498
505
  const apiRoute = http!.request!.path()
499
506
 
500
507
  // Locate the matching route based on the HTTP method and path
501
508
  const matchedRoute = getMatchingRoute(apiType, apiRoute)
502
509
  try {
503
- // If no route matches, log the occurrence and throw a NotFoundError
504
510
  if (!matchedRoute) {
511
+ if (apiType.toLowerCase() === 'options') {
512
+ const httpGroups = pikkuState(null, 'middleware', 'httpGroup')
513
+ const globalMiddleware = httpGroups['*']
514
+ const wire: PikkuWire = { http: http! }
515
+ if (globalMiddleware) {
516
+ await runMiddleware(
517
+ singletonServices,
518
+ wire,
519
+ globalMiddleware as CorePikkuMiddleware[]
520
+ )
521
+ }
522
+ response.status(204).json(undefined as any)
523
+ return
524
+ }
505
525
  singletonServices.logger.info({
506
526
  message: 'Route not found',
507
527
  apiRoute,
@@ -525,7 +545,6 @@ export const fetchData = async <In, Out>(
525
545
 
526
546
  return result
527
547
  } catch (e: any) {
528
- // Handle errors and, depending on configuration, bubble them up or respond with an error
529
548
  handleHTTPError(
530
549
  e,
531
550
  http,
@@ -1,11 +1,7 @@
1
1
  import type { SerializeOptions } from 'cookie'
2
2
  import type { StandardSchemaV1 } from '@standard-schema/spec'
3
- import { PikkuError } from '../../errors/error-handler.js'
3
+ import type { PikkuError } from '../../errors/error-handler.js'
4
4
  import type {
5
- CoreServices,
6
- CoreSingletonServices,
7
- CoreUserSession,
8
- CreateWireServices,
9
5
  CorePikkuMiddleware,
10
6
  CommonWireMeta,
11
7
  } from '../../types/core.types.js'
@@ -43,15 +39,6 @@ export type RunHTTPWiringOptions = Partial<{
43
39
  generateRequestId: () => string
44
40
  }>
45
41
 
46
- export type RunHTTPWiringParams = {
47
- singletonServices: CoreSingletonServices
48
- createWireServices?: CreateWireServices<
49
- CoreSingletonServices,
50
- CoreServices<CoreSingletonServices>,
51
- CoreUserSession
52
- >
53
- }
54
-
55
42
  /**
56
43
  * Represents the HTTP methods supported for API HTTP wirings.
57
44
  */
@@ -1,5 +1,5 @@
1
1
  import { pikkuState } from '../../pikku-state.js'
2
- import { Logger } from '../../services/index.js'
2
+ import type { Logger } from '../../services/index.js'
3
3
 
4
4
  /**
5
5
  * Logs all the loaded routes.
@@ -1,6 +1,6 @@
1
1
  import { parse as parseQuery } from 'picoquery'
2
2
  import { parse as parseCookie } from 'cookie'
3
- import { HTTPMethod, PikkuHTTPRequest, PikkuQuery } from './http.types.js'
3
+ import type { HTTPMethod, PikkuHTTPRequest, PikkuQuery } from './http.types.js'
4
4
  import { UnprocessableContentError } from '../../errors/errors.js'
5
5
 
6
6
  /**
@@ -1,8 +1,6 @@
1
- import { PikkuHTTPResponse } from './http.types.js'
2
- import {
3
- SerializeOptions as CookieSerializeOptions,
4
- serialize as serializeCookie,
5
- } from 'cookie'
1
+ import type { PikkuHTTPResponse } from './http.types.js'
2
+ import type { SerializeOptions as CookieSerializeOptions } from 'cookie'
3
+ import { serialize as serializeCookie } from 'cookie'
6
4
 
7
5
  export class PikkuFetchHTTPResponse implements PikkuHTTPResponse {
8
6
  #statusCode: number = 200
@@ -91,6 +89,15 @@ export class PikkuFetchHTTPResponse implements PikkuHTTPResponse {
91
89
  // }
92
90
 
93
91
  public redirect(location: string, status: number = 302): this {
92
+ if (
93
+ !location.startsWith('/') &&
94
+ !location.startsWith('https://') &&
95
+ !location.startsWith('http://')
96
+ ) {
97
+ throw new Error(
98
+ 'Invalid redirect location: must be a relative path or absolute URL'
99
+ )
100
+ }
94
101
  this.#statusCode = status
95
102
  this.header('Location', location)
96
103
  return this
@@ -1,4 +1,4 @@
1
- import { HTTPMethod } from '../http.types.js'
1
+ import type { HTTPMethod } from '../http.types.js'
2
2
  import { PathToRegexRouter } from './path-to-regex.js'
3
3
 
4
4
  export type MatchResult = {
@@ -2,7 +2,7 @@ import { test, describe, beforeEach } from 'node:test'
2
2
  import * as assert from 'node:assert/strict'
3
3
  import { PathToRegexRouter } from './path-to-regex.js'
4
4
  import { resetPikkuState, pikkuState } from '../../../pikku-state.js'
5
- import { HTTPMethod } from '../http.types.js'
5
+ import type { HTTPMethod } from '../http.types.js'
6
6
 
7
7
  describe('PathToRegexRouter', () => {
8
8
  let router: PathToRegexRouter
@@ -1,6 +1,7 @@
1
- import { match, MatchFunction } from 'path-to-regexp'
2
- import { MatchResult, Router } from './http-router.js'
3
- import { HTTPMethod } from '../http.types.js'
1
+ import type { MatchFunction } from 'path-to-regexp'
2
+ import { match } from 'path-to-regexp'
3
+ import type { MatchResult, Router } from './http-router.js'
4
+ import type { HTTPMethod } from '../http.types.js'
4
5
  import { pikkuState } from '../../../pikku-state.js'
5
6
 
6
7
  interface CompiledRoute {
@@ -1,4 +1,8 @@
1
- import { MCPResourceMeta, MCPToolMeta, MCPPromptMeta } from '@pikku/core/mcp'
1
+ import type {
2
+ MCPResourceMeta,
3
+ MCPToolMeta,
4
+ MCPPromptMeta,
5
+ } from '@pikku/core/mcp'
2
6
 
3
7
  export interface MCPToolEndpoint {
4
8
  name: string
@@ -1,10 +1,4 @@
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 } from '../../types/core.types.js'
8
2
  import type {
9
3
  CoreMCPResource,
10
4
  CoreMCPPrompt,
@@ -19,7 +13,11 @@ import type {
19
13
  } from '../../function/functions.types.js'
20
14
  import { getErrorResponse } from '../../errors/error-handler.js'
21
15
  import { closeWireServices } from '../../utils.js'
22
- import { pikkuState } from '../../pikku-state.js'
16
+ import {
17
+ pikkuState,
18
+ getSingletonServices,
19
+ getCreateWireServices,
20
+ } from '../../pikku-state.js'
23
21
  import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
24
22
  import {
25
23
  BadRequestError,
@@ -40,13 +38,7 @@ export class MCPError extends Error {
40
38
  }
41
39
 
42
40
  export type RunMCPEndpointParams<Tools extends string = any> = {
43
- singletonServices: CoreSingletonServices
44
41
  mcp?: PikkuMCP<Tools>
45
- createWireServices?: CreateWireServices<
46
- CoreSingletonServices,
47
- CoreServices<CoreSingletonServices>,
48
- CoreUserSession
49
- >
50
42
  }
51
43
 
52
44
  export type JsonRpcError = {
@@ -197,8 +189,10 @@ async function runMCPPikkuFunc(
197
189
  name: string,
198
190
  mcp: CoreMCPResource | CoreMCPPrompt | undefined,
199
191
  pikkuFuncId: string | undefined,
200
- { singletonServices, createWireServices, mcp: mcpWire }: RunMCPEndpointParams
192
+ { mcp: mcpWire }: RunMCPEndpointParams
201
193
  ): Promise<JsonRpcResponse> {
194
+ const singletonServices = getSingletonServices()
195
+ const createWireServices = getCreateWireServices()
202
196
  let wireServices: any
203
197
 
204
198
  try {
@@ -1,10 +1,10 @@
1
- import {
1
+ import type {
2
2
  CorePermissionGroup,
3
3
  CorePikkuFunctionConfig,
4
4
  CorePikkuFunctionSessionless,
5
5
  CorePikkuPermission,
6
6
  } from '../../function/functions.types.js'
7
- import {
7
+ import type {
8
8
  CorePikkuMiddleware,
9
9
  MiddlewareMetadata,
10
10
  PermissionMetadata,
@@ -1,6 +1,6 @@
1
- import { OAuth2Token, OAuth2AppCredential } from './oauth2.types.js'
2
- import { OAuth2CredentialConfig } from '../secret/secret.types.js'
3
- import { SecretService } from '../../services/secret-service.js'
1
+ import type { OAuth2Token, OAuth2AppCredential } from './oauth2.types.js'
2
+ import type { OAuth2CredentialConfig } from '../secret/secret.types.js'
3
+ import type { SecretService } from '../../services/secret-service.js'
4
4
 
5
5
  /**
6
6
  * OAuth2 client that acts as a service.
@@ -1,4 +1,4 @@
1
- import { CoreOAuth2Credential } from './oauth2.types.js'
1
+ import type { CoreOAuth2Credential } from './oauth2.types.js'
2
2
 
3
3
  /**
4
4
  * No-op function for declaring OAuth2 credentials.
@@ -16,7 +16,6 @@ export type {
16
16
  export {
17
17
  wireQueueWorker,
18
18
  runQueueJob,
19
- createQueueJobRunner,
20
19
  getQueueWorkers,
21
20
  removeQueueWorker,
22
21
  QueueJobDiscardedError,
@@ -5,12 +5,11 @@ import {
5
5
  getQueueWorkers,
6
6
  removeQueueWorker,
7
7
  runQueueJob,
8
- createQueueJobRunner,
9
8
  QueueJobFailedError,
10
9
  QueueJobDiscardedError,
11
10
  } from './queue-runner.js'
12
11
  import { resetPikkuState, pikkuState } from '../../pikku-state.js'
13
- import { CoreQueueWorker, QueueJob } from './queue.types.js'
12
+ import type { CoreQueueWorker, QueueJob } from './queue.types.js'
14
13
 
15
14
  beforeEach(() => {
16
15
  resetPikkuState()
@@ -219,12 +218,14 @@ describe('runQueueJob', () => {
219
218
  wireQueueWorker(mockWorker)
220
219
 
221
220
  const mockLogger = createMockLogger()
221
+ pikkuState(null, 'package', 'singletonServices', {
222
+ logger: mockLogger,
223
+ } as any)
222
224
  const job = createMockJob('simple-queue', 'job-123', {
223
225
  message: 'test data',
224
226
  })
225
227
 
226
228
  const result = await runQueueJob({
227
- singletonServices: { logger: mockLogger } as any,
228
229
  job,
229
230
  })
230
231
 
@@ -257,12 +258,14 @@ describe('runQueueJob', () => {
257
258
  wireQueueWorker(mockWorker)
258
259
 
259
260
  const mockLogger = createMockLogger()
261
+ pikkuState(null, 'package', 'singletonServices', {
262
+ logger: mockLogger,
263
+ } as any)
260
264
  const job = createMockJob('fail-queue', 'job-fail-123')
261
265
 
262
266
  await assert.rejects(
263
267
  async () => {
264
268
  await runQueueJob({
265
- singletonServices: { logger: mockLogger } as any,
266
269
  job,
267
270
  })
268
271
  },
@@ -295,12 +298,14 @@ describe('runQueueJob', () => {
295
298
  wireQueueWorker(mockWorker)
296
299
 
297
300
  const mockLogger = createMockLogger()
301
+ pikkuState(null, 'package', 'singletonServices', {
302
+ logger: mockLogger,
303
+ } as any)
298
304
  const job = createMockJob('fail-no-reason-queue', 'job-456')
299
305
 
300
306
  await assert.rejects(
301
307
  async () => {
302
308
  await runQueueJob({
303
- singletonServices: { logger: mockLogger } as any,
304
309
  job,
305
310
  })
306
311
  },
@@ -331,12 +336,14 @@ describe('runQueueJob', () => {
331
336
  wireQueueWorker(mockWorker)
332
337
 
333
338
  const mockLogger = createMockLogger()
339
+ pikkuState(null, 'package', 'singletonServices', {
340
+ logger: mockLogger,
341
+ } as any)
334
342
  const job = createMockJob('discard-queue', 'job-discard-789')
335
343
 
336
344
  await assert.rejects(
337
345
  async () => {
338
346
  await runQueueJob({
339
- singletonServices: { logger: mockLogger } as any,
340
347
  job,
341
348
  })
342
349
  },
@@ -374,10 +381,12 @@ describe('runQueueJob', () => {
374
381
  wireQueueWorker(mockWorker)
375
382
 
376
383
  const mockLogger = createMockLogger()
384
+ pikkuState(null, 'package', 'singletonServices', {
385
+ logger: mockLogger,
386
+ } as any)
377
387
  const job = createMockJob('progress-queue', 'job-progress-999')
378
388
 
379
389
  await runQueueJob({
380
- singletonServices: { logger: mockLogger } as any,
381
390
  job,
382
391
  updateProgress: async (progress) => {
383
392
  progressUpdates.push(progress)
@@ -407,10 +416,12 @@ describe('runQueueJob', () => {
407
416
  wireQueueWorker(mockWorker)
408
417
 
409
418
  const mockLogger = createMockLogger()
419
+ pikkuState(null, 'package', 'singletonServices', {
420
+ logger: mockLogger,
421
+ } as any)
410
422
  const job = createMockJob('default-progress-queue', 'job-111')
411
423
 
412
424
  await runQueueJob({
413
- singletonServices: { logger: mockLogger } as any,
414
425
  job,
415
426
  })
416
427
 
@@ -441,10 +452,12 @@ describe('runQueueJob', () => {
441
452
  wireQueueWorker(mockWorker)
442
453
 
443
454
  const mockLogger = createMockLogger()
455
+ pikkuState(null, 'package', 'singletonServices', {
456
+ logger: mockLogger,
457
+ } as any)
444
458
  const job = createMockJob('wire-queue', 'job-int-123')
445
459
 
446
460
  await runQueueJob({
447
- singletonServices: { logger: mockLogger } as any,
448
461
  job,
449
462
  })
450
463
 
@@ -457,12 +470,14 @@ describe('runQueueJob', () => {
457
470
 
458
471
  test('should throw error when processor metadata not found', async () => {
459
472
  const mockLogger = createMockLogger()
473
+ pikkuState(null, 'package', 'singletonServices', {
474
+ logger: mockLogger,
475
+ } as any)
460
476
  const job = createMockJob('missing-meta-queue', 'job-222')
461
477
 
462
478
  await assert.rejects(
463
479
  async () => {
464
480
  await runQueueJob({
465
- singletonServices: { logger: mockLogger } as any,
466
481
  job,
467
482
  })
468
483
  },
@@ -483,12 +498,14 @@ describe('runQueueJob', () => {
483
498
  }
484
499
 
485
500
  const mockLogger = createMockLogger()
501
+ pikkuState(null, 'package', 'singletonServices', {
502
+ logger: mockLogger,
503
+ } as any)
486
504
  const job = createMockJob('no-registration-queue', 'job-333')
487
505
 
488
506
  await assert.rejects(
489
507
  async () => {
490
508
  await runQueueJob({
491
- singletonServices: { logger: mockLogger } as any,
492
509
  job,
493
510
  })
494
511
  },
@@ -520,15 +537,19 @@ describe('runQueueJob', () => {
520
537
  wireQueueWorker(mockWorker)
521
538
 
522
539
  const mockLogger = createMockLogger()
523
- const job = createMockJob('session-services-queue', 'job-444')
524
-
525
- await runQueueJob({
526
- singletonServices: { logger: mockLogger } as any,
527
- job,
540
+ pikkuState(null, 'package', 'singletonServices', {
541
+ logger: mockLogger,
542
+ } as any)
543
+ pikkuState(null, 'package', 'factories', {
528
544
  createWireServices: async () => {
529
545
  createWireServicesCalled = true
530
546
  return mockWireService as any
531
547
  },
548
+ } as any)
549
+ const job = createMockJob('session-services-queue', 'job-444')
550
+
551
+ await runQueueJob({
552
+ job,
532
553
  })
533
554
 
534
555
  assert.equal(createWireServicesCalled, true)
@@ -553,12 +574,14 @@ describe('runQueueJob', () => {
553
574
  wireQueueWorker(mockWorker)
554
575
 
555
576
  const mockLogger = createMockLogger()
577
+ pikkuState(null, 'package', 'singletonServices', {
578
+ logger: mockLogger,
579
+ } as any)
556
580
  const job = createMockJob('error-queue', 'job-555')
557
581
 
558
582
  await assert.rejects(
559
583
  async () => {
560
584
  await runQueueJob({
561
- singletonServices: { logger: mockLogger } as any,
562
585
  job,
563
586
  })
564
587
  },
@@ -602,10 +625,12 @@ describe('runQueueJob', () => {
602
625
  wireQueueWorker(mockWorker)
603
626
 
604
627
  const mockLogger = createMockLogger()
628
+ pikkuState(null, 'package', 'singletonServices', {
629
+ logger: mockLogger,
630
+ } as any)
605
631
  const job = createMockJob('middleware-queue', 'job-666')
606
632
 
607
633
  await runQueueJob({
608
- singletonServices: { logger: mockLogger } as any,
609
634
  job,
610
635
  })
611
636
 
@@ -629,10 +654,12 @@ describe('runQueueJob', () => {
629
654
  wireQueueWorker(mockWorker)
630
655
 
631
656
  const mockLogger = createMockLogger()
657
+ pikkuState(null, 'package', 'singletonServices', {
658
+ logger: mockLogger,
659
+ } as any)
632
660
  const job = createMockJob('debug-queue', 'job-777')
633
661
 
634
662
  await runQueueJob({
635
- singletonServices: { logger: mockLogger } as any,
636
663
  job,
637
664
  })
638
665
 
@@ -643,8 +670,8 @@ describe('runQueueJob', () => {
643
670
  })
644
671
  })
645
672
 
646
- describe('createQueueJobRunner', () => {
647
- test('delegates queue job execution using bound services', async () => {
673
+ describe('runQueueJob with pikkuState services', () => {
674
+ test('delegates queue job execution using pikkuState services', async () => {
648
675
  const mockWorker: CoreQueueWorker = {
649
676
  name: 'bound-runner-queue',
650
677
  func: {
@@ -663,11 +690,11 @@ describe('createQueueJobRunner', () => {
663
690
  wireQueueWorker(mockWorker)
664
691
 
665
692
  const mockLogger = createMockLogger()
666
- const runJob = createQueueJobRunner({
667
- singletonServices: { logger: mockLogger } as any,
668
- })
693
+ pikkuState(null, 'package', 'singletonServices', {
694
+ logger: mockLogger,
695
+ } as any)
669
696
 
670
- await runJob({
697
+ await runQueueJob({
671
698
  job: createMockJob('bound-runner-queue', 'job-888', { value: 41 }),
672
699
  })
673
700