@angular/core 20.0.0-next.1 → 20.0.0-next.3

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.
Files changed (54) hide show
  1. package/fesm2022/core.mjs +770 -2144
  2. package/fesm2022/core.mjs.map +1 -1
  3. package/fesm2022/primitives/di.mjs +3 -2
  4. package/fesm2022/primitives/di.mjs.map +1 -1
  5. package/fesm2022/primitives/event-dispatch.mjs +2 -589
  6. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  7. package/fesm2022/primitives/signals.mjs +44 -13
  8. package/fesm2022/primitives/signals.mjs.map +1 -1
  9. package/fesm2022/rxjs-interop.mjs +7 -39
  10. package/fesm2022/rxjs-interop.mjs.map +1 -1
  11. package/fesm2022/testing.mjs +116 -143
  12. package/fesm2022/testing.mjs.map +1 -1
  13. package/fesm2022/weak_ref-DrMdAIDh.mjs +12 -0
  14. package/fesm2022/weak_ref-DrMdAIDh.mjs.map +1 -0
  15. package/index.d.ts +14366 -15214
  16. package/navigation_types.d-u4EOrrdZ.d.ts +121 -0
  17. package/package.json +2 -2
  18. package/primitives/di/index.d.ts +66 -59
  19. package/primitives/event-dispatch/index.d.ts +205 -309
  20. package/primitives/signals/index.d.ts +161 -195
  21. package/rxjs-interop/index.d.ts +71 -100
  22. package/schematics/bundles/{apply_import_manager-e2a7fe5b.js → apply_import_manager-BXQEjo09.js} +15 -19
  23. package/schematics/bundles/{checker-af521da6.js → checker-BHb19MHt.js} +3695 -1175
  24. package/schematics/bundles/cleanup-unused-imports.js +56 -89
  25. package/schematics/bundles/{compiler_host-5a29293c.js → compiler_host-Bk3repE2.js} +19 -23
  26. package/schematics/bundles/control-flow-migration.js +81 -38
  27. package/schematics/bundles/{imports-047fbbc8.js → imports-CIX-JgAN.js} +9 -14
  28. package/schematics/bundles/{index-1bef3025.js → index-BL9kAIe5.js} +62 -66
  29. package/schematics/bundles/{program-a449f9bf.js → index-I8VbxQcO.js} +1508 -3178
  30. package/schematics/bundles/inject-flags.js +147 -0
  31. package/schematics/bundles/inject-migration.js +121 -127
  32. package/schematics/bundles/{leading_space-f8944434.js → leading_space-D9nQ8UQC.js} +1 -1
  33. package/schematics/bundles/{migrate_ts_type_references-2a3e9e6b.js → migrate_ts_type_references-KlOTWeDl.js} +121 -126
  34. package/schematics/bundles/{ng_decorators-b0d8b324.js → ng_decorators-DznZ5jMl.js} +4 -8
  35. package/schematics/bundles/{nodes-7758dbf6.js → nodes-B16H9JUd.js} +2 -6
  36. package/schematics/bundles/output-migration.js +94 -128
  37. package/schematics/bundles/{project_tsconfig_paths-b558633b.js → project_tsconfig_paths-CDVxT6Ov.js} +1 -1
  38. package/schematics/bundles/{property_name-ac18447e.js → property_name-BBwFuqMe.js} +3 -7
  39. package/schematics/bundles/route-lazy-loading.js +35 -41
  40. package/schematics/bundles/{project_paths-17dc204d.js → run_in_devkit-C0JPtK2u.js} +283 -216
  41. package/schematics/bundles/self-closing-tags-migration.js +55 -91
  42. package/schematics/bundles/signal-input-migration.js +121 -156
  43. package/schematics/bundles/signal-queries-migration.js +119 -154
  44. package/schematics/bundles/signals.js +12 -14
  45. package/schematics/bundles/standalone-migration.js +180 -200
  46. package/schematics/bundles/symbol-VPWguRxr.js +25 -0
  47. package/schematics/bundles/test-bed-get.js +98 -0
  48. package/schematics/migrations.json +8 -14
  49. package/testing/index.d.ts +289 -471
  50. package/weak_ref.d-ttyj86RV.d.ts +9 -0
  51. package/schematics/bundles/explicit-standalone-flag.js +0 -184
  52. package/schematics/bundles/index-ef1bffbb.js +0 -30
  53. package/schematics/bundles/pending-tasks.js +0 -103
  54. package/schematics/bundles/provide-initializer.js +0 -186
@@ -1,42 +1,35 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.1
3
+ * @license Angular v20.0.0-next.3
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
8
 
