@flaid/devmap 0.6.0 → 0.8.0

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 (84) hide show
  1. package/README.md +2 -2
  2. package/dist/analyzers/detectors/adonisRouteDetector.d.ts +4 -0
  3. package/dist/analyzers/detectors/adonisRouteDetector.d.ts.map +1 -0
  4. package/dist/analyzers/detectors/adonisRouteDetector.js +242 -0
  5. package/dist/analyzers/detectors/adonisRouteDetector.js.map +1 -0
  6. package/dist/analyzers/detectors/angularRouteDetector.d.ts +4 -0
  7. package/dist/analyzers/detectors/angularRouteDetector.d.ts.map +1 -0
  8. package/dist/analyzers/detectors/angularRouteDetector.js +186 -0
  9. package/dist/analyzers/detectors/angularRouteDetector.js.map +1 -0
  10. package/dist/analyzers/detectors/astUtils.d.ts +31 -0
  11. package/dist/analyzers/detectors/astUtils.d.ts.map +1 -0
  12. package/dist/analyzers/detectors/astUtils.js +85 -0
  13. package/dist/analyzers/detectors/astUtils.js.map +1 -0
  14. package/dist/analyzers/detectors/clientRouteDetector.d.ts +4 -0
  15. package/dist/analyzers/detectors/clientRouteDetector.d.ts.map +1 -0
  16. package/dist/analyzers/detectors/clientRouteDetector.js +417 -0
  17. package/dist/analyzers/detectors/clientRouteDetector.js.map +1 -0
  18. package/dist/analyzers/detectors/elysiaRouteDetector.d.ts +4 -0
  19. package/dist/analyzers/detectors/elysiaRouteDetector.d.ts.map +1 -0
  20. package/dist/analyzers/detectors/elysiaRouteDetector.js +186 -0
  21. package/dist/analyzers/detectors/elysiaRouteDetector.js.map +1 -0
  22. package/dist/analyzers/detectors/expoRouteDetector.d.ts +4 -0
  23. package/dist/analyzers/detectors/expoRouteDetector.d.ts.map +1 -0
  24. package/dist/analyzers/detectors/expoRouteDetector.js +119 -0
  25. package/dist/analyzers/detectors/expoRouteDetector.js.map +1 -0
  26. package/dist/analyzers/detectors/frameworkDetector.d.ts +2 -2
  27. package/dist/analyzers/detectors/frameworkDetector.d.ts.map +1 -1
  28. package/dist/analyzers/detectors/frameworkDetector.js +86 -3
  29. package/dist/analyzers/detectors/frameworkDetector.js.map +1 -1
  30. package/dist/analyzers/detectors/honoRouteDetector.d.ts +4 -0
  31. package/dist/analyzers/detectors/honoRouteDetector.d.ts.map +1 -0
  32. package/dist/analyzers/detectors/honoRouteDetector.js +485 -0
  33. package/dist/analyzers/detectors/honoRouteDetector.js.map +1 -0
  34. package/dist/analyzers/detectors/koaRouteDetector.d.ts +4 -0
  35. package/dist/analyzers/detectors/koaRouteDetector.d.ts.map +1 -0
  36. package/dist/analyzers/detectors/koaRouteDetector.js +216 -0
  37. package/dist/analyzers/detectors/koaRouteDetector.js.map +1 -0
  38. package/dist/analyzers/detectors/moduleBindings.d.ts +52 -0
  39. package/dist/analyzers/detectors/moduleBindings.d.ts.map +1 -0
  40. package/dist/analyzers/detectors/moduleBindings.js +295 -0
  41. package/dist/analyzers/detectors/moduleBindings.js.map +1 -0
  42. package/dist/analyzers/detectors/qwikRouteDetector.d.ts +4 -0
  43. package/dist/analyzers/detectors/qwikRouteDetector.d.ts.map +1 -0
  44. package/dist/analyzers/detectors/qwikRouteDetector.js +53 -0
  45. package/dist/analyzers/detectors/qwikRouteDetector.js.map +1 -0
  46. package/dist/analyzers/detectors/reactRouterRouteDetector.d.ts +4 -0
  47. package/dist/analyzers/detectors/reactRouterRouteDetector.d.ts.map +1 -0
  48. package/dist/analyzers/detectors/reactRouterRouteDetector.js +142 -0
  49. package/dist/analyzers/detectors/reactRouterRouteDetector.js.map +1 -0
  50. package/dist/analyzers/detectors/remixRouteDetector.d.ts +42 -0
  51. package/dist/analyzers/detectors/remixRouteDetector.d.ts.map +1 -0
  52. package/dist/analyzers/detectors/remixRouteDetector.js +123 -0
  53. package/dist/analyzers/detectors/remixRouteDetector.js.map +1 -0
  54. package/dist/analyzers/detectors/routeDetector.d.ts.map +1 -1
  55. package/dist/analyzers/detectors/routeDetector.js +61 -66
  56. package/dist/analyzers/detectors/routeDetector.js.map +1 -1
  57. package/dist/analyzers/detectors/routeUtils.d.ts +43 -0
  58. package/dist/analyzers/detectors/routeUtils.d.ts.map +1 -0
  59. package/dist/analyzers/detectors/routeUtils.js +162 -0
  60. package/dist/analyzers/detectors/routeUtils.js.map +1 -0
  61. package/dist/analyzers/detectors/solidStartRouteDetector.d.ts +4 -0
  62. package/dist/analyzers/detectors/solidStartRouteDetector.d.ts.map +1 -0
  63. package/dist/analyzers/detectors/solidStartRouteDetector.js +59 -0
  64. package/dist/analyzers/detectors/solidStartRouteDetector.js.map +1 -0
  65. package/dist/analyzers/detectors/tanstackRouteDetector.d.ts +4 -0
  66. package/dist/analyzers/detectors/tanstackRouteDetector.d.ts.map +1 -0
  67. package/dist/analyzers/detectors/tanstackRouteDetector.js +100 -0
  68. package/dist/analyzers/detectors/tanstackRouteDetector.js.map +1 -0
  69. package/dist/analyzers/graph/aliasResolver.d.ts.map +1 -1
  70. package/dist/analyzers/graph/aliasResolver.js +3 -0
  71. package/dist/analyzers/graph/aliasResolver.js.map +1 -1
  72. package/dist/analyzers/graph/bundlerAliases.d.ts +12 -0
  73. package/dist/analyzers/graph/bundlerAliases.d.ts.map +1 -0
  74. package/dist/analyzers/graph/bundlerAliases.js +328 -0
  75. package/dist/analyzers/graph/bundlerAliases.js.map +1 -0
  76. package/dist/analyzers/graph/entryPoints.d.ts.map +1 -1
  77. package/dist/analyzers/graph/entryPoints.js +34 -3
  78. package/dist/analyzers/graph/entryPoints.js.map +1 -1
  79. package/dist/analyzers/pipeline/projectMap.d.ts.map +1 -1
  80. package/dist/analyzers/pipeline/projectMap.js +17 -6
  81. package/dist/analyzers/pipeline/projectMap.js.map +1 -1
  82. package/dist/analyzers/pipeline/projectMetadata.js +11 -0
  83. package/dist/analyzers/pipeline/projectMetadata.js.map +1 -1
  84. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clientRouteDetector.d.ts","sourceRoot":"","sources":["../../../src/analyzers/detectors/clientRouteDetector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAqCpD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAAE,EACpB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAC/B,SAAS,EAAE,CAiCb"}
