1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var path_1 = require("path");
|
4 | var typescript_1 = require("typescript");
|
5 | var logger_1 = require("../logger/logger");
|
6 | var Constants = require("../util/constants");
|
7 | var helpers_1 = require("../util/helpers");
|
8 | var typescript_utils_1 = require("../util/typescript-utils");
|
9 | function getDeepLinkData(appNgModuleFilePath, fileCache, isAot) {
|
10 |
|
11 | var typescriptFiles = filterTypescriptFilesForDeepLinks(fileCache);
|
12 | var deepLinkConfigEntries = new Map();
|
13 | var segmentSet = new Set();
|
14 | typescriptFiles.forEach(function (file) {
|
15 | var sourceFile = typescript_utils_1.getTypescriptSourceFile(file.path, file.content);
|
16 | var deepLinkDecoratorData = getDeepLinkDecoratorContentForSourceFile(sourceFile);
|
17 | if (deepLinkDecoratorData) {
|
18 |
|
19 | var pathInfo = getNgModuleDataFromPage(appNgModuleFilePath, file.path, deepLinkDecoratorData.className, fileCache, isAot);
|
20 | var deepLinkConfigEntry = Object.assign({}, deepLinkDecoratorData, pathInfo);
|
21 | if (deepLinkConfigEntries.has(deepLinkConfigEntry.name)) {
|
22 |
|
23 | throw new Error("There are multiple entries in the deeplink config with the name of " + deepLinkConfigEntry.name);
|
24 | }
|
25 | if (segmentSet.has(deepLinkConfigEntry.segment)) {
|
26 |
|
27 | throw new Error("There are multiple entries in the deeplink config with the segment of " + deepLinkConfigEntry.segment);
|
28 | }
|
29 | segmentSet.add(deepLinkConfigEntry.segment);
|
30 | deepLinkConfigEntries.set(deepLinkConfigEntry.name, deepLinkConfigEntry);
|
31 | }
|
32 | });
|
33 | return deepLinkConfigEntries;
|
34 | }
|
35 | exports.getDeepLinkData = getDeepLinkData;
|
36 | function filterTypescriptFilesForDeepLinks(fileCache) {
|
37 | return fileCache.getAll().filter(function (file) { return isDeepLinkingFile(file.path); });
|
38 | }
|
39 | exports.filterTypescriptFilesForDeepLinks = filterTypescriptFilesForDeepLinks;
|
40 | function isDeepLinkingFile(filePath) {
|
41 | var deepLinksDir = helpers_1.getStringPropertyValue(Constants.ENV_VAR_DEEPLINKS_DIR) + path_1.sep;
|
42 | var moduleSuffix = helpers_1.getStringPropertyValue(Constants.ENV_NG_MODULE_FILE_NAME_SUFFIX);
|
43 | var result = path_1.extname(filePath) === '.ts' && filePath.indexOf(moduleSuffix) === -1 && filePath.indexOf(deepLinksDir) >= 0;
|
44 | return result;
|
45 | }
|
46 | exports.isDeepLinkingFile = isDeepLinkingFile;
|
47 | function getNgModulePathFromCorrespondingPage(filePath) {
|
48 | var newExtension = helpers_1.getStringPropertyValue(Constants.ENV_NG_MODULE_FILE_NAME_SUFFIX);
|
49 | return helpers_1.changeExtension(filePath, newExtension);
|
50 | }
|
51 | exports.getNgModulePathFromCorrespondingPage = getNgModulePathFromCorrespondingPage;
|
52 | function getRelativePathToPageNgModuleFromAppNgModule(pathToAppNgModule, pathToPageNgModule) {
|
53 | return path_1.relative(path_1.dirname(pathToAppNgModule), pathToPageNgModule);
|
54 | }
|
55 | exports.getRelativePathToPageNgModuleFromAppNgModule = getRelativePathToPageNgModuleFromAppNgModule;
|
56 | function getNgModuleDataFromPage(appNgModuleFilePath, filePath, className, fileCache, isAot) {
|
57 | var ngModulePath = getNgModulePathFromCorrespondingPage(filePath);
|
58 | var ngModuleFile = fileCache.get(ngModulePath);
|
59 | if (!ngModuleFile) {
|
60 | throw new Error(filePath + " has a @IonicPage decorator, but it does not have a corresponding \"NgModule\" at " + ngModulePath);
|
61 | }
|
62 |
|
63 | var exportedClassName = typescript_utils_1.getNgModuleClassName(ngModuleFile.path, ngModuleFile.content);
|
64 | var relativePathToAppNgModule = getRelativePathToPageNgModuleFromAppNgModule(appNgModuleFilePath, ngModulePath);
|
65 | var absolutePath = isAot ? helpers_1.changeExtension(ngModulePath, '.ngfactory.js') : helpers_1.changeExtension(ngModulePath, '.ts');
|
66 | var userlandModulePath = isAot ? helpers_1.changeExtension(relativePathToAppNgModule, '.ngfactory') : helpers_1.changeExtension(relativePathToAppNgModule, '');
|
67 | var namedExport = isAot ? exportedClassName + "NgFactory" : exportedClassName;
|
68 | return {
|
69 | absolutePath: absolutePath,
|
70 | userlandModulePath: helpers_1.toUnixPath(userlandModulePath),
|
71 | className: namedExport
|
72 | };
|
73 | }
|
74 | exports.getNgModuleDataFromPage = getNgModuleDataFromPage;
|
75 | function getDeepLinkDecoratorContentForSourceFile(sourceFile) {
|
76 | var classDeclarations = typescript_utils_1.getClassDeclarations(sourceFile);
|
77 | var defaultSegment = path_1.basename(helpers_1.changeExtension(sourceFile.fileName, ''));
|
78 | var list = [];
|
79 | classDeclarations.forEach(function (classDeclaration) {
|
80 | if (classDeclaration.decorators) {
|
81 | classDeclaration.decorators.forEach(function (decorator) {
|
82 | var className = classDeclaration.name.text;
|
83 | if (decorator.expression && decorator.expression.expression && decorator.expression.expression.text === DEEPLINK_DECORATOR_TEXT) {
|
84 | var deepLinkArgs = decorator.expression.arguments;
|
85 | var deepLinkObject = null;
|
86 | if (deepLinkArgs && deepLinkArgs.length) {
|
87 | deepLinkObject = deepLinkArgs[0];
|
88 | }
|
89 | var propertyList = [];
|
90 | if (deepLinkObject && deepLinkObject.properties) {
|
91 | propertyList = deepLinkObject.properties;
|
92 | }
|
93 | var deepLinkName = getStringValueFromDeepLinkDecorator(sourceFile, propertyList, className, DEEPLINK_DECORATOR_NAME_ATTRIBUTE);
|
94 | var deepLinkSegment = getStringValueFromDeepLinkDecorator(sourceFile, propertyList, defaultSegment, DEEPLINK_DECORATOR_SEGMENT_ATTRIBUTE);
|
95 | var deepLinkPriority = getStringValueFromDeepLinkDecorator(sourceFile, propertyList, 'low', DEEPLINK_DECORATOR_PRIORITY_ATTRIBUTE);
|
96 | var deepLinkDefaultHistory = getArrayValueFromDeepLinkDecorator(sourceFile, propertyList, [], DEEPLINK_DECORATOR_DEFAULT_HISTORY_ATTRIBUTE);
|
97 | var rawStringContent = typescript_utils_1.getNodeStringContent(sourceFile, decorator.expression);
|
98 | list.push({
|
99 | name: deepLinkName,
|
100 | segment: deepLinkSegment,
|
101 | priority: deepLinkPriority,
|
102 | defaultHistory: deepLinkDefaultHistory,
|
103 | rawString: rawStringContent,
|
104 | className: className
|
105 | });
|
106 | }
|
107 | });
|
108 | }
|
109 | });
|
110 | if (list.length > 1) {
|
111 | throw new Error('Only one @IonicPage decorator is allowed per file.');
|
112 | }
|
113 | if (list.length === 1) {
|
114 | return list[0];
|
115 | }
|
116 | return null;
|
117 | }
|
118 | exports.getDeepLinkDecoratorContentForSourceFile = getDeepLinkDecoratorContentForSourceFile;
|
119 | function getStringValueFromDeepLinkDecorator(sourceFile, propertyNodeList, defaultValue, identifierToLookFor) {
|
120 | try {
|
121 | var valueToReturn_1 = defaultValue;
|
122 | logger_1.Logger.debug("[DeepLinking util] getNameValueFromDeepLinkDecorator: Setting default deep link " + identifierToLookFor + " to " + defaultValue);
|
123 | propertyNodeList.forEach(function (propertyNode) {
|
124 | if (propertyNode && propertyNode.name && propertyNode.name.text === identifierToLookFor) {
|
125 | var initializer = propertyNode.initializer;
|
126 | var stringContent = typescript_utils_1.getNodeStringContent(sourceFile, initializer);
|
127 | stringContent = helpers_1.replaceAll(stringContent, '\'', '');
|
128 | stringContent = helpers_1.replaceAll(stringContent, '`', '');
|
129 | stringContent = helpers_1.replaceAll(stringContent, '"', '');
|
130 | stringContent = stringContent.trim();
|
131 | valueToReturn_1 = stringContent;
|
132 | }
|
133 | });
|
134 | logger_1.Logger.debug("[DeepLinking util] getNameValueFromDeepLinkDecorator: DeepLink " + identifierToLookFor + " set to " + valueToReturn_1);
|
135 | return valueToReturn_1;
|
136 | }
|
137 | catch (ex) {
|
138 | logger_1.Logger.error("Failed to parse the @IonicPage decorator. The " + identifierToLookFor + " must be an array of strings");
|
139 | throw ex;
|
140 | }
|
141 | }
|
142 | function getArrayValueFromDeepLinkDecorator(sourceFile, propertyNodeList, defaultValue, identifierToLookFor) {
|
143 | try {
|
144 | var valueToReturn_2 = defaultValue;
|
145 | logger_1.Logger.debug("[DeepLinking util] getArrayValueFromDeepLinkDecorator: Setting default deep link " + identifierToLookFor + " to " + defaultValue);
|
146 | propertyNodeList.forEach(function (propertyNode) {
|
147 | if (propertyNode && propertyNode.name && propertyNode.name.text === identifierToLookFor) {
|
148 | var initializer = propertyNode.initializer;
|
149 | if (initializer && initializer.elements) {
|
150 | var stringArray = initializer.elements.map(function (element) {
|
151 | var elementText = element.text;
|
152 | elementText = helpers_1.replaceAll(elementText, '\'', '');
|
153 | elementText = helpers_1.replaceAll(elementText, '`', '');
|
154 | elementText = helpers_1.replaceAll(elementText, '"', '');
|
155 | elementText = elementText.trim();
|
156 | return elementText;
|
157 | });
|
158 | valueToReturn_2 = stringArray;
|
159 | }
|
160 | }
|
161 | });
|
162 | logger_1.Logger.debug("[DeepLinking util] getNameValueFromDeepLinkDecorator: DeepLink " + identifierToLookFor + " set to " + valueToReturn_2);
|
163 | return valueToReturn_2;
|
164 | }
|
165 | catch (ex) {
|
166 | logger_1.Logger.error("Failed to parse the @IonicPage decorator. The " + identifierToLookFor + " must be an array of strings");
|
167 | throw ex;
|
168 | }
|
169 | }
|
170 | function hasExistingDeepLinkConfig(appNgModuleFilePath, appNgModuleFileContent) {
|
171 | var sourceFile = typescript_utils_1.getTypescriptSourceFile(appNgModuleFilePath, appNgModuleFileContent);
|
172 | var decorator = typescript_utils_1.getNgModuleDecorator(appNgModuleFilePath, sourceFile);
|
173 | var functionCall = getIonicModuleForRootCall(decorator);
|
174 | if (functionCall.arguments.length <= 2) {
|
175 | return false;
|
176 | }
|
177 | var deepLinkConfigArg = functionCall.arguments[2];
|
178 | if (deepLinkConfigArg.kind === typescript_1.SyntaxKind.NullKeyword || deepLinkConfigArg.kind === typescript_1.SyntaxKind.UndefinedKeyword) {
|
179 | return false;
|
180 | }
|
181 | if (deepLinkConfigArg.kind === typescript_1.SyntaxKind.ObjectLiteralExpression) {
|
182 | return true;
|
183 | }
|
184 | if (deepLinkConfigArg.text && deepLinkConfigArg.text.length > 0) {
|
185 | return true;
|
186 | }
|
187 | }
|
188 | exports.hasExistingDeepLinkConfig = hasExistingDeepLinkConfig;
|
189 | function getIonicModuleForRootCall(decorator) {
|
190 | var argument = typescript_utils_1.getNgModuleObjectLiteralArg(decorator);
|
191 | var properties = argument.properties.filter(function (property) {
|
192 | return property.name.text === NG_MODULE_IMPORT_DECLARATION;
|
193 | });
|
194 | if (properties.length === 0) {
|
195 | throw new Error('Could not find "import" property in NgModule arguments');
|
196 | }
|
197 | if (properties.length > 1) {
|
198 | throw new Error('Found multiple "import" properties in NgModule arguments. Only one is allowed');
|
199 | }
|
200 | var property = properties[0];
|
201 | var importArrayLiteral = property.initializer;
|
202 | var functionsInImport = importArrayLiteral.elements.filter(function (element) {
|
203 | return element.kind === typescript_1.SyntaxKind.CallExpression;
|
204 | });
|
205 | var ionicModuleFunctionCalls = functionsInImport.filter(function (functionNode) {
|
206 | return (functionNode.expression
|
207 | && functionNode.expression.name
|
208 | && functionNode.expression.name.text === FOR_ROOT_METHOD
|
209 | && functionNode.expression.expression
|
210 | && functionNode.expression.expression.text === IONIC_MODULE_NAME);
|
211 | });
|
212 | if (ionicModuleFunctionCalls.length === 0) {
|
213 | throw new Error('Could not find IonicModule.forRoot call in "imports"');
|
214 | }
|
215 | if (ionicModuleFunctionCalls.length > 1) {
|
216 | throw new Error('Found multiple IonicModule.forRoot calls in "imports". Only one is allowed');
|
217 | }
|
218 | return ionicModuleFunctionCalls[0];
|
219 | }
|
220 | function convertDeepLinkConfigEntriesToString(entries) {
|
221 | var individualLinks = [];
|
222 | entries.forEach(function (entry) {
|
223 | individualLinks.push(convertDeepLinkEntryToJsObjectString(entry));
|
224 | });
|
225 | var deepLinkConfigString = "\n{\n links: [\n " + individualLinks.join(',\n ') + "\n ]\n}";
|
226 | return deepLinkConfigString;
|
227 | }
|
228 | exports.convertDeepLinkConfigEntriesToString = convertDeepLinkConfigEntriesToString;
|
229 | function convertDeepLinkEntryToJsObjectString(entry) {
|
230 | var defaultHistoryWithQuotes = entry.defaultHistory.map(function (defaultHistoryEntry) { return "'" + defaultHistoryEntry + "'"; });
|
231 | var segmentString = entry.segment && entry.segment.length ? "'" + entry.segment + "'" : null;
|
232 | return "{ loadChildren: '" + entry.userlandModulePath + LOAD_CHILDREN_SEPARATOR + entry.className + "', name: '" + entry.name + "', segment: " + segmentString + ", priority: '" + entry.priority + "', defaultHistory: [" + defaultHistoryWithQuotes.join(', ') + "] }";
|
233 | }
|
234 | exports.convertDeepLinkEntryToJsObjectString = convertDeepLinkEntryToJsObjectString;
|
235 | function updateAppNgModuleWithDeepLinkConfig(context, deepLinkString, changedFiles) {
|
236 | var appNgModulePath = helpers_1.getStringPropertyValue(Constants.ENV_APP_NG_MODULE_PATH);
|
237 | var appNgModuleFile = context.fileCache.get(appNgModulePath);
|
238 | if (!appNgModuleFile) {
|
239 | throw new Error("App NgModule " + appNgModulePath + " not found in cache");
|
240 | }
|
241 | var updatedAppNgModuleContent = getUpdatedAppNgModuleContentWithDeepLinkConfig(appNgModulePath, appNgModuleFile.content, deepLinkString);
|
242 | context.fileCache.set(appNgModulePath, { path: appNgModulePath, content: updatedAppNgModuleContent });
|
243 | if (changedFiles) {
|
244 | changedFiles.push({
|
245 | event: 'change',
|
246 | filePath: appNgModulePath,
|
247 | ext: path_1.extname(appNgModulePath).toLowerCase()
|
248 | });
|
249 | }
|
250 | }
|
251 | exports.updateAppNgModuleWithDeepLinkConfig = updateAppNgModuleWithDeepLinkConfig;
|
252 | function getUpdatedAppNgModuleContentWithDeepLinkConfig(appNgModuleFilePath, appNgModuleFileContent, deepLinkStringContent) {
|
253 | var sourceFile = typescript_utils_1.getTypescriptSourceFile(appNgModuleFilePath, appNgModuleFileContent);
|
254 | var decorator = typescript_utils_1.getNgModuleDecorator(appNgModuleFilePath, sourceFile);
|
255 | var functionCall = getIonicModuleForRootCall(decorator);
|
256 | if (functionCall.arguments.length === 1) {
|
257 | appNgModuleFileContent = addDefaultSecondArgumentToAppNgModule(appNgModuleFileContent, functionCall);
|
258 | sourceFile = typescript_utils_1.getTypescriptSourceFile(appNgModuleFilePath, appNgModuleFileContent);
|
259 | decorator = typescript_utils_1.getNgModuleDecorator(appNgModuleFilePath, sourceFile);
|
260 | functionCall = getIonicModuleForRootCall(decorator);
|
261 | }
|
262 | if (functionCall.arguments.length === 2) {
|
263 |
|
264 | return addDeepLinkArgumentToAppNgModule(appNgModuleFileContent, functionCall, deepLinkStringContent);
|
265 | }
|
266 |
|
267 | return typescript_utils_1.replaceNode(appNgModuleFilePath, appNgModuleFileContent, functionCall.arguments[2], deepLinkStringContent);
|
268 | }
|
269 | exports.getUpdatedAppNgModuleContentWithDeepLinkConfig = getUpdatedAppNgModuleContentWithDeepLinkConfig;
|
270 | function getUpdatedAppNgModuleFactoryContentWithDeepLinksConfig(appNgModuleFactoryFileContent, deepLinkStringContent) {
|
271 |
|
272 | var regex = /this.*?DeepLinkConfigToken.*?=([\s\S]*?);/g;
|
273 | var results = regex.exec(appNgModuleFactoryFileContent);
|
274 | if (results && results.length === 2) {
|
275 | var actualString = results[0];
|
276 | var chunkToReplace = results[1];
|
277 | var fullStringToReplace = actualString.replace(chunkToReplace, deepLinkStringContent);
|
278 | return appNgModuleFactoryFileContent.replace(actualString, fullStringToReplace);
|
279 | }
|
280 | throw new Error('The RegExp to find the DeepLinkConfigToken did not return valid data');
|
281 | }
|
282 | exports.getUpdatedAppNgModuleFactoryContentWithDeepLinksConfig = getUpdatedAppNgModuleFactoryContentWithDeepLinksConfig;
|
283 | function addDefaultSecondArgumentToAppNgModule(appNgModuleFileContent, ionicModuleForRoot) {
|
284 | var argOneNode = ionicModuleForRoot.arguments[0];
|
285 | var updatedFileContent = typescript_utils_1.appendAfter(appNgModuleFileContent, argOneNode, ', {}');
|
286 | return updatedFileContent;
|
287 | }
|
288 | exports.addDefaultSecondArgumentToAppNgModule = addDefaultSecondArgumentToAppNgModule;
|
289 | function addDeepLinkArgumentToAppNgModule(appNgModuleFileContent, ionicModuleForRoot, deepLinkString) {
|
290 | var argTwoNode = ionicModuleForRoot.arguments[1];
|
291 | var updatedFileContent = typescript_utils_1.appendAfter(appNgModuleFileContent, argTwoNode, ", " + deepLinkString);
|
292 | return updatedFileContent;
|
293 | }
|
294 | exports.addDeepLinkArgumentToAppNgModule = addDeepLinkArgumentToAppNgModule;
|
295 | function generateDefaultDeepLinkNgModuleContent(pageFilePath, className) {
|
296 | var importFrom = path_1.basename(pageFilePath, '.ts');
|
297 | return "\nimport { NgModule } from '@angular/core';\nimport { IonicPageModule } from 'ionic-angular';\nimport { " + className + " } from './" + importFrom + "';\n\n@NgModule({\n declarations: [\n " + className + ",\n ],\n imports: [\n IonicPageModule.forChild(" + className + ")\n ]\n})\nexport class " + className + "Module {}\n\n";
|
298 | }
|
299 | exports.generateDefaultDeepLinkNgModuleContent = generateDefaultDeepLinkNgModuleContent;
|
300 | function purgeDeepLinkDecoratorTSTransform() {
|
301 | return purgeDeepLinkDecoratorTSTransformImpl;
|
302 | }
|
303 | exports.purgeDeepLinkDecoratorTSTransform = purgeDeepLinkDecoratorTSTransform;
|
304 | function purgeDeepLinkDecoratorTSTransformImpl(transformContext) {
|
305 | function visitClassDeclaration(classDeclaration) {
|
306 | var hasDeepLinkDecorator = false;
|
307 | var diffDecorators = [];
|
308 | for (var _i = 0, _a = classDeclaration.decorators || []; _i < _a.length; _i++) {
|
309 | var decorator = _a[_i];
|
310 | if (decorator.expression && decorator.expression.expression
|
311 | && decorator.expression.expression.text === DEEPLINK_DECORATOR_TEXT) {
|
312 | hasDeepLinkDecorator = true;
|
313 | }
|
314 | else {
|
315 | diffDecorators.push(decorator);
|
316 | }
|
317 | }
|
318 | if (hasDeepLinkDecorator) {
|
319 | return typescript_1.updateClassDeclaration(classDeclaration, diffDecorators, classDeclaration.modifiers, classDeclaration.name, classDeclaration.typeParameters, classDeclaration.heritageClauses, classDeclaration.members);
|
320 | }
|
321 | return classDeclaration;
|
322 | }
|
323 | function visitImportDeclaration(importDeclaration, sourceFile) {
|
324 | if (importDeclaration.moduleSpecifier
|
325 | && importDeclaration.moduleSpecifier.text === 'ionic-angular'
|
326 | && importDeclaration.importClause
|
327 | && importDeclaration.importClause.namedBindings
|
328 | && importDeclaration.importClause.namedBindings.elements) {
|
329 |
|
330 | var importSpecifiers_1 = [];
|
331 | importDeclaration.importClause.namedBindings.elements.forEach(function (importSpecifier) {
|
332 | if (importSpecifier.name.text !== DEEPLINK_DECORATOR_TEXT) {
|
333 | importSpecifiers_1.push(importSpecifier);
|
334 | }
|
335 | });
|
336 | var emptyNamedImports = typescript_1.createNamedImports(importSpecifiers_1);
|
337 | var newImportClause = typescript_1.updateImportClause(importDeclaration.importClause, importDeclaration.importClause.name, emptyNamedImports);
|
338 | return typescript_1.updateImportDeclaration(importDeclaration, importDeclaration.decorators, importDeclaration.modifiers, newImportClause, importDeclaration.moduleSpecifier);
|
339 | }
|
340 | return importDeclaration;
|
341 | }
|
342 | function visit(node, sourceFile) {
|
343 | switch (node.kind) {
|
344 | case typescript_1.SyntaxKind.ClassDeclaration:
|
345 | return visitClassDeclaration(node);
|
346 | case typescript_1.SyntaxKind.ImportDeclaration:
|
347 | return visitImportDeclaration(node, sourceFile);
|
348 | default:
|
349 | return typescript_1.visitEachChild(node, function (node) {
|
350 | return visit(node, sourceFile);
|
351 | }, transformContext);
|
352 | }
|
353 | }
|
354 | return function (sourceFile) {
|
355 | return visit(sourceFile, sourceFile);
|
356 | };
|
357 | }
|
358 | exports.purgeDeepLinkDecoratorTSTransformImpl = purgeDeepLinkDecoratorTSTransformImpl;
|
359 | function purgeDeepLinkDecorator(inputText) {
|
360 | var sourceFile = typescript_utils_1.getTypescriptSourceFile('', inputText);
|
361 | var classDeclarations = typescript_utils_1.getClassDeclarations(sourceFile);
|
362 | var toRemove = [];
|
363 | var toReturn = inputText;
|
364 | for (var _i = 0, classDeclarations_1 = classDeclarations; _i < classDeclarations_1.length; _i++) {
|
365 | var classDeclaration = classDeclarations_1[_i];
|
366 | for (var _a = 0, _b = classDeclaration.decorators || []; _a < _b.length; _a++) {
|
367 | var decorator = _b[_a];
|
368 | if (decorator.expression && decorator.expression.expression
|
369 | && decorator.expression.expression.text === DEEPLINK_DECORATOR_TEXT) {
|
370 | toRemove.push(decorator);
|
371 | }
|
372 | }
|
373 | }
|
374 | toRemove.forEach(function (node) {
|
375 | toReturn = typescript_utils_1.replaceNode('', inputText, node, '');
|
376 | });
|
377 | toReturn = purgeDeepLinkImport(toReturn);
|
378 | return toReturn;
|
379 | }
|
380 | exports.purgeDeepLinkDecorator = purgeDeepLinkDecorator;
|
381 | function purgeDeepLinkImport(inputText) {
|
382 | var sourceFile = typescript_utils_1.getTypescriptSourceFile('', inputText);
|
383 | var importDeclarations = typescript_utils_1.findNodes(sourceFile, sourceFile, typescript_1.SyntaxKind.ImportDeclaration);
|
384 | importDeclarations.forEach(function (importDeclaration) {
|
385 | if (importDeclaration.moduleSpecifier
|
386 | && importDeclaration.moduleSpecifier.text === 'ionic-angular'
|
387 | && importDeclaration.importClause
|
388 | && importDeclaration.importClause.namedBindings
|
389 | && importDeclaration.importClause.namedBindings.elements) {
|
390 |
|
391 | var decoratorIsImported_1 = false;
|
392 | var namedImportStrings_1 = [];
|
393 | importDeclaration.importClause.namedBindings.elements.forEach(function (importSpecifier) {
|
394 | if (importSpecifier.name.text === DEEPLINK_DECORATOR_TEXT) {
|
395 | decoratorIsImported_1 = true;
|
396 | }
|
397 | else {
|
398 | namedImportStrings_1.push(importSpecifier.name.text);
|
399 | }
|
400 | });
|
401 |
|
402 |
|
403 | if (decoratorIsImported_1) {
|
404 | if (namedImportStrings_1.length) {
|
405 |
|
406 | var stringRepresentation = namedImportStrings_1.join(', ');
|
407 | var namedImportString = "{ " + stringRepresentation + " }";
|
408 | inputText = typescript_utils_1.replaceNode('', inputText, importDeclaration.importClause.namedBindings, namedImportString);
|
409 | }
|
410 | else {
|
411 |
|
412 | inputText = typescript_utils_1.replaceNode('', inputText, importDeclaration, '');
|
413 | }
|
414 | }
|
415 | }
|
416 | });
|
417 | return inputText;
|
418 | }
|
419 | exports.purgeDeepLinkImport = purgeDeepLinkImport;
|
420 | function getInjectDeepLinkConfigTypescriptTransform() {
|
421 | var deepLinkString = convertDeepLinkConfigEntriesToString(helpers_1.getParsedDeepLinkConfig());
|
422 | var appNgModulePath = helpers_1.toUnixPath(helpers_1.getStringPropertyValue(Constants.ENV_APP_NG_MODULE_PATH));
|
423 | return injectDeepLinkConfigTypescriptTransform(deepLinkString, appNgModulePath);
|
424 | }
|
425 | exports.getInjectDeepLinkConfigTypescriptTransform = getInjectDeepLinkConfigTypescriptTransform;
|
426 | function injectDeepLinkConfigTypescriptTransform(deepLinkString, appNgModuleFilePath) {
|
427 | function visitDecoratorNode(decorator, sourceFile) {
|
428 | if (decorator.expression && decorator.expression.expression && decorator.expression.expression.text === typescript_utils_1.NG_MODULE_DECORATOR_TEXT) {
|
429 |
|
430 | var functionCall = getIonicModuleForRootCall(decorator);
|
431 | var updatedArgs = functionCall.arguments;
|
432 | if (updatedArgs.length === 1) {
|
433 | updatedArgs.push(typescript_1.createIdentifier('{ }'));
|
434 | }
|
435 | if (updatedArgs.length === 2) {
|
436 | updatedArgs.push(typescript_1.createIdentifier(deepLinkString));
|
437 | }
|
438 | functionCall = typescript_1.updateCall(functionCall, functionCall.expression, functionCall.typeArguments, updatedArgs);
|
439 |
|
440 | for (var i = 0; i < (functionCall.parent.elements || []).length; i++) {
|
441 | var element = functionCall.parent.elements[i];
|
442 | if (element.king === typescript_1.SyntaxKind.CallExpression
|
443 | && element.expression
|
444 | && element.expression.expression
|
445 | && element.expression.expression.escapedText === 'IonicModule') {
|
446 | functionCall.parent.elements[i] = functionCall;
|
447 | }
|
448 | }
|
449 | }
|
450 | return decorator;
|
451 | }
|
452 | return function (transformContext) {
|
453 | function visit(node, sourceFile, sourceFilePath) {
|
454 | if (sourceFilePath !== appNgModuleFilePath) {
|
455 | return node;
|
456 | }
|
457 | switch (node.kind) {
|
458 | case typescript_1.SyntaxKind.Decorator:
|
459 | return visitDecoratorNode(node, sourceFile);
|
460 | default:
|
461 | return typescript_1.visitEachChild(node, function (node) {
|
462 | return visit(node, sourceFile, sourceFilePath);
|
463 | }, transformContext);
|
464 | }
|
465 | }
|
466 | return function (sourceFile) {
|
467 | return visit(sourceFile, sourceFile, sourceFile.fileName);
|
468 | };
|
469 | };
|
470 | }
|
471 | exports.injectDeepLinkConfigTypescriptTransform = injectDeepLinkConfigTypescriptTransform;
|
472 | var DEEPLINK_DECORATOR_TEXT = 'IonicPage';
|
473 | var DEEPLINK_DECORATOR_NAME_ATTRIBUTE = 'name';
|
474 | var DEEPLINK_DECORATOR_SEGMENT_ATTRIBUTE = 'segment';
|
475 | var DEEPLINK_DECORATOR_PRIORITY_ATTRIBUTE = 'priority';
|
476 | var DEEPLINK_DECORATOR_DEFAULT_HISTORY_ATTRIBUTE = 'defaultHistory';
|
477 | var NG_MODULE_IMPORT_DECLARATION = 'imports';
|
478 | var IONIC_MODULE_NAME = 'IonicModule';
|
479 | var FOR_ROOT_METHOD = 'forRoot';
|
480 | var LOAD_CHILDREN_SEPARATOR = '#';
|