9
- Object.defineProperty(exports, '__esModule', { value: true });
10
-
11
- var schematics = require('@angular-devkit/schematics');
12
- var project_tsconfig_paths = require('./project_tsconfig_paths-b558633b.js');
13
- var project_paths = require('./project_paths-17dc204d.js');
14
- require('os');
15
9
  var ts = require('typescript');
16
- var checker = require('./checker-af521da6.js');
17
- var program = require('./program-a449f9bf.js');
10
+ require('os');
11
+ var checker = require('./checker-BHb19MHt.js');
12
+ var index = require('./index-I8VbxQcO.js');
18
13
  require('path');
19
- require('./index-ef1bffbb.js');
20
- var apply_import_manager = require('./apply_import_manager-e2a7fe5b.js');
14
+ var run_in_devkit = require('./run_in_devkit-C0JPtK2u.js');
15
+ var apply_import_manager = require('./apply_import_manager-BXQEjo09.js');
21
16
  require('@angular-devkit/core');
22
17
  require('node:path/posix');
23
18
  require('fs');
24
19
  require('module');
25
20
  require('url');
26
-
27
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
28
-
29
- var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
21
+ require('@angular-devkit/schematics');
22
+ require('./project_tsconfig_paths-CDVxT6Ov.js');
30
23
 
31
24
  /** Migration that cleans up unused imports from a project. */
32
- class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
33
- printer = ts__default["default"].createPrinter();
25
+ class UnusedImportsMigration extends run_in_devkit.TsurgeFunnelMigration {
26
+ printer = ts.createPrinter();
34
27
  createProgram(tsconfigAbsPath, fs) {
35
28
  return super.createProgram(tsconfigAbsPath, fs, {
36
29
  extendedDiagnostics: {
37
30
  checks: {
38
31
  // Ensure that the diagnostic is enabled.
39
- unusedStandaloneImports: program.DiagnosticCategoryLabel.Warning,
32
+ unusedStandaloneImports: index.DiagnosticCategoryLabel.Warning,
40
33
  },
41
34
  },
42
35
  });
@@ -68,10 +61,10 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
68
61
  }
69
62
  this.generateReplacements(sourceFile, resolvedLocations, usageAnalysis, info, replacements);
70
63
  });
71
- return project_paths.confirmAsSerializable({ replacements, removedIdentifiers, changedFiles });
64
+ return run_in_devkit.confirmAsSerializable({ replacements, removedIdentifiers, changedFiles });
72
65
  }
73
66
  async migrate(globalData) {
74
- return project_paths.confirmAsSerializable(globalData);
67
+ return run_in_devkit.confirmAsSerializable(globalData);
75
68
  }
76
69
  async combine(unitA, unitB) {
77
70
  const combinedReplacements = [];
@@ -95,14 +88,14 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
95
88
  }
96
89
  }
97
90
  });