@@ -0,0 +1,417 @@
1
+ import { ts } from "ts-morph";
2
+ import { isArchitectureSource } from "../graph/index.js";
3
+ import { importCallSpecifier, parseSource, propertyKeyName, stringValue, unwrapExpression, walk } from "./astUtils.js";
4
+ import { dropShadowedLayouts, joinRoutePaths, resolveImportedFile, sortRoutes } from "./routeUtils.js";
5
+ /**
6
+ * Routes of single-page apps, where the URL table is code instead of folders:
7
+ *
8
+ * React Router / Solid Router / wouter <Route path="teams/:id" element={<Team />}> trees,
9
+ * createBrowserRouter([{ path, element, children }])
10
+ * Vue Router createRouter({ routes: [{ path, component, children }] })
11
+ * TanStack Router (code-based) createRoute({ getParentRoute, path })
12
+ * svelte-spa-router { '/about': About }
13
+ *
14
+ * Nested paths are composed the way the routers compose them (a child path is
15
+ * relative unless it starts with `/`), a layout with no path adds nothing, and
16
+ * the listed file is the component when it can be found, else the file that
17
+ * declares the route.
18
+ */
19
+ const ROUTER_MODULES = /["'](?:react-router(?:-dom)?|@remix-run\/router|@solidjs\/router|wouter(?:-preact)?|vue-router|@tanstack\/(?:react|solid)-router|svelte-spa-router)["']/;
20
+ // A route table is often its own file that only imports the page components
21
+ // and the router's route type.
22
+ const ROUTE_TYPES = /\b(?:RouteRecordRaw|RouteObject|RouteConfig|createBrowserRouter|createHashRouter)\b/;
23
+ const LAZY_WRAPPERS = new Set(["lazy", "defineAsyncComponent", "loadable", "dynamic"]);
24
+ export function detectClientRoutes(files, graph) {
25
+ const localPaths = new Set(files.map((file) => file.path));
26
+ const entries = [];
27
+ for (const file of files) {
28
+ if (!/\.[cm]?[jt]sx?$/.test(file.path) || !isArchitectureSource(file.path))
29
+ continue;
30
+ if (!ROUTER_MODULES.test(file.content) && !ROUTE_TYPES.test(file.content))
31
+ continue;
32
+ const source = parseSource(file.path, file.content);
33
+ const model = readFileModel(source);
34
+ const found = [
35
+ ...readJsxRoutes(source, file.path, model),
36
+ ...readObjectRoutes(source, file.path),
37
+ ...readTanStackRoutes(source, file.path, model),
38
+ ...readSvelteSpaRoutes(source, file.path, file.content)
39
+ ];
40
+ for (const entry of found) {
41
+ entries.push({ ...entry, file: locateComponent(entry, model, localPaths, graph) });
42
+ }
43
+ }
44
+ const unique = new Map();
45
+ for (const entry of dropShadowedLayouts(entries)) {
46
+ unique.set(`${entry.path}\0${entry.file}`, entry);
47
+ }
48
+ return sortRoutes([...unique.values()].map((entry) => ({
49
+ path: entry.path,
50
+ file: entry.file,
51
+ kind: "page"
52
+ })));
53
+ }
54
+ function readFileModel(source) {
55
+ const model = { imports: new Map(), lazy: new Map(), variables: new Map() };
56
+ for (const statement of source.statements) {
57
+ if (ts.isImportDeclaration(statement)) {
58
+ const specifier = stringValue(statement.moduleSpecifier);
59
+ const clause = statement.importClause;
60
+ if (!specifier || !clause)
61
+ continue;
62
+ if (clause.name)
63
+ model.imports.set(clause.name.text, specifier);
64
+ if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {
65
+ for (const element of clause.namedBindings.elements)
66
+ model.imports.set(element.name.text, specifier);
67
+ }
68
+ }
69
+ }
70
+ walk(source, (node) => {
71
+ if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) {
72
+ if (!model.variables.has(node.name.text))
73
+ model.variables.set(node.name.text, node.initializer);
74
+ const lazy = lazySpecifier(node.initializer);
75
+ if (lazy)
76
+ model.lazy.set(node.name.text, lazy);
77
+ }
78
+ });
79
+ return model;
80
+ }
81
+ /** `lazy(() => import("./x"))`, `defineAsyncComponent(() => import("./x"))`. */
82
+ function lazySpecifier(expression) {
83
+ const node = unwrapExpression(expression);
84
+ if (!ts.isCallExpression(node))
85
+ return undefined;
86
+ const callee = ts.isIdentifier(node.expression)
87
+ ? node.expression.text
88
+ : ts.isPropertyAccessExpression(node.expression) ? node.expression.name.text : "";
89
+ if (!LAZY_WRAPPERS.has(callee) || !node.arguments[0])
90
+ return undefined;
91
+ return importCallSpecifier(node.arguments[0]);
92
+ }
93
+ function locateComponent(entry, model, localPaths, graph) {
94
+ const specifier = entry.component.specifier
95
+ ?? (entry.component.name
96
+ ? model.lazy.get(entry.component.name) ?? model.imports.get(entry.component.name)
97
+ : undefined);
98
+ const resolved = specifier
99
+ ? resolveImportedFile(entry.definedIn, specifier, localPaths, graph)
100
+ : undefined;
101
+ return resolved ?? entry.definedIn;
102
+ }
103
+ // -------------------------------------------------------------- path rules
104
+ function composePath(base, path, isIndex) {
105
+ if (isIndex || path === undefined || path === "")
106
+ return base;
107
+ if (path === "*")
108
+ return joinRoutePaths(base, "*");
109
+ return path.startsWith("/") ? joinRoutePaths(path) : joinRoutePaths(base, path);
110
+ }
111
+ // ---------------------------------------------------- React Router: JSX tree
112
+ const WRAPPER_TAG = /(?:Route|Guard|Protected|Auth|Private|Suspense|Provider|Boundary)/;
113
+ const ROUTE_TAG = /^(?:\w+\.)?\w*Route$/;
114
+ function readJsxRoutes(source, definedIn, model) {
115
+ const entries = [];
116
+ const tagName = (node) => (ts.isJsxElement(node) ? node.openingElement.tagName : node.tagName).getText();
117
+ const attributesOf = (node) => (ts.isJsxElement(node) ? node.openingElement.attributes : node.attributes).properties;
118
+ const visit = (node, base) => {
119
+ if ((ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node)) && ROUTE_TAG.test(tagName(node))) {
120
+ let path;
121
+ let isIndex = false;
122
+ let component = {};
123
+ for (const attribute of attributesOf(node)) {
124
+ if (!ts.isJsxAttribute(attribute) || !ts.isIdentifier(attribute.name))
125
+ continue;
126
+ const key = attribute.name.text;
127
+ const value = attribute.initializer;
128
+ if (key === "path")
129
+ path = jsxString(value);
130
+ else if (key === "index")
131
+ isIndex = !(value && ts.isJsxExpression(value) && value.expression?.kind === ts.SyntaxKind.FalseKeyword);
132
+ else if (key === "element" || key === "Component" || key === "component" || key === "render") {
133
+ component = componentFromJsxValue(value) ?? component;
134
+ }
135
+ else if (key === "lazy") {
136
+ const specifier = value && ts.isJsxExpression(value) && value.expression
137
+ ? importCallSpecifier(value.expression) : undefined;
138
+ if (specifier)
139
+ component = { specifier };
140
+ }
141
+ }
142
+ const children = ts.isJsxElement(node) ? node.children : [];
143
+ // `<Route path="/x"><Home /></Route>` (React Router 5, wouter): the child is the page.
144
+ if (!component.name && !component.specifier) {
145
+ const child = children.filter(isJsxNode).find((item) => !ROUTE_TAG.test(tagName(item)));
146
+ if (child)
147
+ component = { name: tagName(child) };
148
+ }
149
+ const full = composePath(base, path, isIndex);
150
+ const hasRouteChildren = children.filter(isJsxNode).some((item) => ROUTE_TAG.test(tagName(item)));
151
+ const hasOwnUrl = path !== undefined || isIndex;
152
+ if (hasOwnUrl && (component.name || component.specifier)) {
153
+ entries.push({ path: full, isIndex, isLayout: hasRouteChildren, component, definedIn });
154
+ }
155
+ ts.forEachChild(node, (child) => visit(child, full));
156
+ return;
157
+ }
158
+ ts.forEachChild(node, (child) => visit(child, base));
159
+ };
160
+ visit(source, "/");
161
+ return entries.filter((entry) => entry.path !== "" && !isOnlyWildcardFallback(entry));
162
+ }
163
+ /** A lone `*` fallback is a 404 page, not a screen of the app. */
164
+ function isOnlyWildcardFallback(entry) {
165
+ return entry.path === "/*" && !entry.isLayout && /^(?:NotFound|Error|NoMatch|Missing)/i.test(entry.component.name ?? "");
166
+ }
167
+ function isJsxNode(node) {
168
+ return ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node);
169
+ }
170
+ function jsxString(value) {
171
+ if (!value)
172
+ return undefined;
173
+ if (ts.isStringLiteral(value))
174
+ return value.text;
175
+ if (ts.isJsxExpression(value) && value.expression)
176
+ return stringValue(unwrapExpression(value.expression));
177
+ return undefined;
178
+ }
179
+ /** `element={<Home />}`, `Component={Home}`, `component={Home}`. */
180
+ function componentFromJsxValue(value) {
181
+ if (!value || !ts.isJsxExpression(value) || !value.expression)
182
+ return undefined;
183
+ return componentFromExpression(value.expression);
184
+ }
185
+ function componentFromExpression(expression) {
186
+ const node = unwrapExpression(expression);
187
+ if (ts.isIdentifier(node))
188
+ return { name: node.text };
189
+ if (ts.isJsxSelfClosingElement(node))
190
+ return { name: node.tagName.getText() };
191
+ if (ts.isJsxElement(node)) {
192
+ const tag = node.openingElement.tagName.getText();
193
+ // <PrivateRoute><Dashboard /></PrivateRoute>, <Suspense><Home /></Suspense>: the page is inside.
194
+ if (WRAPPER_TAG.test(tag)) {
195
+ const inner = node.children.find(isJsxNode);
196
+ if (inner)
197
+ return componentFromExpression(inner);
198
+ }
199
+ return { name: tag };
200
+ }
201
+ if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
202
+ const specifier = importCallSpecifier(node);
203
+ if (specifier)
204
+ return { specifier };
205
+ // `() => <Home />`
206
+ let rendered;
207
+ walk(node, (child) => {
208
+ if (!rendered && (ts.isJsxSelfClosingElement(child) || ts.isJsxElement(child))) {
209
+ rendered = { name: (ts.isJsxElement(child) ? child.openingElement.tagName : child.tagName).getText() };
210
+ }
211
+ });
212
+ return rendered;
213
+ }
214
+ if (ts.isCallExpression(node)) {
215
+ // lazy(() => import("./x")) written inline, markRaw(Home), shallowRef(Home)
216
+ const specifier = importCallSpecifier(node);
217
+ if (specifier)
218
+ return { specifier };
219
+ const argument = node.arguments[0] ? unwrapExpression(node.arguments[0]) : undefined;
220
+ if (argument && ts.isIdentifier(argument))
221
+ return { name: argument.text };
222
+ }
223
+ return undefined;
224
+ }
225
+ const COMPONENT_KEYS = new Set(["element", "Component", "component", "components", "lazy", "view"]);
226
+ const ROUTE_HINT_KEYS = new Set([...COMPONENT_KEYS, "children", "loader", "redirect", "redirectTo", "name", "meta", "index"]);
227
+ function readRouteObject(node) {
228
+ let path;
229
+ let isIndex = false;
230
+ let component = {};
231
+ let children;
232
+ let redirect = false;
233
+ let hint = false;
234
+ for (const property of node.properties) {
235
+ if (!ts.isPropertyAssignment(property) && !ts.isShorthandPropertyAssignment(property))
236
+ continue;
237
+ const key = propertyKeyName(property.name);
238
+ if (!key)
239
+ continue;
240
+ if (ROUTE_HINT_KEYS.has(key))
241
+ hint = true;
242
+ if (ts.isShorthandPropertyAssignment(property)) {
243
+ if (COMPONENT_KEYS.has(key))
244
+ component = { name: key };
245
+ continue;
246
+ }
247
+ const value = unwrapExpression(property.initializer);
248
+ if (key === "path")
249
+ path = stringValue(value);
250
+ else if (key === "index")
251
+ isIndex = value.kind === ts.SyntaxKind.TrueKeyword;
252
+ else if (key === "children" && ts.isArrayLiteralExpression(value))
253
+ children = value;
254
+ else if (key === "redirect" || key === "redirectTo")
255
+ redirect = true;
256
+ else if (key === "lazy") {
257
+ const specifier = importCallSpecifier(value);
258
+ if (specifier)
259
+ component = { specifier };
260
+ }
261
+ else if (key === "components" && ts.isObjectLiteralExpression(value)) {
262
+ // Vue named views: { default: Home, sidebar: Nav }
263
+ const defaultView = value.properties.find((item) => ts.isPropertyAssignment(item) && propertyKeyName(item.name) === "default");
264
+ component = (defaultView && componentFromExpression(defaultView.initializer)) ?? component;
265
+ }
266
+ else if (COMPONENT_KEYS.has(key)) {
267
+ component = componentFromExpression(value) ?? component;
268
+ }
269
+ }
270
+ if (!hint || (path === undefined && !isIndex && !children))
271
+ return undefined;
272
+ // Vue Router: a leaf with an empty path is its parent's index page. With
273
+ // children it is a pathless layout, so it stays a layout.
274
+ if (path === "" && !children)
275
+ isIndex = true;
276
+ return { path, isIndex, component, children, redirectOnly: redirect && !component.name && !component.specifier };
277
+ }
278
+ function readObjectRoutes(source, definedIn) {
279
+ const entries = [];
280
+ const handled = new Set();
281
+ const process = (array, base) => {
282
+ handled.add(array);
283
+ for (const element of array.elements) {
284
+ const item = unwrapExpression(element);
285
+ if (!ts.isObjectLiteralExpression(item))
286
+ continue;
287
+ const route = readRouteObject(item);
288
+ if (!route)
289
+ continue;
290
+ const full = composePath(base, route.path, route.isIndex);
291
+ const hasOwnUrl = route.path !== undefined || route.isIndex;
292
+ const renders = route.component.name !== undefined || route.component.specifier !== undefined;
293
+ if (hasOwnUrl && renders && !route.redirectOnly) {
294
+ entries.push({ path: full, isIndex: route.isIndex, isLayout: Boolean(route.children?.elements.length), component: route.component, definedIn });
295
+ }
296
+ if (route.children)
297
+ process(route.children, full);
298
+ }
299
+ };
300
+ walk(source, (node) => {
301
+ if (!ts.isArrayLiteralExpression(node) || handled.has(node))
302
+ return;
303
+ const looksLikeRoutes = node.elements.some((element) => {
304
+ const item = unwrapExpression(element);
305
+ return ts.isObjectLiteralExpression(item) && readRouteObject(item) !== undefined;
306
+ });
307
+ // An array that is the `children` of a route object is reached through its parent.
308
+ if (looksLikeRoutes && !isChildrenOfRoute(node))
309
+ process(node, "/");
310
+ });
311
+ return entries;
312
+ }
313
+ function isChildrenOfRoute(array) {
314
+ const parent = array.parent;
315
+ if (!ts.isPropertyAssignment(parent) || propertyKeyName(parent.name) !== "children")
316
+ return false;
317
+ const owner = parent.parent;
318
+ return ts.isObjectLiteralExpression(owner)
319
+ && owner.parent !== undefined
320
+ && ts.isArrayLiteralExpression(owner.parent);
321
+ }
322
+ function readTanStackRoutes(source, definedIn, model) {
323
+ const routes = new Map();
324
+ for (const [variable, initializer] of model.variables) {
325
+ const call = unwrapExpression(initializer);
326
+ if (!ts.isCallExpression(call))
327
+ continue;
328
+ const callee = call.expression.getText();
329
+ const isRoot = /\bcreateRootRoute(?:WithContext)?\b/.test(callee);
330
+ if (!isRoot && !/(^|\.)create(?:Lazy)?Route$/.test(callee))
331
+ continue;
332
+ const options = findOptionsObject(call);
333
+ if (!options) {
334
+ if (isRoot)
335
+ routes.set(variable, { variable, component: {}, isIndex: false });
336
+ continue;
337
+ }
338
+ let path;
339
+ let parent;
340
+ let component = {};
341
+ for (const property of options.properties) {
342
+ if (!ts.isPropertyAssignment(property))
343
+ continue;
344
+ const key = propertyKeyName(property.name);
345
+ const value = unwrapExpression(property.initializer);
346
+ if (key === "path")
347
+ path = stringValue(value);
348
+ else if (key === "component")
349
+ component = componentFromExpression(value) ?? component;
350
+ else if (key === "getParentRoute")
351
+ parent = parentOf(value);
352
+ }
353
+ routes.set(variable, { variable, path, parent: isRoot ? undefined : parent, component, isIndex: path === "/" });
354
+ }
355
+ const entries = [];
356
+ const fullPath = (route, seen = new Set()) => {
357
+ if (seen.has(route.variable))
358
+ return "/";
359
+ seen.add(route.variable);
360
+ const parent = route.parent ? routes.get(route.parent) : undefined;
361
+ const base = parent ? fullPath(parent, seen) : "/";
362
+ return route.path === undefined ? base : joinRoutePaths(base, route.path);
363
+ };
364
+ const parents = new Set([...routes.values()].map((route) => route.parent).filter(Boolean));
365
+ for (const route of routes.values()) {
366
+ // The root route and pathless layouts have no URL of their own.
367
+ if (route.path === undefined || !route.parent)
368
+ continue;
369
+ entries.push({
370
+ path: fullPath(route),
371
+ isIndex: route.isIndex,
372
+ isLayout: parents.has(route.variable),
373
+ component: route.component,
374
+ definedIn
375
+ });
376
+ }
377
+ return entries;
378
+ }
379
+ /** The `{ ... }` of `createRoute({ ... })`, also behind `createRootRouteWithContext<T>()({ ... })`. */
380
+ function findOptionsObject(call) {
381
+ const first = call.arguments[0] ? unwrapExpression(call.arguments[0]) : undefined;
382
+ return first && ts.isObjectLiteralExpression(first) ? first : undefined;
383
+ }
384
+ /** `() => rootRoute` */
385
+ function parentOf(value) {
386
+ if (ts.isArrowFunction(value) || ts.isFunctionExpression(value)) {
387
+ const body = ts.isBlock(value.body)
388
+ ? value.body.statements.find(ts.isReturnStatement)?.expression
389
+ : value.body;
390
+ const target = body ? unwrapExpression(body) : undefined;
391
+ if (target && ts.isIdentifier(target))
392
+ return target.text;
393
+ }
394
+ return undefined;
395
+ }
396
+ // ------------------------------------------------------- svelte-spa-router
397
+ function readSvelteSpaRoutes(source, definedIn, content) {
398
+ if (!/["']svelte-spa-router["']/.test(content))
399
+ return [];
400
+ const entries = [];
401
+ walk(source, (node) => {
402
+ if (!ts.isObjectLiteralExpression(node))
403
+ return;
404
+ const pairs = node.properties.filter((property) => ts.isPropertyAssignment(property)
405
+ && (propertyKeyName(property.name) ?? "").startsWith("/")
406
+ && ts.isIdentifier(unwrapExpression(property.initializer)));
407
+ if (pairs.length === 0 || pairs.length !== node.properties.length)
408
+ return;
409
+ for (const pair of pairs) {
410
+ const path = propertyKeyName(pair.name);
411
+ const name = unwrapExpression(pair.initializer).text;
412
+ entries.push({ path: path === "" ? "/" : path, isIndex: false, isLayout: false, component: { name }, definedIn });
413
+ }
414
+ });
415
+ return entries;
416
+ }
417
+ //# sourceMappingURL=clientRouteDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clientRouteDetector.js","sourceRoot":"","sources":["../../../src/analyzers/detectors/clientRouteDetector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ScannedFile } from "../analysis/index.js";
2
+ import type { RouteInfo } from "./routeDetector.js";
3
+ export declare function detectElysiaRoutes(files: ScannedFile[], graph?: Record<string, string[]>): RouteInfo[];
4
+ //# sourceMappingURL=elysiaRouteDetector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elysiaRouteDetector.d.ts","sourceRoot":"","sources":["../../../src/analyzers/detectors/elysiaRouteDetector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA4BpD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,EAAE,CA4ItG"}
@@ -0,0 +1,186 @@
1
+ import { ts } from "ts-morph";
2
+ import { isArchitectureSource } from "../graph/index.js";
3
+ import { isChainTop, unwindChain, unwrapExpression, walk } from "./astUtils.js";
4
+ import { createModuleIndex, isShadowed, walkOutsideShadow } from "./moduleBindings.js";
5
+ import { joinRoutePaths, sortRoutes } from "./routeUtils.js";
6
+ /**
7
+ * Elysia apps are chains of calls on an instance:
8
+ *
9
+ * new Elysia({ prefix: "/users" }).get("/:id", h).post("/", h)
10
+ * app.group("/v1", (app) => app.get("/ping", h))
11
+ * app.guard({ beforeHandle }, (app) => app.get("/me", h))
12
+ * app.use(users) // a plugin instance, mounted at its own prefix
13
+ *
14
+ * Each `new Elysia()` is one instance. Calls on it are collected wherever they
15
+ * are written (the initializer chain, later `users.get(...)` statements, other
16
+ * files that import it), and an instance that something mounts with `.use()`
17
+ * is walked from that mount, so every endpoint is listed once under its full URL.
18
+ */
19
+ const ELYSIA_MODULE = /["']elysia["']/;
20
+ const METHODS = new Map([
21
+ ["get", "GET"], ["post", "POST"], ["put", "PUT"], ["patch", "PATCH"],
22
+ ["delete", "DELETE"], ["options", "OPTIONS"], ["head", "HEAD"],
23
+ ["all", undefined], ["ws", "WS"]
24
+ ]);
25
+ export function detectElysiaRoutes(files, graph) {
26
+ const gated = files.filter((file) => /\.[cm]?[jt]sx?$/.test(file.path) && isArchitectureSource(file.path) && ELYSIA_MODULE.test(file.content));
27
+ if (gated.length === 0)
28
+ return [];
29
+ const index = createModuleIndex(files, graph);
30
+ const instances = new Map();
31
+ const registrations = new Map();
32
+ const mounted = new Set();
33
+ const routes = new Map();
34
+ const classNames = (module) => new Set([...module.imports].filter(([, value]) => value.specifier === "elysia" && value.imported === "Elysia").map(([name]) => name));
35
+ const instanceOf = (expression, module, depth = 0) => {
36
+ if (depth > 6)
37
+ return undefined;
38
+ const node = unwrapExpression(expression);
39
+ if (ts.isNewExpression(node)) {
40
+ if (!ts.isIdentifier(node.expression) || !classNames(module).has(node.expression.text))
41
+ return undefined;
42
+ const key = `${module.path}:${node.pos}`;
43
+ let instance = instances.get(key);
44
+ if (!instance) {
45
+ instance = { key, module, prefix: prefixOf(node, module, index) };
46
+ instances.set(key, instance);
47
+ }
48
+ return instance;
49
+ }
50
+ if (ts.isCallExpression(node)) {
51
+ const { root } = unwindChain(node);
52
+ return root === node ? undefined : instanceOf(root, module, depth + 1);
53
+ }
54
+ if (ts.isIdentifier(node)) {
55
+ const binding = index.resolve(module.path, node.text);
56
+ return binding?.initializer ? instanceOf(binding.initializer, binding.module, depth + 1) : undefined;
57
+ }
58
+ return undefined;
59
+ };
60
+ // Pass 1: every chain rooted at an instance, wherever it is written.
61
+ for (const file of gated) {
62
+ const module = index.get(file.path);
63
+ if (!module)
64
+ continue;
65
+ walk(module.source, (node) => {
66
+ if (!ts.isCallExpression(node))
67
+ return;
68
+ if (ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === "use" && node.arguments[0]) {
69
+ const plugin = instanceOf(node.arguments[0], module);
70
+ if (plugin)
71
+ mounted.add(plugin.key);
72
+ }
73
+ if (!isChainTop(node))
74
+ return;
75
+ const { root, calls } = unwindChain(node);
76
+ if (calls.length === 0)
77
+ return;
78
+ if (ts.isIdentifier(root) && isShadowed(node, root.text))
79
+ return;
80
+ const instance = instanceOf(root, module);
81
+ if (!instance)
82
+ return;
83
+ const list = registrations.get(instance.key) ?? [];
84
+ list.push({ module, calls });
85
+ registrations.set(instance.key, list);
86
+ });
87
+ }
88
+ const emit = (module, base, path, method) => {
89
+ const full = joinRoutePaths(base, path);
90
+ const route = { path: full, file: module.path, kind: "api", ...(method ? { methods: [method] } : {}) };
91
+ routes.set(`${method ?? "*"} ${full} ${module.path}`, route);
92
+ };
93
+ const stack = new Set();
94
+ const mount = (instance, base) => {
95
+ if (stack.has(instance.key))
96
+ return;
97
+ stack.add(instance.key);
98
+ const here = joinRoutePaths(base, instance.prefix);
99
+ for (const registration of registrations.get(instance.key) ?? []) {
100
+ processCalls(registration.calls, registration.module, here);
101
+ }
102
+ stack.delete(instance.key);
103
+ };
104
+ const processFunction = (fn, module, base) => {
105
+ const first = fn.parameters[0];
106
+ if (!first || !ts.isIdentifier(first.name) || !fn.body)
107
+ return;
108
+ const param = first.name.text;
109
+ walkOutsideShadow(fn.body, param, (node) => {
110
+ if (!ts.isCallExpression(node) || !isChainTop(node))
111
+ return;
112
+ const { root, calls } = unwindChain(node);
113
+ if (calls.length > 0 && ts.isIdentifier(root) && root.text === param) {
114
+ processCalls(calls, module, base);
115
+ return false;
116
+ }
117
+ });
118
+ };
119
+ const processCalls = (calls, module, base) => {
120
+ for (const call of calls) {
121
+ if (METHODS.has(call.name)) {
122
+ const path = index.stringOf(call.args[0], module);
123
+ if (path !== undefined)
124
+ emit(module, base, path, METHODS.get(call.name));
125
+ }
126
+ else if (call.name === "route") {
127
+ const method = index.stringOf(call.args[0], module)?.toUpperCase();
128
+ const path = index.stringOf(call.args[1], module);
129
+ if (path !== undefined)
130
+ emit(module, base, path, method);
131
+ }
132
+ else if (call.name === "group") {
133
+ const prefix = index.stringOf(call.args[0], module);
134
+ const callback = [...call.args].reverse().find(isFunctionExpression);
135
+ if (prefix !== undefined && callback)
136
+ processFunction(callback, module, joinRoutePaths(base, prefix));
137
+ }
138
+ else if (call.name === "guard") {
139
+ const callback = call.args.find(isFunctionExpression);
140
+ if (callback)
141
+ processFunction(callback, module, base);
142
+ }
143
+ else if (call.name === "use" && call.args[0]) {
144
+ usePlugin(call.args[0], module, base);
145
+ }
146
+ }
147
+ };
148
+ const usePlugin = (argument, module, base) => {
149
+ const plugin = instanceOf(argument, module);
150
+ if (plugin)
151
+ return mount(plugin, base);
152
+ const node = unwrapExpression(argument);
153
+ if (isFunctionExpression(node))
154
+ return processFunction(node, module, base);
155
+ if (ts.isIdentifier(node)) {
156
+ const binding = index.resolve(module.path, node.text);
157
+ if (binding?.fn)
158
+ processFunction(binding.fn, binding.module, base);
159
+ }
160
+ };
161
+ for (const instance of instances.values()) {
162
+ if (!mounted.has(instance.key))
163
+ mount(instance, "/");
164
+ }
165
+ return sortRoutes([...routes.values()]);
166
+ }
167
+ function isFunctionExpression(node) {
168
+ return ts.isArrowFunction(node) || ts.isFunctionExpression(node);
169
+ }
170
+ /** `new Elysia({ prefix: "/users" })` */
171
+ function prefixOf(node, module, index) {
172
+ const options = node.arguments?.[0];
173
+ if (!options || !ts.isObjectLiteralExpression(options))
174
+ return "";
175
+ for (const property of options.properties) {
176
+ if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && property.name.text === "prefix") {
177
+ return index.stringOf(property.initializer, module) ?? "";
178
+ }
179
+ // `{ prefix }`
180
+ if (ts.isShorthandPropertyAssignment(property) && property.name.text === "prefix") {
181
+ return index.stringOf(property.name, module) ?? "";
182
+ }
183
+ }
184
+ return "";
185
+ }
186
+ //# sourceMappingURL=elysiaRouteDetector.js.map