@angular/core 20.0.0-next.0 → 20.0.0-next.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.
Files changed (52) hide show
  1. package/fesm2022/core.mjs +3307 -4479
  2. package/fesm2022/core.mjs.map +1 -1
  3. package/fesm2022/primitives/di.mjs +45 -0
  4. package/fesm2022/primitives/di.mjs.map +1 -0
  5. package/fesm2022/primitives/event-dispatch.mjs +3 -590
  6. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  7. package/fesm2022/primitives/signals.mjs +19 -9
  8. package/fesm2022/primitives/signals.mjs.map +1 -1
  9. package/fesm2022/rxjs-interop.mjs +8 -33
  10. package/fesm2022/rxjs-interop.mjs.map +1 -1
  11. package/fesm2022/testing.mjs +392 -250
  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 +14339 -15134
  16. package/navigation_types.d-u4EOrrdZ.d.ts +121 -0
  17. package/package.json +11 -1
  18. package/primitives/di/index.d.ts +91 -0
  19. package/primitives/event-dispatch/index.d.ts +206 -310
  20. package/primitives/signals/index.d.ts +159 -196
  21. package/rxjs-interop/index.d.ts +72 -92
  22. package/schematics/bundles/{apply_import_manager-0959b78c.js → apply_import_manager-CyRT0UvU.js} +13 -17
  23. package/schematics/bundles/{checker-cf6f7980.js → checker-DF8ZaFW5.js} +3363 -1289
  24. package/schematics/bundles/cleanup-unused-imports.js +22 -28
  25. package/schematics/bundles/{compiler_host-cc1379e9.js → compiler_host-Da636uJ8.js} +20 -24
  26. package/schematics/bundles/control-flow-migration.js +82 -39
  27. package/schematics/bundles/{imports-31a38653.js → imports-CIX-JgAN.js} +10 -15
  28. package/schematics/bundles/{index-42d84d69.js → index-DnkWgagp.js} +56 -60
  29. package/schematics/bundles/{index-6675d6bc.js → index-vGJcp5M7.js} +5 -5
  30. package/schematics/bundles/inject-flags.js +181 -0
  31. package/schematics/bundles/inject-migration.js +122 -128
  32. package/schematics/bundles/{leading_space-6e7a8ec6.js → leading_space-D9nQ8UQC.js} +2 -2
  33. package/schematics/bundles/{migrate_ts_type_references-5089e4ef.js → migrate_ts_type_references-DtkOnnv0.js} +113 -120
  34. package/schematics/bundles/{ng_decorators-6878e227.js → ng_decorators-DznZ5jMl.js} +5 -9
  35. package/schematics/bundles/{nodes-ffdce442.js → nodes-B16H9JUd.js} +3 -7
  36. package/schematics/bundles/output-migration.js +40 -46
  37. package/schematics/bundles/{program-362689f0.js → program-BZk27Ndu.js} +846 -2653
  38. package/schematics/bundles/{project_paths-7d2daa1e.js → project_paths-Jtbi76Bs.js} +26 -24
  39. package/schematics/bundles/{project_tsconfig_paths-6c9cde78.js → project_tsconfig_paths-CDVxT6Ov.js} +2 -2
  40. package/schematics/bundles/{property_name-42030525.js → property_name-BBwFuqMe.js} +4 -8
  41. package/schematics/bundles/route-lazy-loading.js +36 -42
  42. package/schematics/bundles/self-closing-tags-migration.js +55 -45
  43. package/schematics/bundles/signal-input-migration.js +61 -68
  44. package/schematics/bundles/signal-queries-migration.js +48 -55
  45. package/schematics/bundles/signals.js +10 -12
  46. package/schematics/bundles/standalone-migration.js +179 -185
  47. package/schematics/migrations.json +4 -15
  48. package/testing/index.d.ts +309 -478
  49. package/weak_ref.d-ttyj86RV.d.ts +9 -0
  50. package/schematics/bundles/explicit-standalone-flag.js +0 -184
  51. package/schematics/bundles/pending-tasks.js +0 -103
  52. package/schematics/bundles/provide-initializer.js +0 -186
@@ -1,36 +1,30 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.0
4
- * (c) 2010-2024 Google LLC. https://angular.io/
3
+ * @license Angular v20.0.0-next.2
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
- var project_tsconfig_paths = require('./project_tsconfig_paths-6c9cde78.js');
13
- var project_paths = require('./project_paths-7d2daa1e.js');
10
+ var project_tsconfig_paths = require('./project_tsconfig_paths-CDVxT6Ov.js');
11
+ var project_paths = require('./project_paths-Jtbi76Bs.js');
14
12
  require('os');
15
13
  var ts = require('typescript');
