legonode 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/README.md +107 -0
  2. package/dist/cli/cli.d.ts +3 -0
  3. package/dist/cli/cli.d.ts.map +1 -0
  4. package/dist/cli/cli.js +44 -0
  5. package/dist/cli/cli.js.map +1 -0
  6. package/dist/cli/commands/build.d.ts +8 -0
  7. package/dist/cli/commands/build.d.ts.map +1 -0
  8. package/dist/cli/commands/build.js +101 -0
  9. package/dist/cli/commands/build.js.map +1 -0
  10. package/dist/cli/commands/dev.d.ts +13 -0
  11. package/dist/cli/commands/dev.d.ts.map +1 -0
  12. package/dist/cli/commands/dev.js +285 -0
  13. package/dist/cli/commands/dev.js.map +1 -0
  14. package/dist/cli/commands/start.d.ts +10 -0
  15. package/dist/cli/commands/start.d.ts.map +1 -0
  16. package/dist/cli/commands/start.js +108 -0
  17. package/dist/cli/commands/start.js.map +1 -0
  18. package/dist/cli/pluginHooks.d.ts +5 -0
  19. package/dist/cli/pluginHooks.d.ts.map +1 -0
  20. package/dist/cli/pluginHooks.js +11 -0
  21. package/dist/cli/pluginHooks.js.map +1 -0
  22. package/dist/src/body/parseBody.d.ts +11 -0
  23. package/dist/src/body/parseBody.d.ts.map +1 -0
  24. package/dist/src/body/parseBody.js +113 -0
  25. package/dist/src/body/parseBody.js.map +1 -0
  26. package/dist/src/config/loadConfig.d.ts +71 -0
  27. package/dist/src/config/loadConfig.d.ts.map +1 -0
  28. package/dist/src/config/loadConfig.js +69 -0
  29. package/dist/src/config/loadConfig.js.map +1 -0
  30. package/dist/src/core/context.d.ts +139 -0
  31. package/dist/src/core/context.d.ts.map +1 -0
  32. package/dist/src/core/context.js +293 -0
  33. package/dist/src/core/context.js.map +1 -0
  34. package/dist/src/core/lifecycle.d.ts +3 -0
  35. package/dist/src/core/lifecycle.d.ts.map +1 -0
  36. package/dist/src/core/lifecycle.js +14 -0
  37. package/dist/src/core/lifecycle.js.map +1 -0
  38. package/dist/src/core/runtime.d.ts +28 -0
  39. package/dist/src/core/runtime.d.ts.map +1 -0
  40. package/dist/src/core/runtime.js +104 -0
  41. package/dist/src/core/runtime.js.map +1 -0
  42. package/dist/src/cors/cors.d.ts +5 -0
  43. package/dist/src/cors/cors.d.ts.map +1 -0
  44. package/dist/src/cors/cors.js +75 -0
  45. package/dist/src/cors/cors.js.map +1 -0
  46. package/dist/src/events/eventBus.d.ts +19 -0
  47. package/dist/src/events/eventBus.d.ts.map +1 -0
  48. package/dist/src/events/eventBus.js +29 -0
  49. package/dist/src/events/eventBus.js.map +1 -0
  50. package/dist/src/events/eventExecutor.d.ts +5 -0
  51. package/dist/src/events/eventExecutor.d.ts.map +1 -0
  52. package/dist/src/events/eventExecutor.js +84 -0
  53. package/dist/src/events/eventExecutor.js.map +1 -0
  54. package/dist/src/index.d.ts +23 -0
  55. package/dist/src/index.d.ts.map +1 -0
  56. package/dist/src/index.js +13 -0
  57. package/dist/src/index.js.map +1 -0
  58. package/dist/src/json/fastStringify.d.ts +7 -0
  59. package/dist/src/json/fastStringify.d.ts.map +1 -0
  60. package/dist/src/json/fastStringify.js +73 -0
  61. package/dist/src/json/fastStringify.js.map +1 -0
  62. package/dist/src/loader/fileScanner.d.ts +18 -0
  63. package/dist/src/loader/fileScanner.d.ts.map +1 -0
  64. package/dist/src/loader/fileScanner.js +133 -0
  65. package/dist/src/loader/fileScanner.js.map +1 -0
  66. package/dist/src/loader/moduleCache.d.ts +3 -0
  67. package/dist/src/loader/moduleCache.d.ts.map +1 -0
  68. package/dist/src/loader/moduleCache.js +19 -0
  69. package/dist/src/loader/moduleCache.js.map +1 -0
  70. package/dist/src/loader/moduleLoader.d.ts +2 -0
  71. package/dist/src/loader/moduleLoader.d.ts.map +1 -0
  72. package/dist/src/loader/moduleLoader.js +4 -0
  73. package/dist/src/loader/moduleLoader.js.map +1 -0
  74. package/dist/src/logger/requestLogger.d.ts +20 -0
  75. package/dist/src/logger/requestLogger.d.ts.map +1 -0
  76. package/dist/src/logger/requestLogger.js +63 -0
  77. package/dist/src/logger/requestLogger.js.map +1 -0
  78. package/dist/src/middleware/middlewareLoader.d.ts +3 -0
  79. package/dist/src/middleware/middlewareLoader.d.ts.map +1 -0
  80. package/dist/src/middleware/middlewareLoader.js +28 -0
  81. package/dist/src/middleware/middlewareLoader.js.map +1 -0
  82. package/dist/src/middleware/middlewareResolver.d.ts +13 -0
  83. package/dist/src/middleware/middlewareResolver.d.ts.map +1 -0
  84. package/dist/src/middleware/middlewareResolver.js +72 -0
  85. package/dist/src/middleware/middlewareResolver.js.map +1 -0
  86. package/dist/src/middleware/middlewareRunner.d.ts +10 -0
  87. package/dist/src/middleware/middlewareRunner.d.ts.map +1 -0
  88. package/dist/src/middleware/middlewareRunner.js +27 -0
  89. package/dist/src/middleware/middlewareRunner.js.map +1 -0
  90. package/dist/src/middleware/middlewareTable.d.ts +6 -0
  91. package/dist/src/middleware/middlewareTable.d.ts.map +1 -0
  92. package/dist/src/middleware/middlewareTable.js +44 -0
  93. package/dist/src/middleware/middlewareTable.js.map +1 -0
  94. package/dist/src/pipeline/compose.d.ts +10 -0
  95. package/dist/src/pipeline/compose.d.ts.map +1 -0
  96. package/dist/src/pipeline/compose.js +35 -0
  97. package/dist/src/pipeline/compose.js.map +1 -0
  98. package/dist/src/pipeline/pipelineCache.d.ts +16 -0
  99. package/dist/src/pipeline/pipelineCache.d.ts.map +1 -0
  100. package/dist/src/pipeline/pipelineCache.js +73 -0
  101. package/dist/src/pipeline/pipelineCache.js.map +1 -0
  102. package/dist/src/plugin/pluginAPI.d.ts +63 -0
  103. package/dist/src/plugin/pluginAPI.d.ts.map +1 -0
  104. package/dist/src/plugin/pluginAPI.js +2 -0
  105. package/dist/src/plugin/pluginAPI.js.map +1 -0
  106. package/dist/src/plugin/pluginManager.d.ts +6 -0
  107. package/dist/src/plugin/pluginManager.d.ts.map +1 -0
  108. package/dist/src/plugin/pluginManager.js +16 -0
  109. package/dist/src/plugin/pluginManager.js.map +1 -0
  110. package/dist/src/router/matcher.d.ts +10 -0
  111. package/dist/src/router/matcher.d.ts.map +1 -0
  112. package/dist/src/router/matcher.js +69 -0
  113. package/dist/src/router/matcher.js.map +1 -0
  114. package/dist/src/router/radixTree.d.ts +24 -0
  115. package/dist/src/router/radixTree.d.ts.map +1 -0
  116. package/dist/src/router/radixTree.js +208 -0
  117. package/dist/src/router/radixTree.js.map +1 -0
  118. package/dist/src/router/routeLoader.d.ts +22 -0
  119. package/dist/src/router/routeLoader.d.ts.map +1 -0
  120. package/dist/src/router/routeLoader.js +94 -0
  121. package/dist/src/router/routeLoader.js.map +1 -0
  122. package/dist/src/router/routeTable.d.ts +25 -0
  123. package/dist/src/router/routeTable.d.ts.map +1 -0
  124. package/dist/src/router/routeTable.js +133 -0
  125. package/dist/src/router/routeTable.js.map +1 -0
  126. package/dist/src/router/router.d.ts +18 -0
  127. package/dist/src/router/router.d.ts.map +1 -0
  128. package/dist/src/router/router.js +158 -0
  129. package/dist/src/router/router.js.map +1 -0
  130. package/dist/src/schedules/parseSchedule.d.ts +15 -0
  131. package/dist/src/schedules/parseSchedule.d.ts.map +1 -0
  132. package/dist/src/schedules/parseSchedule.js +111 -0
  133. package/dist/src/schedules/parseSchedule.js.map +1 -0
  134. package/dist/src/schedules/runScheduler.d.ts +14 -0
  135. package/dist/src/schedules/runScheduler.d.ts.map +1 -0
  136. package/dist/src/schedules/runScheduler.js +58 -0
  137. package/dist/src/schedules/runScheduler.js.map +1 -0
  138. package/dist/src/schedules/scheduleLoader.d.ts +14 -0
  139. package/dist/src/schedules/scheduleLoader.d.ts.map +1 -0
  140. package/dist/src/schedules/scheduleLoader.js +122 -0
  141. package/dist/src/schedules/scheduleLoader.js.map +1 -0
  142. package/dist/src/schedules/types.d.ts +37 -0
  143. package/dist/src/schedules/types.d.ts.map +1 -0
  144. package/dist/src/schedules/types.js +2 -0
  145. package/dist/src/schedules/types.js.map +1 -0
  146. package/dist/src/server/errorHandler.d.ts +4 -0
  147. package/dist/src/server/errorHandler.d.ts.map +1 -0
  148. package/dist/src/server/errorHandler.js +10 -0
  149. package/dist/src/server/errorHandler.js.map +1 -0
  150. package/dist/src/server/requestHandler.d.ts +35 -0
  151. package/dist/src/server/requestHandler.d.ts.map +1 -0
  152. package/dist/src/server/requestHandler.js +439 -0
  153. package/dist/src/server/requestHandler.js.map +1 -0
  154. package/dist/src/server/server.d.ts +20 -0
  155. package/dist/src/server/server.d.ts.map +1 -0
  156. package/dist/src/server/server.js +74 -0
  157. package/dist/src/server/server.js.map +1 -0
  158. package/dist/src/tasks/scheduler.d.ts +10 -0
  159. package/dist/src/tasks/scheduler.d.ts.map +1 -0
  160. package/dist/src/tasks/scheduler.js +10 -0
  161. package/dist/src/tasks/scheduler.js.map +1 -0
  162. package/dist/src/tasks/taskRunner.d.ts +3 -0
  163. package/dist/src/tasks/taskRunner.d.ts.map +1 -0
  164. package/dist/src/tasks/taskRunner.js +4 -0
  165. package/dist/src/tasks/taskRunner.js.map +1 -0
  166. package/dist/src/trace/traceEngine.d.ts +45 -0
  167. package/dist/src/trace/traceEngine.d.ts.map +1 -0
  168. package/dist/src/trace/traceEngine.js +63 -0
  169. package/dist/src/trace/traceEngine.js.map +1 -0
  170. package/dist/src/trace/traceStore.d.ts +10 -0
  171. package/dist/src/trace/traceStore.d.ts.map +1 -0
  172. package/dist/src/trace/traceStore.js +10 -0
  173. package/dist/src/trace/traceStore.js.map +1 -0
  174. package/dist/src/utils/logger.d.ts +6 -0
  175. package/dist/src/utils/logger.d.ts.map +1 -0
  176. package/dist/src/utils/logger.js +21 -0
  177. package/dist/src/utils/logger.js.map +1 -0
  178. package/dist/src/utils/path.d.ts +2 -0
  179. package/dist/src/utils/path.d.ts.map +1 -0
  180. package/dist/src/utils/path.js +4 -0
  181. package/dist/src/utils/path.js.map +1 -0
  182. package/dist/src/validation/routeSchema.d.ts +77 -0
  183. package/dist/src/validation/routeSchema.d.ts.map +1 -0
  184. package/dist/src/validation/routeSchema.js +134 -0
  185. package/dist/src/validation/routeSchema.js.map +1 -0
  186. package/dist/src/validation/validateApp.d.ts +20 -0
  187. package/dist/src/validation/validateApp.d.ts.map +1 -0
  188. package/dist/src/validation/validateApp.js +23 -0
  189. package/dist/src/validation/validateApp.js.map +1 -0
  190. package/dist/src/validation/validateBody.d.ts +7 -0
  191. package/dist/src/validation/validateBody.d.ts.map +1 -0
  192. package/dist/src/validation/validateBody.js +8 -0
  193. package/dist/src/validation/validateBody.js.map +1 -0
  194. package/package.json +31 -0
