a zip code crypto-currency system good for red ONLY

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  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. // 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. }
  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. // 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. }
  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; // 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. }
  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. // 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. }
  269. exports.getUpdatedAppNgModuleContentWithDeepLinkConfig = getUpdatedAppNgModuleContentWithDeepLinkConfig;
  270. function 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. }
  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. // 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. }
  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. // 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. }
  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. // 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. }
  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 = '#';