Skip to content

Commit 60a0976

Browse files
committed
improved route extractions
1 parent 19c27f9 commit 60a0976

File tree

4 files changed

+51
-23
lines changed

4 files changed

+51
-23
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tsharp/ng-component-hierarchy-visualizer",
3-
"version": "1.6.0",
3+
"version": "1.7.0",
44
"description": "generate mermaid representations of your angular component hierarchy",
55
"keywords": [
66
"angular",
@@ -15,7 +15,8 @@
1515
"ng-route-hierarchy": "scripts/generate.js"
1616
},
1717
"scripts": {
18-
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
18+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
19+
"updateSnapshots": "node --experimental-vm-modules node_modules/jest/bin/jest.js --updateSnapshot"
1920
},
2021
"repository": {
2122
"type": "git",

scripts/route.helper.js

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,13 @@ const extractVariableDeclaration = (declarations) => {
9494

9595
export const extractRoutesFromTS = (routesString, rootName = ROOT_COMPONENT) => {
9696
try {
97-
// Stricter parsing mode
9897
const ast = parse(routesString, {
9998
range: true,
10099
});
101100

102101
// Find the top-level array expression
103-
const routesArrayNode = ast.body.find(node => node.type === 'ExpressionStatement' &&
104-
node.expression.type === 'ArrayExpression');
102+
const routesArrayNode = ast.body
103+
.find(node => node.type === 'ExpressionStatement' && node.expression.type === 'ArrayExpression');
105104

106105
if (!routesArrayNode) {
107106
throw new Error('Could not find the routes array in the configuration.');
@@ -111,7 +110,7 @@ export const extractRoutesFromTS = (routesString, rootName = ROOT_COMPONENT) =>
111110
const routes = routesArrayNode.expression.elements.map(e => {
112111
try {
113112
const resolvedRoutes = extractRoutes([e], rootName)
114-
if(resolvedRoutes.length === 1) {
113+
if (resolvedRoutes.length === 1) {
115114
return resolvedRoutes[0];
116115
}
117116

@@ -121,7 +120,7 @@ export const extractRoutesFromTS = (routesString, rootName = ROOT_COMPONENT) =>
121120
} catch (error) {
122121
console.error('Error extracting route configuration:', error);
123122
}
124-
}).filter(Boolean);
123+
});
125124

126125
return routes;
127126
} catch (error) {
@@ -149,40 +148,56 @@ const extractRoutes = (elements, rootName) => {
149148
const children = e.properties.find(n => n.key?.name === 'children')?.value?.elements;
150149
if (children?.length > 0) {
151150
extractRoutes(children, rootName).forEach(element => {
152-
tempRoutes.push(element)
151+
tempRoutes.push(element);
153152
});
154153
}
155-
})
154+
});
156155

157156
return tempRoutes;
158157
};
159158

160159
const extractComponents = (properties, parent) => {
161160
return {
162161
path: properties.find(n => n.key?.name === 'path')?.value?.value,
163-
component: properties.find(n => n.key?.name === 'component')?.value?.name,
162+
component: properties.find(n => n.key?.name === 'component').value.name,
164163
parent
165164
}
166165
};
167166

168167
const extractLoadComponents = (properties, parent) => {
169-
const loadComponent = properties.find(n => n.key?.name === 'loadComponent')
170-
const loadComponentValue = loadComponent?.value?.body?.callee?.object?.source?.value ?? loadComponent?.value?.body?.source?.value;
168+
const loadComponent = extractBaseProperty(properties.find(n => n.key?.name === 'loadComponent'));
169+
170+
const loadComponentValue = loadComponent.callee?.object?.source?.value // if it has .then
171+
?? loadComponent.source.value; // if it has no .then
172+
171173
return {
172174
path: properties.find(n => n.key?.name === 'path')?.value?.value,
173175
loadComponent: loadComponentValue,
174-
componentName: properties.find(n => n.key?.name === 'loadComponent')?.value?.body?.arguments?.[0]?.body?.property?.name ?? loadComponentValue,
176+
componentName: loadComponent.arguments?.[0]?.body?.property?.name ?? loadComponentValue,
175177
parent
176178
}
177179
};
178180

179181
const extractLoadChildren = (properties, parent) => {
180-
const loadChildren = properties.find(n => n.key?.name === 'loadChildren')
181-
const loadChildrenValue = loadChildren?.value?.body?.callee?.object?.source?.value ?? loadChildren?.value?.body?.source?.value;
182+
const loadChildren = extractBaseProperty(properties.find(n => n.key?.name === 'loadChildren'));
183+
184+
const loadChildrenValue = loadChildren.callee?.object?.source?.value // if it has .then
185+
?? loadChildren.source.value; // if it has no .then
186+
182187
return {
183188
path: properties.find(n => n.key?.name === 'path')?.value?.value,
184189
loadChildren: loadChildrenValue,
185-
componentName: properties.find(n => n.key?.name === 'loadChildren')?.value.body.arguments?.[0]?.body?.property?.name ?? loadChildrenValue,
190+
componentName: loadChildren.arguments?.[0]?.body?.property?.name ?? loadChildrenValue,
186191
parent
187192
}
193+
};
194+
195+
const extractBaseProperty = (node) => {
196+
const body = node.value?.body?.body?.[0]?.argument // if it has a body
197+
?? node.value?.consequent?.body // if it has a ternary
198+
?? node.value?.body; // if it has no body
199+
200+
return body.body?.[0]?.consequent?.body?.[0]?.argument // if it has an if statement inside the body of the callback
201+
?? body.consequent // if it has a ternary inside the body of the callback
202+
?? body;
188203
}

test-data/route-definitions/ngx-admin/pages/pages-routing.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,28 @@ const routes: Routes = [{
2121
{
2222
path: 'layout',
2323
loadChildren: () =>
24-
25-
import('./layout/layout.module')
24+
{
25+
if (true) {
26+
return import('./layout/layout.module')
2627
.then(m => m.LayoutModule)
28+
} else{
29+
return import('./bla')
30+
.then(m => m.b)
31+
}
32+
33+
}
34+
2735

2836

2937

3038
},
3139
{
3240
path: 'forms',
33-
loadChildren: () => import('./forms/forms.module')
41+
loadChildren: () => false ? import('./forms/forms.module').then(m => m.FormsModule)
42+
: import('./bla')
43+
.then(m => m.b)
3444

35-
.then(m => m.FormsModule)
45+
3646
},
3747
{
3848
path: 'ui-features',

test-data/route-definitions/real-world/app.routes.satisfies.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ export const routes = [
1111
},
1212
{
1313
path: "login",
14-
loadComponent: () => import("./core/auth/auth.component"),
14+
loadComponent: () => false
15+
? import("./core/auth/auth.component")
16+
: import("./uups"),
1517
canActivate: [
1618
() => inject(UserService).isAuthenticated.pipe(map((isAuth) => !isAuth)),
1719
],
1820
},
1921
{
2022
path: "register",
21-
loadComponent: () => import("./core/auth/auth.component"),
23+
loadComponent: true? () => import("./core/auth/auth.component") : import("./noooo"),
2224
canActivate: [
2325
() => inject(UserService).isAuthenticated.pipe(map((isAuth) => !isAuth)),
2426
],
@@ -30,7 +32,7 @@ export const routes = [
3032
},
3133
{
3234
path: "profile",
33-
loadChildren: () => import("./features/profile/profile.routes"),
35+
loadChildren: () => import("./features/profile/profile.routes")
3436
},
3537
{
3638
path: "editor",

0 commit comments

Comments
 (0)