@@ -0,0 +1,208 @@
1
+ function parsePatternSegments(pathname) {
2
+ const raw = pathname.replace(/^\/+/, "").split("/").filter(Boolean);
3
+ const out = [];
4
+ for (const seg of raw) {
5
+ if (seg.startsWith("(") && seg.endsWith(")"))
6
+ continue;
7
+ const catchAll = seg.match(/^\[\[\.\.\.(.+)\]\]$/);
8
+ if (catchAll) {
9
+ out.push({ type: "catchAll", param: catchAll[1] });
10
+ break;
11
+ }
12
+ const dynamic = seg.match(/^\[(.+)\]$/);
13
+ if (dynamic) {
14
+ out.push({ type: "dynamic", param: dynamic[1] });
15
+ continue;
16
+ }
17
+ out.push({ type: "static", value: seg });
18
+ }
19
+ return out;
20
+ }
21
+ function createNode() {
22
+ return {};
23
+ }
24
+ /** Insert a route into the tree. */
25
+ function insert(node, segments, payload) {
26
+ let n = node;
27
+ for (let i = 0; i < segments.length; i++) {
28
+ const seg = segments[i];
29
+ if (seg.type === "catchAll") {
30
+ n.catchAll = { param: seg.param, route: payload };
31
+ return;
32
+ }
33
+ if (seg.type === "static") {
34
+ if (!n.static)
35
+ n.static = new Map();
36
+ let next = n.static.get(seg.value);
37
+ if (!next) {
38
+ next = createNode();
39
+ n.static.set(seg.value, next);
40
+ }
41
+ n = next;
42
+ continue;
43
+ }
44
+ if (seg.type === "dynamic") {
45
+ if (!n.dynamic)
46
+ n.dynamic = { param: seg.param, node: createNode() };
47
+ n = n.dynamic.node;
48
+ continue;
49
+ }
50
+ }
51
+ n.route = payload;
52
+ }
53
+ /**
54
+ * Build a radix tree from scanned routes. Groups by pathname and merges method-specific files (get.ts, post.ts) with route.ts.
55
+ */
56
+ export function buildRadixTree(routes) {
57
+ const byPath = new Map();
58
+ for (const r of routes) {
59
+ const pathname = r.pathname;
60
+ let fileByMethod = byPath.get(pathname);
61
+ if (!fileByMethod) {
62
+ fileByMethod = {};
63
+ byPath.set(pathname, fileByMethod);
64
+ }
65
+ fileByMethod[r.method ?? ""] = r.filePath;
66
+ }
67
+ const root = createNode();
68
+ for (const [pathname, fileByMethod] of byPath) {
69
+ const segments = parsePatternSegments(pathname);
70
+ const payload = { routeId: pathname, fileByMethod };
71
+ insert(root, segments, payload);
72
+ }
73
+ function match(pathname) {
74
+ const urlSegments = pathname.replace(/^\/+/, "").split("/").filter(Boolean);
75
+ const params = {};
76
+ function walk(n, segIndex) {
77
+ if (segIndex === urlSegments.length) {
78
+ if (n.route) {
79
+ const result = { routeId: n.route.routeId, fileByMethod: n.route.fileByMethod, params: { ...params } };
80
+ return result;
81
+ }
82
+ return null;
83
+ }
84
+ const seg = urlSegments[segIndex] ?? "";
85
+ if (n.static) {
86
+ const next = n.static.get(seg);
87
+ if (next) {
88
+ const result = walk(next, segIndex + 1);
89
+ if (result)
90
+ return result;
91
+ }
92
+ }
93
+ if (n.dynamic) {
94
+ params[n.dynamic.param] = decodeURIComponent(seg);
95
+ const result = walk(n.dynamic.node, segIndex + 1);
96
+ if (result)
97
+ return result;
98
+ delete params[n.dynamic.param];
99
+ }
100
+ if (n.catchAll) {
101
+ params[n.catchAll.param] = urlSegments.slice(segIndex).map(decodeURIComponent);
102
+ const result = {
103
+ routeId: n.catchAll.route.routeId,
104
+ fileByMethod: n.catchAll.route.fileByMethod,
105
+ params: { ...params }
106
+ };
107
+ return result;
108
+ }
109
+ return null;
110
+ }
111
+ return walk(root, 0);
112
+ }
113
+ return { match };
114
+ }
115
+ function createNodePerMethod() {
116
+ return {};
117
+ }
118
+ function insertPerMethod(node, segments, payload) {
119
+ let n = node;
120
+ for (let i = 0; i < segments.length; i++) {
121
+ const seg = segments[i];
122
+ if (seg.type === "catchAll") {
123
+ n.catchAll = { param: seg.param, route: payload };
124
+ return;
125
+ }
126
+ if (seg.type === "static") {
127
+ if (!n.static)
128
+ n.static = new Map();
129
+ let next = n.static.get(seg.value);
130
+ if (!next) {
131
+ next = createNodePerMethod();
132
+ n.static.set(seg.value, next);
133
+ }
134
+ n = next;
135
+ continue;
136
+ }
137
+ if (seg.type === "dynamic") {
138
+ if (!n.dynamic)
139
+ n.dynamic = { param: seg.param, node: createNodePerMethod() };
140
+ n = n.dynamic.node;
141
+ continue;
142
+ }
143
+ }
144
+ n.route = payload;
145
+ }
146
+ /**
147
+ * Build a radix tree for a single HTTP method (find-my-way style).
148
+ * Lookup is O(path depth) with no method map; returns filePath directly.
149
+ */
150
+ export function buildRadixTreeForMethod(routes, method) {
151
+ const byPath = new Map();
152
+ for (const r of routes) {
153
+ const pathname = r.pathname;
154
+ let fileByMethod = byPath.get(pathname);
155
+ if (!fileByMethod) {
156
+ fileByMethod = {};
157
+ byPath.set(pathname, fileByMethod);
158
+ }
159
+ fileByMethod[r.method ?? ""] = r.filePath;
160
+ }
161
+ const root = createNodePerMethod();
162
+ for (const [pathname, fileByMethod] of byPath) {
163
+ const filePath = fileByMethod[method] ?? fileByMethod[""];
164
+ if (!filePath)
165
+ continue;
166
+ const segments = parsePatternSegments(pathname);
167
+ insertPerMethod(root, segments, { routeId: pathname, filePath });
168
+ }
169
+ function match(pathname) {
170
+ const urlSegments = pathname.replace(/^\/+/, "").split("/").filter(Boolean);
171
+ const params = {};
172
+ function walk(n, segIndex) {
173
+ if (segIndex === urlSegments.length) {
174
+ if (n.route)
175
+ return { routeId: n.route.routeId, filePath: n.route.filePath, params: { ...params } };
176
+ return null;
177
+ }
178
+ const seg = urlSegments[segIndex] ?? "";
179
+ if (n.static) {
180
+ const next = n.static.get(seg);
181
+ if (next) {
182
+ const result = walk(next, segIndex + 1);
183
+ if (result)
184
+ return result;
185
+ }
186
+ }
187
+ if (n.dynamic) {
188
+ params[n.dynamic.param] = decodeURIComponent(seg);
189
+ const result = walk(n.dynamic.node, segIndex + 1);
190
+ if (result)
191
+ return result;
192
+ delete params[n.dynamic.param];
193
+ }
194
+ if (n.catchAll) {
195
+ params[n.catchAll.param] = urlSegments.slice(segIndex).map(decodeURIComponent);
196
+ return {
197
+ routeId: n.catchAll.route.routeId,
198
+ filePath: n.catchAll.route.filePath,
199
+ params: { ...params }
200
+ };
201
+ }
202
+ return null;
203
+ }
204
+ return walk(root, 0);
205
+ }
206
+ return { match };
207
+ }
208
+ //# sourceMappingURL=radixTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radixTree.js","sourceRoot":"","sources":["../../../src/router/radixTree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { RouteSchema, ResponseSchemaMap } from "../validation/routeSchema.js";
2
+ export type RouteHandler = (ctx: unknown) => unknown | Promise<unknown>;
3
+ /**
4
+ * Load a route file (e.g. route.ts) and return which HTTP methods it actually exports
5
+ * (named export GET/POST/... or default that is a function).
6
+ */
7
+ export declare function getMethodsExportedByRouteFile(filePath: string): Promise<string[]>;
8
+ export type LoadedRoute = {
9
+ routeId: string;
10
+ handler: RouteHandler;
11
+ schema?: RouteSchema;
12
+ methodSchema?: RouteSchema;
13
+ responseSchema?: ResponseSchemaMap;
14
+ };
15
+ export declare function loadRoute(filePath: string, method: string, routeId: string): Promise<LoadedRoute | null>;
16
+ export declare function reloadRoutes({ currentDir, changedPath, fileExists, filename, }: {
17
+ currentDir: string;
18
+ changedPath: string;
19
+ fileExists: boolean;
20
+ filename: string;
21
+ }): Promise<void>;
22
+ //# sourceMappingURL=routeLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeLoader.d.ts","sourceRoot":"","sources":["../../../src/router/routeLoader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AAiBtC,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAExE;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,EAAE,CAAC,CAgBnB;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,cAAc,CAAC,EAAE,iBAAiB,CAAC;CACpC,CAAC;AAEF,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAyB7B;AAED,wBAAsB,YAAY,CAAC,EACjC,UAAU,EACV,WAAW,EACX,UAAU,EACV,QAAQ,GACT,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBhB"}
@@ -0,0 +1,94 @@
1
+ import { pathToFileURL } from "node:url";
2
+ import { invalidateModuleCache } from "../loader/moduleCache.js";
3
+ import { addRouteFileToTable, getRouteTable, removeRouteFileFromTable } from "./routeTable.js";
4
+ import { resolve } from "node:path";
5
+ import { clearPipelineForRoute } from "../pipeline/pipelineCache.js";
6
+ import { reloadRoute } from "./router.js";
7
+ import { appLogger } from "../utils/logger.js";
8
+ const HTTP_METHODS = [
9
+ "GET",
10
+ "POST",
11
+ "PUT",
12
+ "PATCH",
13
+ "DELETE",
14
+ "HEAD",
15
+ "OPTIONS",
16
+ ];
17
+ /**
18
+ * Load a route file (e.g. route.ts) and return which HTTP methods it actually exports
19
+ * (named export GET/POST/... or default that is a function).
20
+ */
21
+ export async function getMethodsExportedByRouteFile(filePath) {
22
+ try {
23
+ const url = pathToFileURL(filePath).href;
24
+ const bust = process.env.LEGONODE_RELOAD_TOKEN;
25
+ if (bust)
26
+ invalidateModuleCache(filePath);
27
+ const importUrl = bust ? `${url}?t=${bust}` : url;
28
+ const mod = await import(importUrl);
29
+ const methods = [];
30
+ for (const method of HTTP_METHODS) {
31
+ const fn = mod[method] ?? mod.default;
32
+ if (typeof fn === "function")
33
+ methods.push(method);
34
+ }
35
+ return methods;
36
+ }
37
+ catch {
38
+ return [];
39
+ }
40
+ }
41
+ export async function loadRoute(filePath, method, routeId) {
42
+ try {
43
+ const url = pathToFileURL(filePath).href;
44
+ const bust = process.env.LEGONODE_RELOAD_TOKEN;
45
+ if (bust)
46
+ invalidateModuleCache(filePath);
47
+ const importUrl = bust ? `${url}?t=${bust}` : url;
48
+ const mod = await import(importUrl);
49
+ const handlerFn = mod[method] ?? mod.default;
50
+ if (typeof handlerFn !== "function")
51
+ return null;
52
+ return {
53
+ routeId,
54
+ handler: handlerFn,
55
+ ...(mod.SCHEMA != null && { schema: mod.SCHEMA }),
56
+ ...(mod[`${method}_SCHEMA`] != null && {
57
+ methodSchema: mod[`${method}_SCHEMA`],
58
+ }),
59
+ ...((mod[`${method}_RESPONSE_SCHEMA`] ?? mod.RESPONSE_SCHEMA) != null && {
60
+ responseSchema: (mod[`${method}_RESPONSE_SCHEMA`] ??
61
+ mod.RESPONSE_SCHEMA),
62
+ }),
63
+ };
64
+ }
65
+ catch (err) {
66
+ appLogger.error("[legonode] loadRoute error:", err);
67
+ return null;
68
+ }
69
+ }
70
+ export async function reloadRoutes({ currentDir, changedPath, fileExists, filename, }) {
71
+ const table = getRouteTable(currentDir);
72
+ const routeEntries = table.filter((r) => resolve(r.filePath) === resolve(changedPath));
73
+ for (const r of routeEntries)
74
+ clearPipelineForRoute(currentDir, r.pathname, r.method ?? "");
75
+ const label = routeEntries
76
+ .map((r) => `${r.method || "*"} ${r.pathname}`)
77
+ .join(", ");
78
+ if (!fileExists && routeEntries.length > 0) {
79
+ removeRouteFileFromTable(currentDir, changedPath);
80
+ appLogger.info(`[legonode] delete route: ${label} (${filename})`);
81
+ return;
82
+ }
83
+ else if (routeEntries.length > 0) {
84
+ const token = String(Date.now());
85
+ process.env.LEGONODE_RELOAD_TOKEN = token;
86
+ await reloadRoute(currentDir, changedPath);
87
+ appLogger.info(`[legonode] reload: ${label} (${filename})`);
88
+ return;
89
+ }
90
+ addRouteFileToTable(currentDir, changedPath);
91
+ appLogger.info(`[legonode] add route: ${label} (${filename})`);
92
+ return;
93
+ }
94
+ //# sourceMappingURL=routeLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeLoader.js","sourceRoot":"","sources":["../../../src/router/routeLoader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { ScannedRoute } from "../loader/fileScanner.js";
2
+ import type { RadixTree, RadixTreePerMethod } from "./radixTree.js";
3
+ export type ValidateRouteConflictsOptions = {
4
+ /**
5
+ * When true (default), scan appDir recursively and validate all routes.
6
+ * When false, scan only appDir (that directory only, no nested subdirs).
7
+ */
8
+ isRecursive?: boolean;
9
+ };
10
+ /**
11
+ * For each path, collect which methods each file actually provides (by loading route.ts).
12
+ * If any (path, method) has more than one file, throw.
13
+ */
14
+ export declare function validateRouteConflictsAsync(appDir: string, options?: ValidateRouteConflictsOptions): Promise<void>;
15
+ export declare function getRouteTable(appDir: string): ScannedRoute[];
16
+ /** Radix tree for O(path depth) route lookup. Cached per appDir. */
17
+ export declare function getRadixTree(appDir: string): RadixTree;
18
+ /** Per-method radix tree (find-my-way style): one tree per HTTP method, direct filePath in match. Cached per appDir+method. */
19
+ export declare function getRadixTreeForMethod(appDir: string, method: string): RadixTreePerMethod;
20
+ /** Add or refresh routes for a single route file and update radix caches lazily. */
21
+ export declare function addRouteFileToTable(appDir: string, filePath: string): void;
22
+ /** Remove all routes coming from a specific route file and invalidate radix caches. */
23
+ export declare function removeRouteFileFromTable(appDir: string, filePath: string): void;
24
+ export declare function clearRouteTableCache(appDir?: string): void;
25
+ //# sourceMappingURL=routeTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeTable.d.ts","sourceRoot":"","sources":["../../../src/router/routeTable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAqBpE,MAAM,MAAM,6BAA6B,GAAG;IAC1C;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAO5D;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAOtD;AAED,+HAA+H;AAC/H,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,kBAAkB,CAQpB;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CA2B1E;AAED,uFAAuF;AACvF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAU/E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAY1D"}
@@ -0,0 +1,133 @@
1
+ import { scanAppFiles, scanRouteFilesInDir } from "../loader/fileScanner.js";
2
+ import { dirname, resolve } from "node:path";
3
+ import { buildRadixTree, buildRadixTreeForMethod } from "./radixTree.js";
4
+ import { getMethodsExportedByRouteFile } from "./routeLoader.js";
5
+ const cache = new Map();
6
+ const radixCache = new Map();
7
+ /** Per-method trees (find-my-way style): key = `${appDir}\0${method}` */
8
+ const radixPerMethodCache = new Map();
9
+ function getRoutesDir(appDir) {
10
+ return resolve(appDir, "router");
11
+ }
12
+ function normalizeRoutePath(pathname) {
13
+ const segments = pathname.replace(/^\/+/, "").split("/").filter(Boolean);
14
+ const withoutGroups = segments.filter((s) => !(s.startsWith("(") && s.endsWith(")")));
15
+ return "/" + withoutGroups.join("/");
16
+ }
17
+ /**
18
+ * For each path, collect which methods each file actually provides (by loading route.ts).
19
+ * If any (path, method) has more than one file, throw.
20
+ */
21
+ export async function validateRouteConflictsAsync(appDir, options = {}) {
22
+ const { isRecursive = true } = options;
23
+ const routesDir = getRoutesDir(appDir);
24
+ const routes = isRecursive
25
+ ? scanAppFiles(routesDir)
26
+ : scanRouteFilesInDir(routesDir, routesDir);
27
+ const byPath = new Map();
28
+ for (const route of routes) {
29
+ const key = normalizeRoutePath(route.pathname);
30
+ const list = byPath.get(key);
31
+ if (list)
32
+ list.push(route);
33
+ else
34
+ byPath.set(key, [route]);
35
+ }
36
+ for (const [normalizedPath, list] of byPath) {
37
+ /** method -> file paths that provide it */
38
+ const byMethod = new Map();
39
+ for (const r of list) {
40
+ const m = r.method ?? "";
41
+ const methods = m === "" ? await getMethodsExportedByRouteFile(r.filePath) : [m];
42
+ for (const method of methods) {
43
+ const files = byMethod.get(method) ?? [];
44
+ files.push(r.filePath);
45
+ byMethod.set(method, files);
46
+ }
47
+ }
48
+ for (const [method, files] of byMethod) {
49
+ if (files.length > 1) {
50
+ throw new Error(`Duplicate handler for method ${method}.\nKeep only one method per route:\n ${files.join("\n")}`);
51
+ }
52
+ }
53
+ }
54
+ }
55
+ export function getRouteTable(appDir) {
56
+ let table = cache.get(appDir);
57
+ if (!table) {
58
+ table = scanAppFiles(getRoutesDir(appDir));
59
+ cache.set(appDir, table);
60
+ }
61
+ return table;
62
+ }
63
+ /** Radix tree for O(path depth) route lookup. Cached per appDir. */
64
+ export function getRadixTree(appDir) {
65
+ let tree = radixCache.get(appDir);
66
+ if (!tree) {
67
+ tree = buildRadixTree(getRouteTable(appDir));
68
+ radixCache.set(appDir, tree);
69
+ }
70
+ return tree;
71
+ }
72
+ /** Per-method radix tree (find-my-way style): one tree per HTTP method, direct filePath in match. Cached per appDir+method. */
73
+ export function getRadixTreeForMethod(appDir, method) {
74
+ const key = `${appDir}\0${method}`;
75
+ let tree = radixPerMethodCache.get(key);
76
+ if (!tree) {
77
+ tree = buildRadixTreeForMethod(getRouteTable(appDir), method);
78
+ radixPerMethodCache.set(key, tree);
79
+ }
80
+ return tree;
81
+ }
82
+ /** Add or refresh routes for a single route file and update radix caches lazily. */
83
+ export function addRouteFileToTable(appDir, filePath) {
84
+ const table = getRouteTable(appDir);
85
+ const target = resolve(filePath);
86
+ const dir = dirname(target);
87
+ const routesDir = getRoutesDir(appDir);
88
+ const scanned = scanRouteFilesInDir(routesDir, dir).filter((r) => resolve(r.filePath) === target);
89
+ if (scanned.length === 0)
90
+ return;
91
+ // Merge new entries into the existing table, avoiding duplicates.
92
+ for (const r of scanned) {
93
+ const exists = table.some((e) => resolve(e.filePath) === resolve(r.filePath) &&
94
+ (e.method ?? "") === (r.method ?? "") &&
95
+ e.pathname === r.pathname);
96
+ if (!exists)
97
+ table.push(r);
98
+ }
99
+ cache.set(appDir, table);
100
+ // Invalidate radix trees for this appDir; they will rebuild on next access.
101
+ radixCache.delete(appDir);
102
+ for (const key of radixPerMethodCache.keys()) {
103
+ if (key.startsWith(appDir + "\0"))
104
+ radixPerMethodCache.delete(key);
105
+ }
106
+ }
107
+ /** Remove all routes coming from a specific route file and invalidate radix caches. */
108
+ export function removeRouteFileFromTable(appDir, filePath) {
109
+ const target = resolve(filePath);
110
+ const table = getRouteTable(appDir).filter((r) => resolve(r.filePath) !== target);
111
+ cache.set(appDir, table);
112
+ radixCache.delete(appDir);
113
+ for (const key of radixPerMethodCache.keys()) {
114
+ if (key.startsWith(appDir + "\0"))
115
+ radixPerMethodCache.delete(key);
116
+ }
117
+ }
118
+ export function clearRouteTableCache(appDir) {
119
+ if (appDir) {
120
+ cache.delete(appDir);
121
+ radixCache.delete(appDir);
122
+ for (const k of radixPerMethodCache.keys()) {
123
+ if (k.startsWith(appDir + "\0"))
124
+ radixPerMethodCache.delete(k);
125
+ }
126
+ }
127
+ else {
128
+ cache.clear();
129
+ radixCache.clear();
130
+ radixPerMethodCache.clear();
131
+ }
132
+ }
133
+ //# sourceMappingURL=routeTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeTable.js","sourceRoot":"","sources":["../../../src/router/routeTable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type LoadedRoute } from "./routeLoader.js";
2
+ /** Route + params without spreading LoadedRoute (avoids allocation). Catch-all params are string[]. */
3
+ export type ResolvedRoute = {
4
+ route: LoadedRoute;
5
+ params: Record<string, string | string[]>;
6
+ /** Group-aware pathname derived from file path for middleware resolution. */
7
+ middlewarePath: string;
8
+ };
9
+ /**
10
+ * Resolve route using per-method radix tree (find-my-way style): one tree per HTTP method,
11
+ * direct filePath from match, no method map lookup.
12
+ */
13
+ export declare function resolveRoute(method: string, pathname: string, appDir: string): ResolvedRoute | null | Promise<ResolvedRoute | null>;
14
+ /** Preload all routes and warm per-method radix trees so resolveRoute is sync. */
15
+ export declare function preloadRoutes(appDir: string): Promise<void>;
16
+ /** Reload handler cache for the given route file (dev hot reload). */
17
+ export declare function reloadRoute(appDir: string, filePath: string): Promise<void>;
18
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/router/router.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/D,uGAAuG;AACvG,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,6EAA6E;IAC7E,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAwBF;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,aAAa,GAAG,IAAI,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAqCtD;AAED,kFAAkF;AAClF,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CjE;AAID,sEAAsE;AACtE,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCjF"}