@angular/core 20.0.0-next.5 → 20.0.0-next.6
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-mxcXqDpA.d.ts → api.d-DQLNOR5l.d.ts} +4 -4
- package/{discovery.d-CyYpOJ7j.d.ts → discovery.d-CFs2MaLO.d.ts} +7 -17
- package/{event_dispatcher.d-PWnbqZDx.d.ts → event_dispatcher.d-DlbccpYq.d.ts} +3 -3
- package/fesm2022/{attribute-B17mgaqe.mjs → attribute-BWp59EjE.mjs} +3 -3
- package/fesm2022/{attribute-B17mgaqe.mjs.map → attribute-BWp59EjE.mjs.map} +1 -1
- package/fesm2022/core.mjs +20 -18
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/{debug_node-xKpCIZm-.mjs → debug_node-z_3NG8qT.mjs} +77 -68
- package/fesm2022/{debug_node-xKpCIZm-.mjs.map → debug_node-z_3NG8qT.mjs.map} +1 -1
- package/fesm2022/primitives/di.mjs +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +2 -2
- package/fesm2022/primitives/signals.mjs +5 -5
- package/fesm2022/{resource-BPpYEDic.mjs → resource-CPPwEcg7.mjs} +6 -8
- package/fesm2022/resource-CPPwEcg7.mjs.map +1 -0
- package/fesm2022/{root_effect_scheduler-D0_b1cf_.mjs → root_effect_scheduler-VSXfCzDX.mjs} +46 -15
- package/fesm2022/root_effect_scheduler-VSXfCzDX.mjs.map +1 -0
- package/fesm2022/rxjs-interop.mjs +7 -84
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/{signal-DhRAAi7R.mjs → signal-B6pMq7KS.mjs} +3 -3
- package/fesm2022/{signal-DhRAAi7R.mjs.map → signal-B6pMq7KS.mjs.map} +1 -1
- package/fesm2022/testing.mjs +165 -103
- package/fesm2022/testing.mjs.map +1 -1
- package/fesm2022/{untracked-DaaW3JJm.mjs → untracked-Bz5WMeU1.mjs} +4 -4
- package/fesm2022/{untracked-DaaW3JJm.mjs.map → untracked-Bz5WMeU1.mjs.map} +1 -1
- package/fesm2022/{weak_ref-DrMdAIDh.mjs → weak_ref-BaIq-pgY.mjs} +3 -3
- package/fesm2022/{weak_ref-DrMdAIDh.mjs.map → weak_ref-BaIq-pgY.mjs.map} +1 -1
- package/{graph.d-StYigYp1.d.ts → graph.d-BcIOep_B.d.ts} +3 -3
- package/index.d.ts +18 -20
- package/{ng_i18n_closure_mode.d-DLxSUiDr.d.ts → ng_i18n_closure_mode.d-C9d2CaSt.d.ts} +5 -5
- package/package.json +2 -2
- package/primitives/di/index.d.ts +1 -1
- package/primitives/event-dispatch/index.d.ts +3 -3
- package/primitives/signals/index.d.ts +6 -6
- package/rxjs-interop/index.d.ts +8 -17
- package/schematics/bundles/{apply_import_manager-C-ysxahq.js → apply_import_manager-DnMqg1pY.js} +6 -6
- package/schematics/bundles/{change_tracker-0Ktek5Xl.js → change_tracker-UMPkv-eH.js} +3 -3
- package/schematics/bundles/{checker-DqUKCGda.js → checker-BFBQyesT.js} +20 -3
- package/schematics/bundles/cleanup-unused-imports.js +25 -20
- package/schematics/bundles/{compiler-CuoiHqkc.js → compiler-BQ7R7w2v.js} +962 -297
- package/schematics/bundles/compiler_host-CAfDJO3W.js +1 -1
- package/schematics/bundles/control-flow-migration.js +2 -2
- package/schematics/bundles/document-core.js +12 -12
- package/schematics/bundles/imports-CIX-JgAN.js +1 -1
- package/schematics/bundles/{index-WFXCe5Q0.js → index-Cv4Q415G.js} +127 -36
- package/schematics/bundles/{index-CwFQSYXZ.js → index-D8tMJPKa.js} +10 -10
- package/schematics/bundles/inject-flags.js +14 -14
- package/schematics/bundles/inject-migration.js +4 -4
- package/schematics/bundles/leading_space-D9nQ8UQC.js +1 -1
- package/schematics/bundles/{migrate_ts_type_references-BNuHufqZ.js → migrate_ts_type_references-Cq_ZBuT4.js} +21 -21
- package/schematics/bundles/ng_decorators-DznZ5jMl.js +1 -1
- package/schematics/bundles/nodes-B16H9JUd.js +1 -1
- package/schematics/bundles/output-migration.js +80 -22
- package/schematics/bundles/{run_in_devkit-CmHxABFr.js → project_paths-ql6qcf_c.js} +254 -244
- package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.js +1 -1
- package/schematics/bundles/property_name-BBwFuqMe.js +1 -1
- package/schematics/bundles/route-lazy-loading.js +4 -4
- package/schematics/bundles/self-closing-tags-migration.js +20 -15
- package/schematics/bundles/signal-input-migration.js +26 -21
- package/schematics/bundles/signal-queries-migration.js +32 -27
- package/schematics/bundles/signals.js +8 -8
- package/schematics/bundles/standalone-migration.js +5 -5
- package/schematics/bundles/symbol-VPWguRxr.js +1 -1
- package/schematics/bundles/test-bed-get.js +13 -13
- package/{signal.d-BeaTIeOE.d.ts → signal.d-E0e5nW1p.d.ts} +4 -4
- package/testing/index.d.ts +9 -25
- package/{weak_ref.d-ttyj86RV.d.ts → weak_ref.d-eGOEP9S1.d.ts} +2 -2
- package/fesm2022/resource-BPpYEDic.mjs.map +0 -1
- package/fesm2022/root_effect_scheduler-D0_b1cf_.mjs.map +0 -1
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.0-next.
|
|
3
|
+
* @license Angular v20.0.0-next.6
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
var
|
|
10
|
-
var ts = require('typescript');
|
|
11
|
-
var checker = require('./checker-DqUKCGda.js');
|
|
12
|
-
var index = require('./index-WFXCe5Q0.js');
|
|
9
|
+
var index = require('./index-Cv4Q415G.js');
|
|
13
10
|
var schematics = require('@angular-devkit/schematics');
|
|
14
11
|
var core = require('@angular-devkit/core');
|
|
15
12
|
var posixPath = require('node:path/posix');
|
|
16
|
-
require('
|
|
13
|
+
var os = require('os');
|
|
14
|
+
var ts = require('typescript');
|
|
15
|
+
var checker = require('./checker-BFBQyesT.js');
|
|
16
|
+
require('./compiler-BQ7R7w2v.js');
|
|
17
17
|
require('path');
|
|
18
18
|
var project_tsconfig_paths = require('./project_tsconfig_paths-CDVxT6Ov.js');
|
|
19
19
|
|
|
@@ -34,8 +34,8 @@ function _interopNamespaceDefault(e) {
|
|
|
34
34
|
return Object.freeze(n);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
var os__namespace = /*#__PURE__*/_interopNamespaceDefault(os);
|
|
38
37
|
var posixPath__namespace = /*#__PURE__*/_interopNamespaceDefault(posixPath);
|
|
38
|
+
var os__namespace = /*#__PURE__*/_interopNamespaceDefault(os);
|
|
39
39
|
|
|
40
40
|
/// <reference types="node" />
|
|
41
41
|
class NgtscCompilerHost {
|
|
@@ -261,235 +261,6 @@ function getExtendedConfigPathWorker(configFile, extendsValue, host, fs) {
|
|
|
261
261
|
return null;
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
-
/**
|
|
265
|
-
* By default, Tsurge will always create an Angular compiler program
|
|
266
|
-
* for projects analyzed and migrated. This works perfectly fine in
|
|
267
|
-
* third-party where Tsurge migrations run in Angular CLI projects.
|
|
268
|
-
*
|
|
269
|
-
* In first party, when running against full Google3, creating an Angular
|
|
270
|
-
* program for e.g. plain `ts_library` targets is overly expensive and
|
|
271
|
-
* can result in out of memory issues for large TS targets. In 1P we can
|
|
272
|
-
* reliably distinguish between TS and Angular targets via the `angularCompilerOptions`.
|
|
273
|
-
*/
|
|
274
|
-
function google3UsePlainTsProgramIfNoKnownAngularOption() {
|
|
275
|
-
return process.env['GOOGLE3_TSURGE'] === '1';
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/** Options that are good defaults for Tsurge migrations. */
|
|
279
|
-
const defaultMigrationTsOptions = {
|
|
280
|
-
// Avoid checking libraries to speed up migrations.
|
|
281
|
-
skipLibCheck: true,
|
|
282
|
-
skipDefaultLibCheck: true,
|
|
283
|
-
noEmit: true,
|
|
284
|
-
// Does not apply to g3 and externally is enforced when the app is built by the compiler.
|
|
285
|
-
disableTypeScriptVersionCheck: true,
|
|
286
|
-
};
|
|
287
|
-
/**
|
|
288
|
-
* Creates an instance of a TypeScript program for the given project.
|
|
289
|
-
*/
|
|
290
|
-
function createPlainTsProgram(tsHost, tsconfig, optionOverrides) {
|
|
291
|
-
const program = ts.createProgram({
|
|
292
|
-
rootNames: tsconfig.rootNames,
|
|
293
|
-
options: {
|
|
294
|
-
...tsconfig.options,
|
|
295
|
-
...defaultMigrationTsOptions,
|
|
296
|
-
...optionOverrides,
|
|
297
|
-
},
|
|
298
|
-
});
|
|
299
|
-
return {
|
|
300
|
-
ngCompiler: null,
|
|
301
|
-
program,
|
|
302
|
-
userOptions: tsconfig.options,
|
|
303
|
-
programAbsoluteRootFileNames: tsconfig.rootNames,
|
|
304
|
-
host: tsHost,
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Parses the configuration of the given TypeScript project and creates
|
|
310
|
-
* an instance of the Angular compiler for the project.
|
|
311
|
-
*/
|
|
312
|
-
function createNgtscProgram(tsHost, tsconfig, optionOverrides) {
|
|
313
|
-
const ngtscProgram = new index.NgtscProgram(tsconfig.rootNames, {
|
|
314
|
-
...tsconfig.options,
|
|
315
|
-
...defaultMigrationTsOptions,
|
|
316
|
-
...optionOverrides,
|
|
317
|
-
}, tsHost);
|
|
318
|
-
// Expose an easy way to debug-print ng semantic diagnostics.
|
|
319
|
-
if (process.env['DEBUG_NG_SEMANTIC_DIAGNOSTICS'] === '1') {
|
|
320
|
-
console.error(ts.formatDiagnosticsWithColorAndContext(ngtscProgram.getNgSemanticDiagnostics(), tsHost));
|
|
321
|
-
}
|
|
322
|
-
return {
|
|
323
|
-
ngCompiler: ngtscProgram.compiler,
|
|
324
|
-
program: ngtscProgram.getTsProgram(),
|
|
325
|
-
userOptions: tsconfig.options,
|
|
326
|
-
programAbsoluteRootFileNames: tsconfig.rootNames,
|
|
327
|
-
host: tsHost,
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/** Code of the error raised by TypeScript when a tsconfig doesn't match any files. */
|
|
332
|
-
const NO_INPUTS_ERROR_CODE = 18003;
|
|
333
|
-
/** Parses the given tsconfig file, supporting Angular compiler options. */
|
|
334
|
-
function parseTsconfigOrDie(absoluteTsconfigPath, fs) {
|
|
335
|
-
const tsconfig = readConfiguration(absoluteTsconfigPath, {}, fs);
|
|
336
|
-
// Skip the "No inputs found..." error since we don't want to interrupt the migration if a
|
|
337
|
-
// tsconfig doesn't match a file. This will result in an empty `Program` which is still valid.
|
|
338
|
-
const errors = tsconfig.errors.filter((diag) => diag.code !== NO_INPUTS_ERROR_CODE);
|
|
339
|
-
if (errors.length) {
|
|
340
|
-
throw new Error(`Tsconfig could not be parsed or is invalid:\n\n` + `${errors.map((e) => e.messageText)}`);
|
|
341
|
-
}
|
|
342
|
-
return tsconfig;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/** Creates the base program info for the given tsconfig path. */
|
|
346
|
-
function createBaseProgramInfo(absoluteTsconfigPath, fs, optionOverrides = {}) {
|
|
347
|
-
if (fs === undefined) {
|
|
348
|
-
fs = new checker.NodeJSFileSystem();
|
|
349
|
-
checker.setFileSystem(fs);
|
|
350
|
-
}
|
|
351
|
-
const tsconfig = parseTsconfigOrDie(absoluteTsconfigPath, fs);
|
|
352
|
-
const tsHost = new NgtscCompilerHost(fs, tsconfig.options);
|
|
353
|
-
// When enabled, use a plain TS program if we are sure it's not
|
|
354
|
-
// an Angular project based on the `tsconfig.json`.
|
|
355
|
-
if (google3UsePlainTsProgramIfNoKnownAngularOption() &&
|
|
356
|
-
tsconfig.options['_useHostForImportGeneration'] === undefined) {
|
|
357
|
-
return createPlainTsProgram(tsHost, tsconfig, optionOverrides);
|
|
358
|
-
}
|
|
359
|
-
return createNgtscProgram(tsHost, tsconfig, optionOverrides);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* @private
|
|
364
|
-
*
|
|
365
|
-
* Base class for the possible Tsurge migration variants.
|
|
366
|
-
*
|
|
367
|
-
* For example, this class exposes methods to conveniently create
|
|
368
|
-
* TypeScript programs, while also allowing migration authors to override.
|
|
369
|
-
*/
|
|
370
|
-
class TsurgeBaseMigration {
|
|
371
|
-
/**
|
|
372
|
-
* Advanced Tsurge users can override this method, but most of the time,
|
|
373
|
-
* overriding {@link prepareProgram} is more desirable.
|
|
374
|
-
*
|
|
375
|
-
* By default:
|
|
376
|
-
* - In 3P: Ngtsc programs are being created.
|
|
377
|
-
* - In 1P: Ngtsc or TS programs are created based on the Blaze target.
|
|
378
|
-
*/
|
|
379
|
-
createProgram(tsconfigAbsPath, fs, optionOverrides) {
|
|
380
|
-
return createBaseProgramInfo(tsconfigAbsPath, fs, optionOverrides);
|
|
381
|
-
}
|
|
382
|
-
// Optional function to prepare the base `ProgramInfo` even further,
|
|
383
|
-
// for the analyze and migrate phases. E.g. determining source files.
|
|
384
|
-
prepareProgram(info) {
|
|
385
|
-
const fullProgramSourceFiles = [...info.program.getSourceFiles()];
|
|
386
|
-
const sourceFiles = fullProgramSourceFiles.filter((f) => !f.isDeclarationFile &&
|
|
387
|
-
// Note `isShim` will work for the initial program, but for TCB programs, the shims are no longer annotated.
|
|
388
|
-
!checker.isShim(f) &&
|
|
389
|
-
!f.fileName.endsWith('.ngtypecheck.ts'));
|
|
390
|
-
// Sort it by length in reverse order (longest first). This speeds up lookups,
|
|
391
|
-
// since there's no need to keep going through the array once a match is found.
|
|
392
|
-
const sortedRootDirs = checker.getRootDirs(info.host, info.userOptions).sort((a, b) => b.length - a.length);
|
|
393
|
-
// TODO: Consider also following TS's logic here, finding the common source root.
|
|
394
|
-
// See: Program#getCommonSourceDirectory.
|
|
395
|
-
const primaryRoot = checker.absoluteFrom(info.userOptions.rootDir ?? sortedRootDirs.at(-1) ?? info.program.getCurrentDirectory());
|
|
396
|
-
return {
|
|
397
|
-
...info,
|
|
398
|
-
sourceFiles,
|
|
399
|
-
fullProgramSourceFiles,
|
|
400
|
-
sortedRootDirs,
|
|
401
|
-
projectRoot: primaryRoot,
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* A simpler variant of a {@link TsurgeComplexMigration} that does not
|
|
408
|
-
* fan-out into multiple workers per compilation unit to compute
|
|
409
|
-
* the final migration replacements.
|
|
410
|
-
*
|
|
411
|
-
* This is faster and less resource intensive as workers and TS programs
|
|
412
|
-
* are only ever created once.
|
|
413
|
-
*
|
|
414
|
-
* This is commonly the case when migrations are refactored to eagerly
|
|
415
|
-
* compute replacements in the analyze stage, and then leverage the
|
|
416
|
-
* global unit data to filter replacements that turned out to be "invalid".
|
|
417
|
-
*/
|
|
418
|
-
class TsurgeFunnelMigration extends TsurgeBaseMigration {
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Complex variant of a `Tsurge` migration.
|
|
422
|
-
*
|
|
423
|
-
* For example, every analyze worker may contribute to a list of TS
|
|
424
|
-
* references that are later combined. The migrate phase can then compute actual
|
|
425
|
-
* file updates for all individual compilation units, leveraging the global metadata
|
|
426
|
-
* to e.g. see if there are any references from other compilation units that may be
|
|
427
|
-
* problematic and prevent migration of a given file.
|
|
428
|
-
*/
|
|
429
|
-
class TsurgeComplexMigration extends TsurgeBaseMigration {
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
/** A text replacement for the given file. */
|
|
433
|
-
class Replacement {
|
|
434
|
-
projectFile;
|
|
435
|
-
update;
|
|
436
|
-
constructor(projectFile, update) {
|
|
437
|
-
this.projectFile = projectFile;
|
|
438
|
-
this.update = update;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
/** An isolated text update that may be applied to a file. */
|
|
442
|
-
class TextUpdate {
|
|
443
|
-
data;
|
|
444
|
-
constructor(data) {
|
|
445
|
-
this.data = data;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/** Confirms that the given data `T` is serializable. */
|
|
450
|
-
function confirmAsSerializable(data) {
|
|
451
|
-
return data;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* Gets a project file instance for the given file.
|
|
456
|
-
*
|
|
457
|
-
* Use this helper for dealing with project paths throughout your
|
|
458
|
-
* migration. The return type is serializable.
|
|
459
|
-
*
|
|
460
|
-
* See {@link ProjectFile}.
|
|
461
|
-
*/
|
|
462
|
-
function projectFile(file, { sortedRootDirs, projectRoot }) {
|
|
463
|
-
const fs = checker.getFileSystem();
|
|
464
|
-
const filePath = fs.resolve(typeof file === 'string' ? file : file.fileName);
|
|
465
|
-
// Sorted root directories are sorted longest to shortest. First match
|
|
466
|
-
// is the appropriate root directory for ID computation.
|
|
467
|
-
for (const rootDir of sortedRootDirs) {
|
|
468
|
-
if (!isWithinBasePath(fs, rootDir, filePath)) {
|
|
469
|
-
continue;
|
|
470
|
-
}
|
|
471
|
-
return {
|
|
472
|
-
id: fs.relative(rootDir, filePath),
|
|
473
|
-
rootRelativePath: fs.relative(projectRoot, filePath),
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
// E.g. project directory may be `src/`, but files may be looked up
|
|
477
|
-
// from `node_modules/`. This is fine, but in those cases, no root
|
|
478
|
-
// directory matches.
|
|
479
|
-
const rootRelativePath = fs.relative(projectRoot, filePath);
|
|
480
|
-
return {
|
|
481
|
-
id: rootRelativePath,
|
|
482
|
-
rootRelativePath: rootRelativePath,
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Whether `path` is a descendant of the `base`?
|
|
487
|
-
* E.g. `a/b/c` is within `a/b` but not within `a/x`.
|
|
488
|
-
*/
|
|
489
|
-
function isWithinBasePath(fs, base, path) {
|
|
490
|
-
return checker.isLocalRelativePath(fs.relative(base, path));
|
|
491
|
-
}
|
|
492
|
-
|
|
493
264
|
/**
|
|
494
265
|
* Angular compiler file system implementation that leverages an
|
|
495
266
|
* CLI schematic virtual file tree.
|
|
@@ -671,6 +442,174 @@ async function synchronouslyCombineUnitData(migration, unitDatas) {
|
|
|
671
442
|
return combined;
|
|
672
443
|
}
|
|
673
444
|
|
|
445
|
+
/**
|
|
446
|
+
* By default, Tsurge will always create an Angular compiler program
|
|
447
|
+
* for projects analyzed and migrated. This works perfectly fine in
|
|
448
|
+
* third-party where Tsurge migrations run in Angular CLI projects.
|
|
449
|
+
*
|
|
450
|
+
* In first party, when running against full Google3, creating an Angular
|
|
451
|
+
* program for e.g. plain `ts_library` targets is overly expensive and
|
|
452
|
+
* can result in out of memory issues for large TS targets. In 1P we can
|
|
453
|
+
* reliably distinguish between TS and Angular targets via the `angularCompilerOptions`.
|
|
454
|
+
*/
|
|
455
|
+
function google3UsePlainTsProgramIfNoKnownAngularOption() {
|
|
456
|
+
return process.env['GOOGLE3_TSURGE'] === '1';
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/** Options that are good defaults for Tsurge migrations. */
|
|
460
|
+
const defaultMigrationTsOptions = {
|
|
461
|
+
// Avoid checking libraries to speed up migrations.
|
|
462
|
+
skipLibCheck: true,
|
|
463
|
+
skipDefaultLibCheck: true,
|
|
464
|
+
noEmit: true,
|
|
465
|
+
// Does not apply to g3 and externally is enforced when the app is built by the compiler.
|
|
466
|
+
disableTypeScriptVersionCheck: true,
|
|
467
|
+
};
|
|
468
|
+
/**
|
|
469
|
+
* Creates an instance of a TypeScript program for the given project.
|
|
470
|
+
*/
|
|
471
|
+
function createPlainTsProgram(tsHost, tsconfig, optionOverrides) {
|
|
472
|
+
const program = ts.createProgram({
|
|
473
|
+
rootNames: tsconfig.rootNames,
|
|
474
|
+
options: {
|
|
475
|
+
...tsconfig.options,
|
|
476
|
+
...defaultMigrationTsOptions,
|
|
477
|
+
...optionOverrides,
|
|
478
|
+
},
|
|
479
|
+
});
|
|
480
|
+
return {
|
|
481
|
+
ngCompiler: null,
|
|
482
|
+
program,
|
|
483
|
+
userOptions: tsconfig.options,
|
|
484
|
+
programAbsoluteRootFileNames: tsconfig.rootNames,
|
|
485
|
+
host: tsHost,
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Parses the configuration of the given TypeScript project and creates
|
|
491
|
+
* an instance of the Angular compiler for the project.
|
|
492
|
+
*/
|
|
493
|
+
function createNgtscProgram(tsHost, tsconfig, optionOverrides) {
|
|
494
|
+
const ngtscProgram = new index.NgtscProgram(tsconfig.rootNames, {
|
|
495
|
+
...tsconfig.options,
|
|
496
|
+
...defaultMigrationTsOptions,
|
|
497
|
+
...optionOverrides,
|
|
498
|
+
}, tsHost);
|
|
499
|
+
// Expose an easy way to debug-print ng semantic diagnostics.
|
|
500
|
+
if (process.env['DEBUG_NG_SEMANTIC_DIAGNOSTICS'] === '1') {
|
|
501
|
+
console.error(ts.formatDiagnosticsWithColorAndContext(ngtscProgram.getNgSemanticDiagnostics(), tsHost));
|
|
502
|
+
}
|
|
503
|
+
return {
|
|
504
|
+
ngCompiler: ngtscProgram.compiler,
|
|
505
|
+
program: ngtscProgram.getTsProgram(),
|
|
506
|
+
userOptions: tsconfig.options,
|
|
507
|
+
programAbsoluteRootFileNames: tsconfig.rootNames,
|
|
508
|
+
host: tsHost,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/** Code of the error raised by TypeScript when a tsconfig doesn't match any files. */
|
|
513
|
+
const NO_INPUTS_ERROR_CODE = 18003;
|
|
514
|
+
/** Parses the given tsconfig file, supporting Angular compiler options. */
|
|
515
|
+
function parseTsconfigOrDie(absoluteTsconfigPath, fs) {
|
|
516
|
+
const tsconfig = readConfiguration(absoluteTsconfigPath, {}, fs);
|
|
517
|
+
// Skip the "No inputs found..." error since we don't want to interrupt the migration if a
|
|
518
|
+
// tsconfig doesn't match a file. This will result in an empty `Program` which is still valid.
|
|
519
|
+
const errors = tsconfig.errors.filter((diag) => diag.code !== NO_INPUTS_ERROR_CODE);
|
|
520
|
+
if (errors.length) {
|
|
521
|
+
throw new Error(`Tsconfig could not be parsed or is invalid:\n\n` + `${errors.map((e) => e.messageText)}`);
|
|
522
|
+
}
|
|
523
|
+
return tsconfig;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** Creates the base program info for the given tsconfig path. */
|
|
527
|
+
function createBaseProgramInfo(absoluteTsconfigPath, fs, optionOverrides = {}) {
|
|
528
|
+
if (fs === undefined) {
|
|
529
|
+
fs = new checker.NodeJSFileSystem();
|
|
530
|
+
checker.setFileSystem(fs);
|
|
531
|
+
}
|
|
532
|
+
const tsconfig = parseTsconfigOrDie(absoluteTsconfigPath, fs);
|
|
533
|
+
const tsHost = new NgtscCompilerHost(fs, tsconfig.options);
|
|
534
|
+
// When enabled, use a plain TS program if we are sure it's not
|
|
535
|
+
// an Angular project based on the `tsconfig.json`.
|
|
536
|
+
if (google3UsePlainTsProgramIfNoKnownAngularOption() &&
|
|
537
|
+
tsconfig.options['_useHostForImportGeneration'] === undefined) {
|
|
538
|
+
return createPlainTsProgram(tsHost, tsconfig, optionOverrides);
|
|
539
|
+
}
|
|
540
|
+
return createNgtscProgram(tsHost, tsconfig, optionOverrides);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* @private
|
|
545
|
+
*
|
|
546
|
+
* Base class for the possible Tsurge migration variants.
|
|
547
|
+
*
|
|
548
|
+
* For example, this class exposes methods to conveniently create
|
|
549
|
+
* TypeScript programs, while also allowing migration authors to override.
|
|
550
|
+
*/
|
|
551
|
+
class TsurgeBaseMigration {
|
|
552
|
+
/**
|
|
553
|
+
* Advanced Tsurge users can override this method, but most of the time,
|
|
554
|
+
* overriding {@link prepareProgram} is more desirable.
|
|
555
|
+
*
|
|
556
|
+
* By default:
|
|
557
|
+
* - In 3P: Ngtsc programs are being created.
|
|
558
|
+
* - In 1P: Ngtsc or TS programs are created based on the Blaze target.
|
|
559
|
+
*/
|
|
560
|
+
createProgram(tsconfigAbsPath, fs, optionOverrides) {
|
|
561
|
+
return createBaseProgramInfo(tsconfigAbsPath, fs, optionOverrides);
|
|
562
|
+
}
|
|
563
|
+
// Optional function to prepare the base `ProgramInfo` even further,
|
|
564
|
+
// for the analyze and migrate phases. E.g. determining source files.
|
|
565
|
+
prepareProgram(info) {
|
|
566
|
+
const fullProgramSourceFiles = [...info.program.getSourceFiles()];
|
|
567
|
+
const sourceFiles = fullProgramSourceFiles.filter((f) => !f.isDeclarationFile &&
|
|
568
|
+
// Note `isShim` will work for the initial program, but for TCB programs, the shims are no longer annotated.
|
|
569
|
+
!checker.isShim(f) &&
|
|
570
|
+
!f.fileName.endsWith('.ngtypecheck.ts'));
|
|
571
|
+
// Sort it by length in reverse order (longest first). This speeds up lookups,
|
|
572
|
+
// since there's no need to keep going through the array once a match is found.
|
|
573
|
+
const sortedRootDirs = checker.getRootDirs(info.host, info.userOptions).sort((a, b) => b.length - a.length);
|
|
574
|
+
// TODO: Consider also following TS's logic here, finding the common source root.
|
|
575
|
+
// See: Program#getCommonSourceDirectory.
|
|
576
|
+
const primaryRoot = checker.absoluteFrom(info.userOptions.rootDir ?? sortedRootDirs.at(-1) ?? info.program.getCurrentDirectory());
|
|
577
|
+
return {
|
|
578
|
+
...info,
|
|
579
|
+
sourceFiles,
|
|
580
|
+
fullProgramSourceFiles,
|
|
581
|
+
sortedRootDirs,
|
|
582
|
+
projectRoot: primaryRoot,
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* A simpler variant of a {@link TsurgeComplexMigration} that does not
|
|
589
|
+
* fan-out into multiple workers per compilation unit to compute
|
|
590
|
+
* the final migration replacements.
|
|
591
|
+
*
|
|
592
|
+
* This is faster and less resource intensive as workers and TS programs
|
|
593
|
+
* are only ever created once.
|
|
594
|
+
*
|
|
595
|
+
* This is commonly the case when migrations are refactored to eagerly
|
|
596
|
+
* compute replacements in the analyze stage, and then leverage the
|
|
597
|
+
* global unit data to filter replacements that turned out to be "invalid".
|
|
598
|
+
*/
|
|
599
|
+
class TsurgeFunnelMigration extends TsurgeBaseMigration {
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Complex variant of a `Tsurge` migration.
|
|
603
|
+
*
|
|
604
|
+
* For example, every analyze worker may contribute to a list of TS
|
|
605
|
+
* references that are later combined. The migrate phase can then compute actual
|
|
606
|
+
* file updates for all individual compilation units, leveraging the global metadata
|
|
607
|
+
* to e.g. see if there are any references from other compilation units that may be
|
|
608
|
+
* problematic and prevent migration of a given file.
|
|
609
|
+
*/
|
|
610
|
+
class TsurgeComplexMigration extends TsurgeBaseMigration {
|
|
611
|
+
}
|
|
612
|
+
|
|
674
613
|
/*!
|
|
675
614
|
* @license
|
|
676
615
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -678,24 +617,30 @@ async function synchronouslyCombineUnitData(migration, unitDatas) {
|
|
|
678
617
|
* Use of this source code is governed by an MIT-style license that can be
|
|
679
618
|
* found in the LICENSE file at https://angular.dev/license
|
|
680
619
|
*/
|
|
620
|
+
exports.MigrationStage = void 0;
|
|
621
|
+
(function (MigrationStage) {
|
|
622
|
+
/** The migration is analyzing an entrypoint */
|
|
623
|
+
MigrationStage[MigrationStage["Analysis"] = 0] = "Analysis";
|
|
624
|
+
/** The migration is about to migrate an entrypoint */
|
|
625
|
+
MigrationStage[MigrationStage["Migrate"] = 1] = "Migrate";
|
|
626
|
+
})(exports.MigrationStage || (exports.MigrationStage = {}));
|
|
681
627
|
/** Runs a Tsurge within an Angular Devkit context. */
|
|
682
628
|
async function runMigrationInDevkit(config) {
|
|
683
629
|
const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(config.tree);
|
|
684
630
|
if (!buildPaths.length && !testPaths.length) {
|
|
685
631
|
throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the migration.');
|
|
686
632
|
}
|
|
633
|
+
const tsconfigPaths = [...buildPaths, ...testPaths];
|
|
687
634
|
const fs = new DevkitMigrationFilesystem(config.tree);
|
|
688
635
|
checker.setFileSystem(fs);
|
|
689
636
|
const migration = config.getMigration(fs);
|
|
690
637
|
const unitResults = [];
|
|
691
|
-
const
|
|
692
|
-
|
|
638
|
+
const isFunnelMigration = migration instanceof TsurgeFunnelMigration;
|
|
639
|
+
for (const tsconfigPath of tsconfigPaths) {
|
|
640
|
+
config.beforeProgramCreation?.(tsconfigPath, exports.MigrationStage.Analysis);
|
|
693
641
|
const baseInfo = migration.createProgram(tsconfigPath, fs);
|
|
694
642
|
const info = migration.prepareProgram(baseInfo);
|
|
695
|
-
config.afterProgramCreation?.(info, fs);
|
|
696
|
-
return { info, tsconfigPath };
|
|
697
|
-
});
|
|
698
|
-
for (const { info, tsconfigPath } of programInfos) {
|
|
643
|
+
config.afterProgramCreation?.(info, fs, exports.MigrationStage.Analysis);
|
|
699
644
|
config.beforeUnitAnalysis?.(tsconfigPath);
|
|
700
645
|
unitResults.push(await migration.analyze(info));
|
|
701
646
|
}
|
|
@@ -707,12 +652,16 @@ async function runMigrationInDevkit(config) {
|
|
|
707
652
|
}
|
|
708
653
|
const globalMeta = await migration.globalMeta(combined);
|
|
709
654
|
let replacements;
|
|
710
|
-
if (
|
|
655
|
+
if (isFunnelMigration) {
|
|
711
656
|
replacements = (await migration.migrate(globalMeta)).replacements;
|
|
712
657
|
}
|
|
713
658
|
else {
|
|
714
659
|
replacements = [];
|
|
715
|
-
for (const
|
|
660
|
+
for (const tsconfigPath of tsconfigPaths) {
|
|
661
|
+
config.beforeProgramCreation?.(tsconfigPath, exports.MigrationStage.Migrate);
|
|
662
|
+
const baseInfo = migration.createProgram(tsconfigPath, fs);
|
|
663
|
+
const info = migration.prepareProgram(baseInfo);
|
|
664
|
+
config.afterProgramCreation?.(info, fs, exports.MigrationStage.Migrate);
|
|
716
665
|
const result = await migration.migrate(globalMeta, info);
|
|
717
666
|
replacements.push(...result.replacements);
|
|
718
667
|
}
|
|
@@ -736,6 +685,67 @@ async function runMigrationInDevkit(config) {
|
|
|
736
685
|
config.whenDone?.(await migration.stats(globalMeta));
|
|
737
686
|
}
|
|
738
687
|
|
|
688
|
+
/** A text replacement for the given file. */
|
|
689
|
+
class Replacement {
|
|
690
|
+
projectFile;
|
|
691
|
+
update;
|
|
692
|
+
constructor(projectFile, update) {
|
|
693
|
+
this.projectFile = projectFile;
|
|
694
|
+
this.update = update;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
/** An isolated text update that may be applied to a file. */
|
|
698
|
+
class TextUpdate {
|
|
699
|
+
data;
|
|
700
|
+
constructor(data) {
|
|
701
|
+
this.data = data;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/** Confirms that the given data `T` is serializable. */
|
|
706
|
+
function confirmAsSerializable(data) {
|
|
707
|
+
return data;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Gets a project file instance for the given file.
|
|
712
|
+
*
|
|
713
|
+
* Use this helper for dealing with project paths throughout your
|
|
714
|
+
* migration. The return type is serializable.
|
|
715
|
+
*
|
|
716
|
+
* See {@link ProjectFile}.
|
|
717
|
+
*/
|
|
718
|
+
function projectFile(file, { sortedRootDirs, projectRoot }) {
|
|
719
|
+
const fs = checker.getFileSystem();
|
|
720
|
+
const filePath = fs.resolve(typeof file === 'string' ? file : file.fileName);
|
|
721
|
+
// Sorted root directories are sorted longest to shortest. First match
|
|
722
|
+
// is the appropriate root directory for ID computation.
|
|
723
|
+
for (const rootDir of sortedRootDirs) {
|
|
724
|
+
if (!isWithinBasePath(fs, rootDir, filePath)) {
|
|
725
|
+
continue;
|
|
726
|
+
}
|
|
727
|
+
return {
|
|
728
|
+
id: fs.relative(rootDir, filePath),
|
|
729
|
+
rootRelativePath: fs.relative(projectRoot, filePath),
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
// E.g. project directory may be `src/`, but files may be looked up
|
|
733
|
+
// from `node_modules/`. This is fine, but in those cases, no root
|
|
734
|
+
// directory matches.
|
|
735
|
+
const rootRelativePath = fs.relative(projectRoot, filePath);
|
|
736
|
+
return {
|
|
737
|
+
id: rootRelativePath,
|
|
738
|
+
rootRelativePath: rootRelativePath,
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Whether `path` is a descendant of the `base`?
|
|
743
|
+
* E.g. `a/b/c` is within `a/b` but not within `a/x`.
|
|
744
|
+
*/
|
|
745
|
+
function isWithinBasePath(fs, base, path) {
|
|
746
|
+
return checker.isLocalRelativePath(fs.relative(base, path));
|
|
747
|
+
}
|
|
748
|
+
|
|
739
749
|
exports.Replacement = Replacement;
|
|
740
750
|
exports.TextUpdate = TextUpdate;
|
|
741
751
|
exports.TsurgeComplexMigration = TsurgeComplexMigration;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.0-next.
|
|
3
|
+
* @license Angular v20.0.0-next.6
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
var schematics = require('@angular-devkit/schematics');
|
|
10
10
|
var fs = require('fs');
|
|
11
11
|
var p = require('path');
|
|
12
|
-
var change_tracker = require('./change_tracker-
|
|
12
|
+
var change_tracker = require('./change_tracker-UMPkv-eH.js');
|
|
13
13
|
var project_tsconfig_paths = require('./project_tsconfig_paths-CDVxT6Ov.js');
|
|
14
14
|
var compiler_host = require('./compiler_host-CAfDJO3W.js');
|
|
15
15
|
var ts = require('typescript');
|
|
16
|
-
var checker = require('./checker-
|
|
16
|
+
var checker = require('./checker-BFBQyesT.js');
|
|
17
17
|
var property_name = require('./property_name-BBwFuqMe.js');
|
|
18
|
-
require('./compiler-
|
|
18
|
+
require('./compiler-BQ7R7w2v.js');
|
|
19
19
|
require('os');
|
|
20
20
|
require('@angular-devkit/core');
|
|
21
21
|
require('module');
|