@pikku/core 0.12.3 → 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 (218) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/services/in-memory-workflow-service.d.ts +15 -2
  3. package/dist/services/in-memory-workflow-service.js +49 -0
  4. package/lcov.info +18891 -0
  5. package/package.json +1 -1
  6. package/src/crypto-utils.test.ts +0 -214
  7. package/src/crypto-utils.ts +0 -213
  8. package/src/errors/error-handler.ts +0 -62
  9. package/src/errors/error.test.ts +0 -195
  10. package/src/errors/errors.ts +0 -374
  11. package/src/errors/index.ts +0 -2
  12. package/src/factory-functions.test.ts +0 -109
  13. package/src/function/function-runner.test.ts +0 -536
  14. package/src/function/function-runner.ts +0 -365
  15. package/src/function/functions.types.ts +0 -304
  16. package/src/function/index.ts +0 -5
  17. package/src/handle-error.test.ts +0 -424
  18. package/src/handle-error.ts +0 -69
  19. package/src/index.ts +0 -118
  20. package/src/internal.ts +0 -6
  21. package/src/middleware/auth-apikey.test.ts +0 -363
  22. package/src/middleware/auth-apikey.ts +0 -47
  23. package/src/middleware/auth-bearer.test.ts +0 -450
  24. package/src/middleware/auth-bearer.ts +0 -72
  25. package/src/middleware/auth-cookie.test.ts +0 -528
  26. package/src/middleware/auth-cookie.ts +0 -80
  27. package/src/middleware/cors.test.ts +0 -424
  28. package/src/middleware/cors.ts +0 -104
  29. package/src/middleware/index.ts +0 -5
  30. package/src/middleware/remote-auth.test.ts +0 -488
  31. package/src/middleware/remote-auth.ts +0 -68
  32. package/src/middleware/timeout.ts +0 -15
  33. package/src/middleware-runner.test.ts +0 -418
  34. package/src/middleware-runner.ts +0 -234
  35. package/src/permissions.test.ts +0 -434
  36. package/src/permissions.ts +0 -319
  37. package/src/pikku-request.ts +0 -23
  38. package/src/pikku-response.ts +0 -5
  39. package/src/pikku-state.test.ts +0 -224
  40. package/src/pikku-state.ts +0 -216
  41. package/src/run-tests-script.test.ts +0 -49
  42. package/src/schema.test.ts +0 -249
  43. package/src/schema.ts +0 -151
  44. package/src/services/ai-agent-runner-service.ts +0 -41
  45. package/src/services/ai-run-state-service.ts +0 -20
  46. package/src/services/ai-storage-service.ts +0 -39
  47. package/src/services/content-service.ts +0 -76
  48. package/src/services/deployment-service.ts +0 -22
  49. package/src/services/gateway-service.ts +0 -20
  50. package/src/services/gopass-secrets.ts +0 -98
  51. package/src/services/in-memory-ai-run-state-service.ts +0 -73
  52. package/src/services/in-memory-trigger-service.ts +0 -64
  53. package/src/services/in-memory-workflow-service.test.ts +0 -351
  54. package/src/services/in-memory-workflow-service.ts +0 -438
  55. package/src/services/index.ts +0 -56
  56. package/src/services/jwt-service.ts +0 -30
  57. package/src/services/local-content.ts +0 -120
  58. package/src/services/local-gateway-service.ts +0 -62
  59. package/src/services/local-secrets.test.ts +0 -80
  60. package/src/services/local-secrets.ts +0 -94
  61. package/src/services/local-variables.test.ts +0 -61
  62. package/src/services/local-variables.ts +0 -39
  63. package/src/services/logger-console.test.ts +0 -118
  64. package/src/services/logger-console.ts +0 -98
  65. package/src/services/logger.ts +0 -57
  66. package/src/services/scheduler-service.ts +0 -86
  67. package/src/services/schema-service.ts +0 -33
  68. package/src/services/scoped-secret-service.test.ts +0 -74
  69. package/src/services/scoped-secret-service.ts +0 -41
  70. package/src/services/secret-service.ts +0 -38
  71. package/src/services/trigger-service.ts +0 -17
  72. package/src/services/typed-secret-service.test.ts +0 -93
  73. package/src/services/typed-secret-service.ts +0 -70
  74. package/src/services/typed-variables-service.test.ts +0 -73
  75. package/src/services/typed-variables-service.ts +0 -81
  76. package/src/services/user-session-service.test.ts +0 -113
  77. package/src/services/user-session-service.ts +0 -86
  78. package/src/services/variables-service.ts +0 -11
  79. package/src/services/workflow-service.ts +0 -95
  80. package/src/testing/index.ts +0 -2
  81. package/src/testing/service-tests.ts +0 -873
  82. package/src/time-utils.test.ts +0 -56
  83. package/src/time-utils.ts +0 -107
  84. package/src/types/core.types.ts +0 -478
  85. package/src/types/state.types.ts +0 -188
  86. package/src/utils/hash.test.ts +0 -68
  87. package/src/utils/hash.ts +0 -26
  88. package/src/utils.test.ts +0 -350
  89. package/src/utils.ts +0 -129
  90. package/src/version.test.ts +0 -80
  91. package/src/version.ts +0 -25
  92. package/src/wirings/ai-agent/agent-dynamic-workflow.ts +0 -469
  93. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +0 -152
  94. package/src/wirings/ai-agent/ai-agent-helpers.ts +0 -76
  95. package/src/wirings/ai-agent/ai-agent-memory.ts +0 -310
  96. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +0 -115
  97. package/src/wirings/ai-agent/ai-agent-model-config.ts +0 -43
  98. package/src/wirings/ai-agent/ai-agent-prepare.ts +0 -636
  99. package/src/wirings/ai-agent/ai-agent-registry.test.ts +0 -37
  100. package/src/wirings/ai-agent/ai-agent-registry.ts +0 -82
  101. package/src/wirings/ai-agent/ai-agent-runner.test.ts +0 -319
  102. package/src/wirings/ai-agent/ai-agent-runner.ts +0 -773
  103. package/src/wirings/ai-agent/ai-agent-stream.test.ts +0 -859
  104. package/src/wirings/ai-agent/ai-agent-stream.ts +0 -1153
  105. package/src/wirings/ai-agent/ai-agent.types.ts +0 -382
  106. package/src/wirings/ai-agent/index.ts +0 -37
  107. package/src/wirings/channel/channel-common.ts +0 -90
  108. package/src/wirings/channel/channel-handler.ts +0 -250
  109. package/src/wirings/channel/channel-middleware-runner.ts +0 -120
  110. package/src/wirings/channel/channel-runner.ts +0 -166
  111. package/src/wirings/channel/channel-store.ts +0 -29
  112. package/src/wirings/channel/channel.types.ts +0 -172
  113. package/src/wirings/channel/define-channel-routes.ts +0 -25
  114. package/src/wirings/channel/eventhub-service.ts +0 -34
  115. package/src/wirings/channel/eventhub-store.ts +0 -13
  116. package/src/wirings/channel/index.ts +0 -24
  117. package/src/wirings/channel/local/index.ts +0 -3
  118. package/src/wirings/channel/local/local-channel-handler.ts +0 -81
  119. package/src/wirings/channel/local/local-channel-runner.test.ts +0 -215
  120. package/src/wirings/channel/local/local-channel-runner.ts +0 -210
  121. package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -95
  122. package/src/wirings/channel/local/local-eventhub-service.ts +0 -101
  123. package/src/wirings/channel/log-channels.ts +0 -20
  124. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -54
  125. package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -45
  126. package/src/wirings/channel/serverless/index.ts +0 -5
  127. package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -289
  128. package/src/wirings/cli/channel/cli-channel-runner.ts +0 -136
  129. package/src/wirings/cli/channel/index.ts +0 -1
  130. package/src/wirings/cli/cli-runner.test.ts +0 -403
  131. package/src/wirings/cli/cli-runner.ts +0 -529
  132. package/src/wirings/cli/cli.types.ts +0 -358
  133. package/src/wirings/cli/command-parser.test.ts +0 -445
  134. package/src/wirings/cli/command-parser.ts +0 -504
  135. package/src/wirings/cli/define-cli-commands.ts +0 -24
  136. package/src/wirings/cli/index.ts +0 -19
  137. package/src/wirings/gateway/gateway-runner.test.ts +0 -474
  138. package/src/wirings/gateway/gateway-runner.ts +0 -411
  139. package/src/wirings/gateway/gateway.types.ts +0 -149
  140. package/src/wirings/gateway/index.ts +0 -13
  141. package/src/wirings/http/http-routes.test.ts +0 -322
  142. package/src/wirings/http/http-routes.ts +0 -197
  143. package/src/wirings/http/http-runner.test.ts +0 -144
  144. package/src/wirings/http/http-runner.ts +0 -588
  145. package/src/wirings/http/http.types.ts +0 -369
  146. package/src/wirings/http/index.ts +0 -28
  147. package/src/wirings/http/log-http-routes.ts +0 -22
  148. package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -237
  149. package/src/wirings/http/pikku-fetch-http-request.ts +0 -170
  150. package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -82
  151. package/src/wirings/http/pikku-fetch-http-response.ts +0 -147
  152. package/src/wirings/http/routers/http-router.ts +0 -13
  153. package/src/wirings/http/routers/path-to-regex.test.ts +0 -319
  154. package/src/wirings/http/routers/path-to-regex.ts +0 -126
  155. package/src/wirings/http/web-request.test.ts +0 -236
  156. package/src/wirings/http/web-request.ts +0 -104
  157. package/src/wirings/mcp/index.ts +0 -27
  158. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -389
  159. package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
  160. package/src/wirings/mcp/mcp-runner.ts +0 -323
  161. package/src/wirings/mcp/mcp.types.ts +0 -216
  162. package/src/wirings/node/index.ts +0 -2
  163. package/src/wirings/node/node.types.ts +0 -23
  164. package/src/wirings/oauth2/index.ts +0 -3
  165. package/src/wirings/oauth2/oauth2-client.test.ts +0 -929
  166. package/src/wirings/oauth2/oauth2-client.ts +0 -335
  167. package/src/wirings/oauth2/oauth2.types.ts +0 -69
  168. package/src/wirings/oauth2/wire-oauth2-credential.ts +0 -23
  169. package/src/wirings/queue/index.ts +0 -31
  170. package/src/wirings/queue/queue-runner.test.ts +0 -710
  171. package/src/wirings/queue/queue-runner.ts +0 -192
  172. package/src/wirings/queue/queue.types.ts +0 -189
  173. package/src/wirings/queue/register-queue-helper.ts +0 -60
  174. package/src/wirings/queue/validate-worker-config.test.ts +0 -108
  175. package/src/wirings/queue/validate-worker-config.ts +0 -116
  176. package/src/wirings/rpc/index.ts +0 -4
  177. package/src/wirings/rpc/rpc-runner.ts +0 -460
  178. package/src/wirings/rpc/rpc-types.ts +0 -56
  179. package/src/wirings/rpc/wire-addon.ts +0 -21
  180. package/src/wirings/scheduler/index.ts +0 -11
  181. package/src/wirings/scheduler/log-schedulers.ts +0 -20
  182. package/src/wirings/scheduler/scheduler-runner.test.ts +0 -660
  183. package/src/wirings/scheduler/scheduler-runner.ts +0 -133
  184. package/src/wirings/scheduler/scheduler.types.ts +0 -53
  185. package/src/wirings/secret/index.ts +0 -9
  186. package/src/wirings/secret/secret.types.ts +0 -32
  187. package/src/wirings/secret/validate-secret-definitions.test.ts +0 -140
  188. package/src/wirings/secret/validate-secret-definitions.ts +0 -82
  189. package/src/wirings/trigger/index.ts +0 -10
  190. package/src/wirings/trigger/pikku-trigger-service.ts +0 -112
  191. package/src/wirings/trigger/trigger-runner.test.ts +0 -79
  192. package/src/wirings/trigger/trigger-runner.ts +0 -135
  193. package/src/wirings/trigger/trigger.types.ts +0 -178
  194. package/src/wirings/variable/index.ts +0 -8
  195. package/src/wirings/variable/validate-variable-definitions.test.ts +0 -91
  196. package/src/wirings/variable/validate-variable-definitions.ts +0 -69
  197. package/src/wirings/variable/variable.types.ts +0 -22
  198. package/src/wirings/workflow/dsl/index.ts +0 -31
  199. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -320
  200. package/src/wirings/workflow/dsl/workflow-runner.ts +0 -28
  201. package/src/wirings/workflow/graph/graph-node.ts +0 -222
  202. package/src/wirings/workflow/graph/graph-runner.test.ts +0 -487
  203. package/src/wirings/workflow/graph/graph-runner.ts +0 -816
  204. package/src/wirings/workflow/graph/graph-validation.test.ts +0 -170
  205. package/src/wirings/workflow/graph/graph-validation.ts +0 -237
  206. package/src/wirings/workflow/graph/index.ts +0 -19
  207. package/src/wirings/workflow/graph/template.test.ts +0 -49
  208. package/src/wirings/workflow/graph/template.ts +0 -42
  209. package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -29
  210. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -104
  211. package/src/wirings/workflow/index.ts +0 -82
  212. package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -200
  213. package/src/wirings/workflow/pikku-workflow-service.ts +0 -1176
  214. package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
  215. package/src/wirings/workflow/workflow-helpers.ts +0 -79
  216. package/src/wirings/workflow/workflow.types.ts +0 -274
  217. package/tsconfig.json +0 -14
  218. 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
- }