@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,6 +1,6 @@
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
  */
@@ -8,14 +8,10 @@
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
  /** Find the closest parent node of a particular kind. */
16
12
  function closestNode(node, predicate) {
17
13
  let current = node.parent;
18
- while (current && !ts__default["default"].isSourceFile(current)) {
14
+ while (current && !ts.isSourceFile(current)) {
19
15
  if (predicate(current)) {
20
16
  return current;
21
17
  }
@@ -1,43 +1,37 @@
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$1 = require('./index-I8VbxQcO.js');
18
13
  require('path');
19
- var apply_import_manager = require('./apply_import_manager-e2a7fe5b.js');
20
- var index = require('./index-1bef3025.js');
14
+ var run_in_devkit = require('./run_in_devkit-C0JPtK2u.js');
15
+ var apply_import_manager = require('./apply_import_manager-BXQEjo09.js');
16
+ var index = require('./index-BL9kAIe5.js');
21
17
  require('@angular-devkit/core');
22
18
  require('node:path/posix');
23
19
  require('fs');
24
20
  require('module');
25
21
  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);
22
+ require('@angular-devkit/schematics');
23
+ require('./project_tsconfig_paths-CDVxT6Ov.js');
30
24
 
31
25
  function isOutputDeclarationEligibleForMigration(node) {
32
26
  return (node.initializer !== undefined &&
33
- ts__default["default"].isNewExpression(node.initializer) &&
34
- ts__default["default"].isIdentifier(node.initializer.expression) &&
27
+ ts.isNewExpression(node.initializer) &&
28
+ ts.isIdentifier(node.initializer.expression) &&
35
29
  node.initializer.expression.text === 'EventEmitter');
36
30
  }
37
31
  function isPotentialOutputCallUsage(node, name) {
38
- if (ts__default["default"].isCallExpression(node) &&
39
- ts__default["default"].isPropertyAccessExpression(node.expression) &&
40
- ts__default["default"].isIdentifier(node.expression.name)) {
32
+ if (ts.isCallExpression(node) &&
33
+ ts.isPropertyAccessExpression(node.expression) &&
34
+ ts.isIdentifier(node.expression.name)) {
41
35
  return node.expression?.name.text === name;
42
36
  }
43
37
  else {
@@ -68,8 +62,8 @@ function isTargetOutputDeclaration(node, checker, reflector, dtsReader) {
68
62
  function isOutputDeclaration(node, reflector, dtsReader) {
69
63
  // `.d.ts` file, so we check the `static ecmp` metadata on the `declare class`.
70
64
  if (node.getSourceFile().isDeclarationFile) {
71
- if (!ts__default["default"].isIdentifier(node.name) ||
72
- !ts__default["default"].isClassDeclaration(node.parent) ||
65
+ if (!ts.isIdentifier(node.name) ||
66
+ !ts.isClassDeclaration(node.parent) ||
73
67
  node.parent.name === undefined) {
74
68
  return false;
75
69
  }
@@ -82,7 +76,7 @@ function isOutputDeclaration(node, reflector, dtsReader) {
82
76
  }
83
77
  function getTargetPropertyDeclaration(targetSymbol) {
84
78
  const valDeclaration = targetSymbol.valueDeclaration;
85
- if (valDeclaration !== undefined && ts__default["default"].isPropertyDeclaration(valDeclaration)) {
79
+ if (valDeclaration !== undefined && ts.isPropertyDeclaration(valDeclaration)) {
86
80
  return valDeclaration;
87
81
  }
88
82
  return null;
@@ -96,12 +90,12 @@ function getOutputDecorator(node, reflector) {
96
90
  // THINK: this utility + type is not specific to @Output, really, maybe move it to tsurge?
97
91
  /** Computes an unique ID for a given Angular `@Output` property. */
98
92
  function getUniqueIdForProperty(info, prop) {
99
- const { id } = project_paths.projectFile(prop.getSourceFile(), info);
93
+ const { id } = run_in_devkit.projectFile(prop.getSourceFile(), info);
100
94
  id.replace(/\.d\.ts$/, '.ts');
101
95
  return `${id}@@${prop.parent.name ?? 'unknown-class'}@@${prop.name.getText()}`;
102
96
  }
103
97
  function isTestRunnerImport(node) {
104
- if (ts__default["default"].isImportDeclaration(node)) {
98
+ if (ts.isImportDeclaration(node)) {
105
99
  const moduleSpecifier = node.moduleSpecifier.getText();
106
100
  return moduleSpecifier.includes('jasmine') || moduleSpecifier.includes('catalyst');
107
101
  }
@@ -147,27 +141,27 @@ function checkNonTsReferenceCallsField(ref, fieldName) {
147
141
  return potentialRead;
148
142
  }
149
143
 
150
- const printer = ts__default["default"].createPrinter();
144
+ const printer = ts.createPrinter();
151
145
  function calculateDeclarationReplacement(info, node, aliasParam) {
152
146
  const sf = node.getSourceFile();
153
- const payloadTypes = node.initializer !== undefined && ts__default["default"].isNewExpression(node.initializer)
147
+ const payloadTypes = node.initializer !== undefined && ts.isNewExpression(node.initializer)
154
148
  ? node.initializer?.typeArguments
155
149
  : undefined;
156
- const outputCall = ts__default["default"].factory.createCallExpression(ts__default["default"].factory.createIdentifier('output'), payloadTypes, aliasParam !== undefined
150
+ const outputCall = ts.factory.createCallExpression(ts.factory.createIdentifier('output'), payloadTypes, aliasParam !== undefined
157
151
  ? [
158
- ts__default["default"].factory.createObjectLiteralExpression([
159
- ts__default["default"].factory.createPropertyAssignment('alias', ts__default["default"].factory.createStringLiteral(aliasParam, true)),
152
+ ts.factory.createObjectLiteralExpression([
153
+ ts.factory.createPropertyAssignment('alias', ts.factory.createStringLiteral(aliasParam, true)),
160
154
  ], false),
161
155
  ]
162
156
  : []);
163
- const existingModifiers = (node.modifiers ?? []).filter((modifier) => !ts__default["default"].isDecorator(modifier) && modifier.kind !== ts__default["default"].SyntaxKind.ReadonlyKeyword);
164
- const updatedOutputDeclaration = ts__default["default"].factory.createPropertyDeclaration(
157
+ const existingModifiers = (node.modifiers ?? []).filter((modifier) => !ts.isDecorator(modifier) && modifier.kind !== ts.SyntaxKind.ReadonlyKeyword);
158
+ const updatedOutputDeclaration = ts.factory.createPropertyDeclaration(
165
159
  // Think: this logic of dealing with modifiers is applicable to all signal-based migrations
166
- ts__default["default"].factory.createNodeArray([
160
+ ts.factory.createNodeArray([
167
161
  ...existingModifiers,
168
- ts__default["default"].factory.createModifier(ts__default["default"].SyntaxKind.ReadonlyKeyword),
162
+ ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword),
169
163
  ]), node.name, undefined, undefined, outputCall);
170
- return prepareTextReplacementForNode(info, node, printer.printNode(ts__default["default"].EmitHint.Unspecified, updatedOutputDeclaration, sf));
164
+ return prepareTextReplacementForNode(info, node, printer.printNode(ts.EmitHint.Unspecified, updatedOutputDeclaration, sf));
171
165
  }
172
166
  function calculateImportReplacements(info, sourceFiles) {
173
167
  const importReplacements = {};
@@ -175,7 +169,7 @@ function calculateImportReplacements(info, sourceFiles) {
175
169
  const importManager = new checker.ImportManager();
176
170
  const addOnly = [];
177
171
  const addRemove = [];
178
- const file = project_paths.projectFile(sf, info);
172
+ const file = run_in_devkit.projectFile(sf, info);
179
173
  importManager.addImport({
180
174
  requestedFile: sf,
181
175
  exportModuleSpecifier: '@angular/core',
@@ -205,7 +199,7 @@ function calculateCompleteCallReplacement(info, node) {
205
199
  return prepareTextReplacementForNode(info, node, '', node.getFullStart());
206
200
  }
207
201
  function calculatePipeCallReplacement(info, node) {
208
- if (ts__default["default"].isPropertyAccessExpression(node.expression)) {
202
+ if (ts.isPropertyAccessExpression(node.expression)) {
209
203
  const sf = node.getSourceFile();
210
204
  const importManager = new checker.ImportManager();
211
205
  const outputToObservableIdent = importManager.addImport({
@@ -213,13 +207,13 @@ function calculatePipeCallReplacement(info, node) {
213
207
  exportModuleSpecifier: '@angular/core/rxjs-interop',
214
208
  exportSymbolName: 'outputToObservable',
215
209
  });
216
- const toObsCallExp = ts__default["default"].factory.createCallExpression(outputToObservableIdent, undefined, [
210
+ const toObsCallExp = ts.factory.createCallExpression(outputToObservableIdent, undefined, [
217
211
  node.expression.expression,
218
212
  ]);
219
- const pipePropAccessExp = ts__default["default"].factory.updatePropertyAccessExpression(node.expression, toObsCallExp, node.expression.name);
220
- const pipeCallExp = ts__default["default"].factory.updateCallExpression(node, pipePropAccessExp, [], node.arguments);
213
+ const pipePropAccessExp = ts.factory.updatePropertyAccessExpression(node.expression, toObsCallExp, node.expression.name);
214
+ const pipeCallExp = ts.factory.updateCallExpression(node, pipePropAccessExp, [], node.arguments);
221
215
  const replacements = [
222
- prepareTextReplacementForNode(info, node, printer.printNode(ts__default["default"].EmitHint.Unspecified, pipeCallExp, sf)),
216
+ prepareTextReplacementForNode(info, node, printer.printNode(ts.EmitHint.Unspecified, pipeCallExp, sf)),
223
217
  ];
224
218
  apply_import_manager.applyImportManagerChanges(importManager, replacements, [sf], info);
225
219
  return replacements;
@@ -231,36 +225,36 @@ function calculatePipeCallReplacement(info, node) {
231
225
  }
232
226
  function prepareTextReplacementForNode(info, node, replacement, start) {
233
227
  const sf = node.getSourceFile();
234
- return new project_paths.Replacement(project_paths.projectFile(sf, info), new project_paths.TextUpdate({
228
+ return new run_in_devkit.Replacement(run_in_devkit.projectFile(sf, info), new run_in_devkit.TextUpdate({
235
229
  position: start ?? node.getStart(),
236
230
  end: node.getEnd(),
237
231
  toInsert: replacement,
238
232
  }));
239
233
  }
240
234
  function prepareTextReplacement(file, replacement, start, end) {
241
- return new project_paths.Replacement(file, new project_paths.TextUpdate({
235
+ return new run_in_devkit.Replacement(file, new run_in_devkit.TextUpdate({
242
236
  position: start,
243
237
  end: end,
244
238
  toInsert: replacement,
245
239
  }));
246
240
  }
247
241
 
248
- class OutputMigration extends project_paths.TsurgeFunnelMigration {
242
+ class OutputMigration extends run_in_devkit.TsurgeFunnelMigration {
249
243
  config;
250
244
  constructor(config = {}) {
251
245
  super();
252
246
  this.config = config;
253
247
  }
254
248
  async analyze(info) {
255
- const { sourceFiles, program: program$1 } = info;
249
+ const { sourceFiles, program } = info;
256
250
  const outputFieldReplacements = {};
257
251
  const problematicUsages = {};
258
252
  let problematicDeclarationCount = 0;
259
253
  const filesWithOutputDeclarations = new Set();
260
- const checker$1 = program$1.getTypeChecker();
254
+ const checker$1 = program.getTypeChecker();
261
255
  const reflector = new checker.TypeScriptReflectionHost(checker$1);
262
- const dtsReader = new program.DtsMetadataReader(checker$1, reflector);
263
- const evaluator = new program.PartialEvaluator(reflector, checker$1, null);
256
+ const dtsReader = new index$1.DtsMetadataReader(checker$1, reflector);
257
+ const evaluator = new index$1.PartialEvaluator(reflector, checker$1, null);
264
258
  const resourceLoader = info.ngCompiler?.['resourceManager'] ?? null;
265
259
  // Pre-analyze the program and get access to the template type checker.
266
260
  // If we are processing a non-Angular target, there is no template info.
@@ -288,7 +282,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
288
282
  let isTestFile = false;
289
283
  const outputMigrationVisitor = (node) => {
290
284
  // detect output declarations
291
- if (ts__default["default"].isPropertyDeclaration(node)) {
285
+ if (ts.isPropertyDeclaration(node)) {
292
286
  const outputDecorator = getOutputDecorator(node, reflector);
293
287
  if (outputDecorator !== null) {
294
288
  if (isOutputDeclarationEligibleForMigration(node)) {
@@ -296,7 +290,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
296
290
  id: getUniqueIdForProperty(info, node),
297
291
  aliasParam: outputDecorator.args?.at(0),
298
292
  };
299
- const outputFile = project_paths.projectFile(node.getSourceFile(), info);
293
+ const outputFile = run_in_devkit.projectFile(node.getSourceFile(), info);
300
294
  if (this.config.shouldMigrate === undefined ||
301
295
  this.config.shouldMigrate({
302
296
  key: outputDef.id,
@@ -320,21 +314,21 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
320
314
  }
321
315
  }
322
316
  // detect .next usages that should be migrated to .emit
323
- if (isPotentialNextCallUsage(node) && ts__default["default"].isPropertyAccessExpression(node.expression)) {
317
+ if (isPotentialNextCallUsage(node) && ts.isPropertyAccessExpression(node.expression)) {
324
318
  const propertyDeclaration = isTargetOutputDeclaration(node.expression.expression, checker$1, reflector, dtsReader);
325
319
  if (propertyDeclaration !== null) {
326
320
  const id = getUniqueIdForProperty(info, propertyDeclaration);
327
- const outputFile = project_paths.projectFile(node.getSourceFile(), info);
321
+ const outputFile = run_in_devkit.projectFile(node.getSourceFile(), info);
328
322
  addOutputReplacement(outputFieldReplacements, id, outputFile, calculateNextFnReplacement(info, node.expression.name));
329
323
  }
330
324
  }
331
325
  // detect .complete usages that should be removed
332
- if (isPotentialCompleteCallUsage(node) && ts__default["default"].isPropertyAccessExpression(node.expression)) {
326
+ if (isPotentialCompleteCallUsage(node) && ts.isPropertyAccessExpression(node.expression)) {
333
327
  const propertyDeclaration = isTargetOutputDeclaration(node.expression.expression, checker$1, reflector, dtsReader);
334
328
  if (propertyDeclaration !== null) {
335
329
  const id = getUniqueIdForProperty(info, propertyDeclaration);
336
- const outputFile = project_paths.projectFile(node.getSourceFile(), info);
337
- if (ts__default["default"].isExpressionStatement(node.parent)) {
330
+ const outputFile = run_in_devkit.projectFile(node.getSourceFile(), info);
331
+ if (ts.isExpressionStatement(node.parent)) {
338
332
  addOutputReplacement(outputFieldReplacements, id, outputFile, calculateCompleteCallReplacement(info, node.parent));
339
333
  }
340
334
  else {
@@ -347,12 +341,12 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
347
341
  isTestFile = true;
348
342
  }
349
343
  // detect unsafe access of the output property
350
- if (isPotentialPipeCallUsage(node) && ts__default["default"].isPropertyAccessExpression(node.expression)) {
344
+ if (isPotentialPipeCallUsage(node) && ts.isPropertyAccessExpression(node.expression)) {
351
345
  const propertyDeclaration = isTargetOutputDeclaration(node.expression.expression, checker$1, reflector, dtsReader);
352
346
  if (propertyDeclaration !== null) {
353
347
  const id = getUniqueIdForProperty(info, propertyDeclaration);
354
348
  if (isTestFile) {
355
- const outputFile = project_paths.projectFile(node.getSourceFile(), info);
349
+ const outputFile = run_in_devkit.projectFile(node.getSourceFile(), info);
356
350
  addOutputReplacement(outputFieldReplacements, id, outputFile, ...calculatePipeCallReplacement(info, node));
357
351
  }
358
352
  else {
@@ -360,12 +354,12 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
360
354
  }
361
355
  }
362
356
  }
363
- ts__default["default"].forEachChild(node, outputMigrationVisitor);
357
+ ts.forEachChild(node, outputMigrationVisitor);
364
358
  };
365
359
  // calculate output migration replacements
366
360
  for (const sf of sourceFiles) {
367
361
  isTestFile = false;
368
- ts__default["default"].forEachChild(sf, outputMigrationVisitor);
362
+ ts.forEachChild(sf, outputMigrationVisitor);
369
363
  }
370
364
  // take care of the references in templates and host bindings
371
365
  const referenceResult = { references: [] };
@@ -373,7 +367,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
373
367
  referenceResult);
374
368
  // calculate template / host binding replacements
375
369
  for (const sf of sourceFiles) {
376
- ts__default["default"].forEachChild(sf, templateHostRefVisitor);
370
+ ts.forEachChild(sf, templateHostRefVisitor);
377
371
  }
378
372
  for (const ref of referenceResult.references) {
379
373
  // detect .next usages that should be migrated to .emit in template and host binding expressions
@@ -396,7 +390,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
396
390
  }
397
391
  // calculate import replacements but do so only for files that have output declarations
398
392
  const importReplacements = calculateImportReplacements(info, filesWithOutputDeclarations);
399
- return project_paths.confirmAsSerializable({
393
+ return run_in_devkit.confirmAsSerializable({
400
394
  problematicDeclarationCount,
401
395
  outputFields: outputFieldReplacements,
402
396
  importReplacements,
@@ -426,7 +420,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
426
420
  problematicUsages[declId] = unit.problematicUsages[declId];
427
421
  }
428
422
  }
429
- return project_paths.confirmAsSerializable({
423
+ return run_in_devkit.confirmAsSerializable({
430
424
  problematicDeclarationCount,
431
425
  outputFields,
432
426
  importReplacements,
@@ -448,7 +442,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
448
442
  }
449
443
  }
450
444
  // Noop here as we don't have any form of special global metadata.
451
- return project_paths.confirmAsSerializable(combinedData);
445
+ return run_in_devkit.confirmAsSerializable(combinedData);
452
446
  }
453
447
  async stats(globalMetadata) {
454
448
  const detectedOutputs = new Set(Object.keys(globalMetadata.outputFields)).size +
@@ -507,73 +501,45 @@ function addOutputReplacement(outputFieldReplacements, outputId, file, ...replac
507
501
 
508
502
  function migrate(options) {
509
503
  return async (tree, context) => {
510
- const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
511
- if (!buildPaths.length && !testPaths.length) {
512
- throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run output migration.');
513
- }
514
- const fs = new project_paths.DevkitMigrationFilesystem(tree);
515
- checker.setFileSystem(fs);
516
- const migration = new OutputMigration({
517
- shouldMigrate: (_, file) => {
518
- return (file.rootRelativePath.startsWith(fs.normalize(options.path)) &&
519
- !/(^|\/)node_modules\//.test(file.rootRelativePath));
504
+ await run_in_devkit.runMigrationInDevkit({
505
+ tree,
506
+ getMigration: (fs) => new OutputMigration({
507
+ shouldMigrate: (_, file) => {
508
+ return (file.rootRelativePath.startsWith(fs.normalize(options.path)) &&
509
+ !/(^|\/)node_modules\//.test(file.rootRelativePath));
510
+ },
511
+ }),
512
+ beforeProgramCreation: (tsconfigPath) => {
513
+ context.logger.info(`Preparing analysis for: ${tsconfigPath}...`);
520
514
  },
521
- });
522
- const analysisPath = fs.resolve(options.analysisDir);
523
- const unitResults = [];
524
- const programInfos = [...buildPaths, ...testPaths].map((tsconfigPath) => {
525
- context.logger.info(`Preparing analysis for: ${tsconfigPath}..`);
526
- const baseInfo = migration.createProgram(tsconfigPath, fs);
527
- const info = migration.prepareProgram(baseInfo);
528
- // Support restricting the analysis to subfolders for larger projects.
529
- if (analysisPath !== '/') {
530
- info.sourceFiles = info.sourceFiles.filter((sf) => sf.fileName.startsWith(analysisPath));
531
- info.fullProgramSourceFiles = info.fullProgramSourceFiles.filter((sf) => sf.fileName.startsWith(analysisPath));
532
- }
533
- return { info, tsconfigPath };
534
- });
535
- // Analyze phase. Treat all projects as compilation units as
536
- // this allows us to support references between those.
537
- for (const { info, tsconfigPath } of programInfos) {
538
- context.logger.info(`Scanning for outputs: ${tsconfigPath}..`);
539
- unitResults.push(await migration.analyze(info));
540
- }
541
- context.logger.info(``);
542
- context.logger.info(`Processing analysis data between targets..`);
543
- context.logger.info(``);
544
- const combined = await project_paths.synchronouslyCombineUnitData(migration, unitResults);
545
- if (combined === null) {
546
- context.logger.error('Migration failed unexpectedly with no analysis data');
547
- return;
548
- }
549
- const globalMeta = await migration.globalMeta(combined);
550
- const replacementsPerFile = new Map();
551
- for (const { info, tsconfigPath } of programInfos) {
552
- context.logger.info(`Migrating: ${tsconfigPath}..`);
553
- const { replacements } = await migration.migrate(globalMeta);
554
- const changesPerFile = project_paths.groupReplacementsByFile(replacements);
555
- for (const [file, changes] of changesPerFile) {
556
- if (!replacementsPerFile.has(file)) {
557
- replacementsPerFile.set(file, changes);
515
+ afterProgramCreation: (info, fs) => {
516
+ const analysisPath = fs.resolve(options.analysisDir);
517
+ // Support restricting the analysis to subfolders for larger projects.
518
+ if (analysisPath !== '/') {
519
+ info.sourceFiles = info.sourceFiles.filter((sf) => sf.fileName.startsWith(analysisPath));
520
+ info.fullProgramSourceFiles = info.fullProgramSourceFiles.filter((sf) => sf.fileName.startsWith(analysisPath));
558
521
  }
559
- }
560
- }
561
- context.logger.info(`Applying changes..`);
562
- for (const [file, changes] of replacementsPerFile) {
563
- const recorder = tree.beginUpdate(file);
564
- for (const c of changes) {
565
- recorder
566
- .remove(c.data.position, c.data.end - c.data.position)
567
- .insertLeft(c.data.position, c.data.toInsert);
568
- }
569
- tree.commitUpdate(recorder);
570
- }
571
- const { counters: { detectedOutputs, problematicOutputs, successRate }, } = await migration.stats(globalMeta);
572
- const migratedOutputs = detectedOutputs - problematicOutputs;
573
- const successRatePercent = (successRate * 100).toFixed(2);
574
- context.logger.info('');
575
- context.logger.info(`Successfully migrated to outputs as functions 🎉`);
576
- context.logger.info(` -> Migrated ${migratedOutputs} out of ${detectedOutputs} detected outputs (${successRatePercent} %).`);
522
+ },
523
+ beforeUnitAnalysis: (tsconfigPath) => {
524
+ context.logger.info(`Scanning for outputs: ${tsconfigPath}...`);
525
+ },
526
+ afterAllAnalyzed: () => {
527
+ context.logger.info(``);
528
+ context.logger.info(`Processing analysis data between targets...`);
529
+ context.logger.info(``);
530
+ },
531
+ afterAnalysisFailure: () => {
532
+ context.logger.error('Migration failed unexpectedly with no analysis data');
533
+ },
534
+ whenDone: ({ counters }) => {
535
+ const { detectedOutputs, problematicOutputs, successRate } = counters;
536
+ const migratedOutputs = detectedOutputs - problematicOutputs;
537
+ const successRatePercent = (successRate * 100).toFixed(2);
538
+ context.logger.info('');
539
+ context.logger.info(`Successfully migrated to outputs as functions 🎉`);
540
+ context.logger.info(` -> Migrated ${migratedOutputs} out of ${detectedOutputs} detected outputs (${successRatePercent} %).`);
541
+ },
542
+ });
577
543
  };
578
544
  }
579
545
 
@@ -1,6 +1,6 @@
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
  */
@@ -1,6 +1,6 @@
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
  */
@@ -8,23 +8,19 @@
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
  /**
16
12
  * Gets the text of the given property name. Returns null if the property
17
13
  * name couldn't be determined statically.
18
14
  */
19
15
  function getPropertyNameText(node) {
20
- if (ts__default["default"].isIdentifier(node) || ts__default["default"].isStringLiteralLike(node)) {
16
+ if (ts.isIdentifier(node) || ts.isStringLiteralLike(node)) {
21
17
  return node.text;
22
18
  }
23
19
  return null;
24
20
  }
25
21
  /** Finds a property with a specific name in an object literal expression. */
26
22
  function findLiteralProperty(literal, name) {
27
- return literal.properties.find((prop) => prop.name && ts__default["default"].isIdentifier(prop.name) && prop.name.text === name);
23
+ return literal.properties.find((prop) => prop.name && ts.isIdentifier(prop.name) && prop.name.text === name);
28
24
  }
29
25
 
30
26
  exports.findLiteralProperty = findLiteralProperty;