@angular/core 19.0.0-rc.0 → 19.0.0-rc.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 (40) hide show
  1. package/fesm2022/core.mjs +13699 -13802
  2. package/fesm2022/core.mjs.map +1 -1
  3. package/fesm2022/primitives/event-dispatch.mjs +2 -2
  4. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  5. package/fesm2022/primitives/signals.mjs +1 -1
  6. package/fesm2022/primitives/signals.mjs.map +1 -1
  7. package/fesm2022/rxjs-interop.mjs +1 -1
  8. package/fesm2022/rxjs-interop.mjs.map +1 -1
  9. package/fesm2022/testing.mjs +6 -6
  10. package/fesm2022/testing.mjs.map +1 -1
  11. package/index.d.ts +28 -62
  12. package/package.json +1 -1
  13. package/primitives/event-dispatch/index.d.ts +1 -1
  14. package/primitives/signals/index.d.ts +1 -1
  15. package/rxjs-interop/index.d.ts +1 -1
  16. package/schematics/bundles/{checker-2451e7c5.js → checker-cd95ebda.js} +191 -169
  17. package/schematics/bundles/combine_units-528c4a5d.js +1703 -0
  18. package/schematics/bundles/{compiler_host-f54f8309.js → compiler_host-40e8d55f.js} +8 -5
  19. package/schematics/bundles/control-flow-migration.js +3 -3
  20. package/schematics/bundles/explicit-standalone-flag.js +5 -5
  21. package/schematics/bundles/{imports-44987700.js → imports-4ac08251.js} +1 -1
  22. package/schematics/bundles/inject-migration.js +131 -37
  23. package/schematics/bundles/{leading_space-6e7a8ec6.js → leading_space-d190b83b.js} +1 -1
  24. package/schematics/bundles/{migrate_ts_type_references-ab18a7c3.js → migrate_ts_type_references-0bcee7cb.js} +528 -32
  25. package/schematics/bundles/{ng_decorators-3ad437d2.js → nodes-0e7d45ca.js} +15 -2
  26. package/schematics/bundles/output-migration.js +30 -6906
  27. package/schematics/bundles/pending-tasks.js +5 -5
  28. package/schematics/bundles/{program-58424797.js → program-8f30df93.js} +119 -59
  29. package/schematics/bundles/{project_tsconfig_paths-6c9cde78.js → project_tsconfig_paths-e9ccccbf.js} +1 -1
  30. package/schematics/bundles/provide-initializer.js +17 -28
  31. package/schematics/bundles/route-lazy-loading.js +10 -5
  32. package/schematics/bundles/signal-input-migration.js +50 -37
  33. package/schematics/bundles/signal-queries-migration.js +26 -19
  34. package/schematics/bundles/signals.js +7 -7
  35. package/schematics/bundles/standalone-migration.js +167 -84
  36. package/schematics/migrations.json +1 -1
  37. package/schematics/ng-generate/signals/schema.json +1 -0
  38. package/testing/index.d.ts +1 -1
  39. package/schematics/bundles/combine_units-c52492ab.js +0 -31202
  40. package/schematics/bundles/nodes-ffdce442.js +0 -27
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v19.0.0-rc.0
3
+ * @license Angular v19.0.0-rc.2
4
4
  * (c) 2010-2024 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -11,15 +11,14 @@ Object.defineProperty(exports, '__esModule', { value: true });
11
11
  var schematics = require('@angular-devkit/schematics');
12
12
  require('os');
13
13
  var ts = require('typescript');
14
- var checker = require('./checker-2451e7c5.js');
15
- var program = require('./program-58424797.js');
14
+ var checker = require('./checker-cd95ebda.js');
15
+ var program = require('./program-8f30df93.js');
16
16
  var p = require('path');
17
17
  var fs = require('fs');
18
- var compiler_host = require('./compiler_host-f54f8309.js');
19
- var project_tsconfig_paths = require('./project_tsconfig_paths-6c9cde78.js');
20
- var ng_decorators = require('./ng_decorators-3ad437d2.js');
21
- var nodes = require('./nodes-ffdce442.js');
22
- var imports = require('./imports-44987700.js');
18
+ var compiler_host = require('./compiler_host-40e8d55f.js');
19
+ var project_tsconfig_paths = require('./project_tsconfig_paths-e9ccccbf.js');
20
+ var nodes = require('./nodes-0e7d45ca.js');
21
+ var imports = require('./imports-4ac08251.js');
23
22
  require('module');
