@angular/core 20.0.0 → 20.0.1
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/api.d-B0vztftH.d.ts +1 -1
- package/chrome_dev_tools_performance.d-DvzAxqBc.d.ts +1 -1
- package/{discovery.d-DZNIp-Fw.d.ts → discovery.d-CB2iJta5.d.ts} +8 -9
- package/event_dispatcher.d-BReQpZfC.d.ts +1 -1
- package/fesm2022/attribute-BWp59EjE.mjs +1 -1
- package/fesm2022/core.mjs +12 -12
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/{debug_node-Dn-GvQJo.mjs → debug_node-B9JawCEy.mjs} +33 -23
- package/fesm2022/debug_node-B9JawCEy.mjs.map +1 -0
- package/fesm2022/primitives/di.mjs +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +1 -1
- package/fesm2022/primitives/signals.mjs +4 -4
- package/fesm2022/{resource-BPCh38bN.mjs → resource-W6LObBPP.mjs} +8 -6
- package/fesm2022/{resource-BPCh38bN.mjs.map → resource-W6LObBPP.mjs.map} +1 -1
- package/fesm2022/{root_effect_scheduler-0BxwqIgm.mjs → root_effect_scheduler-C4AUixQF.mjs} +19 -13
- package/fesm2022/root_effect_scheduler-C4AUixQF.mjs.map +1 -0
- package/fesm2022/rxjs-interop.mjs +12 -7
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/{signal-ePSl6jXn.mjs → signal-BZ1SD--i.mjs} +8 -9
- package/fesm2022/{signal-ePSl6jXn.mjs.map → signal-BZ1SD--i.mjs.map} +1 -1
- package/fesm2022/testing.mjs +4 -4
- package/fesm2022/{untracked-2ouAFbCz.mjs → untracked-RA6XPQ1Z.mjs} +3 -3
- package/fesm2022/{untracked-2ouAFbCz.mjs.map → untracked-RA6XPQ1Z.mjs.map} +1 -1
- package/fesm2022/weak_ref-BaIq-pgY.mjs +1 -1
- package/graph.d-BcIOep_B.d.ts +1 -1
- package/index.d.ts +19 -14
- package/package.json +2 -2
- package/primitives/di/index.d.ts +1 -1
- package/primitives/event-dispatch/index.d.ts +1 -1
- package/primitives/signals/index.d.ts +3 -3
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/bundles/{apply_import_manager-Bqnvtho4.cjs → apply_import_manager-DT15wSJs.cjs} +3 -3
- package/schematics/bundles/{compiler-Dl11rH6-.cjs → checker-Bu1Wu4f7.cjs} +18350 -336
- package/schematics/bundles/cleanup-unused-imports.cjs +12 -9
- package/schematics/bundles/{change_tracker-DaCWdziV.cjs → compiler_host-C_4Iw5UD.cjs} +121 -3
- package/schematics/bundles/control-flow-migration.cjs +46 -25
- package/schematics/bundles/document-core.cjs +5 -6
- package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
- package/schematics/bundles/{index-CYxAVSJC.cjs → index-CAM7Xiu7.cjs} +29 -30
- package/schematics/bundles/{index-DPvX-lSh.cjs → index-CCX_cTPD.cjs} +516 -517
- package/schematics/bundles/inject-flags.cjs +5 -6
- package/schematics/bundles/inject-migration.cjs +5 -7
- package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
- package/schematics/bundles/{migrate_ts_type_references-DWUePVh6.cjs → migrate_ts_type_references-DSqmdRpG.cjs} +5 -6
- package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
- package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
- package/schematics/bundles/output-migration.cjs +7 -8
- package/schematics/bundles/{project_paths-BPBAn_A2.cjs → project_paths-BjQra9mv.cjs} +3 -4
- package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +1 -1
- package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
- package/schematics/bundles/route-lazy-loading.cjs +5 -7
- package/schematics/bundles/self-closing-tags-migration.cjs +9 -10
- package/schematics/bundles/signal-input-migration.cjs +7 -8
- package/schematics/bundles/signal-queries-migration.cjs +13 -14
- package/schematics/bundles/signals.cjs +7 -8
- package/schematics/bundles/standalone-migration.cjs +9 -11
- package/schematics/bundles/symbol-VPWguRxr.cjs +1 -1
- package/schematics/bundles/test-bed-get.cjs +4 -5
- package/schematics/collection.json +6 -0
- package/schematics/migrations/control-flow-migration/schema.json +20 -0
- package/{signal.d-D6VJ67xi.d.ts → signal.d-fOdF0h0o.d.ts} +4 -3
- package/testing/index.d.ts +3 -3
- package/weak_ref.d-eGOEP9S1.d.ts +1 -1
- package/fesm2022/debug_node-Dn-GvQJo.mjs.map +0 -1
- package/fesm2022/root_effect_scheduler-0BxwqIgm.mjs.map +0 -1
- package/schematics/bundles/checker-BHgMyU8j.cjs +0 -17996
- package/schematics/bundles/compiler_host-CAfDJO3W.cjs +0 -129
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.
|
|
3
|
+
* @license Angular v20.0.1
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -8,14 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
require('@angular-devkit/core');
|
|
10
10
|
require('node:path/posix');
|
|
11
|
-
var project_paths = require('./project_paths-
|
|
11
|
+
var project_paths = require('./project_paths-BjQra9mv.cjs');
|
|
12
12
|
var ts = require('typescript');
|
|
13
13
|
require('os');
|
|
14
|
-
var checker = require('./checker-
|
|
15
|
-
require('./
|
|
16
|
-
var index = require('./index-DPvX-lSh.cjs');
|
|
14
|
+
var checker = require('./checker-Bu1Wu4f7.cjs');
|
|
15
|
+
var index = require('./index-CCX_cTPD.cjs');
|
|
17
16
|
require('path');
|
|
18
|
-
var apply_import_manager = require('./apply_import_manager-
|
|
17
|
+
var apply_import_manager = require('./apply_import_manager-DT15wSJs.cjs');
|
|
19
18
|
var leading_space = require('./leading_space-D9nQ8UQC.cjs');
|
|
20
19
|
require('@angular-devkit/schematics');
|
|
21
20
|
require('./project_tsconfig_paths-CDVxT6Ov.cjs');
|
|
@@ -256,15 +255,19 @@ function getArrayElementRemovalUpdate(node, parent, sourceText) {
|
|
|
256
255
|
// trailing comma at the end of the line is fine.
|
|
257
256
|
if (parent.elements[parent.elements.length - 1] === node) {
|
|
258
257
|
for (let i = position - 1; i >= 0; i--) {
|
|
259
|
-
|
|
258
|
+
const char = sourceText[i];
|
|
259
|
+
if (char === ',' || char === ' ') {
|
|
260
260
|
position--;
|
|
261
261
|
}
|
|
262
262
|
else {
|
|
263
|
+
if (whitespaceOrLineFeed.test(char)) {
|
|
264
|
+
// Replace the node with its leading whitespace to preserve the formatting.
|
|
265
|
+
// This only needs to happen if we're breaking on a newline.
|
|
266
|
+
toInsert = leading_space.getLeadingLineWhitespaceOfNode(node);
|
|
267
|
+
}
|
|
263
268
|
break;
|
|
264
269
|
}
|
|
265
270
|
}
|
|
266
|
-
// Replace the node with its leading whitespace to preserve the formatting.
|
|
267
|
-
toInsert = leading_space.getLeadingLineWhitespaceOfNode(node);
|
|
268
271
|
}
|
|
269
272
|
return new project_paths.TextUpdate({ position, end, toInsert });
|
|
270
273
|
}
|
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.
|
|
3
|
+
* @license Angular v20.0.1
|
|
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
|
-
var checker = require('./checker-BHgMyU8j.cjs');
|
|
10
|
+
var checker = require('./checker-Bu1Wu4f7.cjs');
|
|
12
11
|
require('os');
|
|
12
|
+
var p = require('path');
|
|
13
|
+
|
|
14
|
+
function _interopNamespaceDefault(e) {
|
|
15
|
+
var n = Object.create(null);
|
|
16
|
+
if (e) {
|
|
17
|
+
Object.keys(e).forEach(function (k) {
|
|
18
|
+
if (k !== 'default') {
|
|
19
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
20
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return e[k]; }
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
n.default = e;
|
|
28
|
+
return Object.freeze(n);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
var p__namespace = /*#__PURE__*/_interopNamespaceDefault(p);
|
|
13
32
|
|
|
14
33
|
/** Tracks changes that have to be made for specific files. */
|
|
15
34
|
class ChangeTracker {
|
|
@@ -197,5 +216,104 @@ function normalizePath(path) {
|
|
|
197
216
|
return path.replace(/\\/g, '/');
|
|
198
217
|
}
|
|
199
218
|
|
|
219
|
+
function parseTsconfigFile(tsconfigPath, basePath) {
|
|
220
|
+
const { config } = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
|
|
221
|
+
const parseConfigHost = {
|
|
222
|
+
useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
|
|
223
|
+
fileExists: ts.sys.fileExists,
|
|
224
|
+
readDirectory: ts.sys.readDirectory,
|
|
225
|
+
readFile: ts.sys.readFile,
|
|
226
|
+
};
|
|
227
|
+
// Throw if incorrect arguments are passed to this function. Passing relative base paths
|
|
228
|
+
// results in root directories not being resolved and in later type checking runtime errors.
|
|
229
|
+
// More details can be found here: https://github.com/microsoft/TypeScript/issues/37731.
|
|
230
|
+
if (!p__namespace.isAbsolute(basePath)) {
|
|
231
|
+
throw Error('Unexpected relative base path has been specified.');
|
|
232
|
+
}
|
|
233
|
+
return ts.parseJsonConfigFileContent(config, parseConfigHost, basePath, {});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Creates a TypeScript program instance for a TypeScript project within
|
|
238
|
+
* the virtual file system tree.
|
|
239
|
+
* @param tree Virtual file system tree that contains the source files.
|
|
240
|
+
* @param tsconfigPath Virtual file system path that resolves to the TypeScript project.
|
|
241
|
+
* @param basePath Base path for the virtual file system tree.
|
|
242
|
+
* @param fakeFileRead Optional file reader function. Can be used to overwrite files in
|
|
243
|
+
* the TypeScript program, or to add in-memory files (e.g. to add global types).
|
|
244
|
+
* @param additionalFiles Additional file paths that should be added to the program.
|
|
245
|
+
*/
|
|
246
|
+
function createMigrationProgram(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles) {
|
|
247
|
+
const { rootNames, options, host } = createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead);
|
|
248
|
+
return ts.createProgram(rootNames, options, host);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Creates the options necessary to instantiate a TypeScript program.
|
|
252
|
+
* @param tree Virtual file system tree that contains the source files.
|
|
253
|
+
* @param tsconfigPath Virtual file system path that resolves to the TypeScript project.
|
|
254
|
+
* @param basePath Base path for the virtual file system tree.
|
|
255
|
+
* @param fakeFileRead Optional file reader function. Can be used to overwrite files in
|
|
256
|
+
* the TypeScript program, or to add in-memory files (e.g. to add global types).
|
|
257
|
+
* @param additionalFiles Additional file paths that should be added to the program.
|
|
258
|
+
* @param optionOverrides Overrides of the parsed compiler options.
|
|
259
|
+
*/
|
|
260
|
+
function createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles, optionOverrides) {
|
|
261
|
+
// Resolve the tsconfig path to an absolute path. This is needed as TypeScript otherwise
|
|
262
|
+
// is not able to resolve root directories in the given tsconfig. More details can be found
|
|
263
|
+
// in the following issue: https://github.com/microsoft/TypeScript/issues/37731.
|
|
264
|
+
tsconfigPath = p.resolve(basePath, tsconfigPath);
|
|
265
|
+
const parsed = parseTsconfigFile(tsconfigPath, p.dirname(tsconfigPath));
|
|
266
|
+
const options = optionOverrides ? { ...parsed.options, ...optionOverrides } : parsed.options;
|
|
267
|
+
const host = createMigrationCompilerHost(tree, options, basePath, fakeFileRead);
|
|
268
|
+
return { rootNames: parsed.fileNames.concat([]), options, host };
|
|
269
|
+
}
|
|
270
|
+
function createMigrationCompilerHost(tree, options, basePath, fakeRead) {
|
|
271
|
+
const host = ts.createCompilerHost(options, true);
|
|
272
|
+
const defaultReadFile = host.readFile;
|
|
273
|
+
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
274
|
+
// program to be based on the file contents in the virtual file tree. Otherwise
|
|
275
|
+
// if we run multiple migrations we might have intersecting changes and
|
|
276
|
+
// source files.
|
|
277
|
+
host.readFile = (fileName) => {
|
|
278
|
+
const treeRelativePath = p.relative(basePath, fileName);
|
|
279
|
+
let result = fakeRead?.(treeRelativePath);
|
|
280
|
+
if (typeof result !== 'string') {
|
|
281
|
+
// If the relative path resolved to somewhere outside of the tree, fall back to
|
|
282
|
+
// TypeScript's default file reading function since the `tree` will throw an error.
|
|
283
|
+
result = treeRelativePath.startsWith('..')
|
|
284
|
+
? defaultReadFile.call(host, fileName)
|
|
285
|
+
: tree.read(treeRelativePath)?.toString();
|
|
286
|
+
}
|
|
287
|
+
// Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset,
|
|
288
|
+
// which breaks the CLI UpdateRecorder.
|
|
289
|
+
// See: https://github.com/angular/angular/pull/30719
|
|
290
|
+
return typeof result === 'string' ? result.replace(/^\uFEFF/, '') : undefined;
|
|
291
|
+
};
|
|
292
|
+
return host;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Checks whether a file can be migrate by our automated migrations.
|
|
296
|
+
* @param basePath Absolute path to the project.
|
|
297
|
+
* @param sourceFile File being checked.
|
|
298
|
+
* @param program Program that includes the source file.
|
|
299
|
+
*/
|
|
300
|
+
function canMigrateFile(basePath, sourceFile, program) {
|
|
301
|
+
// We shouldn't migrate .d.ts files, files from an external library or type checking files.
|
|
302
|
+
if (sourceFile.fileName.endsWith('.ngtypecheck.ts') ||
|
|
303
|
+
sourceFile.isDeclarationFile ||
|
|
304
|
+
program.isSourceFileFromExternalLibrary(sourceFile)) {
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
// Our migrations are set up to create a `Program` from the project's tsconfig and to migrate all
|
|
308
|
+
// the files within the program. This can include files that are outside of the Angular CLI
|
|
309
|
+
// project. We can't migrate files outside of the project, because our file system interactions
|
|
310
|
+
// go through the CLI's `Tree` which assumes that all files are within the project. See:
|
|
311
|
+
// https://github.com/angular/angular-cli/blob/0b0961c9c233a825b6e4bb59ab7f0790f9b14676/packages/angular_devkit/schematics/src/tree/host-tree.ts#L131
|
|
312
|
+
return !p.relative(basePath, sourceFile.fileName).startsWith('..');
|
|
313
|
+
}
|
|
314
|
+
|
|
200
315
|
exports.ChangeTracker = ChangeTracker;
|
|
316
|
+
exports.canMigrateFile = canMigrateFile;
|
|
317
|
+
exports.createMigrationProgram = createMigrationProgram;
|
|
318
|
+
exports.createProgramOptions = createProgramOptions;
|
|
201
319
|
exports.normalizePath = normalizePath;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.
|
|
3
|
+
* @license Angular v20.0.1
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -8,10 +8,14 @@
|
|
|
8
8
|
|
|
9
9
|
var schematics = require('@angular-devkit/schematics');
|
|
10
10
|
var p = require('path');
|
|
11
|
-
var compiler_host = require('./compiler_host-
|
|
12
|
-
var
|
|
11
|
+
var compiler_host = require('./compiler_host-C_4Iw5UD.cjs');
|
|
12
|
+
var checker = require('./checker-Bu1Wu4f7.cjs');
|
|
13
13
|
var ts = require('typescript');
|
|
14
14
|
var project_tsconfig_paths = require('./project_tsconfig_paths-CDVxT6Ov.cjs');
|
|
15
|
+
require('os');
|
|
16
|
+
require('fs');
|
|
17
|
+
require('module');
|
|
18
|
+
require('url');
|
|
15
19
|
require('@angular-devkit/core');
|
|
16
20
|
|
|
17
21
|
function lookupIdentifiersInSourceFile(sourceFile, names) {
|
|
@@ -271,7 +275,7 @@ class AnalyzedFile {
|
|
|
271
275
|
}
|
|
272
276
|
}
|
|
273
277
|
/** Finds all non-control flow elements from common module. */
|
|
274
|
-
class CommonCollector extends
|
|
278
|
+
class CommonCollector extends checker.RecursiveVisitor$1 {
|
|
275
279
|
count = 0;
|
|
276
280
|
visitElement(el) {
|
|
277
281
|
if (el.attrs.length > 0) {
|
|
@@ -310,7 +314,7 @@ class CommonCollector extends compiler.RecursiveVisitor$1 {
|
|
|
310
314
|
}
|
|
311
315
|
}
|
|
312
316
|
/** Finds all elements that represent i18n blocks. */
|
|
313
|
-
class i18nCollector extends
|
|
317
|
+
class i18nCollector extends checker.RecursiveVisitor$1 {
|
|
314
318
|
elements = [];
|
|
315
319
|
visitElement(el) {
|
|
316
320
|
if (el.attrs.find((a) => a.name === 'i18n') !== undefined) {
|
|
@@ -320,7 +324,7 @@ class i18nCollector extends compiler.RecursiveVisitor$1 {
|
|
|
320
324
|
}
|
|
321
325
|
}
|
|
322
326
|
/** Finds all elements with ngif structural directives. */
|
|
323
|
-
class ElementCollector extends
|
|
327
|
+
class ElementCollector extends checker.RecursiveVisitor$1 {
|
|
324
328
|
_attributes;
|
|
325
329
|
elements = [];
|
|
326
330
|
constructor(_attributes = []) {
|
|
@@ -373,7 +377,7 @@ class ElementCollector extends compiler.RecursiveVisitor$1 {
|
|
|
373
377
|
}
|
|
374
378
|
}
|
|
375
379
|
/** Finds all elements with ngif structural directives. */
|
|
376
|
-
class TemplateCollector extends
|
|
380
|
+
class TemplateCollector extends checker.RecursiveVisitor$1 {
|
|
377
381
|
elements = [];
|
|
378
382
|
templates = new Map();
|
|
379
383
|
visitElement(el) {
|
|
@@ -587,7 +591,7 @@ function parseTemplate(template) {
|
|
|
587
591
|
// interpolated text as text nodes containing a mixture of interpolation tokens and text tokens,
|
|
588
592
|
// rather than turning them into `BoundText` nodes like the Ivy AST does. This allows us to
|
|
589
593
|
// easily get the text-only ranges without having to reconstruct the original text.
|
|
590
|
-
parsed = new
|
|
594
|
+
parsed = new checker.HtmlParser().parse(template, '', {
|
|
591
595
|
// Allows for ICUs to be parsed.
|
|
592
596
|
tokenizeExpansionForms: true,
|
|
593
597
|
// Explicitly disable blocks so that their characters are treated as plain text.
|
|
@@ -625,7 +629,7 @@ function validateMigratedTemplate(migrated, fileName) {
|
|
|
625
629
|
}
|
|
626
630
|
function validateI18nStructure(parsed, fileName) {
|
|
627
631
|
const visitor = new i18nCollector();
|
|
628
|
-
|
|
632
|
+
checker.visitAll$1(visitor, parsed.rootNodes);
|
|
629
633
|
const parents = visitor.elements.filter((el) => el.children.length > 0);
|
|
630
634
|
for (const p of parents) {
|
|
631
635
|
for (const el of visitor.elements) {
|
|
@@ -705,7 +709,7 @@ function getTemplates(template) {
|
|
|
705
709
|
const parsed = parseTemplate(template);
|
|
706
710
|
if (parsed.tree !== undefined) {
|
|
707
711
|
const visitor = new TemplateCollector();
|
|
708
|
-
|
|
712
|
+
checker.visitAll$1(visitor, parsed.tree.rootNodes);
|
|
709
713
|
for (let [key, tmpl] of visitor.templates) {
|
|
710
714
|
tmpl.count = countTemplateUsage(parsed.tree.rootNodes, key);
|
|
711
715
|
tmpl.generateContents(template);
|
|
@@ -881,7 +885,7 @@ function canRemoveCommonModule(template) {
|
|
|
881
885
|
let removeCommonModule = false;
|
|
882
886
|
if (parsed.tree !== undefined) {
|
|
883
887
|
const visitor = new CommonCollector();
|
|
884
|
-
|
|
888
|
+
checker.visitAll$1(visitor, parsed.tree.rootNodes);
|
|
885
889
|
removeCommonModule = visitor.count === 0;
|
|
886
890
|
}
|
|
887
891
|
return removeCommonModule;
|
|
@@ -1004,7 +1008,7 @@ function generateI18nMarkers(tmpl) {
|
|
|
1004
1008
|
let parsed = parseTemplate(tmpl);
|
|
1005
1009
|
if (parsed.tree !== undefined) {
|
|
1006
1010
|
const visitor = new i18nCollector();
|
|
1007
|
-
|
|
1011
|
+
checker.visitAll$1(visitor, parsed.tree.rootNodes);
|
|
1008
1012
|
for (const [ix, el] of visitor.elements.entries()) {
|
|
1009
1013
|
// we only care about elements with children and i18n tags
|
|
1010
1014
|
// elements without children have nothing to translate
|
|
@@ -1206,7 +1210,7 @@ function migrateCase(template) {
|
|
|
1206
1210
|
}
|
|
1207
1211
|
let result = template;
|
|
1208
1212
|
const visitor = new ElementCollector(cases);
|
|
1209
|
-
|
|
1213
|
+
checker.visitAll$1(visitor, parsed.tree.rootNodes);
|
|
1210
1214
|
calculateNesting(visitor, hasLineBreaks(template));
|
|
1211
1215
|
// this tracks the character shift from different lengths of blocks from
|
|
1212
1216
|
// the prior directives so as to adjust for nested block replacement during
|
|
@@ -1303,7 +1307,7 @@ function migrateFor(template) {
|
|
|
1303
1307
|
}
|
|
1304
1308
|
let result = template;
|
|
1305
1309
|
const visitor = new ElementCollector(fors);
|
|
1306
|
-
|
|
1310
|
+
checker.visitAll$1(visitor, parsed.tree.rootNodes);
|
|
1307
1311
|
calculateNesting(visitor, hasLineBreaks(template));
|
|
1308
1312
|
// this tracks the character shift from different lengths of blocks from
|
|
1309
1313
|
// the prior directives so as to adjust for nested block replacement during
|
|
@@ -1508,7 +1512,7 @@ function migrateIf(template) {
|
|
|
1508
1512
|
}
|
|
1509
1513
|
let result = template;
|
|
1510
1514
|
const visitor = new ElementCollector(ifs);
|
|
1511
|
-
|
|
1515
|
+
checker.visitAll$1(visitor, parsed.tree.rootNodes);
|
|
1512
1516
|
calculateNesting(visitor, hasLineBreaks(template));
|
|
1513
1517
|
// this tracks the character shift from different lengths of blocks from
|
|
1514
1518
|
// the prior directives so as to adjust for nested block replacement during
|
|
@@ -1701,7 +1705,7 @@ function migrateSwitch(template) {
|
|
|
1701
1705
|
}
|
|
1702
1706
|
let result = template;
|
|
1703
1707
|
const visitor = new ElementCollector(switches);
|
|
1704
|
-
|
|
1708
|
+
checker.visitAll$1(visitor, parsed.tree.rootNodes);
|
|
1705
1709
|
calculateNesting(visitor, hasLineBreaks(template));
|
|
1706
1710
|
// this tracks the character shift from different lengths of blocks from
|
|
1707
1711
|
// the prior directives so as to adjust for nested block replacement during
|
|
@@ -1732,11 +1736,11 @@ function migrateSwitch(template) {
|
|
|
1732
1736
|
}
|
|
1733
1737
|
function assertValidSwitchStructure(children) {
|
|
1734
1738
|
for (const child of children) {
|
|
1735
|
-
if (child instanceof
|
|
1739
|
+
if (child instanceof checker.Text && child.value.trim() !== '') {
|
|
1736
1740
|
throw new Error(`Text node: "${child.value}" would result in invalid migrated @switch block structure. ` +
|
|
1737
1741
|
`@switch can only have @case or @default as children.`);
|
|
1738
1742
|
}
|
|
1739
|
-
else if (child instanceof
|
|
1743
|
+
else if (child instanceof checker.Element$1) {
|
|
1740
1744
|
let hasCase = false;
|
|
1741
1745
|
for (const attr of child.attrs) {
|
|
1742
1746
|
if (cases.includes(attr.name)) {
|
|
@@ -1834,17 +1838,27 @@ function migrateTemplate(template, templateType, node, file, format = true, anal
|
|
|
1834
1838
|
return { migrated, errors };
|
|
1835
1839
|
}
|
|
1836
1840
|
|
|
1837
|
-
function migrate() {
|
|
1841
|
+
function migrate(options) {
|
|
1838
1842
|
return async (tree, context) => {
|
|
1839
|
-
|
|
1843
|
+
let allPaths = [];
|
|
1840
1844
|
const basePath = process.cwd();
|
|
1841
|
-
|
|
1845
|
+
let pathToMigrate;
|
|
1846
|
+
if (options.path) {
|
|
1847
|
+
pathToMigrate = compiler_host.normalizePath(p.join(basePath, options.path));
|
|
1848
|
+
if (pathToMigrate.trim() !== '') {
|
|
1849
|
+
allPaths.push(pathToMigrate);
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
else {
|
|
1853
|
+
const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
|
|
1854
|
+
allPaths = [...buildPaths, ...testPaths];
|
|
1855
|
+
}
|
|
1842
1856
|
if (!allPaths.length) {
|
|
1843
1857
|
throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the http providers migration.');
|
|
1844
1858
|
}
|
|
1845
1859
|
let errors = [];
|
|
1846
1860
|
for (const tsconfigPath of allPaths) {
|
|
1847
|
-
const migrateErrors = runControlFlowMigration(tree, tsconfigPath, basePath);
|
|
1861
|
+
const migrateErrors = runControlFlowMigration(tree, tsconfigPath, basePath, pathToMigrate, options);
|
|
1848
1862
|
errors = [...errors, ...migrateErrors];
|
|
1849
1863
|
}
|
|
1850
1864
|
if (errors.length > 0) {
|
|
@@ -1855,11 +1869,18 @@ function migrate() {
|
|
|
1855
1869
|
}
|
|
1856
1870
|
};
|
|
1857
1871
|
}
|
|
1858
|
-
function runControlFlowMigration(tree, tsconfigPath, basePath) {
|
|
1872
|
+
function runControlFlowMigration(tree, tsconfigPath, basePath, pathToMigrate, schematicOptions) {
|
|
1873
|
+
if (schematicOptions?.path?.startsWith('..')) {
|
|
1874
|
+
throw new schematics.SchematicsException('Cannot run control flow migration outside of the current project.');
|
|
1875
|
+
}
|
|
1859
1876
|
const program = compiler_host.createMigrationProgram(tree, tsconfigPath, basePath);
|
|
1860
1877
|
const sourceFiles = program
|
|
1861
1878
|
.getSourceFiles()
|
|
1862
|
-
.filter((sourceFile) =>
|
|
1879
|
+
.filter((sourceFile) => (pathToMigrate ? sourceFile.fileName.startsWith(pathToMigrate) : true) &&
|
|
1880
|
+
compiler_host.canMigrateFile(basePath, sourceFile, program));
|
|
1881
|
+
if (sourceFiles.length === 0) {
|
|
1882
|
+
throw new schematics.SchematicsException(`Could not find any files to migrate under the path ${pathToMigrate}. Cannot run the control flow migration.`);
|
|
1883
|
+
}
|
|
1863
1884
|
const analysis = new Map();
|
|
1864
1885
|
const migrateErrors = new Map();
|
|
1865
1886
|
for (const sourceFile of sourceFiles) {
|
|
@@ -1877,7 +1898,7 @@ function runControlFlowMigration(tree, tsconfigPath, basePath) {
|
|
|
1877
1898
|
for (const { start, end, node, type } of ranges) {
|
|
1878
1899
|
const template = content.slice(start, end);
|
|
1879
1900
|
const length = (end ?? content.length) - start;
|
|
1880
|
-
const { migrated, errors } = migrateTemplate(template, type, node, file, true, analysis);
|
|
1901
|
+
const { migrated, errors } = migrateTemplate(template, type, node, file, schematicOptions?.format ?? true, analysis);
|
|
1881
1902
|
if (migrated !== null) {
|
|
1882
1903
|
update.remove(start, length);
|
|
1883
1904
|
update.insertLeft(start, migrated);
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.
|
|
3
|
+
* @license Angular v20.0.1
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
require('./
|
|
9
|
+
var checker = require('./checker-Bu1Wu4f7.cjs');
|
|
10
10
|
require('typescript');
|
|
11
|
-
var checker = require('./checker-BHgMyU8j.cjs');
|
|
12
11
|
require('os');
|
|
13
|
-
var apply_import_manager = require('./apply_import_manager-
|
|
14
|
-
require('./index-
|
|
12
|
+
var apply_import_manager = require('./apply_import_manager-DT15wSJs.cjs');
|
|
13
|
+
require('./index-CCX_cTPD.cjs');
|
|
15
14
|
require('path');
|
|
16
|
-
var project_paths = require('./project_paths-
|
|
15
|
+
var project_paths = require('./project_paths-BjQra9mv.cjs');
|
|
17
16
|
var imports = require('./imports-CIX-JgAN.cjs');
|
|
18
17
|
require('@angular-devkit/core');
|
|
19
18
|
require('node:path/posix');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.
|
|
3
|
+
* @license Angular v20.0.1
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -8,11 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
var ts = require('typescript');
|
|
10
10
|
require('os');
|
|
11
|
-
var checker = require('./checker-
|
|
12
|
-
var
|
|
13
|
-
var index = require('./index-DPvX-lSh.cjs');
|
|
11
|
+
var checker = require('./checker-Bu1Wu4f7.cjs');
|
|
12
|
+
var index = require('./index-CCX_cTPD.cjs');
|
|
14
13
|
require('path');
|
|
15
|
-
var project_paths = require('./project_paths-
|
|
14
|
+
var project_paths = require('./project_paths-BjQra9mv.cjs');
|
|
16
15
|
|
|
17
16
|
function getMemberName(member) {
|
|
18
17
|
if (member.name === undefined) {
|
|
@@ -189,7 +188,7 @@ function lookupPropertyAccess(checker, type, path, options = {}) {
|
|
|
189
188
|
* This resolution is important to be able to migrate references to inputs
|
|
190
189
|
* that will be migrated to signal inputs.
|
|
191
190
|
*/
|
|
192
|
-
class TemplateReferenceVisitor extends
|
|
191
|
+
class TemplateReferenceVisitor extends checker.RecursiveVisitor {
|
|
193
192
|
result = [];
|
|
194
193
|
/**
|
|
195
194
|
* Whether we are currently descending into HTML AST nodes
|
|
@@ -236,21 +235,21 @@ class TemplateReferenceVisitor extends compiler.RecursiveVisitor {
|
|
|
236
235
|
// of signal calls in templates.
|
|
237
236
|
// TODO: Remove with: https://github.com/angular/angular/pull/55456.
|
|
238
237
|
this.templateAttributeReferencedFields = [];
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
checker.visitAll(this, template.attributes);
|
|
239
|
+
checker.visitAll(this, template.templateAttrs);
|
|
241
240
|
// If we are dealing with a microsyntax template, do not check
|
|
242
241
|
// inputs and outputs as those are already passed to the children.
|
|
243
242
|
// Template attributes may contain relevant expressions though.
|
|
244
243
|
if (template.tagName === 'ng-template') {
|
|
245
|
-
|
|
246
|
-
|
|
244
|
+
checker.visitAll(this, template.inputs);
|
|
245
|
+
checker.visitAll(this, template.outputs);
|
|
247
246
|
}
|
|
248
247
|
const referencedInputs = this.templateAttributeReferencedFields;
|
|
249
248
|
this.templateAttributeReferencedFields = null;
|
|
250
249
|
this.descendAndCheckForNarrowedSimilarReferences(referencedInputs, () => {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
250
|
+
checker.visitAll(this, template.children);
|
|
251
|
+
checker.visitAll(this, template.references);
|
|
252
|
+
checker.visitAll(this, template.variables);
|
|
254
253
|
});
|
|
255
254
|
}
|
|
256
255
|
visitIfBlockBranch(block) {
|
|
@@ -317,7 +316,7 @@ class TemplateReferenceVisitor extends compiler.RecursiveVisitor {
|
|
|
317
316
|
* This resolution is important to be able to migrate references to inputs
|
|
318
317
|
* that will be migrated to signal inputs.
|
|
319
318
|
*/
|
|
320
|
-
class TemplateExpressionReferenceVisitor extends
|
|
319
|
+
class TemplateExpressionReferenceVisitor extends checker.RecursiveAstVisitor {
|
|
321
320
|
typeChecker;
|
|
322
321
|
templateTypeChecker;
|
|
323
322
|
componentClass;
|
|
@@ -383,7 +382,7 @@ class TemplateExpressionReferenceVisitor extends compiler.RecursiveAstVisitor {
|
|
|
383
382
|
!this.fieldNamesToConsiderForReferenceLookup.has(ast.name)) {
|
|
384
383
|
return;
|
|
385
384
|
}
|
|
386
|
-
const isWrite = !!(ast instanceof
|
|
385
|
+
const isWrite = !!(ast instanceof checker.PropertyWrite ||
|
|
387
386
|
(this.activeTmplAstNode && isTwoWayBindingNode(this.activeTmplAstNode)));
|
|
388
387
|
this._checkAccessViaTemplateTypeCheckBlock(ast, isWrite, astPath) ||
|
|
389
388
|
this._checkAccessViaOwningComponentClassType(ast, isWrite, astPath);
|
|
@@ -460,9 +459,9 @@ class TemplateExpressionReferenceVisitor extends compiler.RecursiveAstVisitor {
|
|
|
460
459
|
_isPartOfNarrowingTernary(read) {
|
|
461
460
|
// Note: We do not safe check that the reads are fully matching 1:1. This is acceptable
|
|
462
461
|
// as worst case we just skip an input from being migrated. This is very unlikely too.
|
|
463
|
-
return this.insideConditionalExpressionsWithReads.some((r) => (r instanceof
|
|
464
|
-
r instanceof
|
|
465
|
-
r instanceof
|
|
462
|
+
return this.insideConditionalExpressionsWithReads.some((r) => (r instanceof checker.PropertyRead ||
|
|
463
|
+
r instanceof checker.PropertyWrite ||
|
|
464
|
+
r instanceof checker.SafePropertyRead) &&
|
|
466
465
|
r.name === read.name);
|
|
467
466
|
}
|
|
468
467
|
}
|
|
@@ -470,18 +469,18 @@ class TemplateExpressionReferenceVisitor extends compiler.RecursiveAstVisitor {
|
|
|
470
469
|
* Emulates an access to a given field using the TypeScript `ts.Type`
|
|
471
470
|
* of the given class. The resolved symbol of the access is returned.
|
|
472
471
|
*/
|
|
473
|
-
function traverseReceiverAndLookupSymbol(readOrWrite, componentClass, checker) {
|
|
472
|
+
function traverseReceiverAndLookupSymbol(readOrWrite, componentClass, checker$1) {
|
|
474
473
|
const path = [readOrWrite.name];
|
|
475
474
|
let node = readOrWrite;
|
|
476
|
-
while (node.receiver instanceof
|
|
475
|
+
while (node.receiver instanceof checker.PropertyRead || node.receiver instanceof checker.PropertyWrite) {
|
|
477
476
|
node = node.receiver;
|
|
478
477
|
path.unshift(node.name);
|
|
479
478
|
}
|
|
480
|
-
if (!(node.receiver instanceof
|
|
479
|
+
if (!(node.receiver instanceof checker.ImplicitReceiver || node.receiver instanceof checker.ThisReceiver)) {
|
|
481
480
|
return null;
|
|
482
481
|
}
|
|
483
|
-
const classType = checker.getTypeAtLocation(componentClass.name);
|
|
484
|
-
return (lookupPropertyAccess(checker, classType, path, {
|
|
482
|
+
const classType = checker$1.getTypeAtLocation(componentClass.name);
|
|
483
|
+
return (lookupPropertyAccess(checker$1, classType, path, {
|
|
485
484
|
// Necessary to avoid breaking the resolution if there is
|
|
486
485
|
// some narrowing involved. E.g. `myClass ? myClass.input`.
|
|
487
486
|
ignoreNullability: true,
|
|
@@ -489,8 +488,8 @@ function traverseReceiverAndLookupSymbol(readOrWrite, componentClass, checker) {
|
|
|
489
488
|
}
|
|
490
489
|
/** Whether the given node refers to a two-way binding AST node. */
|
|
491
490
|
function isTwoWayBindingNode(node) {
|
|
492
|
-
return ((node instanceof
|
|
493
|
-
(node instanceof
|
|
491
|
+
return ((node instanceof checker.BoundAttribute && node.type === checker.BindingType.TwoWay) ||
|
|
492
|
+
(node instanceof checker.BoundEvent && node.type === checker.ParsedEventType.TwoWay));
|
|
494
493
|
}
|
|
495
494
|
|
|
496
495
|
/** Possible types of references to known fields detected. */
|
|
@@ -582,11 +581,11 @@ function identifyHostBindingReferences(node, programInfo, checker$1, reflector,
|
|
|
582
581
|
if (!isPropertyBinding && !isEventBinding) {
|
|
583
582
|
continue;
|
|
584
583
|
}
|
|
585
|
-
const parser =
|
|
586
|
-
const sourceSpan = new
|
|
584
|
+
const parser = checker.makeBindingParser();
|
|
585
|
+
const sourceSpan = new checker.ParseSourceSpan(
|
|
587
586
|
// Fake source span to keep parsing offsets zero-based.
|
|
588
587
|
// We then later combine these with the expression TS node offsets.
|
|
589
|
-
new
|
|
588
|
+
new checker.ParseLocation({ content: '', url: '' }, 0, 0, 0), new checker.ParseLocation({ content: '', url: '' }, 0, 0, 0));
|
|
590
589
|
const name = rawName.substring(1, rawName.length - 1);
|
|
591
590
|
let parsed = undefined;
|
|
592
591
|
if (isEventBinding) {
|
|
@@ -650,7 +649,7 @@ function attemptExtractTemplateDefinition(node, checker$1, reflector, resourceLo
|
|
|
650
649
|
return {
|
|
651
650
|
isInline: true,
|
|
652
651
|
expression: templateProp,
|
|
653
|
-
interpolationConfig:
|
|
652
|
+
interpolationConfig: checker.DEFAULT_INTERPOLATION_CONFIG,
|
|
654
653
|
preserveWhitespaces: false,
|
|
655
654
|
resolvedTemplateUrl: containingFile,
|
|
656
655
|
templateUrl: containingFile,
|
|
@@ -664,7 +663,7 @@ function attemptExtractTemplateDefinition(node, checker$1, reflector, resourceLo
|
|
|
664
663
|
if (typeof templateUrl === 'string') {
|
|
665
664
|
return {
|
|
666
665
|
isInline: false,
|
|
667
|
-
interpolationConfig:
|
|
666
|
+
interpolationConfig: checker.DEFAULT_INTERPOLATION_CONFIG,
|
|
668
667
|
preserveWhitespaces: false,
|
|
669
668
|
templateUrlExpression: templateUrlProp,
|
|
670
669
|
templateUrl,
|