UNPKG

27.4 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var path_1 = require("path");
4var typescript_1 = require("typescript");
5var logger_1 = require("../logger/logger");
6var Constants = require("../util/constants");
7var helpers_1 = require("../util/helpers");
8var typescript_utils_1 = require("../util/typescript-utils");
9function getDeepLinkData(appNgModuleFilePath, fileCache, isAot) {
10 // we only care about analyzing a subset of typescript files, so do that for efficiency
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 // sweet, the page has a DeepLinkDecorator, which means it meets the criteria to process that bad boy
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 // gadzooks, it's a duplicate name
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 // gadzooks, it's a duplicate segment
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}
35exports.getDeepLinkData = getDeepLinkData;
36function filterTypescriptFilesForDeepLinks(fileCache) {
37 return fileCache.getAll().filter(function (file) { return isDeepLinkingFile(file.path); });
38}
39exports.filterTypescriptFilesForDeepLinks = filterTypescriptFilesForDeepLinks;
40function 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}
46exports.isDeepLinkingFile = isDeepLinkingFile;
47function getNgModulePathFromCorrespondingPage(filePath) {
48 var newExtension = helpers_1.getStringPropertyValue(Constants.ENV_NG_MODULE_FILE_NAME_SUFFIX);
49 return helpers_1.changeExtension(filePath, newExtension);
50}
51exports.getNgModulePathFromCorrespondingPage = getNgModulePathFromCorrespondingPage;
52function getRelativePathToPageNgModuleFromAppNgModule(pathToAppNgModule, pathToPageNgModule) {
53 return path_1.relative(path_1.dirname(pathToAppNgModule), pathToPageNgModule);
54}
55exports.getRelativePathToPageNgModuleFromAppNgModule = getRelativePathToPageNgModuleFromAppNgModule;
56function 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 // get the class declaration out of NgModule class content
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}
74exports.getNgModuleDataFromPage = getNgModuleDataFromPage;
75function 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; // TODO this typing got jacked up
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}
118exports.getDeepLinkDecoratorContentForSourceFile = getDeepLinkDecoratorContentForSourceFile;
119function 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}
142function 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}
170function 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}
188exports.hasExistingDeepLinkConfig = hasExistingDeepLinkConfig;
189function 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}
220function 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}
228exports.convertDeepLinkConfigEntriesToString = convertDeepLinkConfigEntriesToString;
229function 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}
234exports.convertDeepLinkEntryToJsObjectString = convertDeepLinkEntryToJsObjectString;
235function 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}
251exports.updateAppNgModuleWithDeepLinkConfig = updateAppNgModuleWithDeepLinkConfig;
252function 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 // we need to add the node
264 return addDeepLinkArgumentToAppNgModule(appNgModuleFileContent, functionCall, deepLinkStringContent);
265 }
266 // we need to replace whatever node exists here with the deeplink config
267 return typescript_utils_1.replaceNode(appNgModuleFilePath, appNgModuleFileContent, functionCall.arguments[2], deepLinkStringContent);
268}
269exports.getUpdatedAppNgModuleContentWithDeepLinkConfig = getUpdatedAppNgModuleContentWithDeepLinkConfig;
270function getUpdatedAppNgModuleFactoryContentWithDeepLinksConfig(appNgModuleFactoryFileContent, deepLinkStringContent) {
271 // tried to do this with typescript API, wasn't clear on how to do it
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}
282exports.getUpdatedAppNgModuleFactoryContentWithDeepLinksConfig = getUpdatedAppNgModuleFactoryContentWithDeepLinksConfig;
283function addDefaultSecondArgumentToAppNgModule(appNgModuleFileContent, ionicModuleForRoot) {
284 var argOneNode = ionicModuleForRoot.arguments[0];
285 var updatedFileContent = typescript_utils_1.appendAfter(appNgModuleFileContent, argOneNode, ', {}');
286 return updatedFileContent;
287}
288exports.addDefaultSecondArgumentToAppNgModule = addDefaultSecondArgumentToAppNgModule;
289function addDeepLinkArgumentToAppNgModule(appNgModuleFileContent, ionicModuleForRoot, deepLinkString) {
290 var argTwoNode = ionicModuleForRoot.arguments[1];
291 var updatedFileContent = typescript_utils_1.appendAfter(appNgModuleFileContent, argTwoNode, ", " + deepLinkString);
292 return updatedFileContent;
293}
294exports.addDeepLinkArgumentToAppNgModule = addDeepLinkArgumentToAppNgModule;
295function 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}
299exports.generateDefaultDeepLinkNgModuleContent = generateDefaultDeepLinkNgModuleContent;
300function purgeDeepLinkDecoratorTSTransform() {
301 return purgeDeepLinkDecoratorTSTransformImpl;
302}
303exports.purgeDeepLinkDecoratorTSTransform = purgeDeepLinkDecoratorTSTransform;
304function 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 // loop over each import and store it
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}
358exports.purgeDeepLinkDecoratorTSTransformImpl = purgeDeepLinkDecoratorTSTransformImpl;
359function 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}
380exports.purgeDeepLinkDecorator = purgeDeepLinkDecorator;
381function 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 // loop over each import and store it
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 // okay, cool. If namedImportStrings is empty, then just remove the entire import statement
402 // otherwise, just replace the named imports with the namedImportStrings separated by a comma
403 if (decoratorIsImported_1) {
404 if (namedImportStrings_1.length) {
405 // okay cool, we only want to remove some of these homies
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 // remove the entire import statement
412 inputText = typescript_utils_1.replaceNode('', inputText, importDeclaration, '');
413 }
414 }
415 }
416 });
417 return inputText;
418}
419exports.purgeDeepLinkImport = purgeDeepLinkImport;
420function 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}
425exports.getInjectDeepLinkConfigTypescriptTransform = getInjectDeepLinkConfigTypescriptTransform;
426function 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 // okay cool, we have the ng module
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 // loop over the parent elements and replace the IonicModule expression with ours'
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}
471exports.injectDeepLinkConfigTypescriptTransform = injectDeepLinkConfigTypescriptTransform;
472var DEEPLINK_DECORATOR_TEXT = 'IonicPage';
473var DEEPLINK_DECORATOR_NAME_ATTRIBUTE = 'name';
474var DEEPLINK_DECORATOR_SEGMENT_ATTRIBUTE = 'segment';
475var DEEPLINK_DECORATOR_PRIORITY_ATTRIBUTE = 'priority';
476var DEEPLINK_DECORATOR_DEFAULT_HISTORY_ATTRIBUTE = 'defaultHistory';
477var NG_MODULE_IMPORT_DECLARATION = 'imports';
478var IONIC_MODULE_NAME = 'IonicModule';
479var FOR_ROOT_METHOD = 'forRoot';
480var LOAD_CHILDREN_SEPARATOR = '#';