@pikku/core 0.12.2 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/crypto-utils.d.ts +10 -0
  3. package/dist/crypto-utils.js +62 -0
  4. package/dist/function/function-runner.js +4 -4
  5. package/dist/function/functions.types.d.ts +26 -1
  6. package/dist/function/functions.types.js +16 -0
  7. package/dist/handle-error.d.ts +1 -1
  8. package/dist/handle-error.js +7 -3
  9. package/dist/index.d.ts +14 -2
  10. package/dist/index.js +1 -1
  11. package/dist/pikku-state.js +3 -1
  12. package/dist/schema.js +1 -1
  13. package/dist/services/in-memory-workflow-service.d.ts +22 -3
  14. package/dist/services/in-memory-workflow-service.js +77 -1
  15. package/dist/services/workflow-service.d.ts +8 -2
  16. package/dist/testing/index.d.ts +2 -0
  17. package/dist/testing/index.js +1 -0
  18. package/dist/testing/service-tests.d.ts +31 -0
  19. package/dist/testing/service-tests.js +598 -0
  20. package/dist/types/core.types.d.ts +9 -1
  21. package/dist/types/state.types.d.ts +4 -2
  22. package/dist/utils/hash.d.ts +2 -0
  23. package/dist/utils/hash.js +23 -0
  24. package/dist/wirings/ai-agent/agent-dynamic-workflow.d.ts +6 -0
  25. package/dist/wirings/ai-agent/agent-dynamic-workflow.js +348 -0
  26. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +1 -1
  27. package/dist/wirings/ai-agent/ai-agent-memory.js +6 -5
  28. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -7
  29. package/dist/wirings/ai-agent/ai-agent-prepare.js +127 -47
  30. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +4 -0
  31. package/dist/wirings/ai-agent/ai-agent-runner.js +381 -27
  32. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +7 -2
  33. package/dist/wirings/ai-agent/ai-agent-stream.js +109 -46
  34. package/dist/wirings/ai-agent/ai-agent.types.d.ts +22 -1
  35. package/dist/wirings/ai-agent/index.d.ts +1 -2
  36. package/dist/wirings/ai-agent/index.js +1 -2
  37. package/dist/wirings/channel/channel-handler.js +5 -1
  38. package/dist/wirings/channel/channel.types.d.ts +1 -7
  39. package/dist/wirings/channel/local/local-channel-handler.d.ts +1 -1
  40. package/dist/wirings/channel/local/local-channel-handler.js +5 -3
  41. package/dist/wirings/channel/local/local-channel-runner.js +14 -4
  42. package/dist/wirings/channel/serverless/serverless-channel-runner.js +4 -1
  43. package/dist/wirings/cli/cli-runner.js +10 -2
  44. package/dist/wirings/cli/cli.types.d.ts +1 -0
  45. package/dist/wirings/http/http-routes.js +0 -1
  46. package/dist/wirings/http/http-runner.d.ts +1 -1
  47. package/dist/wirings/http/http-runner.js +25 -3
  48. package/dist/wirings/http/http.types.d.ts +3 -11
  49. package/dist/wirings/http/index.d.ts +2 -1
  50. package/dist/wirings/http/index.js +1 -0
  51. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
  52. package/dist/wirings/http/pikku-fetch-http-request.js +3 -0
  53. package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
  54. package/dist/wirings/http/pikku-fetch-http-response.js +4 -4
  55. package/dist/wirings/http/web-request.d.ts +12 -0
  56. package/dist/wirings/http/web-request.js +85 -0
  57. package/dist/wirings/mcp/mcp-endpoint-registry.js +1 -1
  58. package/dist/wirings/mcp/mcp-runner.js +13 -1
  59. package/dist/wirings/rpc/rpc-runner.d.ts +30 -6
  60. package/dist/wirings/rpc/rpc-runner.js +36 -14
  61. package/dist/wirings/rpc/rpc-types.d.ts +6 -1
  62. package/dist/wirings/rpc/wire-addon.d.ts +1 -0
  63. package/dist/wirings/rpc/wire-addon.js +1 -1
  64. package/dist/wirings/scheduler/scheduler-runner.js +1 -0
  65. package/dist/wirings/workflow/graph/graph-validation.d.ts +3 -0
  66. package/dist/wirings/workflow/graph/graph-validation.js +175 -0
  67. package/dist/wirings/workflow/graph/index.d.ts +1 -0
  68. package/dist/wirings/workflow/graph/index.js +1 -0
  69. package/dist/wirings/workflow/index.d.ts +1 -1
  70. package/dist/wirings/workflow/pikku-workflow-service.d.ts +8 -2
  71. package/dist/wirings/workflow/pikku-workflow-service.js +1 -2
  72. package/dist/wirings/workflow/workflow.types.d.ts +10 -1
  73. package/lcov.info +18891 -0
  74. package/package.json +4 -2
  75. package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +0 -5
  76. package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +0 -168
  77. package/src/crypto-utils.test.ts +0 -116
  78. package/src/crypto-utils.ts +0 -99
  79. package/src/errors/error-handler.ts +0 -62
  80. package/src/errors/error.test.ts +0 -195
  81. package/src/errors/errors.ts +0 -374
  82. package/src/errors/index.ts +0 -2
  83. package/src/factory-functions.test.ts +0 -109
  84. package/src/function/function-runner.test.ts +0 -536
  85. package/src/function/function-runner.ts +0 -365
  86. package/src/function/functions.types.ts +0 -267
  87. package/src/function/index.ts +0 -5
  88. package/src/handle-error.test.ts +0 -361
  89. package/src/handle-error.ts +0 -65
  90. package/src/index.ts +0 -104
  91. package/src/internal.ts +0 -6
  92. package/src/middleware/auth-apikey.test.ts +0 -363
  93. package/src/middleware/auth-apikey.ts +0 -47
  94. package/src/middleware/auth-bearer.test.ts +0 -450
  95. package/src/middleware/auth-bearer.ts +0 -72
  96. package/src/middleware/auth-cookie.test.ts +0 -528
  97. package/src/middleware/auth-cookie.ts +0 -80
  98. package/src/middleware/cors.test.ts +0 -424
  99. package/src/middleware/cors.ts +0 -104
  100. package/src/middleware/index.ts +0 -5
  101. package/src/middleware/remote-auth.test.ts +0 -488
  102. package/src/middleware/remote-auth.ts +0 -68
  103. package/src/middleware/timeout.ts +0 -15
  104. package/src/middleware-runner.test.ts +0 -418
  105. package/src/middleware-runner.ts +0 -234
  106. package/src/permissions.test.ts +0 -434
  107. package/src/permissions.ts +0 -319
  108. package/src/pikku-request.ts +0 -23
  109. package/src/pikku-response.ts +0 -5
  110. package/src/pikku-state.test.ts +0 -224
  111. package/src/pikku-state.ts +0 -214
  112. package/src/run-tests-script.test.ts +0 -49
  113. package/src/schema.test.ts +0 -249
  114. package/src/schema.ts +0 -151
  115. package/src/services/ai-agent-runner-service.ts +0 -41
  116. package/src/services/ai-run-state-service.ts +0 -20
  117. package/src/services/ai-storage-service.ts +0 -39
  118. package/src/services/content-service.ts +0 -76
  119. package/src/services/deployment-service.ts +0 -22
  120. package/src/services/gateway-service.ts +0 -20
  121. package/src/services/gopass-secrets.ts +0 -98
  122. package/src/services/in-memory-ai-run-state-service.ts +0 -73
  123. package/src/services/in-memory-trigger-service.ts +0 -64
  124. package/src/services/in-memory-workflow-service.test.ts +0 -351
  125. package/src/services/in-memory-workflow-service.ts +0 -395
  126. package/src/services/index.ts +0 -56
  127. package/src/services/jwt-service.ts +0 -30
  128. package/src/services/local-content.ts +0 -120
  129. package/src/services/local-gateway-service.ts +0 -62
  130. package/src/services/local-secrets.test.ts +0 -80
  131. package/src/services/local-secrets.ts +0 -94
  132. package/src/services/local-variables.test.ts +0 -61
  133. package/src/services/local-variables.ts +0 -39
  134. package/src/services/logger-console.test.ts +0 -118
  135. package/src/services/logger-console.ts +0 -98
  136. package/src/services/logger.ts +0 -57
  137. package/src/services/scheduler-service.ts +0 -86
  138. package/src/services/schema-service.ts +0 -33
  139. package/src/services/scoped-secret-service.test.ts +0 -74
  140. package/src/services/scoped-secret-service.ts +0 -41
  141. package/src/services/secret-service.ts +0 -38
  142. package/src/services/trigger-service.ts +0 -17
  143. package/src/services/typed-secret-service.test.ts +0 -93
  144. package/src/services/typed-secret-service.ts +0 -70
  145. package/src/services/typed-variables-service.test.ts +0 -73
  146. package/src/services/typed-variables-service.ts +0 -81
  147. package/src/services/user-session-service.test.ts +0 -113
  148. package/src/services/user-session-service.ts +0 -86
  149. package/src/services/variables-service.ts +0 -11
  150. package/src/services/workflow-service.ts +0 -84
  151. package/src/time-utils.test.ts +0 -56
  152. package/src/time-utils.ts +0 -107
  153. package/src/types/core.types.ts +0 -470
  154. package/src/types/state.types.ts +0 -186
  155. package/src/utils.test.ts +0 -350
  156. package/src/utils.ts +0 -129
  157. package/src/version.test.ts +0 -80
  158. package/src/version.ts +0 -25
  159. package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +0 -363
  160. package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +0 -238
  161. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +0 -152
  162. package/src/wirings/ai-agent/ai-agent-helpers.ts +0 -76
  163. package/src/wirings/ai-agent/ai-agent-memory.ts +0 -309
  164. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +0 -115
  165. package/src/wirings/ai-agent/ai-agent-model-config.ts +0 -43
  166. package/src/wirings/ai-agent/ai-agent-prepare.ts +0 -522
  167. package/src/wirings/ai-agent/ai-agent-registry.test.ts +0 -37
  168. package/src/wirings/ai-agent/ai-agent-registry.ts +0 -82
  169. package/src/wirings/ai-agent/ai-agent-runner.test.ts +0 -317
  170. package/src/wirings/ai-agent/ai-agent-runner.ts +0 -251
  171. package/src/wirings/ai-agent/ai-agent-stream.test.ts +0 -652
  172. package/src/wirings/ai-agent/ai-agent-stream.ts +0 -1060
  173. package/src/wirings/ai-agent/ai-agent.types.ts +0 -360
  174. package/src/wirings/ai-agent/index.ts +0 -41
  175. package/src/wirings/channel/channel-common.ts +0 -90
  176. package/src/wirings/channel/channel-handler.ts +0 -241
  177. package/src/wirings/channel/channel-middleware-runner.ts +0 -120
  178. package/src/wirings/channel/channel-runner.ts +0 -166
  179. package/src/wirings/channel/channel-store.ts +0 -29
  180. package/src/wirings/channel/channel.types.ts +0 -178
  181. package/src/wirings/channel/define-channel-routes.ts +0 -25
  182. package/src/wirings/channel/eventhub-service.ts +0 -34
  183. package/src/wirings/channel/eventhub-store.ts +0 -13
  184. package/src/wirings/channel/index.ts +0 -24
  185. package/src/wirings/channel/local/index.ts +0 -3
  186. package/src/wirings/channel/local/local-channel-handler.ts +0 -79
  187. package/src/wirings/channel/local/local-channel-runner.test.ts +0 -215
  188. package/src/wirings/channel/local/local-channel-runner.ts +0 -200
  189. package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -95
  190. package/src/wirings/channel/local/local-eventhub-service.ts +0 -101
  191. package/src/wirings/channel/log-channels.ts +0 -20
  192. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -54
  193. package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -45
  194. package/src/wirings/channel/serverless/index.ts +0 -5
  195. package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -286
  196. package/src/wirings/cli/channel/cli-channel-runner.ts +0 -136
  197. package/src/wirings/cli/channel/index.ts +0 -1
  198. package/src/wirings/cli/cli-runner.test.ts +0 -403
  199. package/src/wirings/cli/cli-runner.ts +0 -519
  200. package/src/wirings/cli/cli.types.ts +0 -357
  201. package/src/wirings/cli/command-parser.test.ts +0 -445
  202. package/src/wirings/cli/command-parser.ts +0 -504
  203. package/src/wirings/cli/define-cli-commands.ts +0 -24
  204. package/src/wirings/cli/index.ts +0 -19
  205. package/src/wirings/gateway/gateway-runner.test.ts +0 -474
  206. package/src/wirings/gateway/gateway-runner.ts +0 -411
  207. package/src/wirings/gateway/gateway.types.ts +0 -149
  208. package/src/wirings/gateway/index.ts +0 -13
  209. package/src/wirings/http/http-routes.test.ts +0 -322
  210. package/src/wirings/http/http-routes.ts +0 -198
  211. package/src/wirings/http/http-runner.test.ts +0 -144
  212. package/src/wirings/http/http-runner.ts +0 -563
  213. package/src/wirings/http/http.types.ts +0 -378
  214. package/src/wirings/http/index.ts +0 -25
  215. package/src/wirings/http/log-http-routes.ts +0 -22
  216. package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -237
  217. package/src/wirings/http/pikku-fetch-http-request.ts +0 -166
  218. package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -82
  219. package/src/wirings/http/pikku-fetch-http-response.ts +0 -147
  220. package/src/wirings/http/routers/http-router.ts +0 -13
  221. package/src/wirings/http/routers/path-to-regex.test.ts +0 -319
  222. package/src/wirings/http/routers/path-to-regex.ts +0 -126
  223. package/src/wirings/mcp/index.ts +0 -27
  224. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -389
  225. package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
  226. package/src/wirings/mcp/mcp-runner.ts +0 -305
  227. package/src/wirings/mcp/mcp.types.ts +0 -216
  228. package/src/wirings/node/index.ts +0 -2
  229. package/src/wirings/node/node.types.ts +0 -23
  230. package/src/wirings/oauth2/index.ts +0 -3
  231. package/src/wirings/oauth2/oauth2-client.test.ts +0 -929
  232. package/src/wirings/oauth2/oauth2-client.ts +0 -335
  233. package/src/wirings/oauth2/oauth2.types.ts +0 -69
  234. package/src/wirings/oauth2/wire-oauth2-credential.ts +0 -23
  235. package/src/wirings/queue/index.ts +0 -31
  236. package/src/wirings/queue/queue-runner.test.ts +0 -710
  237. package/src/wirings/queue/queue-runner.ts +0 -192
  238. package/src/wirings/queue/queue.types.ts +0 -189
  239. package/src/wirings/queue/register-queue-helper.ts +0 -60
  240. package/src/wirings/queue/validate-worker-config.test.ts +0 -108
  241. package/src/wirings/queue/validate-worker-config.ts +0 -116
  242. package/src/wirings/rpc/index.ts +0 -4
  243. package/src/wirings/rpc/rpc-runner.ts +0 -439
  244. package/src/wirings/rpc/rpc-types.ts +0 -51
  245. package/src/wirings/rpc/wire-addon.ts +0 -20
  246. package/src/wirings/scheduler/index.ts +0 -11
  247. package/src/wirings/scheduler/log-schedulers.ts +0 -20
  248. package/src/wirings/scheduler/scheduler-runner.test.ts +0 -660
  249. package/src/wirings/scheduler/scheduler-runner.ts +0 -132
  250. package/src/wirings/scheduler/scheduler.types.ts +0 -53
  251. package/src/wirings/secret/index.ts +0 -9
  252. package/src/wirings/secret/secret.types.ts +0 -32
  253. package/src/wirings/secret/validate-secret-definitions.test.ts +0 -140
  254. package/src/wirings/secret/validate-secret-definitions.ts +0 -82
  255. package/src/wirings/trigger/index.ts +0 -10
  256. package/src/wirings/trigger/pikku-trigger-service.ts +0 -112
  257. package/src/wirings/trigger/trigger-runner.test.ts +0 -79
  258. package/src/wirings/trigger/trigger-runner.ts +0 -135
  259. package/src/wirings/trigger/trigger.types.ts +0 -178
  260. package/src/wirings/variable/index.ts +0 -8
  261. package/src/wirings/variable/validate-variable-definitions.test.ts +0 -91
  262. package/src/wirings/variable/validate-variable-definitions.ts +0 -69
  263. package/src/wirings/variable/variable.types.ts +0 -22
  264. package/src/wirings/workflow/dsl/index.ts +0 -31
  265. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -320
  266. package/src/wirings/workflow/dsl/workflow-runner.ts +0 -28
  267. package/src/wirings/workflow/graph/graph-node.ts +0 -222
  268. package/src/wirings/workflow/graph/graph-runner.test.ts +0 -487
  269. package/src/wirings/workflow/graph/graph-runner.ts +0 -816
  270. package/src/wirings/workflow/graph/index.ts +0 -14
  271. package/src/wirings/workflow/graph/template.test.ts +0 -49
  272. package/src/wirings/workflow/graph/template.ts +0 -42
  273. package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -29
  274. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -104
  275. package/src/wirings/workflow/index.ts +0 -81
  276. package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -200
  277. package/src/wirings/workflow/pikku-workflow-service.ts +0 -1165
  278. package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
  279. package/src/wirings/workflow/workflow-helpers.ts +0 -79
  280. package/src/wirings/workflow/workflow.types.ts +0 -266
  281. package/tsconfig.json +0 -14
  282. package/tsconfig.tsbuildinfo +0 -1