98
- return project_paths.confirmAsSerializable({
91
+ return run_in_devkit.confirmAsSerializable({
99
92
  replacements: combinedReplacements,
100
93
  removedIdentifiers: combinedRemovedIdentifiers,
101
94
  changedFiles: changedFileIds.size,
102
95
  });
103
96
  }
104
97
  async globalMeta(combinedData) {
105
- return project_paths.confirmAsSerializable(combinedData);
98
+ return run_in_devkit.confirmAsSerializable(combinedData);
106
99
  }
107
100
  async stats(globalMetadata) {
108
101
  return {
@@ -133,7 +126,7 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
133
126
  allRemovedIdentifiers: new Set(),
134
127
  };
135
128
  const walk = (node) => {
136
- if (!ts__default["default"].isIdentifier(node)) {
129
+ if (!ts.isIdentifier(node)) {
137
130
  node.forEachChild(walk);
138
131
  return;
139
132
  }
@@ -145,17 +138,17 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
145
138
  if (locations.has(this.getNodeID(node.getStart(), node.getWidth()))) {
146
139
  // When the entire array needs to be cleared, the diagnostic is
147
140
  // reported on the property assignment, rather than an array element.
148
- if (ts__default["default"].isPropertyAssignment(parent) &&
141
+ if (ts.isPropertyAssignment(parent) &&
149
142
  parent.name === node &&
150
- ts__default["default"].isArrayLiteralExpression(parent.initializer)) {
143
+ ts.isArrayLiteralExpression(parent.initializer)) {
151
144
  result.fullRemovals.add(parent.initializer);
152
145
  parent.initializer.elements.forEach((element) => {
153
- if (ts__default["default"].isIdentifier(element)) {
146
+ if (ts.isIdentifier(element)) {
154
147
  result.allRemovedIdentifiers.add(element);
155
148
  }
156
149
  });
157
150
  }
158
- else if (ts__default["default"].isArrayLiteralExpression(parent)) {
151
+ else if (ts.isArrayLiteralExpression(parent)) {
159
152
  if (!result.partialRemovals.has(parent)) {
160
153
  result.partialRemovals.set(parent, new Set());
161
154
  }
@@ -179,24 +172,24 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
179
172
  identifierCounts: new Map(),
180
173
  };
181
174
  const walk = (node) => {
182
- if (ts__default["default"].isIdentifier(node) &&
175
+ if (ts.isIdentifier(node) &&
183
176
  node.parent &&
184
177
  // Don't track individual identifiers marked for removal.
185
- (!ts__default["default"].isArrayLiteralExpression(node.parent) ||
178
+ (!ts.isArrayLiteralExpression(node.parent) ||
186
179
  !partialRemovals.has(node.parent) ||
187
180
  !partialRemovals.get(node.parent).has(node))) {
188
181
  result.identifierCounts.set(node.text, (result.identifierCounts.get(node.text) ?? 0) + 1);
189
182
  }
190
183
  // Don't track identifiers in array literals that are about to be removed.
191
- if (ts__default["default"].isArrayLiteralExpression(node) && fullRemovals.has(node)) {
184
+ if (ts.isArrayLiteralExpression(node) && fullRemovals.has(node)) {
192
185
  return;
193
186
  }
194
- if (ts__default["default"].isImportDeclaration(node)) {
187
+ if (ts.isImportDeclaration(node)) {
195
188
  const namedBindings = node.importClause?.namedBindings;
196
- const moduleName = ts__default["default"].isStringLiteral(node.moduleSpecifier)
189
+ const moduleName = ts.isStringLiteral(node.moduleSpecifier)
197
190
  ? node.moduleSpecifier.text
198
191
  : null;
199
- if (namedBindings && ts__default["default"].isNamedImports(namedBindings) && moduleName !== null) {
192
+ if (namedBindings && ts.isNamedImports(namedBindings) && moduleName !== null) {
200
193
  namedBindings.elements.forEach((imp) => {
201
194
  if (!result.importedSymbols.has(moduleName)) {
202
195
  result.importedSymbols.set(moduleName, new Map());
@@ -229,7 +222,7 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
229
222
  const importManager = new checker.ImportManager();
230
223
  // Replace full arrays with empty ones. This allows preserves more of the user's formatting.
231
224
  fullRemovals.forEach((node) => {
232
- replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
225
+ replacements.push(new run_in_devkit.Replacement(run_in_devkit.projectFile(sourceFile, info), new run_in_devkit.TextUpdate({
233
226
  position: node.getStart(),
234
227
  end: node.getEnd(),
235
228
  toInsert: '[]',
@@ -237,11 +230,11 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
237
230
  });
238
231
  // Filter out the unused identifiers from an array.
239
232
  partialRemovals.forEach((toRemove, node) => {
240
- const newNode = ts__default["default"].factory.updateArrayLiteralExpression(node, node.elements.filter((el) => !toRemove.has(el)));
241
- replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
233
+ const newNode = ts.factory.updateArrayLiteralExpression(node, node.elements.filter((el) => !toRemove.has(el)));
234
+ replacements.push(new run_in_devkit.Replacement(run_in_devkit.projectFile(sourceFile, info), new run_in_devkit.TextUpdate({
242
235
  position: node.getStart(),
243
236
  end: node.getEnd(),
244
- toInsert: this.printer.printNode(ts__default["default"].EmitHint.Unspecified, newNode, sourceFile),
237
+ toInsert: this.printer.printNode(ts.EmitHint.Unspecified, newNode, sourceFile),
245
238
  })));
246
239
  });
247
240
  // Attempt to clean up unused import declarations. Note that this isn't foolproof, because we
@@ -270,59 +263,33 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
270
263
 
271
264
  function migrate() {
272
265
  return async (tree, context) => {
273
- const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
274
- if (!buildPaths.length && !testPaths.length) {
275
- throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot clean up unused imports.');
276
- }
277
- const fs = new project_paths.DevkitMigrationFilesystem(tree);
278
- checker.setFileSystem(fs);
279
- const migration = new UnusedImportsMigration();
280
- const unitResults = [];
281
- const programInfos = [...buildPaths, ...testPaths].map((tsconfigPath) => {
282
- context.logger.info(`Preparing analysis for ${tsconfigPath}`);
283
- const baseInfo = migration.createProgram(tsconfigPath, fs);
284
- const info = migration.prepareProgram(baseInfo);
285
- return { info, tsconfigPath };
266
+ await run_in_devkit.runMigrationInDevkit({
267
+ getMigration: () => new UnusedImportsMigration(),
268
+ tree,
269
+ beforeProgramCreation: (tsconfigPath) => {
270
+ context.logger.info(`Preparing analysis for ${tsconfigPath}`);
271
+ },
272
+ beforeUnitAnalysis: (tsconfigPath) => {
273
+ context.logger.info(`Scanning for unused imports using ${tsconfigPath}`);
274
+ },
275
+ afterAnalysisFailure: () => {
276
+ context.logger.error('Schematic failed unexpectedly with no analysis data');
277
+ },
278
+ whenDone: (stats) => {
279
+ const { removedImports, changedFiles } = stats.counters;
280
+ let statsMessage;
281
+ if (removedImports === 0) {
282
+ statsMessage = 'Schematic could not find unused imports in the project';
283
+ }
284
+ else {
285
+ statsMessage =
286
+ `Removed ${removedImports} import${removedImports !== 1 ? 's' : ''} ` +
287
+ `in ${changedFiles} file${changedFiles !== 1 ? 's' : ''}`;
288
+ }
289
+ context.logger.info('');
290
+ context.logger.info(statsMessage);
291
+ },
286
292
  });
287
- for (const { info, tsconfigPath } of programInfos) {
288
- context.logger.info(`Scanning for unused imports using ${tsconfigPath}`);
289
- unitResults.push(await migration.analyze(info));
290
- }
291
- const combined = await project_paths.synchronouslyCombineUnitData(migration, unitResults);
292
- if (combined === null) {
293
- context.logger.error('Schematic failed unexpectedly with no analysis data');
294
- return;
295
- }
296
- const globalMeta = await migration.globalMeta(combined);
297
- const replacementsPerFile = new Map();
298
- const { replacements } = await migration.migrate(globalMeta);
299
- const changesPerFile = project_paths.groupReplacementsByFile(replacements);
300
- for (const [file, changes] of changesPerFile) {
301
- if (!replacementsPerFile.has(file)) {
302
- replacementsPerFile.set(file, changes);
303
- }
304
- }
305
- for (const [file, changes] of replacementsPerFile) {
306
- const recorder = tree.beginUpdate(file);
307
- for (const c of changes) {
308
- recorder
309
- .remove(c.data.position, c.data.end - c.data.position)
310
- .insertRight(c.data.position, c.data.toInsert);
311
- }
312
- tree.commitUpdate(recorder);
313
- }
314
- const { counters: { removedImports, changedFiles }, } = await migration.stats(globalMeta);
315
- let statsMessage;
316
- if (removedImports === 0) {
317
- statsMessage = 'Schematic could not find unused imports in the project';
318
- }
319
- else {
320
- statsMessage =
321
- `Removed ${removedImports} import${removedImports !== 1 ? 's' : ''} ` +
322
- `in ${changedFiles} file${changedFiles !== 1 ? 's' : ''}`;
323
- }
324
- context.logger.info('');
325
- context.logger.info(statsMessage);
326
293
  };
327
294
  }
328
295
 
@@ -1,20 +1,17 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.1
3
+ * @license Angular v20.0.0-next.3
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
8
 
9
9
  var ts = require('typescript');
10
- var checker = require('./checker-af521da6.js');
10
+ var checker = require('./checker-BHb19MHt.js');
11
11
  require('os');
12
12
  var p = require('path');
13
13
 
14
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
15
-
16
- function _interopNamespace(e) {
17
- if (e && e.__esModule) return e;
14
+ function _interopNamespaceDefault(e) {
18
15
  var n = Object.create(null);
19
16
  if (e) {
20
17
  Object.keys(e).forEach(function (k) {
@@ -27,12 +24,11 @@ function _interopNamespace(e) {
27
24
  }
28
25
  });
29
26
  }
30
- n["default"] = e;
27
+ n.default = e;
31
28
  return Object.freeze(n);
32
29
  }
33
30
 
34
- var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
35
- var p__namespace = /*#__PURE__*/_interopNamespace(p);
31
+ var p__namespace = /*#__PURE__*/_interopNamespaceDefault(p);
36
32
 
37
33
  /** Tracks changes that have to be made for specific files. */
38
34
  class ChangeTracker {
@@ -76,7 +72,7 @@ class ChangeTracker {
76
72
  * when copying nodes from one file to another, because TypeScript might not output literal nodes
77
73
  * without it.
78
74
  */
79
- replaceNode(oldNode, newNode, emitHint = ts__default["default"].EmitHint.Unspecified, sourceFileWhenPrinting) {
75
+ replaceNode(oldNode, newNode, emitHint = ts.EmitHint.Unspecified, sourceFileWhenPrinting) {
80
76
  const sourceFile = oldNode.getSourceFile();
81
77
  this.replaceText(sourceFile, oldNode.getStart(), oldNode.getWidth(), this._printer.printNode(emitHint, newNode, sourceFileWhenPrinting || sourceFile));
82
78
  }
@@ -179,7 +175,7 @@ class ChangeTracker {
179
175
  }
180
176
  let kind = 0 /* QuoteKind.SINGLE */;
181
177
  for (const statement of sourceFile.statements) {
182
- if (ts__default["default"].isImportDeclaration(statement) && ts__default["default"].isStringLiteral(statement.moduleSpecifier)) {
178
+ if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
183
179
  kind = statement.moduleSpecifier.getText()[0] === '"' ? 1 /* QuoteKind.DOUBLE */ : 0 /* QuoteKind.SINGLE */;
184
180
  this._quotesCache.set(sourceFile, kind);
185
181
  break;
@@ -204,12 +200,12 @@ class ChangeTracker {
204
200
  const importLines = [];
205
201
  let lastImport = null;
206
202
  for (const statement of sourceFile.statements) {
207
- if (ts__default["default"].isImportDeclaration(statement)) {
203
+ if (ts.isImportDeclaration(statement)) {
208
204
  lastImport = statement;
209
205
  }
210
206
  }
211
207
  for (const decl of importsToAdd) {
212
- importLines.push(this._printer.printNode(ts__default["default"].EmitHint.Unspecified, decl, sourceFile));
208
+ importLines.push(this._printer.printNode(ts.EmitHint.Unspecified, decl, sourceFile));
213
209
  }
214
210
  this.insertText(sourceFile, lastImport ? lastImport.getEnd() : 0, (lastImport ? '\n' : '') + importLines.join('\n'));
215
211
  }
@@ -221,12 +217,12 @@ function normalizePath(path) {
221
217
  }
222
218
 
223
219
  function parseTsconfigFile(tsconfigPath, basePath) {
224
- const { config } = ts__default["default"].readConfigFile(tsconfigPath, ts__default["default"].sys.readFile);
220
+ const { config } = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
225
221
  const parseConfigHost = {
226
- useCaseSensitiveFileNames: ts__default["default"].sys.useCaseSensitiveFileNames,
227
- fileExists: ts__default["default"].sys.fileExists,
228
- readDirectory: ts__default["default"].sys.readDirectory,
229
- readFile: ts__default["default"].sys.readFile,
222
+ useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
223
+ fileExists: ts.sys.fileExists,
224
+ readDirectory: ts.sys.readDirectory,
225
+ readFile: ts.sys.readFile,
230
226
  };
231
227
  // Throw if incorrect arguments are passed to this function. Passing relative base paths
232
228
  // results in root directories not being resolved and in later type checking runtime errors.
@@ -234,7 +230,7 @@ function parseTsconfigFile(tsconfigPath, basePath) {
234
230
  if (!p__namespace.isAbsolute(basePath)) {
235
231
  throw Error('Unexpected relative base path has been specified.');
236
232
  }
237
- return ts__default["default"].parseJsonConfigFileContent(config, parseConfigHost, basePath, {});
233
+ return ts.parseJsonConfigFileContent(config, parseConfigHost, basePath, {});
238
234
  }
239
235
 
240
236
  /**
@@ -248,8 +244,8 @@ function parseTsconfigFile(tsconfigPath, basePath) {
248
244
  * @param additionalFiles Additional file paths that should be added to the program.
249
245
  */
250
246
  function createMigrationProgram(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles) {
251
- const { rootNames, options, host } = createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles);
252
- return ts__default["default"].createProgram(rootNames, options, host);
247
+ const { rootNames, options, host } = createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead);
248
+ return ts.createProgram(rootNames, options, host);
253
249
  }
254
250
  /**
255
251
  * Creates the options necessary to instantiate a TypeScript program.
@@ -269,10 +265,10 @@ function createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead, additi
269
265
  const parsed = parseTsconfigFile(tsconfigPath, p.dirname(tsconfigPath));
270
266
  const options = optionOverrides ? { ...parsed.options, ...optionOverrides } : parsed.options;
271
267
  const host = createMigrationCompilerHost(tree, options, basePath, fakeFileRead);
272
- return { rootNames: parsed.fileNames.concat(additionalFiles || []), options, host };
268
+ return { rootNames: parsed.fileNames.concat([]), options, host };
273
269
  }
274
270
  function createMigrationCompilerHost(tree, options, basePath, fakeRead) {
275
- const host = ts__default["default"].createCompilerHost(options, true);
271
+ const host = ts.createCompilerHost(options, true);
276
272
  const defaultReadFile = host.readFile;
277
273
  // We need to overwrite the host "readFile" method, as we want the TypeScript
278
274
  // program to be based on the file contents in the virtual file tree. Otherwise
@@ -1,34 +1,28 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.1
3
+ * @license Angular v20.0.0-next.3
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
8
 
9
- Object.defineProperty(exports, '__esModule', { value: true });
10
-
11
9
  var schematics = require('@angular-devkit/schematics');
12
10
  var p = require('path');
13
- var compiler_host = require('./compiler_host-5a29293c.js');
14
- var checker = require('./checker-af521da6.js');
11
+ var compiler_host = require('./compiler_host-Bk3repE2.js');
12
+ var checker = require('./checker-BHb19MHt.js');
15
13
  var ts = require('typescript');
16
14
  require('os');
17
15
  require('fs');
18
16
  require('module');
19
17
  require('url');
20
18
 
21
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
22
-
23
- var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
24
-
25
19
  function lookupIdentifiersInSourceFile(sourceFile, names) {
26
20
  const results = new Set();
27
21
  const visit = (node) => {
28
- if (ts__default["default"].isIdentifier(node) && names.includes(node.text)) {
22
+ if (ts.isIdentifier(node) && names.includes(node.text)) {
29
23
  results.add(node);
30
24
  }
31
- ts__default["default"].forEachChild(node, visit);
25
+ ts.forEachChild(node, visit);
32
26
  };
33
27
  visit(sourceFile);
34
28
  return results;
@@ -421,7 +415,7 @@ const replaceMarkerRegex = new RegExp(`${startMarker}|${endMarker}`, 'gm');
421
415
  */
422
416
  function analyze(sourceFile, analyzedFiles) {
423
417
  forEachClass(sourceFile, (node) => {
424
- if (ts__default["default"].isClassDeclaration(node)) {
418
+ if (ts.isClassDeclaration(node)) {
425
419
  analyzeDecorators(node, sourceFile, analyzedFiles);
426
420
  }
427
421
  else {
@@ -440,7 +434,7 @@ function checkIfShouldChange(decl, file) {
440
434
  const clause = decl.getChildAt(1);
441
435
  return !(!file.removeCommonModule &&
442
436
  clause.namedBindings &&
443
- ts__default["default"].isNamedImports(clause.namedBindings) &&
437
+ ts.isNamedImports(clause.namedBindings) &&
444
438
  clause.namedBindings.elements.length === 1 &&
445
439
  clause.namedBindings.elements[0].getText() === 'CommonModule');
446
440
  }
@@ -454,46 +448,46 @@ function updateImportDeclaration(decl, removeCommonModule) {
454
448
  // when the import declaration is at the top of the file, but right after a comment
455
449
  // without this, the comment gets duplicated when the declaration is updated.
456
450
  // the typescript AST includes that preceding comment as part of the import declaration full text.
457
- const printer = ts__default["default"].createPrinter({
451
+ const printer = ts.createPrinter({
458
452
  removeComments: true,
459
453
  });
460
- const updated = ts__default["default"].factory.updateImportDeclaration(decl, decl.modifiers, updatedClause, decl.moduleSpecifier, undefined);
461
- return printer.printNode(ts__default["default"].EmitHint.Unspecified, updated, clause.getSourceFile());
454
+ const updated = ts.factory.updateImportDeclaration(decl, decl.modifiers, updatedClause, decl.moduleSpecifier, undefined);
455
+ return printer.printNode(ts.EmitHint.Unspecified, updated, clause.getSourceFile());
462
456
  }
463
457
  function updateImportClause(clause, removeCommonModule) {
464
- if (clause.namedBindings && ts__default["default"].isNamedImports(clause.namedBindings)) {
458
+ if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {
465
459
  const removals = removeCommonModule ? importWithCommonRemovals : importRemovals;
466
460
  const elements = clause.namedBindings.elements.filter((el) => !removals.includes(el.getText()));
467
461
  if (elements.length === 0) {
468
462
  return null;
469
463
  }
470
- clause = ts__default["default"].factory.updateImportClause(clause, clause.isTypeOnly, clause.name, ts__default["default"].factory.createNamedImports(elements));
464
+ clause = ts.factory.updateImportClause(clause, clause.isTypeOnly, clause.name, ts.factory.createNamedImports(elements));
471
465
  }
472
466
  return clause;
473
467
  }
474
468
  function updateClassImports(propAssignment, removeCommonModule) {
475
- const printer = ts__default["default"].createPrinter();
469
+ const printer = ts.createPrinter();
476
470
  const importList = propAssignment.initializer;
477
471
  // Can't change non-array literals.
478
- if (!ts__default["default"].isArrayLiteralExpression(importList)) {
472
+ if (!ts.isArrayLiteralExpression(importList)) {
479
473
  return null;
480
474
  }
481
475
  const removals = removeCommonModule ? importWithCommonRemovals : importRemovals;
482
- const elements = importList.elements.filter((el) => !ts__default["default"].isIdentifier(el) || !removals.includes(el.text));
476
+ const elements = importList.elements.filter((el) => !ts.isIdentifier(el) || !removals.includes(el.text));
483
477
  if (elements.length === importList.elements.length) {
484
478
  // nothing changed
485
479
  return null;
486
480
  }
487
- const updatedElements = ts__default["default"].factory.updateArrayLiteralExpression(importList, elements);
488
- const updatedAssignment = ts__default["default"].factory.updatePropertyAssignment(propAssignment, propAssignment.name, updatedElements);
489
- return printer.printNode(ts__default["default"].EmitHint.Unspecified, updatedAssignment, updatedAssignment.getSourceFile());
481
+ const updatedElements = ts.factory.updateArrayLiteralExpression(importList, elements);
482
+ const updatedAssignment = ts.factory.updatePropertyAssignment(propAssignment, propAssignment.name, updatedElements);
483
+ return printer.printNode(ts.EmitHint.Unspecified, updatedAssignment, updatedAssignment.getSourceFile());
490
484
  }
491
485
  function analyzeImportDeclarations(node, sourceFile, analyzedFiles) {
492
486
  if (node.getText().indexOf('@angular/common') === -1) {
493
487
  return;
494
488
  }
495
489
  const clause = node.getChildAt(1);
496
- if (clause.namedBindings && ts__default["default"].isNamedImports(clause.namedBindings)) {
490
+ if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {
497
491
  const elements = clause.namedBindings.elements.filter((el) => importWithCommonRemovals.includes(el.getText()));
498
492
  if (elements.length > 0) {
499
493
  AnalyzedFile.addRange(sourceFile.fileName, sourceFile, analyzedFiles, {
@@ -510,14 +504,14 @@ function analyzeDecorators(node, sourceFile, analyzedFiles) {
510
504
  // Note: we have a utility to resolve the Angular decorators from a class declaration already.
511
505
  // We don't use it here, because it requires access to the type checker which makes it more
512
506
  // time-consuming to run internally.
513
- const decorator = ts__default["default"].getDecorators(node)?.find((dec) => {
514
- return (ts__default["default"].isCallExpression(dec.expression) &&
515
- ts__default["default"].isIdentifier(dec.expression.expression) &&
507
+ const decorator = ts.getDecorators(node)?.find((dec) => {
508
+ return (ts.isCallExpression(dec.expression) &&
509
+ ts.isIdentifier(dec.expression.expression) &&
516
510
  dec.expression.expression.text === 'Component');
517
511
  });
518
512
  const metadata = decorator &&
519
513
  decorator.expression.arguments.length > 0 &&
520
- ts__default["default"].isObjectLiteralExpression(decorator.expression.arguments[0])
514
+ ts.isObjectLiteralExpression(decorator.expression.arguments[0])
521
515
  ? decorator.expression.arguments[0]
522
516
  : null;
523
517
  if (!metadata) {
@@ -526,8 +520,8 @@ function analyzeDecorators(node, sourceFile, analyzedFiles) {
526
520
  for (const prop of metadata.properties) {
527
521
  // All the properties we care about should have static
528
522
  // names and be initialized to a static string.
529
- if (!ts__default["default"].isPropertyAssignment(prop) ||
530
- (!ts__default["default"].isIdentifier(prop.name) && !ts__default["default"].isStringLiteralLike(prop.name))) {
523
+ if (!ts.isPropertyAssignment(prop) ||
524
+ (!ts.isIdentifier(prop.name) && !ts.isStringLiteralLike(prop.name))) {
531
525
  continue;
532
526
  }
533
527
  switch (prop.name.text) {
@@ -552,7 +546,7 @@ function analyzeDecorators(node, sourceFile, analyzedFiles) {
552
546
  break;
553
547
  case 'templateUrl':
554
548
  // Leave the end as undefined which means that the range is until the end of the file.
555
- if (ts__default["default"].isStringLiteralLike(prop.initializer)) {
549
+ if (ts.isStringLiteralLike(prop.initializer)) {
556
550
  const path = p.join(p.dirname(sourceFile.fileName), prop.initializer.text);
557
551
  AnalyzedFile.addRange(path, sourceFile, analyzedFiles, {
558
552
  start: 0,
@@ -747,7 +741,7 @@ function generatei18nContainer(i18nAttr, middle) {
747
741
  /**
748
742
  * Counts, replaces, and removes any necessary ng-templates post control flow migration
749
743
  */
750
- function processNgTemplates(template) {
744
+ function processNgTemplates(template, sourceFile) {
751
745
  // count usage
752
746
  try {
753
747
  const templates = getTemplates(template);
@@ -780,7 +774,18 @@ function processNgTemplates(template) {
780
774
  }
781
775
  // the +1 accounts for the t.count's counting of the original template
782
776
  if (t.count === matches.length + 1 && safeToRemove) {
783
- template = template.replace(t.contents, `${startMarker}${endMarker}`);
777
+ const refsInComponentFile = getViewChildOrViewChildrenNames(sourceFile);
778
+ if (refsInComponentFile?.length > 0) {
779
+ const templateRefs = getTemplateReferences(template);
780
+ for (const ref of refsInComponentFile) {
781
+ if (!templateRefs.includes(ref)) {
782
+ template = template.replace(t.contents, `${startMarker}${endMarker}`);
783
+ }
784
+ }
785
+ }
786
+ else {
787
+ template = template.replace(t.contents, `${startMarker}${endMarker}`);
788
+ }
784
789
  }
785
790
  // templates may have changed structure from nested replaced templates
786
791
  // so we need to reprocess them before the next loop.
@@ -798,6 +803,44 @@ function processNgTemplates(template) {
798
803
  return { migrated: template, err: err };
799
804
  }
800
805
  }
806
+ function getViewChildOrViewChildrenNames(sourceFile) {
807
+ const names = [];
808
+ function visit(node) {
809
+ if (ts.isDecorator(node) && ts.isCallExpression(node.expression)) {
810
+ const expr = node.expression;
811
+ if (ts.isIdentifier(expr.expression) &&
812
+ (expr.expression.text === 'ViewChild' || expr.expression.text === 'ViewChildren')) {
813
+ const firstArg = expr.arguments[0];
814
+ if (firstArg && ts.isStringLiteral(firstArg)) {
815
+ names.push(firstArg.text);
816
+ }
817
+ return;
818
+ }
819
+ }
820
+ ts.forEachChild(node, visit);
821
+ }
822
+ visit(sourceFile);
823
+ return names;
824
+ }
825
+ function getTemplateReferences(template) {
826
+ const parsed = parseTemplate(template);
827
+ if (parsed.tree === undefined) {
828
+ return [];
829
+ }
830
+ const references = [];
831
+ function visitNodes(nodes) {
832
+ for (const node of nodes) {
833
+ if (node?.name === 'ng-template') {
834
+ references.push(...node.attrs?.map((ref) => ref?.name?.slice(1)));
835
+ }
836
+ if (node.children) {
837
+ visitNodes(node.children);
838
+ }
839
+ }
840
+ }
841
+ visitNodes(parsed.tree.rootNodes);
842
+ return references;
843
+ }
801
844
  function replaceRemainingPlaceholders(template) {
802
845
  const pattern = '.*';
803
846
  const placeholderPattern = getPlaceholder(pattern);
@@ -828,11 +871,11 @@ function canRemoveCommonModule(template) {
828
871
  * removes imports from template imports and import declarations
829
872
  */
830
873
  function removeImports(template, node, file) {
831
- if (template.startsWith('imports') && ts__default["default"].isPropertyAssignment(node)) {
874
+ if (template.startsWith('imports') && ts.isPropertyAssignment(node)) {
832
875
  const updatedImport = updateClassImports(node, file.removeCommonModule);
833
876
  return updatedImport ?? template;
834
877
  }
835
- else if (ts__default["default"].isImportDeclaration(node) && checkIfShouldChange(node, file)) {
878
+ else if (ts.isImportDeclaration(node) && checkIfShouldChange(node, file)) {
836
879
  return updateImportDeclaration(node, file.removeCommonModule);
837
880
  }
838
881
  return template;
@@ -1119,7 +1162,7 @@ function formatTemplate(tmpl, templateType) {
1119
1162
  /** Executes a callback on each class declaration in a file. */
1120
1163
  function forEachClass(sourceFile, callback) {
1121
1164
  sourceFile.forEachChild(function walk(node) {
1122
- if (ts__default["default"].isClassDeclaration(node) || ts__default["default"].isImportDeclaration(node)) {
1165
+ if (ts.isClassDeclaration(node) || ts.isImportDeclaration(node)) {
1123
1166
  callback(node);
1124
1167
  }
1125
1168
  node.forEachChild(walk);
@@ -1719,7 +1762,7 @@ function migrateTemplate(template, templateType, node, file, format = true, anal
1719
1762
  return { migrated: template, errors: switchResult.errors };
1720
1763
  }
1721
1764
  const caseResult = migrateCase(switchResult.migrated);
1722
- const templateResult = processNgTemplates(caseResult.migrated);
1765
+ const templateResult = processNgTemplates(caseResult.migrated, file.sourceFile);
1723
1766
  if (templateResult.err !== undefined) {
1724
1767
  return { migrated: template, errors: [{ type: 'template', error: templateResult.err }] };
1725
1768
  }