24
23
  require('url');
25
24
  require('@angular-devkit/core');
@@ -33,7 +32,7 @@ var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
33
32
  * @description
34
33
  * Entry point for all public APIs of the compiler-cli package.
35
34
  */
36
- new checker.Version('19.0.0-rc.0');
35
+ new checker.Version('19.0.0-rc.2');
37
36
 
38
37
  function createProgram({ rootNames, options, host, oldProgram, }) {
39
38
  return new program.NgtscProgram(rootNames, options, host, oldProgram);
@@ -49,6 +48,20 @@ var LogLevel;
49
48
 
50
49
  checker.setFileSystem(new checker.NodeJSFileSystem());
51
50
 
51
+ /** Checks whether a node is referring to a specific import specifier. */
52
+ function isReferenceToImport(typeChecker, node, importSpecifier) {
53
+ // If this function is called on an identifier (should be most cases), we can quickly rule out
54
+ // non-matches by comparing the identifier's string and the local name of the import specifier
55
+ // which saves us some calls to the type checker.
56
+ if (ts__default["default"].isIdentifier(node) && node.text !== importSpecifier.name.text) {
57
+ return false;
58
+ }
59
+ const nodeSymbol = typeChecker.getTypeAtLocation(node).getSymbol();
60
+ const importSymbol = typeChecker.getTypeAtLocation(importSpecifier).getSymbol();
61
+ return (!!(nodeSymbol?.declarations?.[0] && importSymbol?.declarations?.[0]) &&
62
+ nodeSymbol.declarations[0] === importSymbol.declarations[0]);
63
+ }
64
+
52
65
  /*!
53
66
  * @license
54
67
  * Copyright Google LLC All Rights Reserved.
@@ -74,6 +87,9 @@ class UniqueItemTracker {
74
87
  getEntries() {
75
88
  return this._nodes.entries();
76
89
  }
90
+ isEmpty() {
91
+ return this._nodes.size === 0;
92
+ }
77
93
  }
78
94
  /** Resolves references to nodes. */
79
95
  class ReferenceResolver {
@@ -295,19 +311,37 @@ function isClassReferenceInAngularModule(node, className, moduleName, typeChecke
295
311
  : className.test(closestClass.name.text);
296
312
  });
297
313
  }
