@angular/core 20.0.0-next.0 → 20.0.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/core.mjs +3307 -4479
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/di.mjs +45 -0
- package/fesm2022/primitives/di.mjs.map +1 -0
- package/fesm2022/primitives/event-dispatch.mjs +3 -590
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +19 -9
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +8 -33
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +392 -250
- package/fesm2022/testing.mjs.map +1 -1
- package/fesm2022/weak_ref-DrMdAIDh.mjs +12 -0
- package/fesm2022/weak_ref-DrMdAIDh.mjs.map +1 -0
- package/index.d.ts +14339 -15134
- package/navigation_types.d-u4EOrrdZ.d.ts +121 -0
- package/package.json +11 -1
- package/primitives/di/index.d.ts +91 -0
- package/primitives/event-dispatch/index.d.ts +206 -310
- package/primitives/signals/index.d.ts +159 -196
- package/rxjs-interop/index.d.ts +72 -92
- package/schematics/bundles/{apply_import_manager-0959b78c.js → apply_import_manager-CyRT0UvU.js} +13 -17
- package/schematics/bundles/{checker-cf6f7980.js → checker-DF8ZaFW5.js} +3363 -1289
- package/schematics/bundles/cleanup-unused-imports.js +22 -28
- package/schematics/bundles/{compiler_host-cc1379e9.js → compiler_host-Da636uJ8.js} +20 -24
- package/schematics/bundles/control-flow-migration.js +82 -39
- package/schematics/bundles/{imports-31a38653.js → imports-CIX-JgAN.js} +10 -15
- package/schematics/bundles/{index-42d84d69.js → index-DnkWgagp.js} +56 -60
- package/schematics/bundles/{index-6675d6bc.js → index-vGJcp5M7.js} +5 -5
- package/schematics/bundles/inject-flags.js +181 -0
- package/schematics/bundles/inject-migration.js +122 -128
- package/schematics/bundles/{leading_space-6e7a8ec6.js → leading_space-D9nQ8UQC.js} +2 -2
- package/schematics/bundles/{migrate_ts_type_references-5089e4ef.js → migrate_ts_type_references-DtkOnnv0.js} +113 -120
- package/schematics/bundles/{ng_decorators-6878e227.js → ng_decorators-DznZ5jMl.js} +5 -9
- package/schematics/bundles/{nodes-ffdce442.js → nodes-B16H9JUd.js} +3 -7
- package/schematics/bundles/output-migration.js +40 -46
- package/schematics/bundles/{program-362689f0.js → program-BZk27Ndu.js} +846 -2653
- package/schematics/bundles/{project_paths-7d2daa1e.js → project_paths-Jtbi76Bs.js} +26 -24
- package/schematics/bundles/{project_tsconfig_paths-6c9cde78.js → project_tsconfig_paths-CDVxT6Ov.js} +2 -2
- package/schematics/bundles/{property_name-42030525.js → property_name-BBwFuqMe.js} +4 -8
- package/schematics/bundles/route-lazy-loading.js +36 -42
- package/schematics/bundles/self-closing-tags-migration.js +55 -45
- package/schematics/bundles/signal-input-migration.js +61 -68
- package/schematics/bundles/signal-queries-migration.js +48 -55
- package/schematics/bundles/signals.js +10 -12
- package/schematics/bundles/standalone-migration.js +179 -185
- package/schematics/migrations.json +4 -15
- package/testing/index.d.ts +309 -478
- package/weak_ref.d-ttyj86RV.d.ts +9 -0
- package/schematics/bundles/explicit-standalone-flag.js +0 -184
- package/schematics/bundles/pending-tasks.js +0 -103
- package/schematics/bundles/provide-initializer.js +0 -186
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
/**
|
|
3
|
-
* @license Angular v20.0.0-next.0
|
|
4
|
-
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
|
-
* License: MIT
|
|
6
|
-
*/
|
|
7
|
-
'use strict';
|
|
8
|
-
|
|
9
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
10
|
-
|
|
11
|
-
var schematics = require('@angular-devkit/schematics');
|
|
12
|
-
var p = require('path');
|
|
13
|
-
var project_tsconfig_paths = require('./project_tsconfig_paths-6c9cde78.js');
|
|
14
|
-
var compiler_host = require('./compiler_host-cc1379e9.js');
|
|
15
|
-
var ts = require('typescript');
|
|
16
|
-
var imports = require('./imports-31a38653.js');
|
|
17
|
-
require('@angular-devkit/core');
|
|
18
|
-
require('./checker-cf6f7980.js');
|
|
19
|
-
require('os');
|
|
20
|
-
require('fs');
|
|
21
|
-
require('module');
|
|
22
|
-
require('url');
|
|
23
|
-
|
|
24
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
25
|
-
|
|
26
|
-
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
27
|
-
|
|
28
|
-
const CORE = '@angular/core';
|
|
29
|
-
const DIRECTIVE = 'Directive';
|
|
30
|
-
const COMPONENT = 'Component';
|
|
31
|
-
const PIPE = 'Pipe';
|
|
32
|
-
function migrateFile(sourceFile, rewriteFn) {
|
|
33
|
-
const changeTracker = new compiler_host.ChangeTracker(ts__default["default"].createPrinter());
|
|
34
|
-
// Check if there are any imports of the `AfterRenderPhase` enum.
|
|
35
|
-
const coreImports = imports.getNamedImports(sourceFile, CORE);
|
|
36
|
-
if (!coreImports) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const directive = imports.getImportSpecifier(sourceFile, CORE, DIRECTIVE);
|
|
40
|
-
const component = imports.getImportSpecifier(sourceFile, CORE, COMPONENT);
|
|
41
|
-
const pipe = imports.getImportSpecifier(sourceFile, CORE, PIPE);
|
|
42
|
-
if (!directive && !component && !pipe) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
ts__default["default"].forEachChild(sourceFile, function visit(node) {
|
|
46
|
-
ts__default["default"].forEachChild(node, visit);
|
|
47
|
-
// First we need to check for class declarations
|
|
48
|
-
// Decorators will come after
|
|
49
|
-
if (!ts__default["default"].isClassDeclaration(node)) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
ts__default["default"].getDecorators(node)?.forEach((decorator) => {
|
|
53
|
-
if (!ts__default["default"].isDecorator(decorator)) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
const callExpression = decorator.expression;
|
|
57
|
-
if (!ts__default["default"].isCallExpression(callExpression)) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const decoratorIdentifier = callExpression.expression;
|
|
61
|
-
if (!ts__default["default"].isIdentifier(decoratorIdentifier)) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
// Checking the identifier of the decorator by comparing to the import specifier
|
|
65
|
-
switch (decoratorIdentifier.text) {
|
|
66
|
-
case directive?.name.text:
|
|
67
|
-
case component?.name.text:
|
|
68
|
-
case pipe?.name.text:
|
|
69
|
-
break;
|
|
70
|
-
default:
|
|
71
|
-
// It's not a decorator to migrate
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const [decoratorArgument] = callExpression.arguments;
|
|
75
|
-
if (!decoratorArgument || !ts__default["default"].isObjectLiteralExpression(decoratorArgument)) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const properties = decoratorArgument.properties;
|
|
79
|
-
const standaloneProp = getStandaloneProperty(properties);
|
|
80
|
-
const hasImports = decoratorHasImports(decoratorArgument);
|
|
81
|
-
// We'll use the presence of imports to keep the migration idempotent
|
|
82
|
-
// We need to take care of 3 cases
|
|
83
|
-
// - standalone: true => remove the property if we have imports
|
|
84
|
-
// - standalone: false => nothing
|
|
85
|
-
// - No standalone property => add a standalone: false property if there are no imports
|
|
86
|
-
let newProperties;
|
|
87
|
-
if (!standaloneProp) {
|
|
88
|
-
if (!hasImports) {
|
|
89
|
-
const standaloneFalseProperty = ts__default["default"].factory.createPropertyAssignment('standalone', ts__default["default"].factory.createFalse());
|
|
90
|
-
newProperties = [...properties, standaloneFalseProperty];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
else if (standaloneProp.value === ts__default["default"].SyntaxKind.TrueKeyword && hasImports) {
|
|
94
|
-
// To keep the migration idempotent, we'll only remove the standalone prop when there are imports
|
|
95
|
-
newProperties = properties.filter((p) => p !== standaloneProp.property);
|
|
96
|
-
}
|
|
97
|
-
if (newProperties) {
|
|
98
|
-
// At this point we know that we need to add standalone: false or
|
|
99
|
-
// remove an existing standalone: true property.
|
|
100
|
-
const newPropsArr = ts__default["default"].factory.createNodeArray(newProperties);
|
|
101
|
-
const newFirstArg = ts__default["default"].factory.createObjectLiteralExpression(newPropsArr, true);
|
|
102
|
-
changeTracker.replaceNode(decoratorArgument, newFirstArg);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
// Write the changes.
|
|
107
|
-
for (const changesInFile of changeTracker.recordChanges().values()) {
|
|
108
|
-
for (const change of changesInFile) {
|
|
109
|
-
rewriteFn(change.start, change.removeLength ?? 0, change.text);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
function getStandaloneProperty(properties) {
|
|
114
|
-
for (const prop of properties) {
|
|
115
|
-
if (ts__default["default"].isShorthandPropertyAssignment(prop) && prop.name.text) {
|
|
116
|
-
return { property: prop, value: prop.objectAssignmentInitializer };
|
|
117
|
-
}
|
|
118
|
-
if (isStandaloneProperty(prop)) {
|
|
119
|
-
if (prop.initializer.kind === ts__default["default"].SyntaxKind.TrueKeyword ||
|
|
120
|
-
prop.initializer.kind === ts__default["default"].SyntaxKind.FalseKeyword) {
|
|
121
|
-
return { property: prop, value: prop.initializer.kind };
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
return { property: prop, value: prop.initializer };
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
130
|
-
function isStandaloneProperty(prop) {
|
|
131
|
-
return (ts__default["default"].isPropertyAssignment(prop) && ts__default["default"].isIdentifier(prop.name) && prop.name.text === 'standalone');
|
|
132
|
-
}
|
|
133
|
-
function decoratorHasImports(decoratorArgument) {
|
|
134
|
-
for (const prop of decoratorArgument.properties) {
|
|
135
|
-
if (ts__default["default"].isPropertyAssignment(prop) &&
|
|
136
|
-
ts__default["default"].isIdentifier(prop.name) &&
|
|
137
|
-
prop.name.text === 'imports') {
|
|
138
|
-
if (prop.initializer.kind === ts__default["default"].SyntaxKind.ArrayLiteralExpression ||
|
|
139
|
-
prop.initializer.kind === ts__default["default"].SyntaxKind.Identifier) {
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function migrate() {
|
|
148
|
-
return async (tree) => {
|
|
149
|
-
const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
|
|
150
|
-
const basePath = process.cwd();
|
|
151
|
-
const allPaths = [...buildPaths, ...testPaths];
|
|
152
|
-
if (!allPaths.length) {
|
|
153
|
-
throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the explicit-standalone-flag migration.');
|
|
154
|
-
}
|
|
155
|
-
for (const tsconfigPath of allPaths) {
|
|
156
|
-
runMigration(tree, tsconfigPath, basePath);
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
function runMigration(tree, tsconfigPath, basePath) {
|
|
161
|
-
const program = compiler_host.createMigrationProgram(tree, tsconfigPath, basePath);
|
|
162
|
-
const sourceFiles = program
|
|
163
|
-
.getSourceFiles()
|
|
164
|
-
.filter((sourceFile) => compiler_host.canMigrateFile(basePath, sourceFile, program));
|
|
165
|
-
for (const sourceFile of sourceFiles) {
|
|
166
|
-
let update = null;
|
|
167
|
-
const rewriter = (startPos, width, text) => {
|
|
168
|
-
if (update === null) {
|
|
169
|
-
// Lazily initialize update, because most files will not require migration.
|
|
170
|
-
update = tree.beginUpdate(p.relative(basePath, sourceFile.fileName));
|
|
171
|
-
}
|
|
172
|
-
update.remove(startPos, width);
|
|
173
|
-
if (text !== null) {
|
|
174
|
-
update.insertLeft(startPos, text);
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
migrateFile(sourceFile, rewriter);
|
|
178
|
-
if (update !== null) {
|
|
179
|
-
tree.commitUpdate(update);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
exports.migrate = migrate;
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
/**
|
|
3
|
-
* @license Angular v20.0.0-next.0
|
|
4
|
-
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
|
-
* License: MIT
|
|
6
|
-
*/
|
|
7
|
-
'use strict';
|
|
8
|
-
|
|
9
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
10
|
-
|
|
11
|
-
var schematics = require('@angular-devkit/schematics');
|
|
12
|
-
var p = require('path');
|
|
13
|
-
var project_tsconfig_paths = require('./project_tsconfig_paths-6c9cde78.js');
|
|
14
|
-
var compiler_host = require('./compiler_host-cc1379e9.js');
|
|
15
|
-
var ts = require('typescript');
|
|
16
|
-
var imports = require('./imports-31a38653.js');
|
|
17
|
-
require('@angular-devkit/core');
|
|
18
|
-
require('./checker-cf6f7980.js');
|
|
19
|
-
require('os');
|
|
20
|
-
require('fs');
|
|
21
|
-
require('module');
|
|
22
|
-
require('url');
|
|
23
|
-
|
|
24
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
25
|
-
|
|
26
|
-
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
27
|
-
|
|
28
|
-
const CORE = '@angular/core';
|
|
29
|
-
const EXPERIMENTAL_PENDING_TASKS = 'ExperimentalPendingTasks';
|
|
30
|
-
function migrateFile(sourceFile, typeChecker, rewriteFn) {
|
|
31
|
-
const changeTracker = new compiler_host.ChangeTracker(ts__default["default"].createPrinter());
|
|
32
|
-
// Check if there are any imports of the `AfterRenderPhase` enum.
|
|
33
|
-
const coreImports = imports.getNamedImports(sourceFile, CORE);
|
|
34
|
-
if (!coreImports) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const importSpecifier = imports.getImportSpecifier(sourceFile, CORE, EXPERIMENTAL_PENDING_TASKS);
|
|
38
|
-
if (!importSpecifier) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
const nodeToReplace = importSpecifier.propertyName ?? importSpecifier.name;
|
|
42
|
-
if (!ts__default["default"].isIdentifier(nodeToReplace)) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
changeTracker.replaceNode(nodeToReplace, ts__default["default"].factory.createIdentifier('PendingTasks'));
|
|
46
|
-
ts__default["default"].forEachChild(sourceFile, function visit(node) {
|
|
47
|
-
// import handled above
|
|
48
|
-
if (ts__default["default"].isImportDeclaration(node)) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
if (ts__default["default"].isIdentifier(node) &&
|
|
52
|
-
node.text === EXPERIMENTAL_PENDING_TASKS &&
|
|
53
|
-
imports.getImportOfIdentifier(typeChecker, node)?.name === EXPERIMENTAL_PENDING_TASKS) {
|
|
54
|
-
changeTracker.replaceNode(node, ts__default["default"].factory.createIdentifier('PendingTasks'));
|
|
55
|
-
}
|
|
56
|
-
ts__default["default"].forEachChild(node, visit);
|
|
57
|
-
});
|
|
58
|
-
// Write the changes.
|
|
59
|
-
for (const changesInFile of changeTracker.recordChanges().values()) {
|
|
60
|
-
for (const change of changesInFile) {
|
|
61
|
-
rewriteFn(change.start, change.removeLength ?? 0, change.text);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function migrate() {
|
|
67
|
-
return async (tree) => {
|
|
68
|
-
const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
|
|
69
|
-
const basePath = process.cwd();
|
|
70
|
-
const allPaths = [...buildPaths, ...testPaths];
|
|
71
|
-
if (!allPaths.length) {
|
|
72
|
-
throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the afterRender phase migration.');
|
|
73
|
-
}
|
|
74
|
-
for (const tsconfigPath of allPaths) {
|
|
75
|
-
runMigration(tree, tsconfigPath, basePath);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function runMigration(tree, tsconfigPath, basePath) {
|
|
80
|
-
const program = compiler_host.createMigrationProgram(tree, tsconfigPath, basePath);
|
|
81
|
-
const sourceFiles = program
|
|
82
|
-
.getSourceFiles()
|
|
83
|
-
.filter((sourceFile) => compiler_host.canMigrateFile(basePath, sourceFile, program));
|
|
84
|
-
for (const sourceFile of sourceFiles) {
|
|
85
|
-
let update = null;
|
|
86
|
-
const rewriter = (startPos, width, text) => {
|
|
87
|
-
if (update === null) {
|
|
88
|
-
// Lazily initialize update, because most files will not require migration.
|
|
89
|
-
update = tree.beginUpdate(p.relative(basePath, sourceFile.fileName));
|
|
90
|
-
}
|
|
91
|
-
update.remove(startPos, width);
|
|
92
|
-
if (text !== null) {
|
|
93
|
-
update.insertLeft(startPos, text);
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
migrateFile(sourceFile, program.getTypeChecker(), rewriter);
|
|
97
|
-
if (update !== null) {
|
|
98
|
-
tree.commitUpdate(update);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
exports.migrate = migrate;
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
/**
|
|
3
|
-
* @license Angular v20.0.0-next.0
|
|
4
|
-
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
|
-
* License: MIT
|
|
6
|
-
*/
|
|
7
|
-
'use strict';
|
|
8
|
-
|
|
9
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
10
|
-
|
|
11
|
-
var schematics = require('@angular-devkit/schematics');
|
|
12
|
-
var p = require('path');
|
|
13
|
-
var project_tsconfig_paths = require('./project_tsconfig_paths-6c9cde78.js');
|
|
14
|
-
var compiler_host = require('./compiler_host-cc1379e9.js');
|
|
15
|
-
var ts = require('typescript');
|
|
16
|
-
var imports = require('./imports-31a38653.js');
|
|
17
|
-
require('@angular-devkit/core');
|
|
18
|
-
require('./checker-cf6f7980.js');
|
|
19
|
-
require('os');
|
|
20
|
-
require('fs');
|
|
21
|
-
require('module');
|
|
22
|
-
require('url');
|
|
23
|
-
|
|
24
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
25
|
-
|
|
26
|
-
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
27
|
-
|
|
28
|
-
function migrateFile(sourceFile, rewriteFn) {
|
|
29
|
-
const changeTracker = new compiler_host.ChangeTracker(ts__default["default"].createPrinter());
|
|
30
|
-
const visitNode = (node) => {
|
|
31
|
-
const provider = tryParseProviderExpression(node);
|
|
32
|
-
if (provider) {
|
|
33
|
-
replaceProviderWithNewApi({
|
|
34
|
-
sourceFile,
|
|
35
|
-
node,
|
|
36
|
-
provider,
|
|
37
|
-
changeTracker,
|
|
38
|
-
});
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
ts__default["default"].forEachChild(node, visitNode);
|
|
42
|
-
};
|
|
43
|
-
ts__default["default"].forEachChild(sourceFile, visitNode);
|
|
44
|
-
for (const change of changeTracker.recordChanges().get(sourceFile)?.values() ?? []) {
|
|
45
|
-
rewriteFn(change.start, change.removeLength ?? 0, change.text);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function replaceProviderWithNewApi({ sourceFile, node, provider, changeTracker, }) {
|
|
49
|
-
const { initializerCode, importInject, provideInitializerFunctionName, initializerToken } = provider;
|
|
50
|
-
const initializerTokenSpecifier = imports.getImportSpecifier(sourceFile, angularCoreModule, initializerToken);
|
|
51
|
-
// The token doesn't come from `@angular/core`.
|
|
52
|
-
if (!initializerTokenSpecifier) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
// Replace the provider with the new provide function.
|
|
56
|
-
changeTracker.replaceText(sourceFile, node.getStart(), node.getWidth(), `${provideInitializerFunctionName}(${initializerCode})`);
|
|
57
|
-
// Remove the `*_INITIALIZER` token from imports.
|
|
58
|
-
changeTracker.removeImport(sourceFile, initializerToken, angularCoreModule);
|
|
59
|
-
// Add the `inject` function to imports if needed.
|
|
60
|
-
if (importInject) {
|
|
61
|
-
changeTracker.addImport(sourceFile, 'inject', angularCoreModule);
|
|
62
|
-
}
|
|
63
|
-
// Add the `provide*Initializer` function to imports.
|
|
64
|
-
changeTracker.addImport(sourceFile, provideInitializerFunctionName, angularCoreModule);
|
|
65
|
-
}
|
|
66
|
-
function tryParseProviderExpression(node) {
|
|
67
|
-
if (!ts__default["default"].isObjectLiteralExpression(node)) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
let deps = [];
|
|
71
|
-
let initializerToken;
|
|
72
|
-
let useExisting;
|
|
73
|
-
let useFactoryCode;
|
|
74
|
-
let useValue;
|
|
75
|
-
let multi = false;
|
|
76
|
-
for (const property of node.properties) {
|
|
77
|
-
if (ts__default["default"].isPropertyAssignment(property) && ts__default["default"].isIdentifier(property.name)) {
|
|
78
|
-
switch (property.name.text) {
|
|
79
|
-
case 'deps':
|
|
80
|
-
if (ts__default["default"].isArrayLiteralExpression(property.initializer)) {
|
|
81
|
-
deps = property.initializer.elements.map((el) => el.getText());
|
|
82
|
-
}
|
|
83
|
-
break;
|
|
84
|
-
case 'provide':
|
|
85
|
-
initializerToken = property.initializer.getText();
|
|
86
|
-
break;
|
|
87
|
-
case 'useExisting':
|
|
88
|
-
useExisting = property.initializer;
|
|
89
|
-
break;
|
|
90
|
-
case 'useFactory':
|
|
91
|
-
useFactoryCode = property.initializer.getText();
|
|
92
|
-
break;
|
|
93
|
-
case 'useValue':
|
|
94
|
-
useValue = property.initializer;
|
|
95
|
-
break;
|
|
96
|
-
case 'multi':
|
|
97
|
-
multi = property.initializer.kind === ts__default["default"].SyntaxKind.TrueKeyword;
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// Handle the `useFactory() {}` shorthand case.
|
|
102
|
-
if (ts__default["default"].isMethodDeclaration(property) && property.name.getText() === 'useFactory') {
|
|
103
|
-
const params = property.parameters.map((param) => param.getText()).join(', ');
|
|
104
|
-
useFactoryCode = `(${params}) => ${property.body?.getText()}`;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (!initializerToken || !multi) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const provideInitializerFunctionName = initializerTokenToFunctionMap.get(initializerToken);
|
|
111
|
-
if (!provideInitializerFunctionName) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
const info = {
|
|
115
|
-
initializerToken,
|
|
116
|
-
provideInitializerFunctionName,
|
|
117
|
-
importInject: false,
|
|
118
|
-
};
|
|
119
|
-
if (useExisting) {
|
|
120
|
-
return {
|
|
121
|
-
...info,
|
|
122
|
-
importInject: true,
|
|
123
|
-
initializerCode: `() => inject(${useExisting.getText()})()`,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
if (useFactoryCode) {
|
|
127
|
-
const args = deps.map((dep) => `inject(${dep})`);
|
|
128
|
-
return {
|
|
129
|
-
...info,
|
|
130
|
-
importInject: deps.length > 0,
|
|
131
|
-
initializerCode: `() => {
|
|
132
|
-
const initializerFn = (${useFactoryCode})(${args.join(', ')});
|
|
133
|
-
return initializerFn();
|
|
134
|
-
}`,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
if (useValue) {
|
|
138
|
-
return { ...info, initializerCode: useValue.getText() };
|
|
139
|
-
}
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
const angularCoreModule = '@angular/core';
|
|
143
|
-
const initializerTokenToFunctionMap = new Map([
|
|
144
|
-
['APP_INITIALIZER', 'provideAppInitializer'],
|
|
145
|
-
['ENVIRONMENT_INITIALIZER', 'provideEnvironmentInitializer'],
|
|
146
|
-
['PLATFORM_INITIALIZER', 'providePlatformInitializer'],
|
|
147
|
-
]);
|
|
148
|
-
|
|
149
|
-
function migrate() {
|
|
150
|
-
return async (tree) => {
|
|
151
|
-
const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
|
|
152
|
-
const basePath = process.cwd();
|
|
153
|
-
const allPaths = [...buildPaths, ...testPaths];
|
|
154
|
-
if (!allPaths.length) {
|
|
155
|
-
throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the provide initializer migration.');
|
|
156
|
-
}
|
|
157
|
-
for (const tsconfigPath of allPaths) {
|
|
158
|
-
runMigration(tree, tsconfigPath, basePath);
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
function runMigration(tree, tsconfigPath, basePath) {
|
|
163
|
-
const program = compiler_host.createMigrationProgram(tree, tsconfigPath, basePath);
|
|
164
|
-
const sourceFiles = program
|
|
165
|
-
.getSourceFiles()
|
|
166
|
-
.filter((sourceFile) => compiler_host.canMigrateFile(basePath, sourceFile, program));
|
|
167
|
-
for (const sourceFile of sourceFiles) {
|
|
168
|
-
let update = null;
|
|
169
|
-
const rewriter = (startPos, width, text) => {
|
|
170
|
-
if (update === null) {
|
|
171
|
-
// Lazily initialize update, because most files will not require migration.
|
|
172
|
-
update = tree.beginUpdate(p.relative(basePath, sourceFile.fileName));
|
|
173
|
-
}
|
|
174
|
-
update.remove(startPos, width);
|
|
175
|
-
if (text !== null) {
|
|
176
|
-
update.insertLeft(startPos, text);
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
migrateFile(sourceFile, rewriter);
|
|
180
|
-
if (update !== null) {
|
|
181
|
-
tree.commitUpdate(update);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
exports.migrate = migrate;
|