@angular/core 21.0.0-next.0 → 21.0.0-next.10
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/_attribute-chunk.mjs +12 -0
- package/fesm2022/_attribute-chunk.mjs.map +1 -0
- package/fesm2022/_debug_node-chunk.mjs +18469 -0
- package/fesm2022/_debug_node-chunk.mjs.map +1 -0
- package/fesm2022/_effect-chunk.mjs +423 -0
- package/fesm2022/_effect-chunk.mjs.map +1 -0
- package/fesm2022/_effect-chunk2.mjs +2951 -0
- package/fesm2022/_effect-chunk2.mjs.map +1 -0
- package/fesm2022/_not_found-chunk.mjs +39 -0
- package/fesm2022/_not_found-chunk.mjs.map +1 -0
- package/fesm2022/_resource-chunk.mjs +378 -0
- package/fesm2022/_resource-chunk.mjs.map +1 -0
- package/fesm2022/_untracked-chunk.mjs +96 -0
- package/fesm2022/_untracked-chunk.mjs.map +1 -0
- package/fesm2022/_weak_ref-chunk.mjs +10 -0
- package/fesm2022/_weak_ref-chunk.mjs.map +1 -0
- package/fesm2022/core.mjs +2499 -4185
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives-di.mjs +23 -0
- package/fesm2022/primitives-di.mjs.map +1 -0
- package/fesm2022/primitives-event-dispatch.mjs +788 -0
- package/fesm2022/primitives-event-dispatch.mjs.map +1 -0
- package/fesm2022/primitives-signals.mjs +187 -0
- package/fesm2022/primitives-signals.mjs.map +1 -0
- package/fesm2022/rxjs-interop.mjs +210 -308
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +2309 -3170
- package/fesm2022/testing.mjs.map +1 -1
- package/package.json +18 -12
- package/resources/best-practices.md +56 -0
- package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +117 -0
- package/schematics/bundles/application-config-core.cjs +84 -0
- package/schematics/bundles/{apply_import_manager-DR9xXCle.cjs → apply_import_manager-1Zs_gpB6.cjs} +4 -5
- package/schematics/bundles/bootstrap-options-migration.cjs +598 -0
- package/schematics/bundles/cleanup-unused-imports.cjs +9 -13
- package/schematics/bundles/common-to-standalone-migration.cjs +381 -0
- package/schematics/bundles/{compiler_host-BXBP7CE2.cjs → compiler_host-DBwYMlTo.cjs} +10 -11
- package/schematics/bundles/control-flow-migration.cjs +122 -119
- package/schematics/bundles/{imports-CIX-JgAN.cjs → imports-DP72APSx.cjs} +6 -1
- package/schematics/bundles/{index-CfTQUOiz.cjs → index-B7I9sIUx.cjs} +36 -39
- package/schematics/bundles/inject-migration.cjs +148 -70
- package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
- package/schematics/bundles/{migrate_ts_type_references-6NtAj-Wk.cjs → migrate_ts_type_references-UGIUl7En.cjs} +500 -24
- package/schematics/bundles/ng_component_template-Dsuq1Lw7.cjs +185 -0
- package/schematics/bundles/{ng_decorators-B5HCqr20.cjs → ng_decorators-DSFlWYQY.cjs} +2 -2
- package/schematics/bundles/ngclass-to-class-migration.cjs +542 -0
- package/schematics/bundles/ngstyle-to-style-migration.cjs +487 -0
- package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
- package/schematics/bundles/output-migration.cjs +16 -19
- package/schematics/bundles/parse_html-8VLCL37B.cjs +132 -0
- package/schematics/bundles/{project_paths-DcaODbky.cjs → project_paths-DvD50ouC.cjs} +14 -247
- package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +90 -0
- package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
- package/schematics/bundles/route-lazy-loading.cjs +54 -26
- package/schematics/bundles/router-current-navigation.cjs +7 -18
- package/schematics/bundles/router-last-successful-navigation.cjs +7 -18
- package/schematics/bundles/router-testing-module-migration.cjs +502 -0
- package/schematics/bundles/self-closing-tags-migration.cjs +17 -216
- package/schematics/bundles/signal-input-migration.cjs +93 -29
- package/schematics/bundles/signal-queries-migration.cjs +22 -25
- package/schematics/bundles/signals.cjs +10 -13
- package/schematics/bundles/standalone-migration.cjs +135 -102
- package/schematics/bundles/{symbol-VPWguRxr.cjs → symbol-BObKoqes.cjs} +3 -2
- package/schematics/collection.json +23 -0
- package/schematics/migrations/common-to-standalone-migration/schema.json +14 -0
- package/schematics/migrations/ngclass-to-class-migration/schema.json +20 -0
- package/schematics/migrations/ngstyle-to-style-migration/schema.json +20 -0
- package/schematics/migrations/router-testing-module-migration/schema.json +14 -0
- package/schematics/migrations.json +16 -2
- package/{api.d.d.ts → types/_api-chunk.d.ts} +9 -6
- package/{chrome_dev_tools_performance.d.d.ts → types/_chrome_dev_tools_performance-chunk.d.ts} +26 -31
- package/{discovery.d.d.ts → types/_discovery-chunk.d.ts} +135 -98
- package/{signal.d.d.ts → types/_effect-chunk.d.ts} +14 -5
- package/{event_dispatcher.d.d.ts → types/_event_dispatcher-chunk.d.ts} +2 -2
- package/{graph.d.d.ts → types/_formatter-chunk.d.ts} +40 -7
- package/{weak_ref.d.d.ts → types/_weak_ref-chunk.d.ts} +2 -2
- package/{index.d.ts → types/core.d.ts} +233 -305
- package/{primitives/di/index.d.ts → types/primitives-di.d.ts} +2 -2
- package/{primitives/event-dispatch/index.d.ts → types/primitives-event-dispatch.d.ts} +4 -4
- package/{primitives/signals/index.d.ts → types/primitives-signals.d.ts} +7 -8
- package/{rxjs-interop/index.d.ts → types/rxjs-interop.d.ts} +8 -6
- package/{testing/index.d.ts → types/testing.d.ts} +7 -7
- package/fesm2022/attribute.mjs +0 -24
- package/fesm2022/attribute.mjs.map +0 -1
- package/fesm2022/debug_node.mjs +0 -31833
- package/fesm2022/debug_node.mjs.map +0 -1
- package/fesm2022/not_found.mjs +0 -56
- package/fesm2022/not_found.mjs.map +0 -1
- package/fesm2022/primitives/di.mjs +0 -23
- package/fesm2022/primitives/di.mjs.map +0 -1
- package/fesm2022/primitives/event-dispatch.mjs +0 -1622
- package/fesm2022/primitives/event-dispatch.mjs.map +0 -1
- package/fesm2022/primitives/signals.mjs +0 -89
- package/fesm2022/primitives/signals.mjs.map +0 -1
- package/fesm2022/resource.mjs +0 -633
- package/fesm2022/resource.mjs.map +0 -1
- package/fesm2022/root_effect_scheduler.mjs +0 -4007
- package/fesm2022/root_effect_scheduler.mjs.map +0 -1
- package/fesm2022/signal.mjs +0 -560
- package/fesm2022/signal.mjs.map +0 -1
- package/fesm2022/untracked.mjs +0 -117
- package/fesm2022/untracked.mjs.map +0 -1
- package/fesm2022/weak_ref.mjs +0 -12
- package/fesm2022/weak_ref.mjs.map +0 -1
- package/schematics/bundles/index-esqfDjNB.cjs +0 -22074
- package/schematics/bundles/project_tsconfig_paths-CS-eSeHC.cjs +0 -51062
|
@@ -1,233 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v21.0.0-next.
|
|
3
|
+
* @license Angular v21.0.0-next.10
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
9
|
var ts = require('typescript');
|
|
10
|
-
require('
|
|
11
|
-
|
|
12
|
-
require('./index-esqfDjNB.cjs');
|
|
13
|
-
require('path');
|
|
10
|
+
require('@angular/compiler-cli');
|
|
11
|
+
require('@angular/compiler-cli/private/migrations');
|
|
14
12
|
require('node:path');
|
|
15
|
-
var project_paths = require('./project_paths-
|
|
16
|
-
var
|
|
17
|
-
var
|
|
13
|
+
var project_paths = require('./project_paths-DvD50ouC.cjs');
|
|
14
|
+
var ng_component_template = require('./ng_component_template-Dsuq1Lw7.cjs');
|
|
15
|
+
var compiler = require('@angular/compiler');
|
|
16
|
+
var parse_html = require('./parse_html-8VLCL37B.cjs');
|
|
18
17
|
require('@angular-devkit/core');
|
|
19
18
|
require('node:path/posix');
|
|
20
|
-
require('fs');
|
|
21
|
-
require('module');
|
|
22
|
-
require('url');
|
|
23
19
|
require('@angular-devkit/schematics');
|
|
24
|
-
require('./
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* parentheses or as expression. e.g. "(((({exp}))))()". The function should return the
|
|
29
|
-
* TypeScript node referring to the inner expression. e.g "exp".
|
|
30
|
-
*/
|
|
31
|
-
function unwrapExpression(node) {
|
|
32
|
-
if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node)) {
|
|
33
|
-
return unwrapExpression(node.expression);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
return node;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Extracts `@Directive` or `@Component` metadata from the given class. */
|
|
41
|
-
function extractAngularClassMetadata(typeChecker, node) {
|
|
42
|
-
const decorators = ts.getDecorators(node);
|
|
43
|
-
if (!decorators || !decorators.length) {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
const ngDecorators = ng_decorators.getAngularDecorators(typeChecker, decorators);
|
|
47
|
-
const componentDecorator = ngDecorators.find((dec) => dec.name === 'Component');
|
|
48
|
-
const directiveDecorator = ngDecorators.find((dec) => dec.name === 'Directive');
|
|
49
|
-
const decorator = componentDecorator ?? directiveDecorator;
|
|
50
|
-
// In case no decorator could be found on the current class, skip.
|
|
51
|
-
if (!decorator) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
const decoratorCall = decorator.node.expression;
|
|
55
|
-
// In case the decorator call is not valid, skip this class declaration.
|
|
56
|
-
if (decoratorCall.arguments.length !== 1) {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
const metadata = unwrapExpression(decoratorCall.arguments[0]);
|
|
60
|
-
// Ensure that the metadata is an object literal expression.
|
|
61
|
-
if (!ts.isObjectLiteralExpression(metadata)) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
type: componentDecorator ? 'component' : 'directive',
|
|
66
|
-
node: metadata,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const LF_CHAR = 10;
|
|
71
|
-
const CR_CHAR = 13;
|
|
72
|
-
const LINE_SEP_CHAR = 8232;
|
|
73
|
-
const PARAGRAPH_CHAR = 8233;
|
|
74
|
-
/** Gets the line and character for the given position from the line starts map. */
|
|
75
|
-
function getLineAndCharacterFromPosition(lineStartsMap, position) {
|
|
76
|
-
const lineIndex = findClosestLineStartPosition(lineStartsMap, position);
|
|
77
|
-
return { character: position - lineStartsMap[lineIndex], line: lineIndex };
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Computes the line start map of the given text. This can be used in order to
|
|
81
|
-
* retrieve the line and character of a given text position index.
|
|
82
|
-
*/
|
|
83
|
-
function computeLineStartsMap(text) {
|
|
84
|
-
const result = [0];
|
|
85
|
-
let pos = 0;
|
|
86
|
-
while (pos < text.length) {
|
|
87
|
-
const char = text.charCodeAt(pos++);
|
|
88
|
-
// Handles the "CRLF" line break. In that case we peek the character
|
|
89
|
-
// after the "CR" and check if it is a line feed.
|
|
90
|
-
if (char === CR_CHAR) {
|
|
91
|
-
if (text.charCodeAt(pos) === LF_CHAR) {
|
|
92
|
-
pos++;
|
|
93
|
-
}
|
|
94
|
-
result.push(pos);
|
|
95
|
-
}
|
|
96
|
-
else if (char === LF_CHAR || char === LINE_SEP_CHAR || char === PARAGRAPH_CHAR) {
|
|
97
|
-
result.push(pos);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
result.push(pos);
|
|
101
|
-
return result;
|
|
102
|
-
}
|
|
103
|
-
/** Finds the closest line start for the given position. */
|
|
104
|
-
function findClosestLineStartPosition(linesMap, position, low = 0, high = linesMap.length - 1) {
|
|
105
|
-
while (low <= high) {
|
|
106
|
-
const pivotIdx = Math.floor((low + high) / 2);
|
|
107
|
-
const pivotEl = linesMap[pivotIdx];
|
|
108
|
-
if (pivotEl === position) {
|
|
109
|
-
return pivotIdx;
|
|
110
|
-
}
|
|
111
|
-
else if (position > pivotEl) {
|
|
112
|
-
low = pivotIdx + 1;
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
high = pivotIdx - 1;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// In case there was no exact match, return the closest "lower" line index. We also
|
|
119
|
-
// subtract the index by one because want the index of the previous line start.
|
|
120
|
-
return low - 1;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Visitor that can be used to determine Angular templates referenced within given
|
|
125
|
-
* TypeScript source files (inline templates or external referenced templates)
|
|
126
|
-
*/
|
|
127
|
-
class NgComponentTemplateVisitor {
|
|
128
|
-
typeChecker;
|
|
129
|
-
resolvedTemplates = [];
|
|
130
|
-
fs = project_tsconfig_paths.getFileSystem();
|
|
131
|
-
constructor(typeChecker) {
|
|
132
|
-
this.typeChecker = typeChecker;
|
|
133
|
-
}
|
|
134
|
-
visitNode(node) {
|
|
135
|
-
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
|
|
136
|
-
this.visitClassDeclaration(node);
|
|
137
|
-
}
|
|
138
|
-
ts.forEachChild(node, (n) => this.visitNode(n));
|
|
139
|
-
}
|
|
140
|
-
visitClassDeclaration(node) {
|
|
141
|
-
const metadata = extractAngularClassMetadata(this.typeChecker, node);
|
|
142
|
-
if (metadata === null || metadata.type !== 'component') {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
const sourceFile = node.getSourceFile();
|
|
146
|
-
const sourceFileName = sourceFile.fileName;
|
|
147
|
-
// Walk through all component metadata properties and determine the referenced
|
|
148
|
-
// HTML templates (either external or inline)
|
|
149
|
-
metadata.node.properties.forEach((property) => {
|
|
150
|
-
if (!ts.isPropertyAssignment(property)) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const propertyName = property_name.getPropertyNameText(property.name);
|
|
154
|
-
// In case there is an inline template specified, ensure that the value is statically
|
|
155
|
-
// analyzable by checking if the initializer is a string literal-like node.
|
|
156
|
-
if (propertyName === 'template' && ts.isStringLiteralLike(property.initializer)) {
|
|
157
|
-
// Need to add an offset of one to the start because the template quotes are
|
|
158
|
-
// not part of the template content.
|
|
159
|
-
// The `getText()` method gives us the original raw text.
|
|
160
|
-
// We could have used the `text` property, but if the template is defined as a backtick
|
|
161
|
-
// string then the `text` property contains a "cooked" version of the string. Such cooked
|
|
162
|
-
// strings will have converted CRLF characters to only LF. This messes up string
|
|
163
|
-
// replacements in template migrations.
|
|
164
|
-
// The raw text returned by `getText()` includes the enclosing quotes so we change the
|
|
165
|
-
// `content` and `start` values accordingly.
|
|
166
|
-
const content = property.initializer.getText().slice(1, -1);
|
|
167
|
-
const start = property.initializer.getStart() + 1;
|
|
168
|
-
this.resolvedTemplates.push({
|
|
169
|
-
filePath: sourceFileName,
|
|
170
|
-
container: node,
|
|
171
|
-
content,
|
|
172
|
-
inline: true,
|
|
173
|
-
start: start,
|
|
174
|
-
getCharacterAndLineOfPosition: (pos) => ts.getLineAndCharacterOfPosition(sourceFile, pos + start),
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
if (propertyName === 'templateUrl' && ts.isStringLiteralLike(property.initializer)) {
|
|
178
|
-
const absolutePath = this.fs.resolve(this.fs.dirname(sourceFileName), property.initializer.text);
|
|
179
|
-
if (!this.fs.exists(absolutePath)) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
const fileContent = this.fs.readFile(absolutePath);
|
|
183
|
-
const lineStartsMap = computeLineStartsMap(fileContent);
|
|
184
|
-
this.resolvedTemplates.push({
|
|
185
|
-
filePath: absolutePath,
|
|
186
|
-
container: node,
|
|
187
|
-
content: fileContent,
|
|
188
|
-
inline: false,
|
|
189
|
-
start: 0,
|
|
190
|
-
getCharacterAndLineOfPosition: (pos) => getLineAndCharacterFromPosition(lineStartsMap, pos),
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function parseTemplate(template) {
|
|
198
|
-
let parsed;
|
|
199
|
-
try {
|
|
200
|
-
// Note: we use the HtmlParser here, instead of the `parseTemplate` function, because the
|
|
201
|
-
// latter returns an Ivy AST, not an HTML AST. The HTML AST has the advantage of preserving
|
|
202
|
-
// interpolated text as text nodes containing a mixture of interpolation tokens and text tokens,
|
|
203
|
-
// rather than turning them into `BoundText` nodes like the Ivy AST does. This allows us to
|
|
204
|
-
// easily get the text-only ranges without having to reconstruct the original text.
|
|
205
|
-
parsed = new project_tsconfig_paths.HtmlParser().parse(template, '', {
|
|
206
|
-
// Allows for ICUs to be parsed.
|
|
207
|
-
tokenizeExpansionForms: true,
|
|
208
|
-
// Explicitly disable blocks so that their characters are treated as plain text.
|
|
209
|
-
tokenizeBlocks: true,
|
|
210
|
-
preserveLineEndings: true,
|
|
211
|
-
});
|
|
212
|
-
// Don't migrate invalid templates.
|
|
213
|
-
if (parsed.errors && parsed.errors.length > 0) {
|
|
214
|
-
const errors = parsed.errors.map((e) => ({ type: 'parse', error: e }));
|
|
215
|
-
return { tree: undefined, errors };
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
catch (e) {
|
|
219
|
-
return { tree: undefined, errors: [{ type: 'parse', error: e }] };
|
|
220
|
-
}
|
|
221
|
-
return { tree: parsed, errors: [] };
|
|
222
|
-
}
|
|
20
|
+
require('./project_tsconfig_paths-CDVxT6Ov.cjs');
|
|
21
|
+
require('./ng_decorators-DSFlWYQY.cjs');
|
|
22
|
+
require('./imports-DP72APSx.cjs');
|
|
23
|
+
require('./property_name-BBwFuqMe.cjs');
|
|
223
24
|
|
|
224
25
|
function migrateTemplateToSelfClosingTags(template) {
|
|
225
|
-
let parsed = parseTemplate(template);
|
|
26
|
+
let parsed = parse_html.parseTemplate(template);
|
|
226
27
|
if (parsed.tree === undefined) {
|
|
227
28
|
return { migrated: template, changed: false, replacementCount: 0 };
|
|
228
29
|
}
|
|
229
30
|
const visitor = new AngularElementCollector();
|
|
230
|
-
|
|
31
|
+
compiler.visitAll(visitor, parsed.tree.rootNodes);
|
|
231
32
|
let newTemplate = template;
|
|
232
33
|
let changedOffset = 0;
|
|
233
34
|
let replacementCount = 0;
|
|
@@ -255,8 +56,8 @@ function replaceWithSelfClosingTag(html, tagName) {
|
|
|
255
56
|
function replaceTemplate(template, replaceValue, start, end, offset) {
|
|
256
57
|
return template.slice(0, start + offset) + replaceValue + template.slice(end + offset);
|
|
257
58
|
}
|
|
258
|
-
const ALL_HTML_TAGS = new
|
|
259
|
-
class AngularElementCollector extends
|
|
59
|
+
const ALL_HTML_TAGS = new compiler.DomElementSchemaRegistry().allKnownElementNames();
|
|
60
|
+
class AngularElementCollector extends compiler.RecursiveVisitor {
|
|
260
61
|
elements = [];
|
|
261
62
|
constructor() {
|
|
262
63
|
super();
|
|
@@ -279,7 +80,7 @@ class AngularElementCollector extends project_tsconfig_paths.RecursiveVisitor$1
|
|
|
279
80
|
}
|
|
280
81
|
if (element.children.length === 1) {
|
|
281
82
|
const child = element.children[0];
|
|
282
|
-
return child instanceof
|
|
83
|
+
return child instanceof compiler.Text && /^\s*$/.test(child.value);
|
|
283
84
|
}
|
|
284
85
|
return false;
|
|
285
86
|
}
|
|
@@ -305,7 +106,7 @@ class SelfClosingTagsMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
305
106
|
if (this.config.shouldMigrate && this.config.shouldMigrate(file) === false) {
|
|
306
107
|
return;
|
|
307
108
|
}
|
|
308
|
-
const templateVisitor = new NgComponentTemplateVisitor(typeChecker);
|
|
109
|
+
const templateVisitor = new ng_component_template.NgComponentTemplateVisitor(typeChecker);
|
|
309
110
|
templateVisitor.visitNode(node);
|
|
310
111
|
templateVisitor.resolvedTemplates.forEach((template) => {
|
|
311
112
|
const { migrated, changed, replacementCount } = migrateTemplateToSelfClosingTags(template.content);
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v21.0.0-next.
|
|
3
|
+
* @license Angular v21.0.0-next.10
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
var migrate_ts_type_references = require('./migrate_ts_type_references-
|
|
9
|
+
var migrate_ts_type_references = require('./migrate_ts_type_references-UGIUl7En.cjs');
|
|
10
10
|
var ts = require('typescript');
|
|
11
|
-
require('
|
|
12
|
-
var
|
|
13
|
-
var index$1 = require('./index-esqfDjNB.cjs');
|
|
14
|
-
require('path');
|
|
11
|
+
require('@angular/compiler-cli');
|
|
12
|
+
var migrations = require('@angular/compiler-cli/private/migrations');
|
|
15
13
|
require('node:path');
|
|
16
|
-
var project_paths = require('./project_paths-
|
|
17
|
-
var index = require('./index-
|
|
14
|
+
var project_paths = require('./project_paths-DvD50ouC.cjs');
|
|
15
|
+
var index = require('./index-B7I9sIUx.cjs');
|
|
18
16
|
var assert = require('assert');
|
|
19
|
-
var apply_import_manager = require('./apply_import_manager-
|
|
17
|
+
var apply_import_manager = require('./apply_import_manager-1Zs_gpB6.cjs');
|
|
20
18
|
require('@angular-devkit/core');
|
|
21
19
|
require('node:path/posix');
|
|
22
20
|
require('./leading_space-D9nQ8UQC.cjs');
|
|
23
|
-
require('fs');
|
|
24
|
-
require('module');
|
|
25
|
-
require('url');
|
|
26
21
|
require('@angular-devkit/schematics');
|
|
22
|
+
require('./project_tsconfig_paths-CDVxT6Ov.cjs');
|
|
23
|
+
require('@angular/compiler');
|
|
27
24
|
|
|
28
25
|
/**
|
|
29
26
|
* Class that holds information about a given directive and its input fields.
|
|
@@ -274,9 +271,9 @@ function prepareAnalysisInfo(userProgram, compiler, programAbsoluteRootPaths) {
|
|
|
274
271
|
state.templateTypeChecker.generateAllTypeCheckBlocks();
|
|
275
272
|
}
|
|
276
273
|
const typeChecker = userProgram.getTypeChecker();
|
|
277
|
-
const reflector = new
|
|
278
|
-
const evaluator = new
|
|
279
|
-
const dtsMetadataReader = new
|
|
274
|
+
const reflector = new migrations.TypeScriptReflectionHost(typeChecker);
|
|
275
|
+
const evaluator = new migrations.PartialEvaluator(reflector, typeChecker, null);
|
|
276
|
+
const dtsMetadataReader = new migrations.DtsMetadataReader(typeChecker, reflector);
|
|
280
277
|
return {
|
|
281
278
|
metaRegistry: metaReader,
|
|
282
279
|
dtsMetadataReader,
|
|
@@ -337,7 +334,7 @@ function extractDtsInput(node, metadataReader) {
|
|
|
337
334
|
// in the `.d.ts` aren't resolvable. This seems to be unexpected and shouldn't
|
|
338
335
|
// result in the entire migration to be failing.
|
|
339
336
|
try {
|
|
340
|
-
directiveMetadata = metadataReader.getDirectiveMetadata(new
|
|
337
|
+
directiveMetadata = metadataReader.getDirectiveMetadata(new migrations.Reference(node.parent));
|
|
341
338
|
}
|
|
342
339
|
catch (e) {
|
|
343
340
|
console.error('Unexpected error. Gracefully ignoring.');
|
|
@@ -373,7 +370,7 @@ function extractSourceCodeInput(node, host, reflector, evaluator) {
|
|
|
373
370
|
if (decorators === null) {
|
|
374
371
|
return null;
|
|
375
372
|
}
|
|
376
|
-
const ngDecorators =
|
|
373
|
+
const ngDecorators = migrations.getAngularDecorators(decorators, ['Input'], host.isMigratingCore);
|
|
377
374
|
if (ngDecorators.length === 0) {
|
|
378
375
|
return null;
|
|
379
376
|
}
|
|
@@ -396,7 +393,15 @@ function extractSourceCodeInput(node, host, reflector, evaluator) {
|
|
|
396
393
|
isRequired = !!evaluatedInputOpts.get('required');
|
|
397
394
|
}
|
|
398
395
|
if (evaluatedInputOpts.has('transform') && evaluatedInputOpts.get('transform') != null) {
|
|
399
|
-
|
|
396
|
+
const result = parseTransformOfInput(evaluatedInputOpts, node, reflector);
|
|
397
|
+
if (result === 'parsingError') {
|
|
398
|
+
if (!host.config.bestEffortMode) {
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
transformResult = result;
|
|
404
|
+
}
|
|
400
405
|
}
|
|
401
406
|
}
|
|
402
407
|
}
|
|
@@ -417,33 +422,33 @@ function extractSourceCodeInput(node, host, reflector, evaluator) {
|
|
|
417
422
|
*/
|
|
418
423
|
function parseTransformOfInput(evaluatedInputOpts, node, reflector) {
|
|
419
424
|
const transformValue = evaluatedInputOpts.get('transform');
|
|
420
|
-
if (!(transformValue instanceof
|
|
425
|
+
if (!(transformValue instanceof migrations.DynamicValue) && !(transformValue instanceof migrations.Reference)) {
|
|
421
426
|
return null;
|
|
422
427
|
}
|
|
423
428
|
// For parsing the transform, we don't need a real reference emitter, as
|
|
424
429
|
// the emitter is only used for verifying that the transform type could be
|
|
425
430
|
// copied into e.g. an `ngInputAccept` class member.
|
|
426
|
-
const noopRefEmitter = new
|
|
431
|
+
const noopRefEmitter = new migrations.ReferenceEmitter([
|
|
427
432
|
{
|
|
428
433
|
emit: () => ({
|
|
429
|
-
kind:
|
|
430
|
-
expression:
|
|
434
|
+
kind: migrations.ReferenceEmitKind.Success,
|
|
435
|
+
expression: migrate_ts_type_references.NULL_EXPR,
|
|
431
436
|
importedFile: null,
|
|
432
437
|
}),
|
|
433
438
|
},
|
|
434
439
|
]);
|
|
435
440
|
try {
|
|
436
|
-
return
|
|
441
|
+
return migrations.parseDecoratorInputTransformFunction(node.parent, node.name.text, transformValue, reflector, noopRefEmitter, migrations.CompilationMode.FULL,
|
|
437
442
|
/* emitDeclarationOnly */ false);
|
|
438
443
|
}
|
|
439
444
|
catch (e) {
|
|
440
|
-
if (!(e instanceof
|
|
445
|
+
if (!(e instanceof migrations.FatalDiagnosticError)) {
|
|
441
446
|
throw e;
|
|
442
447
|
}
|
|
443
448
|
// TODO: implement error handling.
|
|
444
449
|
// See failing case: e.g. inherit_definition_feature_spec.ts
|
|
445
450
|
console.error(`${e.node.getSourceFile().fileName}: ${e.toString()}`);
|
|
446
|
-
return
|
|
451
|
+
return 'parsingError';
|
|
447
452
|
}
|
|
448
453
|
}
|
|
449
454
|
|
|
@@ -648,7 +653,7 @@ function pass1__IdentifySourceFileAndDeclarationInputs(sf, host, checker, reflec
|
|
|
648
653
|
function pass3__checkIncompatiblePatterns(host, inheritanceGraph, checker, groupedTsAstVisitor, knownInputs) {
|
|
649
654
|
migrate_ts_type_references.checkIncompatiblePatterns(inheritanceGraph, checker, groupedTsAstVisitor, knownInputs, () => knownInputs.getAllInputContainingClasses());
|
|
650
655
|
for (const input of knownInputs.knownInputIds.values()) {
|
|
651
|
-
const hostBindingDecorators =
|
|
656
|
+
const hostBindingDecorators = migrations.getAngularDecorators(input.metadata.fieldDecorators, ['HostBinding'], host.isMigratingCore);
|
|
652
657
|
if (hostBindingDecorators.length > 0) {
|
|
653
658
|
knownInputs.markFieldIncompatible(input.descriptor, {
|
|
654
659
|
context: hostBindingDecorators[0].node,
|
|
@@ -686,7 +691,7 @@ function executeAnalysisPhase(host, knownInputs, result, { sourceFiles, fullProg
|
|
|
686
691
|
fullProgramSourceFiles.forEach((sf) =>
|
|
687
692
|
// Shim shim files. Those are unnecessary and might cause unexpected slowness.
|
|
688
693
|
// e.g. `ngtypecheck` files.
|
|
689
|
-
!
|
|
694
|
+
!migrations.isShim(sf) &&
|
|
690
695
|
pass1__IdentifySourceFileAndDeclarationInputs(sf, host, typeChecker, reflector, dtsMetadataReader, evaluator, knownInputs, result));
|
|
691
696
|
const fieldNamesToConsiderForReferenceLookup = new Set();
|
|
692
697
|
for (const input of knownInputs.knownInputIds.values()) {
|
|
@@ -961,6 +966,12 @@ function populateKnownInputsFromGlobalData(knownInputs, globalData) {
|
|
|
961
966
|
* @returns Replacements for converting the input.
|
|
962
967
|
*/
|
|
963
968
|
function convertToSignalInput(node, { resolvedMetadata: metadata, resolvedType, preferShorthandIfPossible, originalInputDecorator, initialValue, leadingTodoText, }, info, checker, importManager, result) {
|
|
969
|
+
// Check for 'this' references in initializer before doing anything else
|
|
970
|
+
if (node.initializer &&
|
|
971
|
+
(ts.isArrowFunction(node.initializer) || ts.isFunctionExpression(node.initializer)) &&
|
|
972
|
+
containsThisReferences(node.initializer)) {
|
|
973
|
+
return []; // Skip migration for this input by returning empty replacements
|
|
974
|
+
}
|
|
964
975
|
let optionsLiteral = null;
|
|
965
976
|
// We need an options array for the input because:
|
|
966
977
|
// - the input is either aliased,
|
|
@@ -1030,7 +1041,23 @@ function convertToSignalInput(node, { resolvedMetadata: metadata, resolvedType,
|
|
|
1030
1041
|
if (!modifiersWithoutInputDecorator?.some((s) => s.kind === ts.SyntaxKind.ReadonlyKeyword)) {
|
|
1031
1042
|
modifiersWithoutInputDecorator.push(ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword));
|
|
1032
1043
|
}
|
|
1033
|
-
|
|
1044
|
+
// Skip migration if the input is a function that references class members via 'this'
|
|
1045
|
+
if (inputInitializer &&
|
|
1046
|
+
(ts.isArrowFunction(inputInitializer) || ts.isFunctionExpression(inputInitializer))) {
|
|
1047
|
+
if (containsThisReferences(inputInitializer)) {
|
|
1048
|
+
return []; // Skip migration for this input by returning empty replacements
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
let finalInitializer = inputInitializer;
|
|
1052
|
+
if (inputInitializer === undefined) {
|
|
1053
|
+
if (preferShorthandIfPossible === null) {
|
|
1054
|
+
finalInitializer = ts.factory.createIdentifier('undefined');
|
|
1055
|
+
}
|
|
1056
|
+
else {
|
|
1057
|
+
resolvedType = preferShorthandIfPossible.originalType;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
const newNode = ts.factory.createPropertyDeclaration(modifiersWithoutInputDecorator, node.name, undefined, undefined, finalInitializer);
|
|
1034
1061
|
const newPropertyText = result.printer.printNode(ts.EmitHint.Unspecified, newNode, node.getSourceFile());
|
|
1035
1062
|
const replacements = [];
|
|
1036
1063
|
if (leadingTodoText !== null) {
|
|
@@ -1074,6 +1101,43 @@ function extractTransformOfInput(transform, resolvedType, checker) {
|
|
|
1074
1101
|
leadingTodoText,
|
|
1075
1102
|
};
|
|
1076
1103
|
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Checks if a function node contains any references to 'this'.
|
|
1106
|
+
* This is used to skip migration for functions that reference class members.
|
|
1107
|
+
*/
|
|
1108
|
+
function containsThisReferences(node) {
|
|
1109
|
+
let hasThis = false;
|
|
1110
|
+
const visit = (node) => {
|
|
1111
|
+
if (hasThis)
|
|
1112
|
+
return;
|
|
1113
|
+
if (node.kind === ts.SyntaxKind.ThisKeyword) {
|
|
1114
|
+
hasThis = true;
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
1118
|
+
const expr = node.expression;
|
|
1119
|
+
if (ts.isIdentifier(expr) && expr.text === 'this') {
|
|
1120
|
+
hasThis = true;
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
ts.forEachChild(node, visit);
|
|
1125
|
+
};
|
|
1126
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
|
|
1127
|
+
if (node.body) {
|
|
1128
|
+
if (node.body.kind === ts.SyntaxKind.Block) {
|
|
1129
|
+
node.body.statements.forEach(visit);
|
|
1130
|
+
}
|
|
1131
|
+
else {
|
|
1132
|
+
visit(node.body);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
else {
|
|
1137
|
+
ts.forEachChild(node, visit);
|
|
1138
|
+
}
|
|
1139
|
+
return hasThis;
|
|
1140
|
+
}
|
|
1077
1141
|
|
|
1078
1142
|
/**
|
|
1079
1143
|
* Phase that migrates `@Input()` declarations to signal inputs and
|
|
@@ -1234,7 +1298,7 @@ function pass9__migrateTypeScriptTypeReferences(host, references, importManager,
|
|
|
1234
1298
|
*/
|
|
1235
1299
|
function executeMigrationPhase(host, knownInputs, result, info) {
|
|
1236
1300
|
const { typeChecker, sourceFiles } = info;
|
|
1237
|
-
const importManager = new
|
|
1301
|
+
const importManager = new migrations.ImportManager({
|
|
1238
1302
|
// For the purpose of this migration, we always use `input` and don't alias
|
|
1239
1303
|
// it to e.g. `input_1`.
|
|
1240
1304
|
generateUniqueIdentifier: () => null,
|
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v21.0.0-next.
|
|
3
|
+
* @license Angular v21.0.0-next.10
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var migrations = require('@angular/compiler-cli/private/migrations');
|
|
10
10
|
var ts = require('typescript');
|
|
11
|
-
require('
|
|
12
|
-
var index$1 = require('./index-esqfDjNB.cjs');
|
|
13
|
-
require('path');
|
|
11
|
+
require('@angular/compiler-cli');
|
|
14
12
|
require('node:path');
|
|
15
|
-
var project_paths = require('./project_paths-
|
|
16
|
-
var apply_import_manager = require('./apply_import_manager-
|
|
17
|
-
var migrate_ts_type_references = require('./migrate_ts_type_references-
|
|
13
|
+
var project_paths = require('./project_paths-DvD50ouC.cjs');
|
|
14
|
+
var apply_import_manager = require('./apply_import_manager-1Zs_gpB6.cjs');
|
|
15
|
+
var migrate_ts_type_references = require('./migrate_ts_type_references-UGIUl7En.cjs');
|
|
18
16
|
var assert = require('assert');
|
|
19
|
-
var index = require('./index-
|
|
17
|
+
var index = require('./index-B7I9sIUx.cjs');
|
|
18
|
+
var compiler = require('@angular/compiler');
|
|
20
19
|
require('@angular-devkit/core');
|
|
21
20
|
require('node:path/posix');
|
|
22
|
-
require('fs');
|
|
23
|
-
require('module');
|
|
24
|
-
require('url');
|
|
25
21
|
require('@angular-devkit/schematics');
|
|
22
|
+
require('./project_tsconfig_paths-CDVxT6Ov.cjs');
|
|
26
23
|
require('./leading_space-D9nQ8UQC.cjs');
|
|
27
24
|
|
|
28
25
|
/**
|
|
@@ -159,7 +156,7 @@ function computeReplacementsToMigrateQuery(node, metadata, importManager, info,
|
|
|
159
156
|
}
|
|
160
157
|
}
|
|
161
158
|
if (metadata.queryInfo.read !== null) {
|
|
162
|
-
assert(metadata.queryInfo.read instanceof
|
|
159
|
+
assert(metadata.queryInfo.read instanceof compiler.WrappedNodeExpr);
|
|
163
160
|
optionProperties.push(ts.factory.createPropertyAssignment('read', metadata.queryInfo.read.node));
|
|
164
161
|
}
|
|
165
162
|
if (metadata.queryInfo.descendants !== defaultDescendants) {
|
|
@@ -203,7 +200,7 @@ function computeReplacementsToMigrateQuery(node, metadata, importManager, info,
|
|
|
203
200
|
// If the original property type and the read type are matching, we can rely
|
|
204
201
|
// on the TS inference, instead of repeating types, like in `viewChild<Button>(Button)`.
|
|
205
202
|
if (type !== undefined &&
|
|
206
|
-
resolvedReadType instanceof
|
|
203
|
+
resolvedReadType instanceof compiler.WrappedNodeExpr &&
|
|
207
204
|
ts.isIdentifier(resolvedReadType.node) &&
|
|
208
205
|
ts.isTypeReferenceNode(type) &&
|
|
209
206
|
ts.isIdentifier(type.typeName) &&
|
|
@@ -291,7 +288,7 @@ function extractSourceQueryDefinition(node, reflector, evaluator, info) {
|
|
|
291
288
|
return null;
|
|
292
289
|
}
|
|
293
290
|
const decorators = reflector.getDecoratorsOfDeclaration(node) ?? [];
|
|
294
|
-
const ngDecorators =
|
|
291
|
+
const ngDecorators = migrations.getAngularDecorators(decorators, migrations.queryDecoratorNames, /* isCore */ false);
|
|
295
292
|
if (ngDecorators.length === 0) {
|
|
296
293
|
return null;
|
|
297
294
|
}
|
|
@@ -318,10 +315,10 @@ function extractSourceQueryDefinition(node, reflector, evaluator, info) {
|
|
|
318
315
|
}
|
|
319
316
|
let queryInfo = null;
|
|
320
317
|
try {
|
|
321
|
-
queryInfo =
|
|
318
|
+
queryInfo = migrations.extractDecoratorQueryMetadata(node, decorator.name, decorator.args ?? [], node.name.text, reflector, evaluator);
|
|
322
319
|
}
|
|
323
320
|
catch (e) {
|
|
324
|
-
if (!(e instanceof
|
|
321
|
+
if (!(e instanceof migrations.FatalDiagnosticError)) {
|
|
325
322
|
throw e;
|
|
326
323
|
}
|
|
327
324
|
console.error(`Skipping query: ${e.node.getSourceFile().fileName}: ${e.toString()}`);
|
|
@@ -532,7 +529,7 @@ function checkNonTsReferenceAccessesField(ref, fieldName) {
|
|
|
532
529
|
if (ref.from.read !== readFromPath) {
|
|
533
530
|
return null;
|
|
534
531
|
}
|
|
535
|
-
if (!(parentRead instanceof
|
|
532
|
+
if (!(parentRead instanceof compiler.PropertyRead) || parentRead.name !== fieldName) {
|
|
536
533
|
return null;
|
|
537
534
|
}
|
|
538
535
|
return parentRead;
|
|
@@ -570,7 +567,7 @@ function checkNonTsReferenceCallsField(ref, fieldName) {
|
|
|
570
567
|
return null;
|
|
571
568
|
}
|
|
572
569
|
const potentialCall = ref.from.readAstPath[accessIdx - 1];
|
|
573
|
-
if (potentialCall === undefined || !(potentialCall instanceof
|
|
570
|
+
if (potentialCall === undefined || !(potentialCall instanceof compiler.Call)) {
|
|
574
571
|
return null;
|
|
575
572
|
}
|
|
576
573
|
return potentialCall;
|
|
@@ -740,8 +737,8 @@ class SignalQueriesMigration extends project_paths.TsurgeComplexMigration {
|
|
|
740
737
|
}
|
|
741
738
|
const { sourceFiles, program } = info;
|
|
742
739
|
const checker = program.getTypeChecker();
|
|
743
|
-
const reflector = new
|
|
744
|
-
const evaluator = new
|
|
740
|
+
const reflector = new migrations.TypeScriptReflectionHost(checker);
|
|
741
|
+
const evaluator = new migrations.PartialEvaluator(reflector, checker, null);
|
|
745
742
|
const res = {
|
|
746
743
|
knownQueryFields: {},
|
|
747
744
|
potentialProblematicQueries: {},
|
|
@@ -789,7 +786,7 @@ class SignalQueriesMigration extends project_paths.TsurgeComplexMigration {
|
|
|
789
786
|
}
|
|
790
787
|
// Migrating fields with `@HostBinding` is incompatible as
|
|
791
788
|
// the host binding decorator does not invoke the signal.
|
|
792
|
-
const hostBindingDecorators =
|
|
789
|
+
const hostBindingDecorators = migrations.getAngularDecorators(extractedQuery.fieldDecorators, ['HostBinding'],
|
|
793
790
|
/* isCore */ false);
|
|
794
791
|
if (hostBindingDecorators.length > 0) {
|
|
795
792
|
markFieldIncompatibleInMetadata(res.potentialProblematicQueries, extractedQuery.id, migrate_ts_type_references.FieldIncompatibilityReason.SignalIncompatibleWithHostBinding);
|
|
@@ -928,10 +925,10 @@ class SignalQueriesMigration extends project_paths.TsurgeComplexMigration {
|
|
|
928
925
|
const resourceLoader = info.ngCompiler?.['resourceManager'] ?? null;
|
|
929
926
|
const { program, sourceFiles } = info;
|
|
930
927
|
const checker = program.getTypeChecker();
|
|
931
|
-
const reflector = new
|
|
932
|
-
const evaluator = new
|
|
928
|
+
const reflector = new migrations.TypeScriptReflectionHost(checker);
|
|
929
|
+
const evaluator = new migrations.PartialEvaluator(reflector, checker, null);
|
|
933
930
|
const replacements = [];
|
|
934
|
-
const importManager = new
|
|
931
|
+
const importManager = new migrations.ImportManager();
|
|
935
932
|
const printer = ts.createPrinter();
|
|
936
933
|
const filesWithSourceQueries = new Map();
|
|
937
934
|
const filesWithIncompleteMigration = new Map();
|