16
- var checker = require('./checker-cf6f7980.js');
17
- var program = require('./program-362689f0.js');
14
+ var checker = require('./checker-DF8ZaFW5.js');
15
+ var program = require('./program-BZk27Ndu.js');
18
16
  require('path');
19
- require('./index-6675d6bc.js');
20
- var apply_import_manager = require('./apply_import_manager-0959b78c.js');
17
+ require('./index-vGJcp5M7.js');
18
+ var apply_import_manager = require('./apply_import_manager-CyRT0UvU.js');
21
19
  require('@angular-devkit/core');
22
20
  require('node:path/posix');
23
21
  require('fs');
24
22
  require('module');
25
23
  require('url');
26
24
 
27
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
28
-
29
- var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
30
-
31
25
  /** Migration that cleans up unused imports from a project. */
32
26
  class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
33
- printer = ts__default["default"].createPrinter();
27
+ printer = ts.createPrinter();
34
28
  createProgram(tsconfigAbsPath, fs) {
35
29
  return super.createProgram(tsconfigAbsPath, fs, {
36
30
  extendedDiagnostics: {
@@ -133,7 +127,7 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
133
127
  allRemovedIdentifiers: new Set(),
134
128
  };
135
129
  const walk = (node) => {
136
- if (!ts__default["default"].isIdentifier(node)) {
130
+ if (!ts.isIdentifier(node)) {
137
131
  node.forEachChild(walk);
138
132
  return;
139
133
  }
@@ -145,17 +139,17 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
145
139
  if (locations.has(this.getNodeID(node.getStart(), node.getWidth()))) {
146
140
  // When the entire array needs to be cleared, the diagnostic is
147
141
  // reported on the property assignment, rather than an array element.
148
- if (ts__default["default"].isPropertyAssignment(parent) &&
142
+ if (ts.isPropertyAssignment(parent) &&
149
143
  parent.name === node &&
150
- ts__default["default"].isArrayLiteralExpression(parent.initializer)) {
144
+ ts.isArrayLiteralExpression(parent.initializer)) {
151
145
  result.fullRemovals.add(parent.initializer);
152
146
  parent.initializer.elements.forEach((element) => {
153
- if (ts__default["default"].isIdentifier(element)) {
147
+ if (ts.isIdentifier(element)) {
154
148
  result.allRemovedIdentifiers.add(element);
155
149
  }
156
150
  });
157
151
  }
158
- else if (ts__default["default"].isArrayLiteralExpression(parent)) {
152
+ else if (ts.isArrayLiteralExpression(parent)) {
159
153
  if (!result.partialRemovals.has(parent)) {
160
154
  result.partialRemovals.set(parent, new Set());
161
155
  }
@@ -179,24 +173,24 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
179
173
  identifierCounts: new Map(),
180
174
  };
181
175
  const walk = (node) => {
182
- if (ts__default["default"].isIdentifier(node) &&
176
+ if (ts.isIdentifier(node) &&
183
177
  node.parent &&
184
178
  // Don't track individual identifiers marked for removal.
185
- (!ts__default["default"].isArrayLiteralExpression(node.parent) ||
179
+ (!ts.isArrayLiteralExpression(node.parent) ||
186
180
  !partialRemovals.has(node.parent) ||
187
181
  !partialRemovals.get(node.parent).has(node))) {
188
182
  result.identifierCounts.set(node.text, (result.identifierCounts.get(node.text) ?? 0) + 1);
189
183
  }
190
184
  // Don't track identifiers in array literals that are about to be removed.
191
- if (ts__default["default"].isArrayLiteralExpression(node) && fullRemovals.has(node)) {
185
+ if (ts.isArrayLiteralExpression(node) && fullRemovals.has(node)) {
192
186
  return;
193
187
  }
194
- if (ts__default["default"].isImportDeclaration(node)) {
188
+ if (ts.isImportDeclaration(node)) {
195
189
  const namedBindings = node.importClause?.namedBindings;
196
- const moduleName = ts__default["default"].isStringLiteral(node.moduleSpecifier)
190
+ const moduleName = ts.isStringLiteral(node.moduleSpecifier)
197
191
  ? node.moduleSpecifier.text
198
192
  : null;
199
- if (namedBindings && ts__default["default"].isNamedImports(namedBindings) && moduleName !== null) {
193
+ if (namedBindings && ts.isNamedImports(namedBindings) && moduleName !== null) {
200
194
  namedBindings.elements.forEach((imp) => {
201
195
  if (!result.importedSymbols.has(moduleName)) {
202
196
  result.importedSymbols.set(moduleName, new Map());
@@ -237,11 +231,11 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
237
231
  });
238
232
  // Filter out the unused identifiers from an array.
239
233
  partialRemovals.forEach((toRemove, node) => {
240
- const newNode = ts__default["default"].factory.updateArrayLiteralExpression(node, node.elements.filter((el) => !toRemove.has(el)));
234
+ const newNode = ts.factory.updateArrayLiteralExpression(node, node.elements.filter((el) => !toRemove.has(el)));
241
235
  replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
242
236
  position: node.getStart(),
243
237
  end: node.getEnd(),
244
- toInsert: this.printer.printNode(ts__default["default"].EmitHint.Unspecified, newNode, sourceFile),
238
+ toInsert: this.printer.printNode(ts.EmitHint.Unspecified, newNode, sourceFile),
245
239
  })));
246
240
  });
247
241
  // Attempt to clean up unused import declarations. Note that this isn't foolproof, because we
@@ -1,20 +1,17 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.0
4
- * (c) 2010-2024 Google LLC. https://angular.io/
3
+ * @license Angular v20.0.0-next.2
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-cf6f7980.js');
10
+ var checker = require('./checker-DF8ZaFW5.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.0
4
- * (c) 2010-2024 Google LLC. https://angular.io/
3
+ * @license Angular v20.0.0-next.2
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-cc1379e9.js');
14
- var checker = require('./checker-cf6f7980.js');
11
+ var compiler_host = require('./compiler_host-Da636uJ8.js');
12
+ var checker = require('./checker-DF8ZaFW5.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
  }
@@ -1,17 +1,13 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.0
4
- * (c) 2010-2024 Google LLC. https://angular.io/
3
+ * @license Angular v20.0.0-next.2
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
10
 
11
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
-
13
- var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
14
-
15
11
  /** Gets import information about the specified identifier by using the Type checker. */
16
12
  function getImportOfIdentifier(typeChecker, node) {
17
13
  const symbol = typeChecker.getSymbolAtLocation(node);
@@ -19,11 +15,11 @@ function getImportOfIdentifier(typeChecker, node) {
19
15
  return null;
20
16
  }
21
17
  const decl = symbol.declarations[0];
22
- if (!ts__default["default"].isImportSpecifier(decl)) {
18
+ if (!ts.isImportSpecifier(decl)) {
23
19
  return null;
24
20
  }
25
21
  const importDecl = decl.parent.parent.parent;
26
- if (!ts__default["default"].isImportDeclaration(importDecl) || !ts__default["default"].isStringLiteral(importDecl.moduleSpecifier)) {
22
+ if (!ts.isImportDeclaration(importDecl) || !ts.isStringLiteral(importDecl.moduleSpecifier)) {
27
23
  return null;
28
24
  }
29
25
  return {
@@ -56,14 +52,14 @@ function getImportSpecifier(sourceFile, moduleName, specifierName) {
56
52
  function getImportSpecifiers(sourceFile, moduleName, specifierOrSpecifiers) {
57
53
  const matches = [];
58
54
  for (const node of sourceFile.statements) {
59
- if (!ts__default["default"].isImportDeclaration(node) || !ts__default["default"].isStringLiteral(node.moduleSpecifier)) {
55
+ if (!ts.isImportDeclaration(node) || !ts.isStringLiteral(node.moduleSpecifier)) {
60
56
  continue;
61
57
  }
62
58
  const namedBindings = node.importClause?.namedBindings;
63
59
  const isMatch = typeof moduleName === 'string'
64
60
  ? node.moduleSpecifier.text === moduleName
65
61
  : moduleName.test(node.moduleSpecifier.text);
66
- if (!isMatch || !namedBindings || !ts__default["default"].isNamedImports(namedBindings)) {
62
+ if (!isMatch || !namedBindings || !ts.isNamedImports(namedBindings)) {
67
63
  continue;
68
64
  }
69
65
  if (typeof specifierOrSpecifiers === 'string') {
@@ -85,12 +81,11 @@ function getImportSpecifiers(sourceFile, moduleName, specifierOrSpecifiers) {
85
81
  }
86
82
  function getNamedImports(sourceFile, moduleName) {
87
83
  for (const node of sourceFile.statements) {
88
- if (ts__default["default"].isImportDeclaration(node) && ts__default["default"].isStringLiteral(node.moduleSpecifier)) {
89
- const isMatch = typeof moduleName === 'string'
90
- ? node.moduleSpecifier.text === moduleName
91
- : moduleName.test(node.moduleSpecifier.text);
84
+ if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
85
+ const isMatch = node.moduleSpecifier.text === moduleName
86
+ ;
92
87
  const namedBindings = node.importClause?.namedBindings;
93
- if (isMatch && namedBindings && ts__default["default"].isNamedImports(namedBindings)) {
88
+ if (isMatch && namedBindings && ts.isNamedImports(namedBindings)) {
94
89
  return namedBindings;
95
90
  }
96
91
  }