@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.
- package/fesm2022/core.mjs +13699 -13802
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +2 -2
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +6 -6
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +28 -62
- package/package.json +1 -1
- package/primitives/event-dispatch/index.d.ts +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/bundles/{checker-2451e7c5.js → checker-cd95ebda.js} +191 -169
- package/schematics/bundles/combine_units-528c4a5d.js +1703 -0
- package/schematics/bundles/{compiler_host-f54f8309.js → compiler_host-40e8d55f.js} +8 -5
- package/schematics/bundles/control-flow-migration.js +3 -3
- package/schematics/bundles/explicit-standalone-flag.js +5 -5
- package/schematics/bundles/{imports-44987700.js → imports-4ac08251.js} +1 -1
- package/schematics/bundles/inject-migration.js +131 -37
- package/schematics/bundles/{leading_space-6e7a8ec6.js → leading_space-d190b83b.js} +1 -1
- package/schematics/bundles/{migrate_ts_type_references-ab18a7c3.js → migrate_ts_type_references-0bcee7cb.js} +528 -32
- package/schematics/bundles/{ng_decorators-3ad437d2.js → nodes-0e7d45ca.js} +15 -2
- package/schematics/bundles/output-migration.js +30 -6906
- package/schematics/bundles/pending-tasks.js +5 -5
- package/schematics/bundles/{program-58424797.js → program-8f30df93.js} +119 -59
- package/schematics/bundles/{project_tsconfig_paths-6c9cde78.js → project_tsconfig_paths-e9ccccbf.js} +1 -1
- package/schematics/bundles/provide-initializer.js +17 -28
- package/schematics/bundles/route-lazy-loading.js +10 -5
- package/schematics/bundles/signal-input-migration.js +50 -37
- package/schematics/bundles/signal-queries-migration.js +26 -19
- package/schematics/bundles/signals.js +7 -7
- package/schematics/bundles/standalone-migration.js +167 -84
- package/schematics/migrations.json +1 -1
- package/schematics/ng-generate/signals/schema.json +1 -0
- package/testing/index.d.ts +1 -1
- package/schematics/bundles/combine_units-c52492ab.js +0 -31202
- 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.
|
|
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-
|
|
15
|
-
var program = require('./program-
|
|
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-
|
|
19
|
-
var project_tsconfig_paths = require('./project_tsconfig_paths-
|
|
20
|
-
var
|
|
21
|
-
var
|
|
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.
|
|
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
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
456
|
+
function potentialImportsToExpressions(potentialImports, toFile, tracker, importRemapper) {
|
|
423
457
|
const processedDependencies = importRemapper
|
|
424
|
-
? importRemapper(potentialImports
|
|
458
|
+
? importRemapper(potentialImports)
|
|
425
459
|
: potentialImports;
|
|
426
460
|
return processedDependencies.map((importLocation) => {
|
|
427
461
|
if (importLocation.moduleSpecifier) {
|
|
428
|
-
return tracker.addImport(
|
|
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(
|
|
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
|
|
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,
|
|
620
|
-
const importLocations = typeChecker.getPotentialImportsFor(target,
|
|
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 =
|
|
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
|
|
674
|
-
|
|
675
|
-
if (testBedImport || catalystImport) {
|
|
707
|
+
const { testBed, catalyst } = getTestingImports(sourceFile);
|
|
708
|
+
if (testBed || catalyst) {
|
|
676
709
|
sourceFile.forEachChild(function walk(node) {
|
|
677
|
-
|
|
678
|
-
node.arguments
|
|
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] =
|
|
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,
|
|
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
|
-
|
|
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
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
1187
|
+
const importLocation = findImportLocation(ref, array, checker.PotentialImportMode.Normal, templateTypeChecker);
|
|
1109
1188
|
if (importLocation) {
|
|
1110
1189
|
potentialImports.push(importLocation);
|
|
1111
1190
|
}
|
|
1112
1191
|
}
|
|
1113
|
-
|
|
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 =
|
|
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,
|
|
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,
|
|
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 =
|
|
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
|
-
?
|
|
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`,
|
|
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
|
}
|
package/testing/index.d.ts
CHANGED