@@ -1,418 +0,0 @@
1
- import { describe, test, beforeEach } from 'node:test'
2
- import assert from 'node:assert'
3
- import {
4
- combineMiddleware,
5
- addMiddleware,
6
- runMiddleware,
7
- } from './middleware-runner.js'
8
- import { resetPikkuState } from './pikku-state.js'
9
- import type { CorePikkuMiddleware } from './types/core.types.js'
10
-
11
- beforeEach(() => {
12
- resetPikkuState()
13
- })
14
-
15
- describe('combineMiddleware', () => {
16
- test('should return empty array when no parameters provided', () => {
17
- const result = combineMiddleware('http', Math.random().toString())
18
- assert.deepEqual(result, [])
19
- })
20
-
21
- test('should return empty array when all parameters are undefined', () => {
22
- const result = combineMiddleware('http', Math.random().toString(), {
23
- wiringMiddleware: undefined,
24
- wiringTags: undefined,
25
- funcMiddleware: undefined,
26
- funcTags: undefined,
27
- })
28
- assert.deepEqual(result, [])
29
- })
30
-
31
- test('should combine wiring middleware only', () => {
32
- const mockMiddleware1: CorePikkuMiddleware = async (
33
- services,
34
- wire,
35
- next
36
- ) => {
37
- await next()
38
- }
39
- const mockMiddleware2: CorePikkuMiddleware = async (
40
- services,
41
- wire,
42
- next
43
- ) => {
44
- await next()
45
- }
46
-
47
- const result = combineMiddleware('http', Math.random().toString(), {
48
- wireMiddleware: [mockMiddleware1, mockMiddleware2],
49
- })
50
-
51
- assert.equal(result.length, 2)
52
- assert.equal(result[0], mockMiddleware1)
53
- assert.equal(result[1], mockMiddleware2)
54
- })
55
-
56
- test('should combine function middleware only', () => {
57
- const mockMiddleware1: CorePikkuMiddleware = async (
58
- services,
59
- wire,
60
- next
61
- ) => {
62
- await next()
63
- }
64
- const mockMiddleware2: CorePikkuMiddleware = async (
65
- services,
66
- wire,
67
- next
68
- ) => {
69
- await next()
70
- }
71
-
72
- const result = combineMiddleware('http', Math.random().toString(), {
73
- funcMiddleware: [mockMiddleware1, mockMiddleware2],
74
- })
75
-
76
- assert.equal(result.length, 2)
77
- assert.equal(result[0], mockMiddleware1)
78
- assert.equal(result[1], mockMiddleware2)
79
- })
80
-
81
- test('should execute middleware in correct order: wireInheritedMiddleware (tags) → wireMiddleware → funcInheritedMiddleware (tags) → funcMiddleware', () => {
82
- // Setup tagged middleware
83
- const wiringTagMiddleware: CorePikkuMiddleware = async (
84
- services,
85
- wire,
86
- next
87
- ) => {
88
- await next()
89
- }
90
- const funcTagMiddleware: CorePikkuMiddleware = async (
91
- services,
92
- wire,
93
- next
94
- ) => {
95
- await next()
96
- }
97
-
98
- addMiddleware('wiringTag', [wiringTagMiddleware])
99
- addMiddleware('funcTag', [funcTagMiddleware])
100
-
101
- const wiringMiddleware: CorePikkuMiddleware = async (
102
- services,
103
- wire,
104
- next
105
- ) => {
106
- await next()
107
- }
108
- const funcMiddleware: CorePikkuMiddleware = async (
109
- services,
110
- wire,
111
- next
112
- ) => {
113
- await next()
114
- }
115
-
116
- const result = combineMiddleware('http', Math.random().toString(), {
117
- wireInheritedMiddleware: [{ type: 'tag', tag: 'wiringTag' }],
118
- wireMiddleware: [wiringMiddleware],
119
- funcInheritedMiddleware: [{ type: 'tag', tag: 'funcTag' }],
120
- funcMiddleware: [funcMiddleware],
121
- })
122
-
123
- assert.equal(result.length, 4)
124
- // Order: wireInheritedMiddleware (tags), wireMiddleware, funcInheritedMiddleware (tags), funcMiddleware
125
- assert.equal(result[0], wiringTagMiddleware) // wireInheritedMiddleware tags first
126
- assert.equal(result[1], wiringMiddleware) // wireMiddleware second
127
- assert.equal(result[2], funcTagMiddleware) // funcInheritedMiddleware tags third
128
- assert.equal(result[3], funcMiddleware) // funcMiddleware last
129
- })
130
-
131
- test('should handle wiring tags only', () => {
132
- const taggedMiddleware: CorePikkuMiddleware = async (
133
- services,
134
- wire,
135
- next
136
- ) => {
137
- await next()
138
- }
139
-
140
- addMiddleware('testTag', [taggedMiddleware])
141
-
142
- const result = combineMiddleware('http', Math.random().toString(), {
143
- wireInheritedMiddleware: [{ type: 'tag', tag: 'testTag' }],
144
- })
145
-
146
- assert.equal(result.length, 1)
147
- assert.equal(result[0], taggedMiddleware)
148
- })
149
-
150
- test('should handle function tags only', () => {
151
- const taggedMiddleware: CorePikkuMiddleware = async (
152
- services,
153
- wire,
154
- next
155
- ) => {
156
- await next()
157
- }
158
-
159
- addMiddleware('funcTestTag', [taggedMiddleware])
160
-
161
- const result = combineMiddleware('http', Math.random().toString(), {
162
- funcInheritedMiddleware: [{ type: 'tag', tag: 'funcTestTag' }],
163
- })
164
-
165
- assert.equal(result.length, 1)
166
- assert.equal(result[0], taggedMiddleware)
167
- })
168
-
169
- test('should handle multiple tags', () => {
170
- const middleware1: CorePikkuMiddleware = async (services, wire, next) => {
171
- await next()
172
- }
173
- const middleware2: CorePikkuMiddleware = async (services, wire, next) => {
174
- await next()
175
- }
176
-
177
- addMiddleware('tag1', [middleware1])
178
- addMiddleware('tag2', [middleware2])
179
-
180
- const result = combineMiddleware('http', Math.random().toString(), {
181
- wireInheritedMiddleware: [
182
- { type: 'tag', tag: 'tag1' },
183
- { type: 'tag', tag: 'tag2' },
184
- ],
185
- })
186
-
187
- assert.equal(result.length, 2)
188
- assert.equal(result[0], middleware1)
189
- assert.equal(result[1], middleware2)
190
- })
191
-
192
- test('should apply parent tag middleware to namespaced tag', () => {
193
- const billingMiddleware: CorePikkuMiddleware = async (
194
- services,
195
- wire,
196
- next
197
- ) => {
198
- await next()
199
- }
200
-
201
- addMiddleware('billing', [billingMiddleware])
202
-
203
- const result = combineMiddleware('http', Math.random().toString(), {
204
- wireInheritedMiddleware: [{ type: 'tag', tag: 'billing:read' }],
205
- })
206
-
207
- assert.equal(result.length, 1)
208
- assert.equal(result[0], billingMiddleware)
209
- })
210
-
211
- test('should apply exact tag middleware for non-namespaced tag', () => {
212
- const billingMiddleware: CorePikkuMiddleware = async (
213
- services,
214
- wire,
215
- next
216
- ) => {
217
- await next()
218
- }
219
-
220
- addMiddleware('billing', [billingMiddleware])
221
-
222
- const result = combineMiddleware('http', Math.random().toString(), {
223
- wireInheritedMiddleware: [{ type: 'tag', tag: 'billing' }],
224
- })
225
-
226
- assert.equal(result.length, 1)
227
- assert.equal(result[0], billingMiddleware)
228
- })
229
-
230
- test('should apply both exact and parent tag middleware (specific first)', () => {
231
- const billingMiddleware: CorePikkuMiddleware = async (
232
- services,
233
- wire,
234
- next
235
- ) => {
236
- await next()
237
- }
238
- const billingReadMiddleware: CorePikkuMiddleware = async (
239
- services,
240
- wire,
241
- next
242
- ) => {
243
- await next()
244
- }
245
-
246
- addMiddleware('billing', [billingMiddleware])
247
- addMiddleware('billing:read', [billingReadMiddleware])
248
-
249
- const result = combineMiddleware('http', Math.random().toString(), {
250
- wireInheritedMiddleware: [{ type: 'tag', tag: 'billing:read' }],
251
- })
252
-
253
- assert.equal(result.length, 2)
254
- assert.equal(result[0], billingReadMiddleware)
255
- assert.equal(result[1], billingMiddleware)
256
- })
257
-
258
- test('should resolve multi-level namespace tags', () => {
259
- const billingMiddleware: CorePikkuMiddleware = async (
260
- services,
261
- wire,
262
- next
263
- ) => {
264
- await next()
265
- }
266
- const billingReadMiddleware: CorePikkuMiddleware = async (
267
- services,
268
- wire,
269
- next
270
- ) => {
271
- await next()
272
- }
273
- const billingReadAdminMiddleware: CorePikkuMiddleware = async (
274
- services,
275
- wire,
276
- next
277
- ) => {
278
- await next()
279
- }
280
-
281
- addMiddleware('billing', [billingMiddleware])
282
- addMiddleware('billing:read', [billingReadMiddleware])
283
- addMiddleware('billing:read:admin', [billingReadAdminMiddleware])
284
-
285
- const result = combineMiddleware('http', Math.random().toString(), {
286
- wireInheritedMiddleware: [{ type: 'tag', tag: 'billing:read:admin' }],
287
- })
288
-
289
- assert.equal(result.length, 3)
290
- assert.equal(result[0], billingReadAdminMiddleware)
291
- assert.equal(result[1], billingReadMiddleware)
292
- assert.equal(result[2], billingMiddleware)
293
- })
294
-
295
- test('should apply parent tag middleware via funcInheritedMiddleware', () => {
296
- const billingMiddleware: CorePikkuMiddleware = async (
297
- services,
298
- wire,
299
- next
300
- ) => {
301
- await next()
302
- }
303
-
304
- addMiddleware('billing', [billingMiddleware])
305
-
306
- const result = combineMiddleware('http', Math.random().toString(), {
307
- funcInheritedMiddleware: [{ type: 'tag', tag: 'billing:write' }],
308
- })
309
-
310
- assert.equal(result.length, 1)
311
- assert.equal(result[0], billingMiddleware)
312
- })
313
-
314
- test('should ignore non-existent tags', () => {
315
- const middleware: CorePikkuMiddleware = async (services, wire, next) => {
316
- await next()
317
- }
318
-
319
- addMiddleware('existingTag', [middleware])
320
-
321
- const result = combineMiddleware('http', Math.random().toString(), {
322
- wireInheritedMiddleware: [
323
- { type: 'tag', tag: 'existingTag' },
324
- { type: 'tag', tag: 'nonExistentTag' },
325
- ],
326
- funcInheritedMiddleware: [{ type: 'tag', tag: 'anotherNonExistentTag' }],
327
- })
328
-
329
- assert.equal(result.length, 1)
330
- assert.equal(result[0], middleware)
331
- })
332
- })
333
-
334
- describe('runMiddleware', () => {
335
- test('should deduplicate middleware using Set', async () => {
336
- const executionOrder: string[] = []
337
-
338
- const middleware1: CorePikkuMiddleware = async (services, wire, next) => {
339
- executionOrder.push('middleware1')
340
- await next()
341
- }
342
-
343
- const middleware2: CorePikkuMiddleware = async (services, wire, next) => {
344
- executionOrder.push('middleware2')
345
- await next()
346
- }
347
-
348
- await runMiddleware(
349
- {} as any,
350
- {} as any,
351
- combineMiddleware('rpc', Math.random().toString(), {
352
- wireMiddleware: [middleware1, middleware2, middleware1, middleware2],
353
- }),
354
- async () => {
355
- executionOrder.push('main')
356
- }
357
- )
358
-
359
- // Should only execute each middleware once
360
- assert.deepEqual(executionOrder, ['middleware1', 'middleware2', 'main'])
361
- })
362
-
363
- test('should execute middleware in correct order', async () => {
364
- const executionOrder: string[] = []
365
-
366
- const middleware1: CorePikkuMiddleware = async (services, wire, next) => {
367
- executionOrder.push('start1')
368
- await next()
369
- executionOrder.push('end1')
370
- }
371
-
372
- const middleware2: CorePikkuMiddleware = async (services, wire, next) => {
373
- executionOrder.push('start2')
374
- await next()
375
- executionOrder.push('end2')
376
- }
377
-
378
- await runMiddleware(
379
- {} as any,
380
- {} as any,
381
- [middleware1, middleware2],
382
- async () => {
383
- executionOrder.push('main')
384
- }
385
- )
386
-
387
- assert.deepEqual(executionOrder, [
388
- 'start1',
389
- 'start2',
390
- 'main',
391
- 'end2',
392
- 'end1',
393
- ])
394
- })
395
-
396
- test('should work with empty middleware array', async () => {
397
- let mainExecuted = false
398
-
399
- await runMiddleware({} as any, {} as any, [], async () => {
400
- mainExecuted = true
401
- })
402
-
403
- assert.equal(mainExecuted, true)
404
- })
405
-
406
- test('should work without main function', async () => {
407
- const executionOrder: string[] = []
408
-
409
- const middleware: CorePikkuMiddleware = async (services, wire, next) => {
410
- executionOrder.push('middleware')
411
- await next()
412
- }
413
-
414
- await runMiddleware({} as any, {} as any, [middleware])
415
-
416
- assert.deepEqual(executionOrder, ['middleware'])
417
- })
418
- })
@@ -1,234 +0,0 @@
1
- import type {
2
- CoreSingletonServices,
3
- PikkuWire,
4
- CorePikkuMiddleware,
5
- CorePikkuMiddlewareGroup,
6
- PikkuWiringTypes,
7
- MiddlewareMetadata,
8
- } from './types/core.types.js'
9
- import { pikkuState } from './pikku-state.js'
10
- import { freezeDedupe, getTagGroups } from './utils.js'
11
-
12
- /**
13
- * Runs a chain of middleware functions in sequence before executing the main function.
14
- *
15
- * @param services - An object containing services (e.g., singletonServices, userSession, etc.)
16
- * @param wire - The wire context, e.g., { http }.
17
- * @param middlewares - An array of middleware functions to run.
18
- * @param main - The main function to execute after all middleware have run.
19
- * @returns A promise resolving to the result of the main function.
20
- *
21
- * @example
22
- * runMiddleware(
23
- * { ...services, userSession },
24
- * { http },
25
- * [middleware1, middleware2, middleware3],
26
- * async () => { return await runMain(); }
27
- * );
28
- */
29
- export const runMiddleware = async <Middleware extends CorePikkuMiddleware>(
30
- services: CoreSingletonServices,
31
- wire: PikkuWire,
32
- middlewares: readonly Middleware[],
33
- main?: () => Promise<unknown>
34
- ): Promise<unknown> => {
35
- // Deduplicate middleware using Set to avoid running the same middleware multiple times
36
- let result: any
37
- const dispatch = async (index: number): Promise<any> => {
38
- if (middlewares && index < middlewares.length) {
39
- return await middlewares[index]!(services as any, wire, () =>
40
- dispatch(index + 1)
41
- )
42
- } else if (main) {
43
- result = await main()
44
- }
45
- }
46
- await dispatch(0)
47
- return result
48
- }
49
-
50
- /**
51
- * Registers global middleware for a specific tag.
52
- *
53
- * This function registers middleware at runtime that will be applied to
54
- * any wiring (HTTP, Channel, Queue, Scheduler, MCP, CLI) that includes the matching tag.
55
- *
56
- * For tree-shaking benefits, wrap in a factory function:
57
- * `export const x = () => addMiddleware('tag', [...])`
58
- *
59
- * Accepts an array that can contain:
60
- * - Direct middleware functions (CorePikkuMiddleware)
61
- * - Factory middleware functions (CorePikkuMiddlewareFactory)
62
- *
63
- * @template PikkuMiddleware The middleware type.
64
- * @param {string} tag - The tag that the middleware should apply to.
65
- * @param {CorePikkuMiddlewareGroup} middleware - Array of middleware for this tag.
66
- *
67
- * @returns {CorePikkuMiddlewareGroup} The middleware array (for chaining/wrapping).
68
- *
69
- * @example
70
- * ```typescript
71
- * // Recommended: tree-shakeable
72
- * export const adminMiddleware = () => addMiddleware('admin', [
73
- * authMiddleware,
74
- * loggingMiddleware({ level: 'info' })
75
- * ])
76
- *
77
- * // Also works: no tree-shaking
78
- * export const apiMiddleware = addMiddleware('api', [
79
- * rateLimitMiddleware
80
- * ])
81
- * ```
82
- */
83
- export const addMiddleware = <PikkuMiddleware extends CorePikkuMiddleware>(
84
- tag: string,
85
- middleware: CorePikkuMiddlewareGroup,
86
- packageName: string | null = null
87
- ): CorePikkuMiddlewareGroup => {
88
- const tagGroups = pikkuState(packageName, 'middleware', 'tagGroup')
89
- tagGroups[tag] = middleware
90
- return middleware
91
- }
92
-
93
- /**
94
- * Retrieves a registered middleware function by its name.
95
- *
96
- * This function looks up middleware that was registered with registerMiddleware.
97
- * It's used internally by the framework to resolve middleware references in metadata.
98
- *
99
- * @param {string} name - The unique name (pikkuFuncId) of the middleware function.
100
- * @returns {CorePikkuMiddleware | undefined} The middleware function, or undefined if not found.
101
- *
102
- * @internal
103
- */
104
- const getMiddlewareByName = (name: string): CorePikkuMiddleware | undefined => {
105
- const middlewareStore = pikkuState(null, 'misc', 'middleware')
106
- const middleware = middlewareStore[name]
107
- return middleware?.[0]
108
- }
109
-
110
- const middlewareCache: Record<
111
- PikkuWiringTypes,
112
- Record<string, readonly CorePikkuMiddleware[]>
113
- > = {
114
- http: {},
115
- rpc: {},
116
- channel: {},
117
- queue: {},
118
- scheduler: {},
119
- trigger: {},
120
- mcp: {},
121
- agent: {},
122
- cli: {},
123
- workflow: {},
124
- gateway: {},
125
- }
126
-
127
- /**
128
- * Combines wiring-specific middleware with function-level middleware.
129
- *
130
- * This function resolves middleware metadata into actual middleware functions and combines them.
131
- * It filters out wire middleware without tags from inheritedMiddleware to avoid duplication
132
- * (those are passed separately as wireMiddleware).
133
- *
134
- * @param {object} options - Configuration object for combining middleware.
135
- * @param {MiddlewareMetadata[] | undefined} options.inheritedMiddleware - Metadata from wiring (HTTP + tags + wire with tags).
136
- * @param {CorePikkuMiddleware[] | undefined} options.wireMiddleware - Inline wire middleware.
137
- * @param {MiddlewareMetadata[] | undefined} options.funcMiddleware - Function middleware metadata.
138
- * @returns {CorePikkuMiddleware[]} Combined array of resolved middleware.
139
- *
140
- * @example
141
- * ```typescript
142
- * const combined = combineMiddleware(wireType, wireId, {
143
- * inheritedMiddleware: meta.middleware,
144
- * wireMiddleware: [inlineMiddleware],
145
- * funcMiddleware: funcMeta.middleware
146
- * })
147
- * ```
148
- */
149
- export const combineMiddleware = (
150
- wireType: PikkuWiringTypes,
151
- uid: string,
152
- {
153
- wireInheritedMiddleware,
154
- wireMiddleware,
155
- funcInheritedMiddleware,
156
- funcMiddleware,
157
- packageName = null,
158
- }: {
159
- wireInheritedMiddleware?: MiddlewareMetadata[]
160
- wireMiddleware?: CorePikkuMiddleware[]
161
- funcInheritedMiddleware?: MiddlewareMetadata[]
162
- funcMiddleware?: CorePikkuMiddleware[]
163
- packageName?: string | null
164
- } = {}
165
- ): readonly CorePikkuMiddleware[] => {
166
- if (middlewareCache[wireType][uid]) {
167
- return middlewareCache[wireType][uid]
168
- }
169
-
170
- const resolved: CorePikkuMiddleware[] = []
171
-
172
- // 1. Resolve wire inherited middleware (HTTP + tag groups + individual wire middleware)
173
- if (wireInheritedMiddleware) {
174
- for (const meta of wireInheritedMiddleware) {
175
- if (meta.type === 'http') {
176
- // Look up HTTP middleware group from pikkuState
177
- const group = pikkuState(packageName, 'middleware', 'httpGroup')[
178
- meta.route
179
- ]
180
- if (group) {
181
- // At runtime, all factories should be resolved to middleware
182
- resolved.push(...(group as CorePikkuMiddleware[]))
183
- }
184
- } else if (meta.type === 'tag') {
185
- const groups = getTagGroups(
186
- pikkuState(packageName, 'middleware', 'tagGroup'),
187
- meta.tag
188
- )
189
- for (const group of groups) {
190
- resolved.push(...(group as CorePikkuMiddleware[]))
191
- }
192
- } else if (meta.type === 'wire') {
193
- // Individual wire middleware (exported, not inline)
194
- const middleware = getMiddlewareByName(meta.name)
195
- if (middleware) {
196
- resolved.push(middleware)
197
- }
198
- }
199
- }
200
- }
201
-
202
- // 2. Add inline wire middleware
203
- if (wireMiddleware) {
204
- resolved.push(...wireMiddleware)
205
- }
206
-
207
- // 3. Resolve function inherited middleware (only tags, wire middleware already handled)
208
- if (funcInheritedMiddleware) {
209
- for (const meta of funcInheritedMiddleware) {
210
- if (meta.type === 'tag') {
211
- const groups = getTagGroups(
212
- pikkuState(packageName, 'middleware', 'tagGroup'),
213
- meta.tag
214
- )
215
- for (const group of groups) {
216
- resolved.push(...(group as CorePikkuMiddleware[]))
217
- }
218
- }
219
- // Note: wire middleware is already handled in wireInheritedMiddleware
220
- }
221
- }
222
-
223
- // 4. Add inline function middleware
224
- if (funcMiddleware) {
225
- resolved.push(...funcMiddleware)
226
- }
227
-
228
- // Deduplicate and freeze
229
- middlewareCache[wireType][uid] = freezeDedupe(
230
- resolved
231
- ) as readonly CorePikkuMiddleware[]
232
-
233
- return middlewareCache[wireType][uid]
234
- }