1 | import * as path from 'path';
|
2 |
|
3 | import { Project, ts, PropertyDeclaration, SyntaxKind, VariableDeclaration } from 'ts-morph';
|
4 | import FileEngine from '../app/engines/file.engine';
|
5 |
|
6 | const ast = new Project();
|
7 |
|
8 | export class ImportsUtil {
|
9 | private static instance: ImportsUtil;
|
10 | private constructor() {}
|
11 | public static getInstance() {
|
12 | if (!ImportsUtil.instance) {
|
13 | ImportsUtil.instance = new ImportsUtil();
|
14 | }
|
15 | return ImportsUtil.instance;
|
16 | }
|
17 | |
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | private findInEnums(srcFile, variableName: string, variableValue: string) {
|
24 | let res = '';
|
25 | srcFile.getEnum(e => {
|
26 | if (e.getName() === variableName) {
|
27 | e.getMember(m => {
|
28 | if (m.getName() === variableValue) {
|
29 | res = m.getValue();
|
30 | }
|
31 | });
|
32 | }
|
33 | });
|
34 | return res;
|
35 | }
|
36 |
|
37 | |
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | private findInClasses(srcFile, variableName: string, variableValue: string) {
|
44 | let res = '';
|
45 | srcFile.getClass(c => {
|
46 | let staticProperty: PropertyDeclaration = c.getStaticProperty(variableValue);
|
47 | if (staticProperty) {
|
48 | if (staticProperty.getInitializer()) {
|
49 | res = staticProperty.getInitializer().getText();
|
50 | }
|
51 | }
|
52 | });
|
53 | return res;
|
54 | }
|
55 |
|
56 | |
57 |
|
58 |
|
59 |
|
60 |
|
61 | private findInObjectVariableDeclaration(variableDeclaration, variablesAttributes) {
|
62 | let variableKind = variableDeclaration.getKind();
|
63 | if (variableKind && variableKind === SyntaxKind.VariableDeclaration) {
|
64 | let initializer = variableDeclaration.getInitializer();
|
65 | if (initializer) {
|
66 | let initializerKind = initializer.getKind();
|
67 | if (initializerKind && initializerKind === SyntaxKind.ObjectLiteralExpression) {
|
68 | let compilerNode = initializer.compilerNode as ts.ObjectLiteralExpression,
|
69 | finalValue = '';
|
70 |
|
71 | let depth = 0;
|
72 | let loopProperties = properties => {
|
73 | properties.forEach(prop => {
|
74 | if (prop.name) {
|
75 | if (variablesAttributes[depth + 1]) {
|
76 | if (prop.name.getText() === variablesAttributes[depth + 1]) {
|
77 | if (prop.initializer) {
|
78 | if (prop.initializer.properties) {
|
79 | depth += 1;
|
80 | loopProperties(prop.initializer.properties);
|
81 | } else {
|
82 | finalValue = prop.initializer.text;
|
83 | }
|
84 | } else {
|
85 | finalValue = prop.initializer.text;
|
86 | }
|
87 | }
|
88 | }
|
89 | }
|
90 | });
|
91 | };
|
92 | loopProperties(compilerNode.properties);
|
93 | return finalValue;
|
94 | }
|
95 | }
|
96 | }
|
97 | }
|
98 |
|
99 | |
100 |
|
101 |
|
102 |
|
103 |
|
104 | public findValueInImportOrLocalVariables(
|
105 | inputVariableName: string,
|
106 | sourceFile: ts.SourceFile,
|
107 | decoratorType?: string
|
108 | ) {
|
109 | let metadataVariableName = inputVariableName,
|
110 | searchedImport,
|
111 | aliasOriginalName = '',
|
112 | foundWithNamedImport = false,
|
113 | foundWithDefaultImport = false,
|
114 | foundWithAlias = false;
|
115 |
|
116 | const file =
|
117 | typeof ast.getSourceFile(sourceFile.fileName) !== 'undefined'
|
118 | ? ast.getSourceFile(sourceFile.fileName)
|
119 | : ast.addSourceFileAtPathIfExists(sourceFile.fileName);
|
120 | const imports = file.getImportDeclarations();
|
121 |
|
122 | |
123 |
|
124 |
|
125 | imports.forEach(i => {
|
126 | let namedImports = i.getNamedImports(),
|
127 | namedImportsLength = namedImports.length,
|
128 | j = 0;
|
129 |
|
130 | if (namedImportsLength > 0) {
|
131 | for (j; j < namedImportsLength; j++) {
|
132 | let importName = namedImports[j].getNameNode().getText() as string,
|
133 | importAlias;
|
134 |
|
135 | if (namedImports[j].getAliasNode()) {
|
136 | importAlias = namedImports[j].getAliasNode().getText();
|
137 | }
|
138 | if (importName === metadataVariableName) {
|
139 | foundWithNamedImport = true;
|
140 | searchedImport = i;
|
141 | break;
|
142 | }
|
143 | if (importAlias === metadataVariableName) {
|
144 | foundWithNamedImport = true;
|
145 | foundWithAlias = true;
|
146 | aliasOriginalName = importName;
|
147 | searchedImport = i;
|
148 | break;
|
149 | }
|
150 | }
|
151 | }
|
152 | const namespaceImport = i.getNamespaceImport();
|
153 | if (namespaceImport) {
|
154 | const namespaceImportLocalName = namespaceImport.getText();
|
155 | if (namespaceImportLocalName === metadataVariableName) {
|
156 | searchedImport = i;
|
157 | }
|
158 | }
|
159 |
|
160 | if (!foundWithNamedImport) {
|
161 | const defaultImport = i.getDefaultImport();
|
162 | if (defaultImport) {
|
163 | const defaultImportText = defaultImport.getText();
|
164 | if (defaultImportText === metadataVariableName) {
|
165 | foundWithDefaultImport = true;
|
166 | searchedImport = i;
|
167 | }
|
168 | }
|
169 | }
|
170 | });
|
171 |
|
172 | function hasFoundValues(variableDeclaration) {
|
173 | let variableKind = variableDeclaration.getKind();
|
174 |
|
175 | if (variableKind && variableKind === SyntaxKind.VariableDeclaration) {
|
176 | let initializer = variableDeclaration.getInitializer();
|
177 | if (initializer) {
|
178 | let initializerKind = initializer.getKind();
|
179 | if (initializerKind && initializerKind === SyntaxKind.ObjectLiteralExpression) {
|
180 | let compilerNode = initializer.compilerNode as ts.ObjectLiteralExpression;
|
181 | return compilerNode.properties;
|
182 | }
|
183 | }
|
184 | }
|
185 | }
|
186 |
|
187 | if (typeof searchedImport !== 'undefined') {
|
188 | let importPathReference = searchedImport.getModuleSpecifierSourceFile();
|
189 | let importPath;
|
190 | if (typeof importPathReference !== 'undefined') {
|
191 | importPath = importPathReference.compilerNode.fileName;
|
192 |
|
193 | const sourceFileImport =
|
194 | typeof ast.getSourceFile(importPath) !== 'undefined'
|
195 | ? ast.getSourceFile(importPath)
|
196 | : ast.addSourceFileAtPathIfExists(importPath);
|
197 |
|
198 | if (sourceFileImport) {
|
199 | let variableName = foundWithAlias ? aliasOriginalName : metadataVariableName;
|
200 | let variableDeclaration = sourceFileImport.getVariableDeclaration(variableName);
|
201 |
|
202 | if (variableDeclaration) {
|
203 | return hasFoundValues(variableDeclaration);
|
204 | } else {
|
205 |
|
206 | const exportDeclarations = sourceFileImport.getExportedDeclarations();
|
207 |
|
208 | if (exportDeclarations && exportDeclarations.size > 0) {
|
209 | for (const [
|
210 | exportDeclarationKey,
|
211 | exportDeclarationValues
|
212 | ] of exportDeclarations) {
|
213 | exportDeclarationValues.forEach(exportDeclarationValue => {
|
214 | if (
|
215 | exportDeclarationValue instanceof VariableDeclaration &&
|
216 | exportDeclarationValue.getName() === variableName
|
217 | ) {
|
218 | return hasFoundValues(exportDeclarationValue);
|
219 | }
|
220 | });
|
221 | }
|
222 | }
|
223 | }
|
224 | }
|
225 | }
|
226 | if (
|
227 | !importPathReference &&
|
228 | decoratorType === 'template' &&
|
229 | searchedImport.getModuleSpecifierValue().indexOf('.html') !== -1
|
230 | ) {
|
231 | const originalSourceFilePath = sourceFile.path;
|
232 | const originalSourceFilePathFolder = originalSourceFilePath.substring(
|
233 | 0,
|
234 | originalSourceFilePath.lastIndexOf('/')
|
235 | );
|
236 | const finalImportedPath =
|
237 | originalSourceFilePathFolder + '/' + searchedImport.getModuleSpecifierValue();
|
238 | const finalImportedPathData = FileEngine.getSync(finalImportedPath);
|
239 | return finalImportedPathData;
|
240 | }
|
241 | } else {
|
242 |
|
243 | const variableDeclaration = file.getVariableDeclaration(metadataVariableName);
|
244 | if (variableDeclaration) {
|
245 | let variableKind = variableDeclaration.getKind();
|
246 |
|
247 | if (variableKind && variableKind === SyntaxKind.VariableDeclaration) {
|
248 | let initializer = variableDeclaration.getInitializer();
|
249 | if (initializer) {
|
250 | let initializerKind = initializer.getKind();
|
251 | if (
|
252 | initializerKind &&
|
253 | initializerKind === SyntaxKind.ObjectLiteralExpression
|
254 | ) {
|
255 | let compilerNode =
|
256 | initializer.compilerNode as ts.ObjectLiteralExpression;
|
257 | return compilerNode.properties;
|
258 | } else if (
|
259 | initializerKind &&
|
260 | (initializerKind === SyntaxKind.StringLiteral ||
|
261 | initializerKind === SyntaxKind.NoSubstitutionTemplateLiteral)
|
262 | ) {
|
263 | if (decoratorType === 'template') {
|
264 | return initializer.getText();
|
265 | } else {
|
266 | return variableDeclaration.compilerNode;
|
267 | }
|
268 | } else if (initializerKind) {
|
269 | return variableDeclaration.compilerNode;
|
270 | }
|
271 | }
|
272 | }
|
273 | }
|
274 | }
|
275 |
|
276 | return [];
|
277 | }
|
278 |
|
279 | public getFileNameOfImport(variableName: string, sourceFile: ts.SourceFile) {
|
280 | const file =
|
281 | typeof ast.getSourceFile(sourceFile.fileName) !== 'undefined'
|
282 | ? ast.getSourceFile(sourceFile.fileName)
|
283 | : ast.addSourceFileAtPath(sourceFile.fileName);
|
284 | const imports = file.getImportDeclarations();
|
285 | let searchedImport,
|
286 | aliasOriginalName = '',
|
287 | finalPath = '',
|
288 | foundWithAlias = false;
|
289 | imports.forEach(i => {
|
290 | let namedImports = i.getNamedImports(),
|
291 | namedImportsLength = namedImports.length,
|
292 | j = 0;
|
293 |
|
294 | if (namedImportsLength > 0) {
|
295 | for (j; j < namedImportsLength; j++) {
|
296 | let importName = namedImports[j].getNameNode().getText() as string,
|
297 | importAlias;
|
298 |
|
299 | if (namedImports[j].getAliasNode()) {
|
300 | importAlias = namedImports[j].getAliasNode().getText();
|
301 | }
|
302 | if (importName === variableName) {
|
303 | searchedImport = i;
|
304 | break;
|
305 | }
|
306 | if (importAlias === variableName) {
|
307 | foundWithAlias = true;
|
308 | aliasOriginalName = importName;
|
309 | searchedImport = i;
|
310 | break;
|
311 | }
|
312 | }
|
313 | }
|
314 | });
|
315 | if (typeof searchedImport !== 'undefined') {
|
316 | let importPath = path.resolve(
|
317 | path.dirname(sourceFile.fileName) +
|
318 | '/' +
|
319 | searchedImport.getModuleSpecifierValue() +
|
320 | '.ts'
|
321 | );
|
322 | let cleaner = (process.cwd() + path.sep).replace(/\\/g, '/');
|
323 | finalPath = importPath.replace(cleaner, '');
|
324 | }
|
325 | return finalPath;
|
326 | }
|
327 |
|
328 | |
329 |
|
330 |
|
331 |
|
332 |
|
333 | public findFilePathOfImportedVariable(inputVariableName, sourceFilePath: string) {
|
334 | let searchedImport,
|
335 | finalPath = '',
|
336 | aliasOriginalName = '',
|
337 | foundWithAlias = false;
|
338 | const file =
|
339 | typeof ast.getSourceFile(sourceFilePath) !== 'undefined'
|
340 | ? ast.getSourceFile(sourceFilePath)
|
341 | : ast.addSourceFileAtPath(sourceFilePath);
|
342 | const imports = file.getImportDeclarations();
|
343 |
|
344 | |
345 |
|
346 |
|
347 | imports.forEach(i => {
|
348 | let namedImports = i.getNamedImports(),
|
349 | namedImportsLength = namedImports.length,
|
350 | j = 0;
|
351 |
|
352 | if (namedImportsLength > 0) {
|
353 | for (j; j < namedImportsLength; j++) {
|
354 | let importName = namedImports[j].getNameNode().getText() as string,
|
355 | importAlias;
|
356 |
|
357 | if (namedImports[j].getAliasNode()) {
|
358 | importAlias = namedImports[j].getAliasNode().getText();
|
359 | }
|
360 | if (importName === inputVariableName) {
|
361 | searchedImport = i;
|
362 | break;
|
363 | }
|
364 | if (importAlias === inputVariableName) {
|
365 | foundWithAlias = true;
|
366 | aliasOriginalName = importName;
|
367 | searchedImport = i;
|
368 | break;
|
369 | }
|
370 | }
|
371 | }
|
372 | });
|
373 | if (typeof searchedImport !== 'undefined') {
|
374 | finalPath = path.resolve(
|
375 | path.dirname(sourceFilePath) +
|
376 | '/' +
|
377 | searchedImport.getModuleSpecifierValue() +
|
378 | '.ts'
|
379 | );
|
380 | }
|
381 | return finalPath;
|
382 | }
|
383 |
|
384 | |
385 |
|
386 |
|
387 |
|
388 |
|
389 | public findPropertyValueInImportOrLocalVariables(inputVariableName, sourceFile: ts.SourceFile) {
|
390 | let variablesAttributes = inputVariableName.split('.'),
|
391 | metadataVariableName = variablesAttributes[0],
|
392 | searchedImport,
|
393 | aliasOriginalName = '',
|
394 | foundWithAlias = false;
|
395 |
|
396 | const file =
|
397 | typeof ast.getSourceFile(sourceFile.fileName) !== 'undefined'
|
398 | ? ast.getSourceFile(sourceFile.fileName)
|
399 | : ast.addSourceFileAtPath(sourceFile.fileName);
|
400 | const imports = file.getImportDeclarations();
|
401 |
|
402 | |
403 |
|
404 |
|
405 | imports.forEach(i => {
|
406 | let namedImports = i.getNamedImports(),
|
407 | namedImportsLength = namedImports.length,
|
408 | j = 0;
|
409 |
|
410 | if (namedImportsLength > 0) {
|
411 | for (j; j < namedImportsLength; j++) {
|
412 | let importName = namedImports[j].getNameNode().getText() as string,
|
413 | importAlias;
|
414 |
|
415 | if (namedImports[j].getAliasNode()) {
|
416 | importAlias = namedImports[j].getAliasNode().getText();
|
417 | }
|
418 | if (importName === metadataVariableName) {
|
419 | searchedImport = i;
|
420 | break;
|
421 | }
|
422 | if (importAlias === metadataVariableName) {
|
423 | foundWithAlias = true;
|
424 | aliasOriginalName = importName;
|
425 | searchedImport = i;
|
426 | break;
|
427 | }
|
428 | }
|
429 | }
|
430 | });
|
431 |
|
432 | let fileToSearchIn, variableDeclaration;
|
433 | if (typeof searchedImport !== 'undefined') {
|
434 | let importPath = path.resolve(
|
435 | path.dirname(sourceFile.fileName) +
|
436 | '/' +
|
437 | searchedImport.getModuleSpecifierValue() +
|
438 | '.ts'
|
439 | );
|
440 | const sourceFileImport =
|
441 | typeof ast.getSourceFile(importPath) !== 'undefined'
|
442 | ? ast.getSourceFile(importPath)
|
443 | : ast.addSourceFileAtPath(importPath);
|
444 | if (sourceFileImport) {
|
445 | fileToSearchIn = sourceFileImport;
|
446 | let variableName = foundWithAlias ? aliasOriginalName : metadataVariableName;
|
447 | variableDeclaration = fileToSearchIn.getVariableDeclaration(variableName);
|
448 | }
|
449 | } else {
|
450 | fileToSearchIn = file;
|
451 |
|
452 | variableDeclaration = fileToSearchIn.getVariableDeclaration(metadataVariableName);
|
453 | }
|
454 |
|
455 | if (variableDeclaration) {
|
456 | return this.findInObjectVariableDeclaration(variableDeclaration, variablesAttributes);
|
457 | }
|
458 |
|
459 | if (variablesAttributes.length > 0) {
|
460 | if (typeof fileToSearchIn !== 'undefined') {
|
461 | let val = this.findInEnums(
|
462 | fileToSearchIn,
|
463 | metadataVariableName,
|
464 | variablesAttributes[1]
|
465 | );
|
466 | if (val !== '') {
|
467 | return val;
|
468 | }
|
469 | val = this.findInClasses(
|
470 | fileToSearchIn,
|
471 | metadataVariableName,
|
472 | variablesAttributes[1]
|
473 | );
|
474 | if (val !== '') {
|
475 | return val;
|
476 | }
|
477 | }
|
478 | }
|
479 | }
|
480 | }
|
481 |
|
482 | export default ImportsUtil.getInstance();
|