1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | Object.defineProperty(exports, "__esModule", { value: true });
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | const path_1 = require("path");
|
18 | const ts = require("typescript");
|
19 | const fs_1 = require("fs");
|
20 | const transformers_1 = require("@ngtools/webpack/src/transformers");
|
21 | function getMainModulePath(entryFilePath, tsConfigName) {
|
22 | try {
|
23 |
|
24 | tsConfigName = tsConfigName || "tsconfig.tns.json";
|
25 | const tsModuleName = findBootstrappedModulePath(entryFilePath);
|
26 | const result = tsResolve(tsModuleName, entryFilePath, tsConfigName);
|
27 | return result;
|
28 | }
|
29 | catch (e) {
|
30 | return null;
|
31 | }
|
32 | }
|
33 | exports.getMainModulePath = getMainModulePath;
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | function tsResolve(moduleName, containingFilePath, tsConfigName) {
|
42 | let result = moduleName;
|
43 | try {
|
44 | const parseConfigFileHost = {
|
45 | getCurrentDirectory: ts.sys.getCurrentDirectory,
|
46 | useCaseSensitiveFileNames: false,
|
47 | readDirectory: ts.sys.readDirectory,
|
48 | fileExists: ts.sys.fileExists,
|
49 | readFile: ts.sys.readFile,
|
50 | onUnRecoverableConfigFileDiagnostic: undefined
|
51 | };
|
52 | const tsConfig = ts.getParsedCommandLineOfConfigFile(tsConfigName, ts.getDefaultCompilerOptions(), parseConfigFileHost);
|
53 | const compilerOptions = tsConfig.options || ts.getDefaultCompilerOptions();
|
54 | const moduleResolutionHost = {
|
55 | fileExists: ts.sys.fileExists,
|
56 | readFile: ts.sys.readFile
|
57 | };
|
58 | const resolutionResult = ts.resolveModuleName(moduleName, containingFilePath, compilerOptions, moduleResolutionHost);
|
59 | if (resolutionResult && resolutionResult.resolvedModule && resolutionResult.resolvedModule.resolvedFileName) {
|
60 | result = path_1.relative(path_1.dirname(containingFilePath), resolutionResult.resolvedModule.resolvedFileName);
|
61 | }
|
62 | }
|
63 | catch (err) { }
|
64 | return result;
|
65 | }
|
66 | function findBootstrapModuleCall(mainPath) {
|
67 | const source = getSourceFile(mainPath);
|
68 | return findBootstrapModuleCallInSource(source);
|
69 | }
|
70 | exports.findBootstrapModuleCall = findBootstrapModuleCall;
|
71 | function findBootstrapModuleCallInSource(source) {
|
72 | return findMethodCallInSource(source, "bootstrapModule") || findMethodCallInSource(source, "bootstrapModuleFactory");
|
73 | }
|
74 | exports.findBootstrapModuleCallInSource = findBootstrapModuleCallInSource;
|
75 | function findNativeScriptPlatformCallInSource(source) {
|
76 | return findMethodCallInSource(source, "platformNativeScriptDynamic") || findMethodCallInSource(source, "platformNativeScript");
|
77 | }
|
78 | exports.findNativeScriptPlatformCallInSource = findNativeScriptPlatformCallInSource;
|
79 | function findMethodCallInSource(source, methodName) {
|
80 | const allMethodCalls = transformers_1.collectDeepNodes(source, ts.SyntaxKind.CallExpression);
|
81 | let methodCallNode = null;
|
82 | for (const callNode of allMethodCalls) {
|
83 | const currentMethodName = getExpressionName(callNode.expression);
|
84 | if (methodName === currentMethodName) {
|
85 | methodCallNode = callNode;
|
86 | }
|
87 | }
|
88 | return methodCallNode;
|
89 | }
|
90 | exports.findMethodCallInSource = findMethodCallInSource;
|
91 | function findBootstrappedModulePath(mainPath) {
|
92 | const source = getSourceFile(mainPath);
|
93 | return findBootstrappedModulePathInSource(source);
|
94 | }
|
95 | exports.findBootstrappedModulePath = findBootstrappedModulePath;
|
96 | function findBootstrappedModulePathInSource(source) {
|
97 | const bootstrapCall = findBootstrapModuleCallInSource(source);
|
98 | if (!bootstrapCall) {
|
99 | throw new Error("Bootstrap call not found");
|
100 | }
|
101 | const appModulePath = getExpressionImportPath(source, bootstrapCall.arguments[0]);
|
102 | return appModulePath;
|
103 | }
|
104 | exports.findBootstrappedModulePathInSource = findBootstrappedModulePathInSource;
|
105 | function findNativeScriptPlatformPathInSource(source) {
|
106 | const nsPlatformCall = findNativeScriptPlatformCallInSource(source);
|
107 | if (!nsPlatformCall) {
|
108 | throw new Error("NativeScriptPlatform call not found");
|
109 | }
|
110 | const nsPlatformImportPath = getExpressionImportPath(source, nsPlatformCall.expression);
|
111 | return nsPlatformImportPath;
|
112 | }
|
113 | exports.findNativeScriptPlatformPathInSource = findNativeScriptPlatformPathInSource;
|
114 | function getImportPathInSource(source, importName) {
|
115 | const allImports = transformers_1.collectDeepNodes(source, ts.SyntaxKind.ImportDeclaration);
|
116 | const importPath = allImports
|
117 | .filter(imp => {
|
118 | return findIdentifierNode(imp, importName);
|
119 | })
|
120 | .map((imp) => {
|
121 | const modulePathStringLiteral = imp.moduleSpecifier;
|
122 | return modulePathStringLiteral.text;
|
123 | })[0];
|
124 | return importPath;
|
125 | }
|
126 | function getAppModulePath(mainPath) {
|
127 | const moduleRelativePath = findBootstrappedModulePath(mainPath);
|
128 | const mainDir = path_1.dirname(mainPath);
|
129 | const modulePath = path_1.join(mainDir, `${moduleRelativePath}.ts`);
|
130 | return modulePath;
|
131 | }
|
132 | exports.getAppModulePath = getAppModulePath;
|
133 | function findIdentifierNode(node, text) {
|
134 | if (node.kind === ts.SyntaxKind.Identifier && node.text === text) {
|
135 | return node;
|
136 | }
|
137 | let foundNode = null;
|
138 | ts.forEachChild(node, childNode => {
|
139 | foundNode = foundNode || findIdentifierNode(childNode, text);
|
140 | });
|
141 | return foundNode;
|
142 | }
|
143 | exports.findIdentifierNode = findIdentifierNode;
|
144 | function getObjectPropertyMatches(objectNode, sourceFile, targetPropertyName) {
|
145 | return objectNode.properties
|
146 | .filter(prop => prop.kind == ts.SyntaxKind.PropertyAssignment)
|
147 | .filter((prop) => {
|
148 | const name = prop.name;
|
149 | switch (name.kind) {
|
150 | case ts.SyntaxKind.Identifier:
|
151 | return name.text == targetPropertyName;
|
152 | case ts.SyntaxKind.StringLiteral:
|
153 | return name.text == targetPropertyName;
|
154 | }
|
155 | return false;
|
156 | });
|
157 | }
|
158 | exports.getObjectPropertyMatches = getObjectPropertyMatches;
|
159 | function getDecoratorMetadata(source, identifier, module) {
|
160 | const angularImports = transformers_1.collectDeepNodes(source, ts.SyntaxKind.ImportDeclaration)
|
161 | .map((node) => angularImportsFromNode(node, source))
|
162 | .reduce((acc, current) => {
|
163 | for (const key of Object.keys(current)) {
|
164 | acc[key] = current[key];
|
165 | }
|
166 | return acc;
|
167 | }, {});
|
168 | return transformers_1.collectDeepNodes(source, ts.SyntaxKind.Decorator)
|
169 | .filter(node => {
|
170 | return node.expression.kind == ts.SyntaxKind.CallExpression;
|
171 | })
|
172 | .map(node => node.expression)
|
173 | .filter(expr => {
|
174 | if (expr.expression.kind == ts.SyntaxKind.Identifier) {
|
175 | const id = expr.expression;
|
176 | return id.getFullText(source) == identifier
|
177 | && angularImports[id.getFullText(source)] === module;
|
178 | }
|
179 | else if (expr.expression.kind == ts.SyntaxKind.PropertyAccessExpression) {
|
180 |
|
181 | const paExpr = expr.expression;
|
182 |
|
183 | if (paExpr.expression.kind !== ts.SyntaxKind.Identifier) {
|
184 | return false;
|
185 | }
|
186 | const id = paExpr.name.text;
|
187 | const moduleId = paExpr.expression.text;
|
188 | return id === identifier && (angularImports[moduleId + '.'] === module);
|
189 | }
|
190 | return false;
|
191 | })
|
192 | .filter(expr => expr.arguments[0]
|
193 | && (expr.arguments[0].kind == ts.SyntaxKind.ObjectLiteralExpression ||
|
194 | expr.arguments[0].kind == ts.SyntaxKind.Identifier))
|
195 | .map(expr => expr.arguments[0]);
|
196 | }
|
197 | exports.getDecoratorMetadata = getDecoratorMetadata;
|
198 | function angularImportsFromNode(node, _sourceFile) {
|
199 | const ms = node.moduleSpecifier;
|
200 | let modulePath;
|
201 | switch (ms.kind) {
|
202 | case ts.SyntaxKind.StringLiteral:
|
203 | modulePath = ms.text;
|
204 | break;
|
205 | default:
|
206 | return {};
|
207 | }
|
208 | if (!modulePath.startsWith('@angular/')) {
|
209 | return {};
|
210 | }
|
211 | if (node.importClause) {
|
212 | if (node.importClause.name) {
|
213 |
|
214 | return {};
|
215 | }
|
216 | else if (node.importClause.namedBindings) {
|
217 | const nb = node.importClause.namedBindings;
|
218 | if (nb.kind == ts.SyntaxKind.NamespaceImport) {
|
219 |
|
220 | return {
|
221 | [nb.name.text + '.']: modulePath,
|
222 | };
|
223 | }
|
224 | else {
|
225 |
|
226 | const namedImports = nb;
|
227 | return namedImports.elements
|
228 | .map((is) => is.propertyName ? is.propertyName.text : is.name.text)
|
229 | .reduce((acc, curr) => {
|
230 | acc[curr] = modulePath;
|
231 | return acc;
|
232 | }, {});
|
233 | }
|
234 | }
|
235 | return {};
|
236 | }
|
237 | else {
|
238 |
|
239 | return {};
|
240 | }
|
241 | }
|
242 | exports.angularImportsFromNode = angularImportsFromNode;
|
243 | function getExpressionName(expression) {
|
244 | let text = "";
|
245 | if (!expression) {
|
246 | return text;
|
247 | }
|
248 | if (expression.kind == ts.SyntaxKind.Identifier) {
|
249 | text = expression.text;
|
250 | }
|
251 | else if (expression.kind == ts.SyntaxKind.PropertyAccessExpression) {
|
252 | text = expression.name.text;
|
253 | }
|
254 | return text;
|
255 | }
|
256 | exports.getExpressionName = getExpressionName;
|
257 | function getExpressionImportPath(source, expression) {
|
258 | let importString = "";
|
259 | if (!expression) {
|
260 | return undefined;
|
261 | }
|
262 | if (expression.kind == ts.SyntaxKind.Identifier) {
|
263 | importString = expression.text;
|
264 | }
|
265 | else if (expression.kind == ts.SyntaxKind.PropertyAccessExpression) {
|
266 | const targetPAArg = expression;
|
267 | if (targetPAArg.expression.kind == ts.SyntaxKind.Identifier) {
|
268 | importString = targetPAArg.expression.text;
|
269 | }
|
270 | }
|
271 | const importPath = getImportPathInSource(source, importString);
|
272 | return importPath;
|
273 | }
|
274 | function getSourceFile(mainPath) {
|
275 | if (!fs_1.existsSync(mainPath)) {
|
276 | throw new Error(`Main file (${mainPath}) not found`);
|
277 | }
|
278 | const mainText = fs_1.readFileSync(mainPath, "utf8");
|
279 | const source = ts.createSourceFile(mainPath, mainText, ts.ScriptTarget.Latest, true);
|
280 | return source;
|
281 | }
|
282 |
|
\ | No newline at end of file |