@schematics/angular 20.0.0 → 20.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,10 +31,10 @@ function addTsProjectReference(...paths) {
31
31
  };
32
32
  }
33
33
  function default_1(options) {
34
- return async (host, context) => {
34
+ return async (host) => {
35
35
  const { appDir, appRootSelector, componentOptions, folderName, sourceDir } = await getAppOptions(host, options);
36
36
  return (0, schematics_1.chain)([
37
- addAppToWorkspaceFile(options, appDir, folderName),
37
+ addAppToWorkspaceFile(options, appDir),
38
38
  addTsProjectReference('./' + (0, core_1.join)((0, core_1.normalize)(appDir), 'tsconfig.app.json')),
39
39
  options.skipTests || options.minimal
40
40
  ? (0, schematics_1.noop)()
@@ -121,13 +121,27 @@ function addDependenciesToPackageJson(options) {
121
121
  version: latest_versions_1.latestVersions['typescript'],
122
122
  },
123
123
  ].forEach((dependency) => (0, dependencies_1.addPackageJsonDependency)(host, dependency));
124
+ if (!options.zoneless) {
125
+ (0, dependencies_1.addPackageJsonDependency)(host, {
126
+ type: dependencies_1.NodeDependencyType.Default,
127
+ name: 'zone.js',
128
+ version: latest_versions_1.latestVersions['zone.js'],
129
+ });
130
+ }
131
+ if (options.style === schema_1.Style.Less) {
132
+ (0, dependencies_1.addPackageJsonDependency)(host, {
133
+ type: dependencies_1.NodeDependencyType.Dev,
134
+ name: 'less',
135
+ version: latest_versions_1.latestVersions['less'],
136
+ });
137
+ }
124
138
  if (!options.skipInstall) {
125
139
  context.addTask(new tasks_1.NodePackageInstallTask());
126
140
  }
127
141
  return host;
128
142
  };
129
143
  }
130
- function addAppToWorkspaceFile(options, appDir, folderName) {
144
+ function addAppToWorkspaceFile(options, appDir) {
131
145
  let projectRoot = appDir;
132
146
  if (projectRoot) {
133
147
  projectRoot += '/';
@@ -35,16 +35,7 @@ function default_1(options) {
35
35
  if (options.path === undefined) {
36
36
  options.path = (0, workspace_1.buildDefaultPath)(project);
37
37
  }
38
- try {
39
- options.module = (0, find_module_1.findModuleFromOptions)(host, options);
40
- }
41
- catch {
42
- options.module = (0, find_module_1.findModuleFromOptions)(host, {
43
- ...options,
44
- moduleExt: '-module.ts',
45
- routingModuleExt: '-routing-module.ts',
46
- });
47
- }
38
+ options.module = (0, find_module_1.findModuleFromOptions)(host, options);
48
39
  // Schematic templates require a defined type value
49
40
  options.type ??= '';
50
41
  const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
@@ -35,16 +35,7 @@ function default_1(options) {
35
35
  if (options.path === undefined) {
36
36
  options.path = (0, workspace_1.buildDefaultPath)(project);
37
37
  }
38
- try {
39
- options.module = (0, find_module_1.findModuleFromOptions)(host, options);
40
- }
41
- catch {
42
- options.module = (0, find_module_1.findModuleFromOptions)(host, {
43
- ...options,
44
- moduleExt: '-module.ts',
45
- routingModuleExt: '-routing-module.ts',
46
- });
47
- }
38
+ options.module = (0, find_module_1.findModuleFromOptions)(host, options);
48
39
  const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
49
40
  options.name = parsedPath.name;
50
41
  options.path = parsedPath.path;
package/library/index.js CHANGED
@@ -72,7 +72,7 @@ function addDependenciesToPackageJson() {
72
72
  return host;
73
73
  };
74
74
  }
75
- function addLibToWorkspaceFile(options, projectRoot, projectName) {
75
+ function addLibToWorkspaceFile(options, projectRoot, projectName, hasZoneDependency) {
76
76
  return (0, workspace_1.updateWorkspace)((workspace) => {
77
77
  workspace.projects.add({
78
78
  name: projectName,
@@ -97,7 +97,7 @@ function addLibToWorkspaceFile(options, projectRoot, projectName) {
97
97
  builder: workspace_models_1.Builders.BuildKarma,
98
98
  options: {
99
99
  tsConfig: `${projectRoot}/tsconfig.spec.json`,
100
- polyfills: ['zone.js', 'zone.js/testing'],
100
+ polyfills: hasZoneDependency ? ['zone.js', 'zone.js/testing'] : undefined,
101
101
  },
102
102
  },
103
103
  },
@@ -139,9 +139,10 @@ function default_1(options) {
139
139
  }),
140
140
  (0, schematics_1.move)(libDir),
141
141
  ]);
142
+ const hasZoneDependency = (0, dependencies_1.getPackageJsonDependency)(host, 'zone.js') !== null;
142
143
  return (0, schematics_1.chain)([
143
144
  (0, schematics_1.mergeWith)(templateSource),
144
- addLibToWorkspaceFile(options, libDir, packageName),
145
+ addLibToWorkspaceFile(options, libDir, packageName, hasZoneDependency),
145
146
  options.skipPackageJson ? (0, schematics_1.noop)() : addDependenciesToPackageJson(),
146
147
  options.skipTsConfig ? (0, schematics_1.noop)() : updateTsConfig(packageName, './' + distRoot),
147
148
  options.skipTsConfig
@@ -163,6 +163,7 @@ function updateProjects(tree, context) {
163
163
  }
164
164
  // Use @angular/build directly if there is no devkit package usage
165
165
  if (!hasAngularDevkitUsage) {
166
+ const karmaConfigFiles = new Set();
166
167
  for (const [, target] of (0, workspace_1.allWorkspaceTargets)(workspace)) {
167
168
  switch (target.builder) {
168
169
  case workspace_models_1.Builders.Application:
@@ -176,9 +177,14 @@ function updateProjects(tree, context) {
176
177
  break;
177
178
  case workspace_models_1.Builders.Karma:
178
179
  target.builder = '@angular/build:karma';
179
- // Remove "builderMode" option since the builder will always use "application"
180
180
  for (const [, karmaOptions] of (0, workspace_1.allTargetOptions)(target)) {
181
+ // Remove "builderMode" option since the builder will always use "application"
181
182
  delete karmaOptions['builderMode'];
183
+ // Collect custom karma configurations for @angular-devkit/build-angular plugin removal
184
+ const karmaConfig = karmaOptions['karmaConfig'];
185
+ if (karmaConfig && typeof karmaConfig === 'string') {
186
+ karmaConfigFiles.add(karmaConfig);
187
+ }
182
188
  }
183
189
  break;
184
190
  case workspace_models_1.Builders.NgPackagr:
@@ -214,6 +220,29 @@ function updateProjects(tree, context) {
214
220
  existing: dependency_1.ExistingBehavior.Replace,
215
221
  }));
216
222
  }
223
+ for (const karmaConfigFile of karmaConfigFiles) {
224
+ if (!tree.exists(karmaConfigFile)) {
225
+ continue;
226
+ }
227
+ try {
228
+ const originalKarmaConfigText = tree.readText(karmaConfigFile);
229
+ const updatedKarmaConfigText = originalKarmaConfigText
230
+ .replaceAll(`require('@angular-devkit/build-angular/plugins/karma'),`, '')
231
+ .replaceAll(`require('@angular-devkit/build-angular/plugins/karma')`, '');
232
+ if (updatedKarmaConfigText.includes('@angular-devkit/build-angular/plugins')) {
233
+ throw new Error('Migration does not support found usage of "@angular-devkit/build-angular".');
234
+ }
235
+ else {
236
+ tree.overwrite(karmaConfigFile, updatedKarmaConfigText);
237
+ }
238
+ }
239
+ catch (error) {
240
+ const reason = error instanceof Error ? `Reason: ${error.message}` : '';
241
+ context.logger.warn(`Unable to update custom karma configuration file ("${karmaConfigFile}"). ` +
242
+ reason +
243
+ '\nReferences to the "@angular-devkit/build-angular" package within the file may need to be removed manually.');
244
+ }
245
+ }
217
246
  }
218
247
  return (0, schematics_1.chain)(rules);
219
248
  });
package/module/index.js CHANGED
@@ -99,11 +99,11 @@ function addRouteDeclarationToNgModule(options, routingModulePath) {
99
99
  };
100
100
  }
101
101
  function getRoutingModulePath(host, modulePath) {
102
- const routingModulePath = modulePath.endsWith(find_module_1.ROUTING_MODULE_EXT) || modulePath.endsWith('-routing-module.ts')
102
+ const routingModulePath = modulePath.endsWith(find_module_1.ROUTING_MODULE_EXT_LEGACY) || modulePath.endsWith(find_module_1.ROUTING_MODULE_EXT)
103
103
  ? modulePath
104
104
  : modulePath
105
- .replace(find_module_1.MODULE_EXT, find_module_1.ROUTING_MODULE_EXT)
106
- .replace('-module.ts', '-routing-module.ts');
105
+ .replace(find_module_1.MODULE_EXT_LEGACY, find_module_1.ROUTING_MODULE_EXT_LEGACY)
106
+ .replace(find_module_1.MODULE_EXT, find_module_1.ROUTING_MODULE_EXT);
107
107
  return host.exists(routingModulePath) ? routingModulePath : undefined;
108
108
  }
109
109
  function buildRoute(options, modulePath) {
@@ -118,16 +118,7 @@ function default_1(options) {
118
118
  options.path = await (0, workspace_1.createDefaultPath)(host, options.project);
119
119
  }
120
120
  if (options.module) {
121
- try {
122
- options.module = (0, find_module_1.findModuleFromOptions)(host, options);
123
- }
124
- catch {
125
- options.module = (0, find_module_1.findModuleFromOptions)(host, {
126
- ...options,
127
- moduleExt: '-module.ts',
128
- routingModuleExt: '-routing-module.ts',
129
- });
130
- }
121
+ options.module = (0, find_module_1.findModuleFromOptions)(host, options);
131
122
  }
132
123
  let routingModulePath;
133
124
  const isLazyLoadedModuleGen = !!(options.route && options.module);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematics/angular",
3
- "version": "20.0.0",
3
+ "version": "20.0.2",
4
4
  "description": "Schematics specific to Angular",
5
5
  "homepage": "https://github.com/angular/angular-cli",
6
6
  "keywords": [
@@ -22,8 +22,8 @@
22
22
  },
23
23
  "schematics": "./collection.json",
24
24
  "dependencies": {
25
- "@angular-devkit/core": "20.0.0",
26
- "@angular-devkit/schematics": "20.0.0",
25
+ "@angular-devkit/core": "20.0.2",
26
+ "@angular-devkit/schematics": "20.0.2",
27
27
  "jsonc-parser": "3.3.1"
28
28
  },
29
29
  "repository": {
package/pipe/index.js CHANGED
@@ -18,16 +18,7 @@ const workspace_1 = require("../utility/workspace");
18
18
  function default_1(options) {
19
19
  return async (host) => {
20
20
  options.path ??= await (0, workspace_1.createDefaultPath)(host, options.project);
21
- try {
22
- options.module = (0, find_module_1.findModuleFromOptions)(host, options);
23
- }
24
- catch {
25
- options.module = (0, find_module_1.findModuleFromOptions)(host, {
26
- ...options,
27
- moduleExt: '-module.ts',
28
- routingModuleExt: '-routing-module.ts',
29
- });
30
- }
21
+ options.module = (0, find_module_1.findModuleFromOptions)(host, options);
31
22
  const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
32
23
  options.name = parsedPath.name;
33
24
  options.path = parsedPath.path;
@@ -17,8 +17,10 @@ export interface ModuleOptions {
17
17
  routingModuleExt?: string;
18
18
  standalone?: boolean;
19
19
  }
20
- export declare const MODULE_EXT = ".module.ts";
21
- export declare const ROUTING_MODULE_EXT = "-routing.module.ts";
20
+ export declare const MODULE_EXT = "-module.ts";
21
+ export declare const ROUTING_MODULE_EXT = "-routing-module.ts";
22
+ export declare const MODULE_EXT_LEGACY = ".module.ts";
23
+ export declare const ROUTING_MODULE_EXT_LEGACY = "-routing.module.ts";
22
24
  /**
23
25
  * Find the module referred by a set of options passed to the schematics.
24
26
  */
@@ -7,13 +7,15 @@
7
7
  * found in the LICENSE file at https://angular.dev/license
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.ROUTING_MODULE_EXT = exports.MODULE_EXT = void 0;
10
+ exports.ROUTING_MODULE_EXT_LEGACY = exports.MODULE_EXT_LEGACY = exports.ROUTING_MODULE_EXT = exports.MODULE_EXT = void 0;
11
11
  exports.findModuleFromOptions = findModuleFromOptions;
12
12
  exports.findModule = findModule;
13
13
  exports.buildRelativePath = buildRelativePath;
14
14
  const core_1 = require("@angular-devkit/core");
15
- exports.MODULE_EXT = '.module.ts';
16
- exports.ROUTING_MODULE_EXT = '-routing.module.ts';
15
+ exports.MODULE_EXT = '-module.ts';
16
+ exports.ROUTING_MODULE_EXT = '-routing-module.ts';
17
+ exports.MODULE_EXT_LEGACY = '.module.ts';
18
+ exports.ROUTING_MODULE_EXT_LEGACY = '-routing.module.ts';
17
19
  /**
18
20
  * Find the module referred by a set of options passed to the schematics.
19
21
  */
@@ -21,11 +23,9 @@ function findModuleFromOptions(host, options) {
21
23
  if (options.standalone || options.skipImport) {
22
24
  return undefined;
23
25
  }
24
- const moduleExt = options.moduleExt || exports.MODULE_EXT;
25
- const routingModuleExt = options.routingModuleExt || exports.ROUTING_MODULE_EXT;
26
26
  if (!options.module) {
27
27
  const pathToCheck = (options.path || '') + '/' + options.name;
28
- return (0, core_1.normalize)(findModule(host, pathToCheck, moduleExt, routingModuleExt));
28
+ return (0, core_1.normalize)(findModule(host, pathToCheck, options.moduleExt, options.routingModuleExt));
29
29
  }
30
30
  else {
31
31
  const modulePath = (0, core_1.normalize)(`/${options.path}/${options.module}`);
@@ -39,11 +39,18 @@ function findModuleFromOptions(host, options) {
39
39
  candidateSet.add(dir);
40
40
  }
41
41
  const candidatesDirs = [...candidateSet].sort((a, b) => b.length - a.length);
42
+ const candidateFiles = ['', `${moduleBaseName}.ts`];
43
+ if (options.moduleExt) {
44
+ candidateFiles.push(`${moduleBaseName}${options.moduleExt}`);
45
+ }
46
+ else {
47
+ candidateFiles.push(`${moduleBaseName}${exports.MODULE_EXT}`, `${moduleBaseName}${exports.MODULE_EXT_LEGACY}`);
48
+ }
42
49
  for (const c of candidatesDirs) {
43
- const candidateFiles = ['', `${moduleBaseName}.ts`, `${moduleBaseName}${moduleExt}`].map((x) => (0, core_1.join)(c, x));
44
50
  for (const sc of candidateFiles) {
45
- if (host.exists(sc) && host.readText(sc).includes('@NgModule')) {
46
- return (0, core_1.normalize)(sc);
51
+ const scPath = (0, core_1.join)(c, sc);
52
+ if (host.exists(scPath) && host.readText(scPath).includes('@NgModule')) {
53
+ return (0, core_1.normalize)(scPath);
47
54
  }
48
55
  }
49
56
  }
@@ -54,12 +61,16 @@ function findModuleFromOptions(host, options) {
54
61
  /**
55
62
  * Function to find the "closest" module to a generated file's path.
56
63
  */
57
- function findModule(host, generateDir, moduleExt = exports.MODULE_EXT, routingModuleExt = exports.ROUTING_MODULE_EXT) {
64
+ function findModule(host, generateDir, moduleExt, routingModuleExt) {
58
65
  let dir = host.getDir('/' + generateDir);
59
66
  let foundRoutingModule = false;
67
+ const moduleExtensions = moduleExt ? [moduleExt] : [exports.MODULE_EXT, exports.MODULE_EXT_LEGACY];
68
+ const routingModuleExtensions = routingModuleExt
69
+ ? [routingModuleExt]
70
+ : [exports.ROUTING_MODULE_EXT, exports.ROUTING_MODULE_EXT_LEGACY];
60
71
  while (dir) {
61
- const allMatches = dir.subfiles.filter((p) => p.endsWith(moduleExt));
62
- const filteredMatches = allMatches.filter((p) => !p.endsWith(routingModuleExt));
72
+ const allMatches = dir.subfiles.filter((p) => moduleExtensions.some((m) => p.endsWith(m)));
73
+ const filteredMatches = allMatches.filter((p) => !routingModuleExtensions.some((m) => p.endsWith(m)));
63
74
  foundRoutingModule = foundRoutingModule || allMatches.length !== filteredMatches.length;
64
75
  if (filteredMatches.length == 1) {
65
76
  return (0, core_1.join)(dir.path, filteredMatches[0]);
@@ -63,9 +63,15 @@ class JSONFile {
63
63
  tabSize: 2,
64
64
  },
65
65
  });
66
- this.content = (0, jsonc_parser_1.applyEdits)(this.content, edits);
67
- this.host.overwrite(this.path, this.content);
68
- this._jsonAst = undefined;
66
+ if (edits.length > 0) {
67
+ const editedContent = (0, jsonc_parser_1.applyEdits)(this.content, edits);
68
+ // Update the file content if it changed
69
+ if (editedContent !== this.content) {
70
+ this.content = editedContent;
71
+ this.host.overwrite(this.path, editedContent);
72
+ this._jsonAst = undefined;
73
+ }
74
+ }
69
75
  }
70
76
  remove(jsonPath) {
71
77
  if (this.get(jsonPath) !== undefined) {
@@ -16,7 +16,7 @@ exports.latestVersions = {
16
16
  // As Angular CLI works with same minor versions of Angular Framework, a tilde match for the current
17
17
  Angular: '^20.0.0',
18
18
  NgPackagr: '^20.0.0',
19
- DevkitBuildAngular: '^20.0.0',
20
- AngularBuild: '^20.0.0',
21
- AngularSSR: '^20.0.0',
19
+ DevkitBuildAngular: '^20.0.2',
20
+ AngularBuild: '^20.0.2',
21
+ AngularSSR: '^20.0.2',
22
22
  };
@@ -17,8 +17,7 @@
17
17
  "@angular/platform-browser": "<%= latestVersions.Angular %>",
18
18
  "@angular/router": "<%= latestVersions.Angular %>",
19
19
  "rxjs": "<%= latestVersions['rxjs'] %>",
20
- "tslib": "<%= latestVersions['tslib'] %>",
21
- "zone.js": "<%= latestVersions['zone.js'] %>"
20
+ "tslib": "<%= latestVersions['tslib'] %>"
22
21
  },
23
22
  "devDependencies": {
24
23
  "@angular/cli": "<%= '^' + version %>",