find-module.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. "use strict";
  2. /**
  3. * @license
  4. * Copyright Google LLC All Rights Reserved.
  5. *
  6. * Use of this source code is governed by an MIT-style license that can be
  7. * found in the LICENSE file at https://angular.dev/license
  8. */
  9. Object.defineProperty(exports, "__esModule", { value: true });
  10. exports.ROUTING_MODULE_EXT = exports.MODULE_EXT = void 0;
  11. exports.findModuleFromOptions = findModuleFromOptions;
  12. exports.findModule = findModule;
  13. exports.buildRelativePath = buildRelativePath;
  14. const core_1 = require("@angular-devkit/core");
  15. exports.MODULE_EXT = '.module.ts';
  16. exports.ROUTING_MODULE_EXT = '-routing.module.ts';
  17. /**
  18. * Find the module referred by a set of options passed to the schematics.
  19. */
  20. function findModuleFromOptions(host, options) {
  21. if (options.standalone || options.skipImport) {
  22. return undefined;
  23. }
  24. const moduleExt = options.moduleExt || exports.MODULE_EXT;
  25. const routingModuleExt = options.routingModuleExt || exports.ROUTING_MODULE_EXT;
  26. if (!options.module) {
  27. const pathToCheck = (options.path || '') + '/' + options.name;
  28. return (0, core_1.normalize)(findModule(host, pathToCheck, moduleExt, routingModuleExt));
  29. }
  30. else {
  31. const modulePath = (0, core_1.normalize)(`/${options.path}/${options.module}`);
  32. const componentPath = (0, core_1.normalize)(`/${options.path}/${options.name}`);
  33. const moduleBaseName = (0, core_1.normalize)(modulePath).split('/').pop();
  34. const candidateSet = new Set([(0, core_1.normalize)(options.path || '/')]);
  35. for (let dir = modulePath; dir != core_1.NormalizedRoot; dir = (0, core_1.dirname)(dir)) {
  36. candidateSet.add(dir);
  37. }
  38. for (let dir = componentPath; dir != core_1.NormalizedRoot; dir = (0, core_1.dirname)(dir)) {
  39. candidateSet.add(dir);
  40. }
  41. const candidatesDirs = [...candidateSet].sort((a, b) => b.length - a.length);
  42. for (const c of candidatesDirs) {
  43. const candidateFiles = ['', `${moduleBaseName}.ts`, `${moduleBaseName}${moduleExt}`].map((x) => (0, core_1.join)(c, x));
  44. for (const sc of candidateFiles) {
  45. if (host.exists(sc)) {
  46. return (0, core_1.normalize)(sc);
  47. }
  48. }
  49. }
  50. throw new Error(`Specified module '${options.module}' does not exist.\n` +
  51. `Looked in the following directories:\n ${candidatesDirs.join('\n ')}`);
  52. }
  53. }
  54. /**
  55. * Function to find the "closest" module to a generated file's path.
  56. */
  57. function findModule(host, generateDir, moduleExt = exports.MODULE_EXT, routingModuleExt = exports.ROUTING_MODULE_EXT) {
  58. let dir = host.getDir('/' + generateDir);
  59. let foundRoutingModule = false;
  60. while (dir) {
  61. const allMatches = dir.subfiles.filter((p) => p.endsWith(moduleExt));
  62. const filteredMatches = allMatches.filter((p) => !p.endsWith(routingModuleExt));
  63. foundRoutingModule = foundRoutingModule || allMatches.length !== filteredMatches.length;
  64. if (filteredMatches.length == 1) {
  65. return (0, core_1.join)(dir.path, filteredMatches[0]);
  66. }
  67. else if (filteredMatches.length > 1) {
  68. throw new Error(`More than one module matches. Use the '--skip-import' option to skip importing ` +
  69. 'the component into the closest module or use the module option to specify a module.');
  70. }
  71. dir = dir.parent;
  72. }
  73. const errorMsg = foundRoutingModule
  74. ? 'Could not find a non Routing NgModule.' +
  75. `\nModules with suffix '${routingModuleExt}' are strictly reserved for routing.` +
  76. `\nUse the '--skip-import' option to skip importing in NgModule.`
  77. : `Could not find an NgModule. Use the '--skip-import' option to skip importing in NgModule.`;
  78. throw new Error(errorMsg);
  79. }
  80. /**
  81. * Build a relative path from one file path to another file path.
  82. */
  83. function buildRelativePath(from, to) {
  84. from = (0, core_1.normalize)(from);
  85. to = (0, core_1.normalize)(to);
  86. // Convert to arrays.
  87. const fromParts = from.split('/');
  88. const toParts = to.split('/');
  89. // Remove file names (preserving destination)
  90. fromParts.pop();
  91. const toFileName = toParts.pop();
  92. const relativePath = (0, core_1.relative)((0, core_1.normalize)(fromParts.join('/') || '/'), (0, core_1.normalize)(toParts.join('/') || '/'));
  93. let pathPrefix = '';
  94. // Set the path prefix for same dir or child dir, parent dir starts with `..`
  95. if (!relativePath) {
  96. pathPrefix = '.';
  97. }
  98. else if (!relativePath.startsWith('.')) {
  99. pathPrefix = `./`;
  100. }
  101. if (pathPrefix && !pathPrefix.endsWith('/')) {
  102. pathPrefix += '/';
  103. }
  104. return pathPrefix + (relativePath ? relativePath + '/' : '') + toFileName;
  105. }