298
-
299
- /** Checks whether a node is referring to a specific import specifier. */
300
- function isReferenceToImport(typeChecker, node, importSpecifier) {
301
- // If this function is called on an identifier (should be most cases), we can quickly rule out
302
- // non-matches by comparing the identifier's string and the local name of the import specifier
303
- // which saves us some calls to the type checker.
304
- if (ts__default["default"].isIdentifier(node) && node.text !== importSpecifier.name.text) {
305
- return false;
306
- }
307
- const nodeSymbol = typeChecker.getTypeAtLocation(node).getSymbol();
308
- const importSymbol = typeChecker.getTypeAtLocation(importSpecifier).getSymbol();
309
- return (!!(nodeSymbol?.declarations?.[0] && importSymbol?.declarations?.[0]) &&
310
- nodeSymbol.declarations[0] === importSymbol.declarations[0]);
314
+ /**
315
+ * Finds the imports of testing libraries in a file.
316
+ */
317
+ function getTestingImports(sourceFile) {
318
+ return {
319
+ testBed: imports.getImportSpecifier(sourceFile, '@angular/core/testing', 'TestBed'),
320
+ catalyst: imports.getImportSpecifier(sourceFile, /testing\/catalyst(\/(fake_)?async)?$/, 'setupModule'),
321
+ };
322
+ }
323
+ /**
324
+ * Determines if a node is a call to a testing API.
325
+ * @param typeChecker Type checker to use when resolving references.
326
+ * @param node Node to check.
327
+ * @param testBedImport Import of TestBed within the file.
328
+ * @param catalystImport Import of Catalyst within the file.
329
+ */
330
+ function isTestCall(typeChecker, node, testBedImport, catalystImport) {
331
+ const isObjectLiteralCall = ts__default["default"].isCallExpression(node) &&
332
+ node.arguments.length > 0 &&
333
+ // `arguments[0]` is the testing module config.
334
+ ts__default["default"].isObjectLiteralExpression(node.arguments[0]);
335
+ const isTestBedCall = isObjectLiteralCall &&
336
+ testBedImport &&
337
+ ts__default["default"].isPropertyAccessExpression(node.expression) &&
338
+ node.expression.name.text === 'configureTestingModule' &&
339
+ isReferenceToImport(typeChecker, node.expression.expression, testBedImport);
340
+ const isCatalystCall = isObjectLiteralCall &&
341
+ catalystImport &&
342
+ ts__default["default"].isIdentifier(node.expression) &&
343
+ isReferenceToImport(typeChecker, node.expression, catalystImport);
344
+ return !!(isTestBedCall || isCatalystCall);
311
345
  }
312
346
 
313
347
  /*!
@@ -323,10 +357,10 @@ function isReferenceToImport(typeChecker, node, importSpecifier) {
323
357
  * @param program
324
358
  * @param printer
325
359
  * @param fileImportRemapper Optional function that can be used to remap file-level imports.
326
- * @param componentImportRemapper Optional function that can be used to remap component-level
360
+ * @param declarationImportRemapper Optional function that can be used to remap declaration-level
327
361
  * imports.
328
362
  */
329
- function toStandalone(sourceFiles, program, printer, fileImportRemapper, componentImportRemapper) {
363
+ function toStandalone(sourceFiles, program, printer, fileImportRemapper, declarationImportRemapper) {
330
364
  const templateTypeChecker = program.compiler.getTemplateTypeChecker();
331
365
  const typeChecker = program.getTsProgram().getTypeChecker();
332
366
  const modulesToMigrate = new Set();
@@ -347,7 +381,7 @@ function toStandalone(sourceFiles, program, printer, fileImportRemapper, compone
347
381
  testObjects.forEach((obj) => testObjectsToMigrate.add(obj));
348
382
  }
349
383
  for (const declaration of declarations) {
350
- convertNgModuleDeclarationToStandalone(declaration, declarations, tracker, templateTypeChecker, componentImportRemapper);
384
+ convertNgModuleDeclarationToStandalone(declaration, declarations, tracker, templateTypeChecker, declarationImportRemapper);
351
385
  }
352
386
  for (const node of modulesToMigrate) {
353
387
  migrateNgModuleClass(node, declarations, tracker, typeChecker, templateTypeChecker);
@@ -409,7 +443,7 @@ function getComponentImportExpressions(decl, allDeclarations, tracker, typeCheck
409
443
  resolvedDependencies.push(importLocation);
410
444
  }
411
445
  }
412
- return potentialImportsToExpressions(resolvedDependencies, decl, tracker, importRemapper);
446
+ return potentialImportsToExpressions(resolvedDependencies, decl.getSourceFile(), tracker, importRemapper);
413
447
  }
414
448
  /**
415
449
  * Converts an array of potential imports to an array of expressions that can be
@@ -419,19 +453,19 @@ function getComponentImportExpressions(decl, allDeclarations, tracker, typeCheck
419
453
  * @param tracker
420
454
  * @param importRemapper
421
455
  */
422
- function potentialImportsToExpressions(potentialImports, component, tracker, importRemapper) {
456
+ function potentialImportsToExpressions(potentialImports, toFile, tracker, importRemapper) {
423
457
  const processedDependencies = importRemapper
424
- ? importRemapper(potentialImports, component)
458
+ ? importRemapper(potentialImports)
425
459
  : potentialImports;
426
460
  return processedDependencies.map((importLocation) => {
427
461
  if (importLocation.moduleSpecifier) {
428
- return tracker.addImport(component.getSourceFile(), importLocation.symbolName, importLocation.moduleSpecifier);
462
+ return tracker.addImport(toFile, importLocation.symbolName, importLocation.moduleSpecifier);
429
463
  }
430
464
  const identifier = ts__default["default"].factory.createIdentifier(importLocation.symbolName);
431
465
  if (!importLocation.isForwardReference) {
432
466
  return identifier;
433
467
  }
434
- const forwardRefExpression = tracker.addImport(component.getSourceFile(), 'forwardRef', '@angular/core');
468
+ const forwardRefExpression = tracker.addImport(toFile, 'forwardRef', '@angular/core');
435
469
  const arrowFunction = ts__default["default"].factory.createArrowFunction(undefined, undefined, [], undefined, undefined, identifier);
436
470
  return ts__default["default"].factory.createCallExpression(forwardRefExpression, undefined, [arrowFunction]);
437
471
  });
@@ -612,12 +646,12 @@ function isNamedPropertyAssignment(node) {
612
646
  /**
613
647
  * Finds the import from which to bring in a template dependency of a component.
614
648
  * @param target Dependency that we're searching for.
615
- * @param inComponent Component in which the dependency is used.
649
+ * @param inContext Component in which the dependency is used.
616
650
  * @param importMode Mode in which to resolve the import target.
617
651
  * @param typeChecker
618
652
  */
619
- function findImportLocation(target, inComponent, importMode, typeChecker) {
620
- const importLocations = typeChecker.getPotentialImportsFor(target, inComponent, importMode);
653
+ function findImportLocation(target, inContext, importMode, typeChecker) {
654
+ const importLocations = typeChecker.getPotentialImportsFor(target, inContext, importMode);
621
655
  let firstSameFileImport = null;
622
656
  let firstModuleImport = null;
623
657
  for (const location of importLocations) {
@@ -653,7 +687,7 @@ function findNgModuleClassesToMigrate(sourceFile, typeChecker) {
653
687
  if (imports.getImportSpecifier(sourceFile, '@angular/core', 'NgModule')) {
654
688
  sourceFile.forEachChild(function walk(node) {
655
689
  if (ts__default["default"].isClassDeclaration(node)) {
656
- const decorator = ng_decorators.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(node) || []).find((current) => current.name === 'NgModule');
690
+ const decorator = nodes.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(node) || []).find((current) => current.name === 'NgModule');
657
691
  const metadata = decorator ? extractMetadataLiteral(decorator.node) : null;
658
692
  if (metadata) {
659
693
  const declarations = findLiteralProperty(metadata, 'declarations');
@@ -670,25 +704,11 @@ function findNgModuleClassesToMigrate(sourceFile, typeChecker) {
670
704
  /** Finds all testing object literals that need to be migrated. */
671
705
  function findTestObjectsToMigrate(sourceFile, typeChecker) {
672
706
  const testObjects = [];
673
- const testBedImport = imports.getImportSpecifier(sourceFile, '@angular/core/testing', 'TestBed');
674
- const catalystImport = imports.getImportSpecifier(sourceFile, /testing\/catalyst$/, 'setupModule');
675
- if (testBedImport || catalystImport) {
707
+ const { testBed, catalyst } = getTestingImports(sourceFile);
708
+ if (testBed || catalyst) {
676
709
  sourceFile.forEachChild(function walk(node) {
677
- const isObjectLiteralCall = ts__default["default"].isCallExpression(node) &&
678
- node.arguments.length > 0 &&
679
- // `arguments[0]` is the testing module config.
680
- ts__default["default"].isObjectLiteralExpression(node.arguments[0]);
681
- const config = isObjectLiteralCall ? node.arguments[0] : null;
682
- const isTestBedCall = isObjectLiteralCall &&
683
- testBedImport &&
684
- ts__default["default"].isPropertyAccessExpression(node.expression) &&
685
- node.expression.name.text === 'configureTestingModule' &&
686
- isReferenceToImport(typeChecker, node.expression.expression, testBedImport);
687
- const isCatalystCall = isObjectLiteralCall &&
688
- catalystImport &&
689
- ts__default["default"].isIdentifier(node.expression) &&
690
- isReferenceToImport(typeChecker, node.expression, catalystImport);
691
- if ((isTestBedCall || isCatalystCall) && config) {
710
+ if (isTestCall(typeChecker, node, testBed, catalyst)) {
711
+ const config = node.arguments[0];
692
712
  const declarations = findLiteralProperty(config, 'declarations');
693
713
  if (declarations &&
694
714
  ts__default["default"].isPropertyAssignment(declarations) &&
@@ -850,7 +870,7 @@ function analyzeTestingModules(testObjects, typeChecker) {
850
870
  if (seenDeclarations.has(decl)) {
851
871
  continue;
852
872
  }
853
- const [decorator] = ng_decorators.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(decl) || []);
873
+ const [decorator] = nodes.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(decl) || []);
854
874
  if (decorator) {
855
875
  seenDeclarations.add(decl);
856
876
  decorators.push(decorator);
@@ -923,7 +943,7 @@ function isStandaloneDeclaration(node, declarationsInMigration, templateTypeChec
923
943
  * Use of this source code is governed by an MIT-style license that can be
924
944
  * found in the LICENSE file at https://angular.dev/license
925
945
  */
926
- function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, printer, importRemapper, referenceLookupExcludedFiles, componentImportRemapper) {
946
+ function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, printer, importRemapper, referenceLookupExcludedFiles, declarationImportRemapper) {
927
947
  const filesToRemove = new Set();
928
948
  const tracker = new compiler_host.ChangeTracker(printer, importRemapper);
929
949
  const tsProgram = program.getTsProgram();
@@ -939,10 +959,11 @@ function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, pri
939
959
  const classesToRemove = new Set();
940
960
  const barrelExports = new UniqueItemTracker();
941
961
  const componentImportArrays = new UniqueItemTracker();
962
+ const testArrays = new UniqueItemTracker();
942
963
  const nodesToRemove = new Set();
943
964
  sourceFiles.forEach(function walk(node) {
944
965
  if (ts__default["default"].isClassDeclaration(node) && canRemoveClass(node, typeChecker)) {
945
- collectChangeLocations(node, removalLocations, componentImportArrays, templateTypeChecker, referenceResolver, program);
966
+ collectChangeLocations(node, removalLocations, componentImportArrays, testArrays, templateTypeChecker, referenceResolver, program);
946
967
  classesToRemove.add(node);
947
968
  }
948
969
  else if (ts__default["default"].isExportDeclaration(node) &&
@@ -959,7 +980,8 @@ function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, pri
959
980
  }
960
981
  node.forEachChild(walk);
961
982
  });
962
- replaceInImportsArray(componentImportArrays, classesToRemove, tracker, typeChecker, templateTypeChecker, componentImportRemapper);
983
+ replaceInComponentImportsArray(componentImportArrays, classesToRemove, tracker, typeChecker, templateTypeChecker, declarationImportRemapper);
984
+ replaceInTestImportsArray(testArrays, removalLocations, classesToRemove, tracker, typeChecker, templateTypeChecker, declarationImportRemapper);
963
985
  // We collect all the places where we need to remove references first before generating the
964
986
  // removal instructions since we may have to remove multiple references from one node.
965
987
  removeArrayReferences(removalLocations.arrays, tracker);
@@ -998,12 +1020,14 @@ function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, pri
998
1020
  * @param ngModule Module being removed.
999
1021
  * @param removalLocations Tracks the different places from which the class should be removed.
1000
1022
  * @param componentImportArrays Set of `imports` arrays of components that need to be adjusted.
1023
+ * @param testImportArrays Set of `imports` arrays of tests that need to be adjusted.
1001
1024
  * @param referenceResolver
1002
1025
  * @param program
1003
1026
  */
1004
- function collectChangeLocations(ngModule, removalLocations, componentImportArrays, templateTypeChecker, referenceResolver, program) {
1027
+ function collectChangeLocations(ngModule, removalLocations, componentImportArrays, testImportArrays, templateTypeChecker, referenceResolver, program) {
1005
1028
  const refsByFile = referenceResolver.findReferencesInProject(ngModule.name);
1006
1029
  const tsProgram = program.getTsProgram();
1030
+ const typeChecker = tsProgram.getTypeChecker();
1007
1031
  const nodes$1 = new Set();
1008
1032
  for (const [fileName, refs] of refsByFile) {
1009
1033
  const sourceFile = tsProgram.getSourceFile(fileName);
@@ -1015,20 +1039,31 @@ function collectChangeLocations(ngModule, removalLocations, componentImportArray
1015
1039
  const closestArray = nodes.closestNode(node, ts__default["default"].isArrayLiteralExpression);
1016
1040
  if (closestArray) {
1017
1041
  const closestAssignment = nodes.closestNode(closestArray, ts__default["default"].isPropertyAssignment);
1018
- // If the module was flagged as being removable, but it's still being used in a standalone
1019
- // component's `imports` array, it means that it was likely changed outside of the migration
1020
- // and deleting it now will be breaking. Track it separately so it can be handled properly.
1021
1042
  if (closestAssignment && isInImportsArray(closestAssignment, closestArray)) {
1022
- const closestDecorator = nodes.closestNode(closestAssignment, ts__default["default"].isDecorator);
1023
- const closestClass = closestDecorator
1024
- ? nodes.closestNode(closestDecorator, ts__default["default"].isClassDeclaration)
1025
- : null;
1026
- const directiveMeta = closestClass
1027
- ? templateTypeChecker.getDirectiveMetadata(closestClass)
1028
- : null;
1029
- if (directiveMeta && directiveMeta.isComponent && directiveMeta.isStandalone) {
1030
- componentImportArrays.track(closestArray, node);
1031
- continue;
1043
+ const closestCall = nodes.closestNode(closestAssignment, ts__default["default"].isCallExpression);
1044
+ if (closestCall) {
1045
+ const closestDecorator = nodes.closestNode(closestCall, ts__default["default"].isDecorator);
1046
+ const closestClass = closestDecorator
1047
+ ? nodes.closestNode(closestDecorator, ts__default["default"].isClassDeclaration)
1048
+ : null;
1049
+ const directiveMeta = closestClass
1050
+ ? templateTypeChecker.getDirectiveMetadata(closestClass)
1051
+ : null;
1052
+ // If the module was flagged as being removable, but it's still being used in a
1053
+ // standalone component's `imports` array, it means that it was likely changed
1054
+ // outside of the migration and deleting it now will be breaking. Track it
1055
+ // separately so it can be handled properly.
1056
+ if (directiveMeta && directiveMeta.isComponent && directiveMeta.isStandalone) {
1057
+ componentImportArrays.track(closestArray, node);
1058
+ continue;
1059
+ }
1060
+ // If the module is removable and used inside a test's `imports`,
1061
+ // we track it separately so it can be replaced with its `exports`.
1062
+ const { testBed, catalyst } = getTestingImports(node.getSourceFile());
1063
+ if (isTestCall(typeChecker, closestCall, testBed, catalyst)) {
1064
+ testImportArrays.track(closestArray, node);
1065
+ continue;
1066
+ }
1032
1067
  }
1033
1068
  }
1034
1069
  removalLocations.arrays.track(closestArray, node);
@@ -1048,7 +1083,7 @@ function collectChangeLocations(ngModule, removalLocations, componentImportArray
1048
1083
  }
1049
1084
  }
1050
1085
  /**
1051
- * Replaces all the leftover modules in imports arrays with their exports.
1086
+ * Replaces all the leftover modules in component `imports` arrays with their exports.
1052
1087
  * @param componentImportArrays All the imports arrays and their nodes that represent NgModules.
1053
1088
  * @param classesToRemove Set of classes that were marked for removal.
1054
1089
  * @param tracker
@@ -1056,7 +1091,7 @@ function collectChangeLocations(ngModule, removalLocations, componentImportArray
1056
1091
  * @param templateTypeChecker
1057
1092
  * @param importRemapper
1058
1093
  */
1059
- function replaceInImportsArray(componentImportArrays, classesToRemove, tracker, typeChecker, templateTypeChecker, importRemapper) {
1094
+ function replaceInComponentImportsArray(componentImportArrays, classesToRemove, tracker, typeChecker, templateTypeChecker, importRemapper) {
1060
1095
  for (const [array, toReplace] of componentImportArrays.getEntries()) {
1061
1096
  const closestClass = nodes.closestNode(array, ts__default["default"].isClassDeclaration);
1062
1097
  if (!closestClass) {
@@ -1082,21 +1117,65 @@ function replaceInImportsArray(componentImportArrays, classesToRemove, tracker,
1082
1117
  }
1083
1118
  }
1084
1119
  }
1085
- replaceModulesInImportsArray(array, closestClass, replacements, tracker, templateTypeChecker, importRemapper);
1120
+ replaceModulesInImportsArray(array, replacements, tracker, templateTypeChecker, importRemapper);
1121
+ }
1122
+ }
1123
+ /**
1124
+ * Replaces all the leftover modules in testing `imports` arrays with their exports.
1125
+ * @param testImportArrays All test `imports` arrays and their nodes that represent modules.
1126
+ * @param classesToRemove Classes marked for removal by the migration.
1127
+ * @param tracker
1128
+ * @param typeChecker
1129
+ * @param templateTypeChecker
1130
+ * @param importRemapper
1131
+ */
1132
+ function replaceInTestImportsArray(testImportArrays, removalLocations, classesToRemove, tracker, typeChecker, templateTypeChecker, importRemapper) {
1133
+ for (const [array, toReplace] of testImportArrays.getEntries()) {
1134
+ const replacements = new UniqueItemTracker();
1135
+ for (const node of toReplace) {
1136
+ const moduleDecl = findClassDeclaration(node, typeChecker);
1137
+ if (moduleDecl) {
1138
+ const moduleMeta = templateTypeChecker.getNgModuleMetadata(moduleDecl);
1139
+ if (moduleMeta) {
1140
+ // Since we don't have access to the template type checker in tests,
1141
+ // we copy over all the `exports` that aren't flagged for removal.
1142
+ const exports = moduleMeta.exports.filter((exp) => !classesToRemove.has(exp.node));
1143
+ if (exports.length > 0) {
1144
+ exports.forEach((exp) => replacements.track(node, exp));
1145
+ }
1146
+ else {
1147
+ removalLocations.arrays.track(array, node);
1148
+ }
1149
+ }
1150
+ else {
1151
+ // It's unlikely not to have module metadata at this point, but just in
1152
+ // case unmark the class for removal to reduce the chance of breakages.
1153
+ classesToRemove.delete(moduleDecl);
1154
+ }
1155
+ }
1156
+ }
1157
+ replaceModulesInImportsArray(array, replacements, tracker, templateTypeChecker, importRemapper);
1086
1158
  }
1087
1159
  }
1088
1160
  /**
1089
- * Replaces any leftover modules in `imports` arrays with their exports that are used within a
1090
- * component.
1161
+ * Replaces any leftover modules in an `imports` arrays with a set of specified exports
1091
1162
  * @param array Imports array which is being migrated.
1092
- * @param componentClass Class that the imports array belongs to.
1093
1163
  * @param replacements Map of NgModule references to their exports.
1094
1164
  * @param tracker
1095
1165
  * @param templateTypeChecker
1096
1166
  * @param importRemapper
1097
1167
  */
1098
- function replaceModulesInImportsArray(array, componentClass, replacements, tracker, templateTypeChecker, importRemapper) {
1168
+ function replaceModulesInImportsArray(array, replacements, tracker, templateTypeChecker, importRemapper) {
1169
+ if (replacements.isEmpty()) {
1170
+ return;
1171
+ }
1099
1172
  const newElements = [];
1173
+ const identifiers = new Set();
1174
+ for (const element of array.elements) {
1175
+ if (ts__default["default"].isIdentifier(element)) {
1176
+ identifiers.add(element.text);
1177
+ }
1178
+ }
1100
1179
  for (const element of array.elements) {
1101
1180
  const replacementRefs = replacements.get(element);
1102
1181
  if (!replacementRefs) {
@@ -1105,12 +1184,16 @@ function replaceModulesInImportsArray(array, componentClass, replacements, track
1105
1184
  }
1106
1185
  const potentialImports = [];
1107
1186
  for (const ref of replacementRefs) {
1108
- const importLocation = findImportLocation(ref, componentClass, checker.PotentialImportMode.Normal, templateTypeChecker);
1187
+ const importLocation = findImportLocation(ref, array, checker.PotentialImportMode.Normal, templateTypeChecker);
1109
1188
  if (importLocation) {
1110
1189
  potentialImports.push(importLocation);
1111
1190
  }
1112
1191
  }
1113
- newElements.push(...potentialImportsToExpressions(potentialImports, componentClass, tracker, importRemapper));
1192
+ potentialImportsToExpressions(potentialImports, array.getSourceFile(), tracker, importRemapper).forEach((expr) => {
1193
+ if (!ts__default["default"].isIdentifier(expr) || !identifiers.has(expr.text)) {
1194
+ newElements.push(expr);
1195
+ }
1196
+ });
1114
1197
  }
1115
1198
  tracker.replaceNode(array, ts__default["default"].factory.updateArrayLiteralExpression(array, newElements));
1116
1199
  }
@@ -1324,7 +1407,7 @@ function addRemovalTodos(nodes, tracker) {
1324
1407
  }
1325
1408
  /** Finds the `NgModule` decorator in a class, if it exists. */
1326
1409
  function findNgModuleDecorator(node, typeChecker) {
1327
- const decorators = ng_decorators.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(node) || []);
1410
+ const decorators = nodes.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(node) || []);
1328
1411
  return decorators.find((decorator) => decorator.name === 'NgModule') || null;
1329
1412
  }
1330
1413
  /**
@@ -1345,7 +1428,7 @@ function isInImportsArray(closestAssignment, closestArray) {
1345
1428
  * Use of this source code is governed by an MIT-style license that can be
1346
1429
  * found in the LICENSE file at https://angular.dev/license
1347
1430
  */
1348
- function toStandaloneBootstrap(program, host, basePath, rootFileNames, sourceFiles, printer, importRemapper, referenceLookupExcludedFiles, componentImportRemapper) {
1431
+ function toStandaloneBootstrap(program, host, basePath, rootFileNames, sourceFiles, printer, importRemapper, referenceLookupExcludedFiles, declarationImportRemapper) {
1349
1432
  const tracker = new compiler_host.ChangeTracker(printer, importRemapper);
1350
1433
  const typeChecker = program.getTsProgram().getTypeChecker();
1351
1434
  const templateTypeChecker = program.compiler.getTemplateTypeChecker();
@@ -1380,7 +1463,7 @@ function toStandaloneBootstrap(program, host, basePath, rootFileNames, sourceFil
1380
1463
  // The previous migrations explicitly skip over bootstrapped
1381
1464
  // declarations so we have to migrate them now.
1382
1465
  for (const declaration of allDeclarations) {
1383
- convertNgModuleDeclarationToStandalone(declaration, allDeclarations, tracker, templateTypeChecker, componentImportRemapper);
1466
+ convertNgModuleDeclarationToStandalone(declaration, allDeclarations, tracker, templateTypeChecker, declarationImportRemapper);
1384
1467
  }
1385
1468
  migrateTestDeclarations(testObjects, allDeclarations, tracker, templateTypeChecker, typeChecker);
1386
1469
  return tracker.recordChanges();
@@ -1400,7 +1483,7 @@ function analyzeBootstrapCall(call, typeChecker, templateTypeChecker) {
1400
1483
  if (!declaration) {
1401
1484
  return null;
1402
1485
  }
1403
- const decorator = ng_decorators.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(declaration) || []).find((decorator) => decorator.name === 'NgModule');
1486
+ const decorator = nodes.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(declaration) || []).find((decorator) => decorator.name === 'NgModule');
1404
1487
  if (!decorator ||
1405
1488
  decorator.node.expression.arguments.length === 0 ||
1406
1489
  !ts__default["default"].isObjectLiteralExpression(decorator.node.expression.arguments[0])) {
@@ -1589,7 +1672,7 @@ function migrateImportsForBootstrapCall(sourceFile, imports, nodeLookup, imports
1589
1672
  : element;
1590
1673
  const classDeclaration = findClassDeclaration(target, typeChecker);
1591
1674
  const decorators = classDeclaration
1592
- ? ng_decorators.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(classDeclaration) || [])
1675
+ ? nodes.getAngularDecorators(typeChecker, ts__default["default"].getDecorators(classDeclaration) || [])
1593
1676
  : undefined;
1594
1677
  if (!decorators ||
1595
1678
  decorators.length === 0 ||
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "provide-initializer": {
14
14
  "version": "19.0.0",
15
- "description": "Replaces `APP_INITIALIZER`, 'ENVIRONMENT_INITIALIZER' & 'PLATFORM_INITIALIZER' respectively with `provideAppInitializer`, `provideEnvironmentInitializer` & `providePlatormInitializer`.",
15
+ "description": "Replaces `APP_INITIALIZER`, `ENVIRONMENT_INITIALIZER` & `PLATFORM_INITIALIZER` respectively with `provideAppInitializer`, `provideEnvironmentInitializer` & `providePlatformInitializer`.",
16
16
  "factory": "./bundles/provide-initializer#migrate",
17
17
  "optional": true
18
18
  }
@@ -8,6 +8,7 @@
8
8
  "type": "array",
9
9
  "default": [
10
10
  "inputs",
11
+ "outputs",
11
12
  "queries"
12
13
  ],
13
14
  "items": {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v19.0.0-rc.0
2
+ * @license Angular v19.0.0-rc.2
3
3
  * (c) 2010-2024 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */