@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,319 +0,0 @@
1
- import { test, describe, beforeEach } from 'node:test'
2
- import * as assert from 'node:assert/strict'
3
- import { PathToRegexRouter } from './path-to-regex.js'
4
- import { resetPikkuState, pikkuState } from '../../../pikku-state.js'
5
- import type { HTTPMethod } from '../http.types.js'
6
-
7
- describe('PathToRegexRouter', () => {
8
- let router: PathToRegexRouter
9
-
10
- // Helper to create mock route wiring
11
- const mockRoute = (route: string) => ({
12
- route,
13
- method: 'get' as HTTPMethod,
14
- func: (() => {}) as any,
15
- })
16
-
17
- beforeEach(() => {
18
- resetPikkuState()
19
- router = new PathToRegexRouter()
20
- })
21
-
22
- describe('Static Route Optimization', () => {
23
- test('should correctly identify static routes', () => {
24
- // Setup test routes
25
- pikkuState(
26
- null,
27
- 'http',
28
- 'routes',
29
- new Map([
30
- [
31
- 'get',
32
- new Map([
33
- ['/static', mockRoute('/static')],
34
- ['/api/about', mockRoute('/api/about')],
35
- ['/health', mockRoute('/health')],
36
- ]),
37
- ],
38
- ])
39
- )
40
- pikkuState(null, 'http', 'middleware', new Map())
41
- pikkuState(null, 'channel', 'channels', new Map())
42
-
43
- router.initialize()
44
-
45
- // Test static routes - should return exact matches with empty params
46
- const staticResult = router.match('get', '/static')
47
- assert.ok(staticResult, 'Static route should match')
48
- assert.strictEqual(staticResult.route, '/static')
49
- assert.deepStrictEqual(staticResult.params, {})
50
-
51
- const aboutResult = router.match('get', '/api/about')
52
- assert.ok(aboutResult, 'Static route /api/about should match')
53
- assert.strictEqual(aboutResult.route, '/api/about')
54
- assert.deepStrictEqual(aboutResult.params, {})
55
- })
56
-
57
- test('should handle dynamic routes with parameters', () => {
58
- // Setup test routes with parameters
59
- pikkuState(
60
- null,
61
- 'http',
62
- 'routes',
63
- new Map([
64
- [
65
- 'get',
66
- new Map([
67
- ['/api/users/:id', mockRoute('/api/users/:id')],
68
- [
69
- '/posts/:slug/comments/:commentId',
70
- mockRoute('/posts/:slug/comments/:commentId'),
71
- ],
72
- ]),
73
- ],
74
- ])
75
- )
76
- pikkuState(null, 'http', 'middleware', new Map())
77
- pikkuState(null, 'channel', 'channels', new Map())
78
-
79
- router.initialize()
80
-
81
- // Test dynamic routes - should return matches with extracted parameters
82
- const userResult = router.match('get', '/api/users/123')
83
- assert.ok(userResult, 'Dynamic route should match')
84
- assert.strictEqual(userResult.route, '/api/users/:id')
85
- assert.strictEqual(userResult.params.id, '123')
86
-
87
- const commentResult = router.match(
88
- 'get',
89
- '/posts/hello-world/comments/456'
90
- )
91
- assert.ok(commentResult, 'Complex dynamic route should match')
92
- assert.strictEqual(
93
- commentResult.route,
94
- '/posts/:slug/comments/:commentId'
95
- )
96
- assert.strictEqual(commentResult.params.slug, 'hello-world')
97
- assert.strictEqual(commentResult.params.commentId, '456')
98
- })
99
-
100
- test('should handle multi-parameter routes', () => {
101
- // Setup routes with multiple parameters
102
- pikkuState(
103
- null,
104
- 'http',
105
- 'routes',
106
- new Map([
107
- [
108
- 'get',
109
- new Map([
110
- [
111
- '/api/:version/users/:userId',
112
- mockRoute('/api/:version/users/:userId'),
113
- ],
114
- [
115
- '/blog/:year/:month/:slug',
116
- mockRoute('/blog/:year/:month/:slug'),
117
- ],
118
- ]),
119
- ],
120
- ])
121
- )
122
- pikkuState(null, 'http', 'middleware', new Map())
123
- pikkuState(null, 'channel', 'channels', new Map())
124
-
125
- router.initialize()
126
-
127
- // Test multi-parameter routes
128
- const apiResult = router.match('get', '/api/v2/users/456')
129
- assert.ok(apiResult, 'Multi-parameter route should match')
130
- assert.strictEqual(apiResult.route, '/api/:version/users/:userId')
131
- assert.strictEqual(apiResult.params.version, 'v2')
132
- assert.strictEqual(apiResult.params.userId, '456')
133
-
134
- const blogResult = router.match('get', '/blog/2024/03/hello-world')
135
- assert.ok(blogResult, 'Deep multi-parameter route should match')
136
- assert.strictEqual(blogResult.route, '/blog/:year/:month/:slug')
137
- assert.strictEqual(blogResult.params.year, '2024')
138
- assert.strictEqual(blogResult.params.month, '03')
139
- assert.strictEqual(blogResult.params.slug, 'hello-world')
140
- })
141
-
142
- test('should prioritize static routes over dynamic routes for performance', () => {
143
- // Setup mixed routes where static could conflict with dynamic
144
- pikkuState(
145
- null,
146
- 'http',
147
- 'routes',
148
- new Map([
149
- [
150
- 'get',
151
- new Map([
152
- ['/api/users', mockRoute('/api/users')], // static
153
- ['/api/:resource', mockRoute('/api/:resource')], // dynamic that could match above
154
- ]),
155
- ],
156
- ])
157
- )
158
- pikkuState(null, 'http', 'middleware', new Map())
159
- pikkuState(null, 'channel', 'channels', new Map())
160
-
161
- router.initialize()
162
-
163
- // Static route should be found first (O(1) lookup)
164
- const result = router.match('get', '/api/users')
165
- assert.ok(result, 'Route should match')
166
- assert.strictEqual(result.route, '/api/users') // Should match static, not dynamic
167
- assert.deepStrictEqual(result.params, {})
168
- })
169
- })
170
-
171
- describe('Path Normalization', () => {
172
- test('should normalize paths without leading slash', () => {
173
- pikkuState(
174
- null,
175
- 'http',
176
- 'routes',
177
- new Map([
178
- [
179
- 'get',
180
- new Map([
181
- ['test', mockRoute('test')], // route without leading slash
182
- ['api/health', mockRoute('api/health')],
183
- ]),
184
- ],
185
- ])
186
- )
187
- pikkuState(null, 'http', 'middleware', new Map())
188
- pikkuState(null, 'channel', 'channels', new Map())
189
-
190
- router.initialize()
191
-
192
- // Should match with or without leading slash in request
193
- const result1 = router.match('get', '/test')
194
- assert.ok(result1, 'Should match /test')
195
- assert.strictEqual(result1.route, 'test')
196
-
197
- const result2 = router.match('get', 'test')
198
- assert.ok(result2, 'Should match test')
199
- assert.strictEqual(result2.route, 'test')
200
-
201
- const result3 = router.match('get', '/api/health')
202
- assert.ok(result3, 'Should match /api/health')
203
- assert.strictEqual(result3.route, 'api/health')
204
- })
205
- })
206
-
207
- describe('Channel Routes Integration', () => {
208
- test('should handle channel routes as GET routes', () => {
209
- pikkuState(null, 'http', 'routes', new Map())
210
- pikkuState(null, 'http', 'middleware', new Map())
211
- pikkuState(
212
- null,
213
- 'channel',
214
- 'channels',
215
- new Map([
216
- ['websocket-test', { name: 'websocket-test', route: '/ws/test' }],
217
- ['chat', { name: 'chat', route: '/chat/:room' }],
218
- ])
219
- )
220
-
221
- router.initialize()
222
-
223
- // Channel routes should be accessible via GET method
224
- const wsResult = router.match('get', '/ws/test')
225
- assert.ok(wsResult, 'Static channel route should match')
226
- assert.strictEqual(wsResult.route, '/ws/test')
227
- assert.deepStrictEqual(wsResult.params, {})
228
-
229
- const chatResult = router.match('get', '/chat/general')
230
- assert.ok(chatResult, 'Dynamic channel route should match')
231
- assert.strictEqual(chatResult.route, '/chat/:room')
232
- assert.strictEqual(chatResult.params.room, 'general')
233
- })
234
- })
235
-
236
- describe('Middleware Integration', () => {
237
- test('should match route without returning middleware', () => {
238
- const globalMiddleware = [async () => {}]
239
- const routeMiddleware = [async () => {}]
240
-
241
- pikkuState(
242
- null,
243
- 'http',
244
- 'routes',
245
- new Map([['get', new Map([['/api/test', mockRoute('/api/test')]])]])
246
- )
247
- pikkuState(
248
- null,
249
- 'http',
250
- 'middleware',
251
- new Map([
252
- ['*', globalMiddleware],
253
- ['/api/test', routeMiddleware],
254
- ])
255
- )
256
- pikkuState(null, 'channel', 'channels', new Map())
257
-
258
- router.initialize()
259
-
260
- const result = router.match('get', '/api/test')
261
- assert.ok(result, 'Route should match')
262
- // Router only returns route and params, middleware is handled separately
263
- assert.strictEqual(result.route, '/api/test')
264
- assert.deepStrictEqual(result.params, {})
265
- })
266
- })
267
-
268
- describe('No Match Scenarios', () => {
269
- test('should return null for non-existent routes', () => {
270
- pikkuState(
271
- null,
272
- 'http',
273
- 'routes',
274
- new Map([['get', new Map([['/existing', mockRoute('/existing')]])]])
275
- )
276
- pikkuState(null, 'http', 'middleware', new Map())
277
- pikkuState(null, 'channel', 'channels', new Map())
278
-
279
- router.initialize()
280
-
281
- const result = router.match('get', '/non-existent')
282
- assert.strictEqual(result, null)
283
- })
284
-
285
- test('should return null for unsupported HTTP methods', () => {
286
- pikkuState(
287
- null,
288
- 'http',
289
- 'routes',
290
- new Map([['get', new Map([['/test', mockRoute('/test')]])]])
291
- )
292
- pikkuState(null, 'http', 'middleware', new Map())
293
- pikkuState(null, 'channel', 'channels', new Map())
294
-
295
- router.initialize()
296
-
297
- const result = router.match('post', '/test')
298
- assert.strictEqual(result, null)
299
- })
300
- })
301
-
302
- describe('Lazy Initialization', () => {
303
- test('should initialize automatically on first match call', () => {
304
- pikkuState(
305
- null,
306
- 'http',
307
- 'routes',
308
- new Map([['get', new Map([['/test', mockRoute('/test')]])]])
309
- )
310
- pikkuState(null, 'http', 'middleware', new Map())
311
- pikkuState(null, 'channel', 'channels', new Map())
312
-
313
- // Don't call initialize manually
314
- const result = router.match('get', '/test')
315
- assert.ok(result, 'Should auto-initialize and match')
316
- assert.strictEqual(result.route, '/test')
317
- })
318
- })
319
- })
@@ -1,126 +0,0 @@
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'
5
- import { pikkuState } from '../../../pikku-state.js'
6
-
7
- interface CompiledRoute {
8
- matcher: MatchFunction<Partial<Record<string, string | string[]>>>
9
- route: string
10
- }
11
-
12
- interface StaticRoute {
13
- route: string
14
- }
15
-
16
- export class PathToRegexRouter implements Router {
17
- private compiledRoutes: Map<HTTPMethod, Map<string, CompiledRoute>> =
18
- new Map()
19
- private staticRoutes: Map<HTTPMethod, Map<string, StaticRoute>> = new Map()
20
- private isInitialized = false
21
-
22
- public reset() {
23
- this.compiledRoutes = new Map()
24
- this.staticRoutes = new Map()
25
- this.isInitialized = false
26
- }
27
-
28
- public initialize() {
29
- const routes = pikkuState(null, 'http', 'routes')
30
- const channelRoutes = pikkuState(null, 'channel', 'channels')
31
-
32
- // Helper function to compile routes for a given method
33
- const compileRoutesForMethod = (
34
- method: HTTPMethod,
35
- routeEntries: Iterable<[string, any]>
36
- ) => {
37
- const methodCompiledRoutes =
38
- this.compiledRoutes.get(method) || new Map<string, CompiledRoute>()
39
- const methodStaticRoutes =
40
- this.staticRoutes.get(method) || new Map<string, StaticRoute>()
41
-
42
- for (const [routePath] of routeEntries) {
43
- // Normalize route path - ensure it starts with /
44
- const normalizedRoutePath = routePath.startsWith('/')
45
- ? routePath
46
- : `/${routePath}`
47
-
48
- // Check if route is static (no parameters or wildcards)
49
- const isStaticRoute = !/\*|:/.test(normalizedRoutePath)
50
-
51
- if (isStaticRoute) {
52
- // Store static routes for O(1) lookup
53
- methodStaticRoutes.set(normalizedRoutePath, {
54
- route: routePath, // Keep the original route path for lookup in pikkuState
55
- })
56
- } else {
57
- // Compile dynamic routes with path-to-regexp
58
- const matcher = match(normalizedRoutePath, {
59
- decode: decodeURIComponent,
60
- })
61
-
62
- methodCompiledRoutes.set(normalizedRoutePath, {
63
- matcher,
64
- route: routePath, // Keep the original route path for lookup in pikkuState
65
- })
66
- }
67
- }
68
-
69
- this.compiledRoutes.set(method, methodCompiledRoutes)
70
- this.staticRoutes.set(method, methodStaticRoutes)
71
- }
72
-
73
- // Precompile all HTTP route matchers
74
- for (const [method, routeMap] of routes.entries()) {
75
- compileRoutesForMethod(method, routeMap.entries())
76
- }
77
-
78
- // Precompile all channel route matchers (treating them as GET routes for WebSocket upgrades)
79
- const channelRoutesArray: Array<[string, any]> = Array.from(
80
- channelRoutes.entries()
81
- ).map(([, channel]) => [channel.route, channel])
82
- compileRoutesForMethod('get', channelRoutesArray)
83
-
84
- this.isInitialized = true
85
- }
86
-
87
- match(method: HTTPMethod, path: string): MatchResult {
88
- if (!this.isInitialized) {
89
- this.initialize()
90
- }
91
-
92
- // Normalize path - ensure it starts with /
93
- const normalizedPath = path.startsWith('/') ? path : `/${path}`
94
-
95
- // First, try static routes for O(1) lookup
96
- const methodStaticRoutes = this.staticRoutes.get(method)
97
- if (methodStaticRoutes) {
98
- const staticRoute = methodStaticRoutes.get(normalizedPath)
99
- if (staticRoute) {
100
- return {
101
- route: staticRoute.route,
102
- params: {},
103
- }
104
- }
105
- }
106
-
107
- // If no static route matched, try dynamic routes
108
- const methodRoutes = this.compiledRoutes.get(method)
109
- if (!methodRoutes) {
110
- return null
111
- }
112
-
113
- // Try each compiled route for this method
114
- for (const [, compiledRoute] of methodRoutes.entries()) {
115
- const result = compiledRoute.matcher(normalizedPath)
116
- if (result) {
117
- return {
118
- route: compiledRoute.route,
119
- params: result.params,
120
- }
121
- }
122
- }
123
-
124
- return null
125
- }
126
- }
@@ -1,27 +0,0 @@
1
- export { MCPEndpointRegistry } from './mcp-endpoint-registry.js'
2
- export {
3
- MCPError,
4
- wireMCPResource,
5
- wireMCPPrompt,
6
- runMCPResource,
7
- runMCPTool,
8
- runMCPPrompt,
9
- } from './mcp-runner.js'
10
- export {
11
- getMCPResourcesMeta,
12
- getMCPToolsMeta,
13
- getMCPPromptsMeta,
14
- } from './mcp-runner.js'
15
- export type {
16
- AssertMCPResourceURIParams,
17
- CoreMCPPrompt,
18
- CoreMCPResource,
19
- CoreMCPTool,
20
- MCPPromptResponse,
21
- MCPResourceMeta,
22
- MCPResourceResponse,
23
- MCPToolMeta,
24
- MCPToolResponse,
25
- MCPPromptMeta,
26
- PikkuMCP,
27
- } from './mcp.types.js'