util.js 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. "use strict";
  2. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  3. return new (P || (P = Promise))(function (resolve, reject) {
  4. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  5. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  6. function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
  7. step((generator = generator.apply(thisArg, _arguments || [])).next());
  8. });
  9. };
  10. var __generator = (this && this.__generator) || function (thisArg, body) {
  11. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  12. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  13. function verb(n) { return function (v) { return step([n, v]); }; }
  14. function step(op) {
  15. if (f) throw new TypeError("Generator is already executing.");
  16. while (_) try {
  17. if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
  18. if (y = 0, t) op = [0, t.value];
  19. switch (op[0]) {
  20. case 0: case 1: t = op; break;
  21. case 4: _.label++; return { value: op[1], done: false };
  22. case 5: _.label++; y = op[1]; op = [0]; continue;
  23. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  24. default:
  25. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  26. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  27. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  28. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  29. if (t[2]) _.ops.pop();
  30. _.trys.pop(); continue;
  31. }
  32. op = body.call(thisArg, _);
  33. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  34. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  35. }
  36. };
  37. Object.defineProperty(exports, "__esModule", { value: true });
  38. var path_1 = require("path");
  39. var fs_1 = require("fs");
  40. var logger_1 = require("../logger/logger");
  41. var helpers_1 = require("../util/helpers");
  42. var Constants = require("../util/constants");
  43. var GeneratorConstants = require("./constants");
  44. var helpers_2 = require("../util/helpers");
  45. var glob_util_1 = require("../util/glob-util");
  46. var helpers_3 = require("../util/helpers");
  47. var typescript_utils_1 = require("../util/typescript-utils");
  48. function hydrateRequest(context, request) {
  49. var hydrated = request;
  50. var suffix = getSuffixFromGeneratorType(context, request.type);
  51. hydrated.className = helpers_3.ensureSuffix(helpers_2.pascalCase(request.name), helpers_2.upperCaseFirst(suffix));
  52. hydrated.fileName = helpers_3.removeSuffix(helpers_2.paramCase(request.name), "-" + helpers_2.paramCase(suffix));
  53. if (request.type === 'pipe')
  54. hydrated.pipeName = helpers_2.camelCase(request.name);
  55. if (!!hydrated.includeNgModule) {
  56. if (hydrated.type === 'tabs') {
  57. hydrated.importStatement = "import { IonicPage, NavController } from 'ionic-angular';";
  58. }
  59. else {
  60. hydrated.importStatement = "import { IonicPage, NavController, NavParams } from 'ionic-angular';";
  61. }
  62. hydrated.ionicPage = '\n@IonicPage()';
  63. }
  64. else {
  65. hydrated.ionicPage = null;
  66. hydrated.importStatement = "import { NavController, NavParams } from 'ionic-angular';";
  67. }
  68. hydrated.dirToRead = path_1.join(helpers_2.getStringPropertyValue(Constants.ENV_VAR_IONIC_ANGULAR_TEMPLATE_DIR), request.type);
  69. var baseDir = getDirToWriteToByType(context, request.type);
  70. hydrated.dirToWrite = path_1.join(baseDir, hydrated.fileName);
  71. return hydrated;
  72. }
  73. exports.hydrateRequest = hydrateRequest;
  74. function createCommonModule(envVar, requestType) {
  75. var className = requestType.charAt(0).toUpperCase() + requestType.slice(1) + 's';
  76. var tmplt = "import { NgModule } from '@angular/core';\n@NgModule({\n\tdeclarations: [],\n\timports: [],\n\texports: []\n})\nexport class " + className + "Module {}\n";
  77. fs_1.writeFileSync(envVar, tmplt);
  78. }
  79. exports.createCommonModule = createCommonModule;
  80. function hydrateTabRequest(context, request) {
  81. var h = hydrateRequest(context, request);
  82. var hydrated = Object.assign({
  83. tabs: request.tabs,
  84. tabContent: '',
  85. tabVariables: '',
  86. tabsImportStatement: '',
  87. }, h);
  88. if (hydrated.includeNgModule) {
  89. hydrated.tabsImportStatement += "import { IonicPage, NavController } from 'ionic-angular';";
  90. }
  91. else {
  92. hydrated.tabsImportStatement += "import { NavController } from 'ionic-angular';";
  93. }
  94. for (var i = 0; i < request.tabs.length; i++) {
  95. var tabVar = helpers_2.camelCase(request.tabs[i].name) + "Root";
  96. if (hydrated.includeNgModule) {
  97. hydrated.tabVariables += " " + tabVar + " = '" + request.tabs[i].className + "'\n";
  98. }
  99. else {
  100. hydrated.tabVariables += " " + tabVar + " = " + request.tabs[i].className + "\n";
  101. }
  102. // If this is the last ion-tab to insert
  103. // then we do not want a new line
  104. if (i === request.tabs.length - 1) {
  105. hydrated.tabContent += " <ion-tab [root]=\"" + tabVar + "\" tabTitle=\"" + helpers_2.sentenceCase(request.tabs[i].name) + "\" tabIcon=\"information-circle\"></ion-tab>";
  106. }
  107. else {
  108. hydrated.tabContent += " <ion-tab [root]=\"" + tabVar + "\" tabTitle=\"" + helpers_2.sentenceCase(request.tabs[i].name) + "\" tabIcon=\"information-circle\"></ion-tab>\n";
  109. }
  110. }
  111. return hydrated;
  112. }
  113. exports.hydrateTabRequest = hydrateTabRequest;
  114. function readTemplates(pathToRead) {
  115. var fileNames = fs_1.readdirSync(pathToRead);
  116. var absolutePaths = fileNames.map(function (fileName) {
  117. return path_1.join(pathToRead, fileName);
  118. });
  119. var filePathToContent = new Map();
  120. var promises = absolutePaths.map(function (absolutePath) {
  121. var promise = helpers_2.readFileAsync(absolutePath);
  122. promise.then(function (fileContent) {
  123. filePathToContent.set(absolutePath, fileContent);
  124. });
  125. return promise;
  126. });
  127. return Promise.all(promises).then(function () {
  128. return filePathToContent;
  129. });
  130. }
  131. exports.readTemplates = readTemplates;
  132. function filterOutTemplates(request, templates) {
  133. var templatesToUseMap = new Map();
  134. templates.forEach(function (fileContent, filePath) {
  135. var newFileExtension = path_1.basename(filePath, GeneratorConstants.KNOWN_FILE_EXTENSION);
  136. var shouldSkip = (!request.includeNgModule && newFileExtension === GeneratorConstants.NG_MODULE_FILE_EXTENSION) || (!request.includeSpec && newFileExtension === GeneratorConstants.SPEC_FILE_EXTENSION);
  137. if (!shouldSkip) {
  138. templatesToUseMap.set(filePath, fileContent);
  139. }
  140. });
  141. return templatesToUseMap;
  142. }
  143. exports.filterOutTemplates = filterOutTemplates;
  144. function applyTemplates(request, templates) {
  145. var appliedTemplateMap = new Map();
  146. templates.forEach(function (fileContent, filePath) {
  147. fileContent = helpers_2.replaceAll(fileContent, GeneratorConstants.CLASSNAME_VARIABLE, request.className);
  148. fileContent = helpers_2.replaceAll(fileContent, GeneratorConstants.PIPENAME_VARIABLE, request.pipeName);
  149. fileContent = helpers_2.replaceAll(fileContent, GeneratorConstants.IMPORTSTATEMENT_VARIABLE, request.importStatement);
  150. fileContent = helpers_2.replaceAll(fileContent, GeneratorConstants.IONICPAGE_VARIABLE, request.ionicPage);
  151. fileContent = helpers_2.replaceAll(fileContent, GeneratorConstants.FILENAME_VARIABLE, request.fileName);
  152. fileContent = helpers_2.replaceAll(fileContent, GeneratorConstants.SUPPLIEDNAME_VARIABLE, request.name);
  153. fileContent = helpers_2.replaceAll(fileContent, GeneratorConstants.TAB_CONTENT_VARIABLE, request.tabContent);
  154. fileContent = helpers_2.replaceAll(fileContent, GeneratorConstants.TAB_VARIABLES_VARIABLE, request.tabVariables);
  155. fileContent = helpers_2.replaceAll(fileContent, GeneratorConstants.TABS_IMPORTSTATEMENT_VARIABLE, request.tabsImportStatement);
  156. appliedTemplateMap.set(filePath, fileContent);
  157. });
  158. return appliedTemplateMap;
  159. }
  160. exports.applyTemplates = applyTemplates;
  161. function writeGeneratedFiles(request, processedTemplates) {
  162. var promises = [];
  163. var createdFileList = [];
  164. processedTemplates.forEach(function (fileContent, filePath) {
  165. var newFileExtension = path_1.basename(filePath, GeneratorConstants.KNOWN_FILE_EXTENSION);
  166. var newFileName = request.fileName + "." + newFileExtension;
  167. var fileToWrite = path_1.join(request.dirToWrite, newFileName);
  168. createdFileList.push(fileToWrite);
  169. promises.push(createDirAndWriteFile(fileToWrite, fileContent));
  170. });
  171. return Promise.all(promises).then(function () {
  172. return createdFileList;
  173. });
  174. }
  175. exports.writeGeneratedFiles = writeGeneratedFiles;
  176. function createDirAndWriteFile(filePath, fileContent) {
  177. var directory = path_1.dirname(filePath);
  178. return helpers_2.mkDirpAsync(directory).then(function () {
  179. return helpers_2.writeFileAsync(filePath, fileContent);
  180. });
  181. }
  182. function getNgModules(context, types) {
  183. var ngModuleSuffix = helpers_2.getStringPropertyValue(Constants.ENV_NG_MODULE_FILE_NAME_SUFFIX);
  184. var patterns = types.map(function (type) { return path_1.join(getDirToWriteToByType(context, type), '**', "*" + ngModuleSuffix); });
  185. return glob_util_1.globAll(patterns);
  186. }
  187. exports.getNgModules = getNgModules;
  188. function getSuffixFromGeneratorType(context, type) {
  189. if (type === Constants.COMPONENT) {
  190. return 'Component';
  191. }
  192. else if (type === Constants.DIRECTIVE) {
  193. return 'Directive';
  194. }
  195. else if (type === Constants.PAGE || type === Constants.TABS) {
  196. return 'Page';
  197. }
  198. else if (type === Constants.PIPE) {
  199. return 'Pipe';
  200. }
  201. else if (type === Constants.PROVIDER) {
  202. return 'Provider';
  203. }
  204. throw new Error("Unknown Generator Type: " + type);
  205. }
  206. function getDirToWriteToByType(context, type) {
  207. if (type === Constants.COMPONENT) {
  208. return context.componentsDir;
  209. }
  210. else if (type === Constants.DIRECTIVE) {
  211. return context.directivesDir;
  212. }
  213. else if (type === Constants.PAGE || type === Constants.TABS) {
  214. return context.pagesDir;
  215. }
  216. else if (type === Constants.PIPE) {
  217. return context.pipesDir;
  218. }
  219. else if (type === Constants.PROVIDER) {
  220. return context.providersDir;
  221. }
  222. throw new Error("Unknown Generator Type: " + type);
  223. }
  224. exports.getDirToWriteToByType = getDirToWriteToByType;
  225. function nonPageFileManipulation(context, name, ngModulePath, type) {
  226. return __awaiter(this, void 0, void 0, function () {
  227. var hydratedRequest, envVar, importPath, fileContent, templatesArray, typescriptFilePath;
  228. return __generator(this, function (_a) {
  229. switch (_a.label) {
  230. case 0:
  231. hydratedRequest = hydrateRequest(context, { type: type, name: name });
  232. envVar = helpers_2.getStringPropertyValue("IONIC_" + hydratedRequest.type.toUpperCase() + "S_NG_MODULE_PATH");
  233. return [4 /*yield*/, generateTemplates(context, hydratedRequest, false)];
  234. case 1:
  235. templatesArray = _a.sent();
  236. if (hydratedRequest.type === 'pipe' || hydratedRequest.type === 'component' || hydratedRequest.type === 'directive') {
  237. if (!fs_1.existsSync(envVar))
  238. createCommonModule(envVar, hydratedRequest.type);
  239. }
  240. typescriptFilePath = helpers_3.changeExtension(templatesArray.filter(function (path) { return path_1.extname(path) === '.ts'; })[0], '');
  241. helpers_2.readFileAsync(ngModulePath).then(function (content) {
  242. importPath = type === 'pipe' || type === 'component' || type === 'directive'
  243. ? helpers_1.toUnixPath("./" + path_1.relative(path_1.dirname(ngModulePath), hydratedRequest.dirToWrite) + path_1.sep + hydratedRequest.fileName)
  244. : helpers_1.toUnixPath("" + path_1.relative(path_1.dirname(ngModulePath), hydratedRequest.dirToWrite) + path_1.sep + hydratedRequest.fileName);
  245. content = typescript_utils_1.insertNamedImportIfNeeded(ngModulePath, content, hydratedRequest.className, importPath);
  246. if (type === 'pipe' || type === 'component' || type === 'directive') {
  247. content = typescript_utils_1.appendNgModuleDeclaration(ngModulePath, content, hydratedRequest.className);
  248. content = typescript_utils_1.appendNgModuleExports(ngModulePath, content, hydratedRequest.className);
  249. }
  250. if (type === 'provider') {
  251. content = typescript_utils_1.appendNgModuleProvider(ngModulePath, content, hydratedRequest.className);
  252. }
  253. return helpers_2.writeFileAsync(ngModulePath, content);
  254. });
  255. return [2 /*return*/];
  256. }
  257. });
  258. });
  259. }
  260. exports.nonPageFileManipulation = nonPageFileManipulation;
  261. function tabsModuleManipulation(tabs, hydratedRequest, tabHydratedRequests) {
  262. tabHydratedRequests.forEach(function (tabRequest, index) {
  263. tabRequest.generatedFileNames = tabs[index];
  264. });
  265. var ngModulePath = tabs[0].find(function (element) { return element.indexOf('module') !== -1; });
  266. if (!ngModulePath) {
  267. // Static imports
  268. var tabsPath_1 = path_1.join(hydratedRequest.dirToWrite, hydratedRequest.fileName + ".ts");
  269. var modifiedContent_1 = null;
  270. return helpers_2.readFileAsync(tabsPath_1).then(function (content) {
  271. tabHydratedRequests.forEach(function (tabRequest) {
  272. var typescriptFilePath = helpers_3.changeExtension(tabRequest.generatedFileNames.filter(function (path) { return path_1.extname(path) === '.ts'; })[0], '');
  273. var importPath = helpers_1.toUnixPath(path_1.relative(path_1.dirname(tabsPath_1), typescriptFilePath));
  274. modifiedContent_1 = typescript_utils_1.insertNamedImportIfNeeded(tabsPath_1, content, tabRequest.className, importPath);
  275. content = modifiedContent_1;
  276. });
  277. return helpers_2.writeFileAsync(tabsPath_1, modifiedContent_1);
  278. });
  279. }
  280. }
  281. exports.tabsModuleManipulation = tabsModuleManipulation;
  282. function generateTemplates(context, request, includePageConstants) {
  283. logger_1.Logger.debug('[Generators] generateTemplates: Reading templates ...');
  284. var pageConstantFile = path_1.join(context.pagesDir, 'pages.constants.ts');
  285. if (includePageConstants && !fs_1.existsSync(pageConstantFile))
  286. createPageConstants(context);
  287. return readTemplates(request.dirToRead).then(function (map) {
  288. logger_1.Logger.debug('[Generators] generateTemplates: Filtering out NgModule and Specs if needed ...');
  289. return filterOutTemplates(request, map);
  290. }).then(function (filteredMap) {
  291. logger_1.Logger.debug('[Generators] generateTemplates: Applying templates ...');
  292. var appliedTemplateMap = applyTemplates(request, filteredMap);
  293. logger_1.Logger.debug('[Generators] generateTemplates: Writing generated files to disk ...');
  294. // Adding const to gets some type completion
  295. if (includePageConstants)
  296. createConstStatments(pageConstantFile, request);
  297. return writeGeneratedFiles(request, appliedTemplateMap);
  298. });
  299. }
  300. exports.generateTemplates = generateTemplates;
  301. function createConstStatments(pageConstantFile, request) {
  302. helpers_2.readFileAsync(pageConstantFile).then(function (content) {
  303. content += "\nexport const " + helpers_2.constantCase(request.className) + " = '" + request.className + "';";
  304. helpers_2.writeFileAsync(pageConstantFile, content);
  305. });
  306. }
  307. exports.createConstStatments = createConstStatments;
  308. function createPageConstants(context) {
  309. var pageConstantFile = path_1.join(context.pagesDir, 'pages.constants.ts');
  310. helpers_2.writeFileAsync(pageConstantFile, '//Constants for getting type references');
  311. }
  312. exports.createPageConstants = createPageConstants;