UNPKG

31.8 kBPlain TextView Raw
1import * as Handlebars from 'handlebars';
2import * as JSON5 from 'json5';
3import * as _ from 'lodash';
4import * as path from 'path';
5import Ast, { ts, SourceFile, SyntaxKind, TypeGuards } from 'ts-simple-ast';
6
7import FileEngine from '../app/engines/file.engine';
8import { RoutingGraphNode } from '../app/nodes/routing-graph-node';
9
10import ImportsUtil from './imports.util';
11import { logger } from './logger';
12
13const traverse = require('traverse');
14
15const ast = new Ast();
16
17export class RouterParserUtil {
18 private routes: any[] = [];
19 private incompleteRoutes = [];
20 private modules = [];
21 private modulesTree;
22 private rootModule: string;
23 private cleanModulesTree;
24 private modulesWithRoutes = [];
25 private transformAngular8ImportSyntax = /(['"]loadChildren['"]:)\(\)=>"import\((\\'|'|")([^'"]+?)(\\'|'|")\)\.then\(\w+?=>\S+?\.([^)]+?)\)(\\'|'|")/g;
26
27 private static instance: RouterParserUtil;
28 private constructor() {}
29 public static getInstance() {
30 if (!RouterParserUtil.instance) {
31 RouterParserUtil.instance = new RouterParserUtil();
32 }
33 return RouterParserUtil.instance;
34 }
35
36 public addRoute(route): void {
37 this.routes.push(route);
38 this.routes = _.sortBy(_.uniqWith(this.routes, _.isEqual), ['name']);
39 }
40
41 public addIncompleteRoute(route): void {
42 this.incompleteRoutes.push(route);
43 this.incompleteRoutes = _.sortBy(_.uniqWith(this.incompleteRoutes, _.isEqual), ['name']);
44 }
45
46 public addModuleWithRoutes(moduleName, moduleImports, filename): void {
47 this.modulesWithRoutes.push({
48 name: moduleName,
49 importsNode: moduleImports,
50 filename: filename
51 });
52 this.modulesWithRoutes = _.sortBy(_.uniqWith(this.modulesWithRoutes, _.isEqual), ['name']);
53 }
54
55 public addModule(moduleName: string, moduleImports): void {
56 this.modules.push({
57 name: moduleName,
58 importsNode: moduleImports
59 });
60 this.modules = _.sortBy(_.uniqWith(this.modules, _.isEqual), ['name']);
61 }
62
63 public cleanRawRouteParsed(route: string): object {
64 let routesWithoutSpaces = route.replace(/ /gm, '');
65 let testTrailingComma = routesWithoutSpaces.indexOf('},]');
66 if (testTrailingComma !== -1) {
67 routesWithoutSpaces = routesWithoutSpaces.replace('},]', '}]');
68 }
69
70 routesWithoutSpaces = routesWithoutSpaces.replace(
71 this.transformAngular8ImportSyntax,
72 '$1"$3#$5"'
73 );
74
75 return JSON5.parse(routesWithoutSpaces);
76 }
77
78 public cleanRawRoute(route: string): string {
79 let routesWithoutSpaces = route.replace(/ /gm, '');
80 let testTrailingComma = routesWithoutSpaces.indexOf('},]');
81 if (testTrailingComma !== -1) {
82 routesWithoutSpaces = routesWithoutSpaces.replace('},]', '}]');
83 }
84
85 routesWithoutSpaces = routesWithoutSpaces.replace(
86 this.transformAngular8ImportSyntax,
87 '$1"$3#$5"'
88 );
89
90 return routesWithoutSpaces;
91 }
92
93 public setRootModule(module: string): void {
94 this.rootModule = module;
95 }
96
97 public hasRouterModuleInImports(imports: Array<any>): boolean {
98 for (let i = 0; i < imports.length; i++) {
99 if (
100 imports[i].name.indexOf('RouterModule.forChild') !== -1 ||
101 imports[i].name.indexOf('RouterModule.forRoot') !== -1 ||
102 imports[i].name.indexOf('RouterModule') !== -1
103 ) {
104 return true;
105 }
106 }
107
108 return false;
109 }
110
111 public fixIncompleteRoutes(miscellaneousVariables: Array<any>): void {
112 let matchingVariables = [];
113 // For each incompleteRoute, scan if one misc variable is in code
114 // if ok, try recreating complete route
115 for (let i = 0; i < this.incompleteRoutes.length; i++) {
116 for (let j = 0; j < miscellaneousVariables.length; j++) {
117 if (this.incompleteRoutes[i].data.indexOf(miscellaneousVariables[j].name) !== -1) {
118 console.log('found one misc var inside incompleteRoute');
119 console.log(miscellaneousVariables[j].name);
120 matchingVariables.push(miscellaneousVariables[j]);
121 }
122 }
123 // Clean incompleteRoute
124 this.incompleteRoutes[i].data = this.incompleteRoutes[i].data.replace('[', '');
125 this.incompleteRoutes[i].data = this.incompleteRoutes[i].data.replace(']', '');
126 }
127 }
128
129 public linkModulesAndRoutes(): void {
130 let i = 0;
131 let len = this.modulesWithRoutes.length;
132 for (i; i < len; i++) {
133 _.forEach(this.modulesWithRoutes[i].importsNode, (node: ts.PropertyDeclaration) => {
134 let initializer = node.initializer as ts.ArrayLiteralExpression;
135 if (initializer) {
136 if (initializer.elements) {
137 _.forEach(initializer.elements, (element: ts.CallExpression) => {
138 // find element with arguments
139 if (element.arguments) {
140 _.forEach(element.arguments, (argument: ts.Identifier) => {
141 _.forEach(this.routes, route => {
142 if (
143 argument.text &&
144 route.name === argument.text &&
145 route.filename === this.modulesWithRoutes[i].filename
146 ) {
147 route.module = this.modulesWithRoutes[i].name;
148 } else if (
149 argument.text &&
150 route.name === argument.text &&
151 route.filename !== this.modulesWithRoutes[i].filename
152 ) {
153 let argumentImportPath = ImportsUtil.findFilePathOfImportedVariable(
154 argument.text,
155 this.modulesWithRoutes[i].filename
156 );
157
158 argumentImportPath = argumentImportPath
159 .replace(process.cwd() + path.sep, '')
160 .replace(/\\/g, '/');
161
162 if (
163 argument.text &&
164 route.name === argument.text &&
165 route.filename === argumentImportPath
166 ) {
167 route.module = this.modulesWithRoutes[i].name;
168 }
169 }
170 });
171 });
172 }
173 });
174 }
175 }
176 /**
177 * direct support of for example
178 * export const HomeRoutingModule: ModuleWithProviders = RouterModule.forChild(HOME_ROUTES);
179 */
180 if (ts.isCallExpression(node)) {
181 if (node.arguments) {
182 _.forEach(node.arguments, (argument: ts.Identifier) => {
183 _.forEach(this.routes, route => {
184 if (
185 argument.text &&
186 route.name === argument.text &&
187 route.filename === this.modulesWithRoutes[i].filename
188 ) {
189 route.module = this.modulesWithRoutes[i].name;
190 }
191 });
192 });
193 }
194 }
195 });
196 }
197 }
198
199 public foundRouteWithModuleName(moduleName: string): any {
200 return _.find(this.routes, { module: moduleName });
201 }
202
203 public foundLazyModuleWithPath(modulePath: string): string {
204 // path is like app/customers/customers.module#CustomersModule
205 let split = modulePath.split('#');
206 let lazyModulePath = split[0];
207 let lazyModuleName = split[1];
208 return lazyModuleName;
209 }
210
211 public constructRoutesTree() {
212 // routes[] contains routes with module link
213 // modulesTree contains modules tree
214 // make a final routes tree with that
215 traverse(this.modulesTree).forEach(function(node) {
216 if (node) {
217 if (node.parent) {
218 delete node.parent;
219 }
220 if (node.initializer) {
221 delete node.initializer;
222 }
223 if (node.importsNode) {
224 delete node.importsNode;
225 }
226 }
227 });
228
229 this.cleanModulesTree = _.cloneDeep(this.modulesTree);
230
231 let routesTree = {
232 name: '<root>',
233 kind: 'module',
234 className: this.rootModule,
235 children: []
236 };
237
238 let loopModulesParser = node => {
239 if (node.children && node.children.length > 0) {
240 // If module has child modules
241 for (let i in node.children) {
242 let route = this.foundRouteWithModuleName(node.children[i].name);
243 if (route && route.data) {
244 try {
245 route.children = JSON5.parse(route.data);
246 } catch (e) {
247 logger.error(
248 'Error during generation of routes JSON file, maybe a trailing comma or an external variable inside one route.'
249 );
250 }
251 delete route.data;
252 route.kind = 'module';
253 routesTree.children.push(route);
254 }
255 if (node.children[i].children) {
256 loopModulesParser(node.children[i]);
257 }
258 }
259 } else {
260 // else routes are directly inside the module
261 let rawRoutes = this.foundRouteWithModuleName(node.name);
262
263 if (rawRoutes) {
264 let routes = JSON5.parse(rawRoutes.data);
265 if (routes) {
266 let i = 0;
267 let len = routes.length;
268 let routeAddedOnce = false;
269 for (i; i < len; i++) {
270 let route = routes[i];
271 if (routes[i].component) {
272 routeAddedOnce = true;
273 routesTree.children.push({
274 kind: 'component',
275 component: routes[i].component,
276 path: routes[i].path
277 });
278 }
279 }
280 if (!routeAddedOnce) {
281 routesTree.children = [...routesTree.children, ...routes];
282 }
283 }
284 }
285 }
286 };
287
288 let startModule = _.find(this.cleanModulesTree, { name: this.rootModule });
289
290 if (startModule) {
291 loopModulesParser(startModule);
292 // Loop twice for routes with lazy loading
293 // loopModulesParser(routesTree);
294 }
295
296 let cleanedRoutesTree = undefined;
297
298 let cleanRoutesTree = route => {
299 for (let i in route.children) {
300 let routes = route.children[i].routes;
301 }
302 return route;
303 };
304
305 cleanedRoutesTree = cleanRoutesTree(routesTree);
306
307 // Try updating routes with lazy loading
308
309 let loopInsideModule = (mod, _rawModule) => {
310 if (mod.children) {
311 for (let z in mod.children) {
312 let route = this.foundRouteWithModuleName(mod.children[z].name);
313 if (typeof route !== 'undefined') {
314 if (route.data) {
315 route.children = JSON5.parse(route.data);
316 delete route.data;
317 route.kind = 'module';
318 _rawModule.children.push(route);
319 }
320 }
321 }
322 } else {
323 let route = this.foundRouteWithModuleName(mod.name);
324 if (typeof route !== 'undefined') {
325 if (route.data) {
326 route.children = JSON5.parse(route.data);
327 delete route.data;
328 route.kind = 'module';
329 _rawModule.children.push(route);
330 }
331 }
332 }
333 };
334
335 let loopRoutesParser = route => {
336 if (route.children) {
337 for (let i in route.children) {
338 if (route.children[i].loadChildren) {
339 let child = this.foundLazyModuleWithPath(route.children[i].loadChildren);
340 let module: RoutingGraphNode = _.find(this.cleanModulesTree, {
341 name: child
342 });
343 if (module) {
344 let _rawModule: RoutingGraphNode = {};
345 _rawModule.kind = 'module';
346 _rawModule.children = [];
347 _rawModule.module = module.name;
348 loopInsideModule(module, _rawModule);
349
350 route.children[i].children = [];
351 route.children[i].children.push(_rawModule);
352 }
353 }
354 loopRoutesParser(route.children[i]);
355 }
356 }
357 };
358 loopRoutesParser(cleanedRoutesTree);
359
360 return cleanedRoutesTree;
361 }
362
363 public constructModulesTree(): void {
364 let getNestedChildren = (arr, parent?) => {
365 let out = [];
366 for (let i in arr) {
367 if (arr[i].parent === parent) {
368 let children = getNestedChildren(arr, arr[i].name);
369 if (children.length) {
370 arr[i].children = children;
371 }
372 out.push(arr[i]);
373 }
374 }
375 return out;
376 };
377
378 // Scan each module and add parent property
379 _.forEach(this.modules, firstLoopModule => {
380 _.forEach(firstLoopModule.importsNode, importNode => {
381 _.forEach(this.modules, module => {
382 if (module.name === importNode.name) {
383 module.parent = firstLoopModule.name;
384 }
385 });
386 });
387 });
388 this.modulesTree = getNestedChildren(this.modules);
389 }
390
391 public generateRoutesIndex(outputFolder: string, routes: Array<any>): Promise<void> {
392 return FileEngine.get(__dirname + '/../src/templates/partials/routes-index.hbs').then(
393 data => {
394 let template: any = Handlebars.compile(data);
395 let result = template({
396 routes: JSON.stringify(routes)
397 });
398 let testOutputDir = outputFolder.match(process.cwd());
399
400 if (testOutputDir && testOutputDir.length > 0) {
401 outputFolder = outputFolder.replace(process.cwd() + path.sep, '');
402 }
403
404 return FileEngine.write(
405 outputFolder + path.sep + '/js/routes/routes_index.js',
406 result
407 );
408 },
409 err => Promise.reject('Error during routes index generation')
410 );
411 }
412
413 public routesLength(): number {
414 let _n = 0;
415 let routesParser = route => {
416 if (typeof route.path !== 'undefined') {
417 _n += 1;
418 }
419 if (route.children) {
420 for (let j in route.children) {
421 routesParser(route.children[j]);
422 }
423 }
424 };
425
426 for (let i in this.routes) {
427 routesParser(this.routes[i]);
428 }
429
430 return _n;
431 }
432
433 public printRoutes(): void {
434 console.log('');
435 console.log('printRoutes: ');
436 console.log(this.routes);
437 }
438
439 public printModulesRoutes(): void {
440 console.log('');
441 console.log('printModulesRoutes: ');
442 console.log(this.modulesWithRoutes);
443 }
444
445 public isVariableRoutes(node) {
446 let result = false;
447 if (node.declarationList && node.declarationList.declarations) {
448 let i = 0;
449 let len = node.declarationList.declarations.length;
450 for (i; i < len; i++) {
451 if (node.declarationList.declarations[i].type) {
452 if (
453 node.declarationList.declarations[i].type.typeName &&
454 node.declarationList.declarations[i].type.typeName.text === 'Routes'
455 ) {
456 result = true;
457 }
458 }
459 }
460 }
461 return result;
462 }
463
464 public cleanFileIdentifiers(sourceFile: SourceFile): SourceFile {
465 let file = sourceFile;
466 const identifiers = file.getDescendantsOfKind(SyntaxKind.Identifier).filter(p => {
467 return (
468 TypeGuards.isArrayLiteralExpression(p.getParentOrThrow()) ||
469 TypeGuards.isPropertyAssignment(p.getParentOrThrow())
470 );
471 });
472
473 let identifiersInRoutesVariableStatement = [];
474
475 for (const identifier of identifiers) {
476 // Loop through their parents nodes, and if one is a variableStatement and === 'routes'
477 let foundParentVariableStatement = false;
478 let parent = identifier.getParentWhile(n => {
479 if (n.getKind() === SyntaxKind.VariableStatement) {
480 if (this.isVariableRoutes(n.compilerNode)) {
481 foundParentVariableStatement = true;
482 }
483 }
484 return true;
485 });
486 if (foundParentVariableStatement) {
487 identifiersInRoutesVariableStatement.push(identifier);
488 }
489 }
490
491 // inline the property access expressions
492 for (const identifier of identifiersInRoutesVariableStatement) {
493 const identifierDeclaration = identifier
494 .getSymbolOrThrow()
495 .getValueDeclarationOrThrow();
496 if (
497 !TypeGuards.isPropertyAssignment(identifierDeclaration) &&
498 TypeGuards.isVariableDeclaration(identifierDeclaration) &&
499 (TypeGuards.isPropertyAssignment(identifierDeclaration) &&
500 !TypeGuards.isVariableDeclaration(identifierDeclaration))
501 ) {
502 throw new Error(
503 `Not implemented referenced declaration kind: ${identifierDeclaration.getKindName()}`
504 );
505 }
506 if (TypeGuards.isVariableDeclaration(identifierDeclaration)) {
507 identifier.replaceWithText(identifierDeclaration.getInitializerOrThrow().getText());
508 }
509 }
510
511 return file;
512 }
513
514 public cleanFileSpreads(sourceFile: SourceFile): SourceFile {
515 let file = sourceFile;
516 const spreadElements = file
517 .getDescendantsOfKind(SyntaxKind.SpreadElement)
518 .filter(p => TypeGuards.isArrayLiteralExpression(p.getParentOrThrow()));
519
520 let spreadElementsInRoutesVariableStatement = [];
521
522 for (const spreadElement of spreadElements) {
523 // Loop through their parents nodes, and if one is a variableStatement and === 'routes'
524 let foundParentVariableStatement = false;
525 let parent = spreadElement.getParentWhile(n => {
526 if (n.getKind() === SyntaxKind.VariableStatement) {
527 if (this.isVariableRoutes(n.compilerNode)) {
528 foundParentVariableStatement = true;
529 }
530 }
531 return true;
532 });
533 if (foundParentVariableStatement) {
534 spreadElementsInRoutesVariableStatement.push(spreadElement);
535 }
536 }
537
538 // inline the ArrayLiteralExpression SpreadElements
539 for (const spreadElement of spreadElementsInRoutesVariableStatement) {
540 let spreadElementIdentifier = spreadElement.getExpression().getText(),
541 searchedImport,
542 aliasOriginalName = '',
543 foundWithAliasInImports = false,
544 foundWithAlias = false;
545
546 // Try to find it in imports
547 const imports = file.getImportDeclarations();
548
549 imports.forEach(i => {
550 let namedImports = i.getNamedImports(),
551 namedImportsLength = namedImports.length,
552 j = 0;
553
554 if (namedImportsLength > 0) {
555 for (j; j < namedImportsLength; j++) {
556 let importName = namedImports[j].getNameNode().getText() as string,
557 importAlias;
558
559 if (namedImports[j].getAliasIdentifier()) {
560 importAlias = namedImports[j].getAliasIdentifier().getText();
561 }
562
563 if (importName === spreadElementIdentifier) {
564 foundWithAliasInImports = true;
565 searchedImport = i;
566 break;
567 }
568 if (importAlias === spreadElementIdentifier) {
569 foundWithAliasInImports = true;
570 foundWithAlias = true;
571 aliasOriginalName = importName;
572 searchedImport = i;
573 break;
574 }
575 }
576 }
577 });
578
579 let referencedDeclaration;
580
581 if (foundWithAliasInImports) {
582 if (typeof searchedImport !== 'undefined') {
583 let importPath = path.resolve(
584 path.dirname(file.getFilePath()) +
585 '/' +
586 searchedImport.getModuleSpecifierValue() +
587 '.ts'
588 );
589 const sourceFileImport =
590 typeof ast.getSourceFile(importPath) !== 'undefined'
591 ? ast.getSourceFile(importPath)
592 : ast.addExistingSourceFile(importPath);
593 if (sourceFileImport) {
594 let variableName = foundWithAlias
595 ? aliasOriginalName
596 : spreadElementIdentifier;
597 referencedDeclaration = sourceFileImport.getVariableDeclaration(
598 variableName
599 );
600 }
601 }
602 } else {
603 // if not, try directly in file
604 referencedDeclaration = spreadElement
605 .getExpression()
606 .getSymbolOrThrow()
607 .getValueDeclarationOrThrow();
608 }
609
610 if (!TypeGuards.isVariableDeclaration(referencedDeclaration)) {
611 throw new Error(
612 `Not implemented referenced declaration kind: ${referencedDeclaration.getKindName()}`
613 );
614 }
615
616 const referencedArray = referencedDeclaration.getInitializerIfKindOrThrow(
617 SyntaxKind.ArrayLiteralExpression
618 );
619 const spreadElementArray = spreadElement.getParentIfKindOrThrow(
620 SyntaxKind.ArrayLiteralExpression
621 );
622 const insertIndex = spreadElementArray.getElements().indexOf(spreadElement);
623 spreadElementArray.removeElement(spreadElement);
624 spreadElementArray.insertElements(
625 insertIndex,
626 referencedArray.getElements().map(e => e.getText())
627 );
628 }
629
630 return file;
631 }
632
633 public cleanFileDynamics(sourceFile: SourceFile): SourceFile {
634 let file = sourceFile;
635 const propertyAccessExpressions = file
636 .getDescendantsOfKind(SyntaxKind.PropertyAccessExpression)
637 .filter(p => !TypeGuards.isPropertyAccessExpression(p.getParentOrThrow()));
638
639 let propertyAccessExpressionsInRoutesVariableStatement = [];
640
641 for (const propertyAccessExpression of propertyAccessExpressions) {
642 // Loop through their parents nodes, and if one is a variableStatement and === 'routes'
643 let foundParentVariableStatement = false;
644 let parent = propertyAccessExpression.getParentWhile(n => {
645 if (n.getKind() === SyntaxKind.VariableStatement) {
646 if (this.isVariableRoutes(n.compilerNode)) {
647 foundParentVariableStatement = true;
648 }
649 }
650 return true;
651 });
652 if (foundParentVariableStatement) {
653 propertyAccessExpressionsInRoutesVariableStatement.push(propertyAccessExpression);
654 }
655 }
656
657 // inline the property access expressions
658 for (const propertyAccessExpression of propertyAccessExpressionsInRoutesVariableStatement) {
659 const referencedDeclaration = propertyAccessExpression
660 .getNameNode()
661 .getSymbolOrThrow()
662 .getValueDeclarationOrThrow();
663 if (
664 !TypeGuards.isPropertyAssignment(referencedDeclaration) &&
665 TypeGuards.isEnumMember(referencedDeclaration) &&
666 (TypeGuards.isPropertyAssignment(referencedDeclaration) &&
667 !TypeGuards.isEnumMember(referencedDeclaration))
668 ) {
669 throw new Error(
670 `Not implemented referenced declaration kind: ${referencedDeclaration.getKindName()}`
671 );
672 }
673 if (typeof referencedDeclaration.getInitializerOrThrow !== 'undefined') {
674 propertyAccessExpression.replaceWithText(
675 referencedDeclaration.getInitializerOrThrow().getText()
676 );
677 }
678 }
679
680 return file;
681 }
682
683 /**
684 * replace callexpressions with string : utils.doWork() -> 'utils.doWork()' doWork() -> 'doWork()'
685 * @param sourceFile ts.SourceFile
686 */
687 public cleanCallExpressions(sourceFile: SourceFile): SourceFile {
688 let file = sourceFile;
689
690 const variableStatements = sourceFile.getVariableDeclaration(v => {
691 let result = false;
692 if (typeof v.compilerNode.type !== 'undefined') {
693 result = v.compilerNode.type.typeName.text === 'Routes';
694 }
695 return result;
696 });
697
698 const initializer = variableStatements.getInitializer();
699
700 for (const callExpr of initializer.getDescendantsOfKind(SyntaxKind.CallExpression)) {
701 if (callExpr.wasForgotten()) {
702 continue;
703 }
704 callExpr.replaceWithText(writer => writer.quote(callExpr.getText()));
705 }
706
707 return file;
708 }
709
710 /**
711 * Clean routes definition with imported data, for example path, children, or dynamic stuff inside data
712 *
713 * const MY_ROUTES: Routes = [
714 * {
715 * path: 'home',
716 * component: HomeComponent
717 * },
718 * {
719 * path: PATHS.home,
720 * component: HomeComponent
721 * }
722 * ];
723 *
724 * The initializer is an array (ArrayLiteralExpression - 177 ), it has elements, objects (ObjectLiteralExpression - 178)
725 * with properties (PropertyAssignment - 261)
726 *
727 * For each know property (https://angular.io/api/router/Routes#description), we try to see if we have what we want
728 *
729 * Ex: path and pathMatch want a string, component a component reference.
730 *
731 * It is an imperative approach, not a generic way, parsing all the tree
732 * and find something like this which willl break JSON.stringify : MYIMPORT.path
733 *
734 * @param {ts.Node} initializer The node of routes definition
735 * @return {ts.Node} The edited node
736 */
737 public cleanRoutesDefinitionWithImport(
738 initializer: ts.ArrayLiteralExpression,
739 node: ts.Node,
740 sourceFile: ts.SourceFile
741 ): ts.Node {
742 initializer.elements.forEach((element: ts.ObjectLiteralExpression) => {
743 element.properties.forEach((property: ts.PropertyAssignment) => {
744 let propertyName = property.name.getText(),
745 propertyInitializer = property.initializer;
746 switch (propertyName) {
747 case 'path':
748 case 'redirectTo':
749 case 'outlet':
750 case 'pathMatch':
751 if (propertyInitializer) {
752 if (propertyInitializer.kind !== SyntaxKind.StringLiteral) {
753 // Identifier(71) won't break parsing, but it will be better to retrive them
754 // PropertyAccessExpression(179) ex: MYIMPORT.path will break it, find it in import
755 if (
756 propertyInitializer.kind === SyntaxKind.PropertyAccessExpression
757 ) {
758 let lastObjectLiteralAttributeName = propertyInitializer.name.getText(),
759 firstObjectLiteralAttributeName;
760 if (propertyInitializer.expression) {
761 firstObjectLiteralAttributeName = propertyInitializer.expression.getText();
762 let result = ImportsUtil.findPropertyValueInImportOrLocalVariables(
763 firstObjectLiteralAttributeName +
764 '.' +
765 lastObjectLiteralAttributeName,
766 sourceFile
767 ); // tslint:disable-line
768 if (result !== '') {
769 propertyInitializer.kind = 9;
770 propertyInitializer.text = result;
771 }
772 }
773 }
774 }
775 }
776 break;
777 }
778 });
779 });
780 return initializer;
781 }
782}
783
784export default RouterParserUtil.getInstance();