@angular/core 21.0.0-next.3 → 21.0.0-next.5
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.d.ts +7 -4
- package/chrome_dev_tools_performance.d.d.ts +1 -1
- package/discovery.d.d.ts +48 -21
- package/effect.d.d.ts +1 -2
- package/event_dispatcher.d.d.ts +1 -1
- package/fesm2022/attribute.mjs +1 -1
- package/fesm2022/attribute.mjs.map +1 -1
- package/fesm2022/core.mjs +228 -72
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/debug_node.mjs +564 -747
- package/fesm2022/debug_node.mjs.map +1 -1
- package/fesm2022/effect.mjs +3 -4
- package/fesm2022/effect.mjs.map +1 -1
- package/fesm2022/not_found.mjs +1 -1
- package/fesm2022/not_found.mjs.map +1 -1
- package/fesm2022/primitives/di.mjs +1 -1
- package/fesm2022/primitives/di.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +1 -1
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +4 -5
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/resource.mjs +5 -4
- package/fesm2022/resource.mjs.map +1 -1
- package/fesm2022/root_effect_scheduler.mjs +61 -45
- package/fesm2022/root_effect_scheduler.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +3 -1
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/signal.mjs +32 -11
- package/fesm2022/signal.mjs.map +1 -1
- package/fesm2022/testing.mjs +4 -4
- package/fesm2022/testing.mjs.map +1 -1
- package/fesm2022/weak_ref.mjs +1 -1
- package/fesm2022/weak_ref.mjs.map +1 -1
- package/graph.d.d.ts +24 -4
- package/index.d.ts +19 -140
- 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 +2 -3
- package/rxjs-interop/index.d.ts +3 -1
- package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +5 -5
- package/schematics/bundles/application-config-core.cjs +6 -6
- package/schematics/bundles/{apply_import_manager-tNexl58m.cjs → apply_import_manager-Bx60Uquz.cjs} +3 -3
- package/schematics/bundles/bootstrap-options-migration.cjs +637 -0
- package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
- package/schematics/bundles/{compiler_host-Df7s6Riz.cjs → compiler_host-Aouk-n4F.cjs} +2 -2
- package/schematics/bundles/control-flow-migration.cjs +71 -39
- package/schematics/bundles/{imports-26VeX8i-.cjs → imports-DwPXlGFl.cjs} +27 -1
- package/schematics/bundles/{index-Clvp4COX.cjs → index-BZQb51Qf.cjs} +4 -4
- package/schematics/bundles/{index-CBaykQBv.cjs → index-Bb6iejCd.cjs} +130 -41
- package/schematics/bundles/inject-migration.cjs +5 -5
- package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
- package/schematics/bundles/{migrate_ts_type_references-C_gTvDtH.cjs → migrate_ts_type_references-By2ZtKls.cjs} +5 -5
- package/schematics/bundles/{ng_component_template-HYGPuVhy.cjs → ng_component_template-B4M8mTyv.cjs} +3 -3
- package/schematics/bundles/{ng_decorators-CtYwz9Lw.cjs → ng_decorators-BI0uV7KI.cjs} +2 -2
- package/schematics/bundles/ngclass-to-class-migration.cjs +110 -98
- package/schematics/bundles/ngstyle-to-style-migration.cjs +490 -0
- package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
- package/schematics/bundles/output-migration.cjs +6 -6
- package/schematics/bundles/parse_html-7Wl_HDnw.cjs +132 -0
- package/schematics/bundles/{project_paths-BJTqcWvC.cjs → project_paths-Dr2s3Pq3.cjs} +3 -3
- package/schematics/bundles/{project_tsconfig_paths-bRwOJEk9.cjs → project_tsconfig_paths-DX9KHLn9.cjs} +423 -236
- package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
- package/schematics/bundles/route-lazy-loading.cjs +48 -4
- package/schematics/bundles/router-current-navigation.cjs +6 -6
- package/schematics/bundles/router-last-successful-navigation.cjs +6 -6
- package/schematics/bundles/self-closing-tags-migration.cjs +8 -8
- package/schematics/bundles/signal-input-migration.cjs +17 -9
- package/schematics/bundles/signal-queries-migration.cjs +7 -7
- package/schematics/bundles/signals.cjs +7 -7
- package/schematics/bundles/standalone-migration.cjs +17 -10
- package/schematics/bundles/{symbol-VPWguRxr.cjs → symbol-BObKoqes.cjs} +3 -2
- package/schematics/collection.json +6 -0
- package/schematics/migrations/ngstyle-to-style-migration/schema.json +20 -0
- package/schematics/migrations.json +5 -0
- package/testing/index.d.ts +1 -1
- package/weak_ref.d.d.ts +1 -1
- package/schematics/bundles/parse_html-CLFKoiOK.cjs +0 -41
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* @license Angular v21.0.0-next.5
|
|
4
|
+
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
|
+
* License: MIT
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
require('@angular-devkit/core');
|
|
10
|
+
require('node:path/posix');
|
|
11
|
+
var project_paths = require('./project_paths-Dr2s3Pq3.cjs');
|
|
12
|
+
require('os');
|
|
13
|
+
var ts = require('typescript');
|
|
14
|
+
var project_tsconfig_paths = require('./project_tsconfig_paths-DX9KHLn9.cjs');
|
|
15
|
+
var index = require('./index-Bb6iejCd.cjs');
|
|
16
|
+
require('path');
|
|
17
|
+
require('node:path');
|
|
18
|
+
var apply_import_manager = require('./apply_import_manager-Bx60Uquz.cjs');
|
|
19
|
+
var property_name = require('./property_name-BBwFuqMe.cjs');
|
|
20
|
+
var imports = require('./imports-DwPXlGFl.cjs');
|
|
21
|
+
var symbol = require('./symbol-BObKoqes.cjs');
|
|
22
|
+
require('@angular-devkit/schematics');
|
|
23
|
+
require('fs');
|
|
24
|
+
require('module');
|
|
25
|
+
require('url');
|
|
26
|
+
|
|
27
|
+
const CORE_PACKAGE = '@angular/core';
|
|
28
|
+
const PROVIDE_ZONE_CHANGE_DETECTION = 'provideZoneChangeDetection';
|
|
29
|
+
const ZONE_CD_PROVIDER = `${PROVIDE_ZONE_CHANGE_DETECTION}()`;
|
|
30
|
+
class BootstrapOptionsMigration extends project_paths.TsurgeFunnelMigration {
|
|
31
|
+
async analyze(info) {
|
|
32
|
+
let replacements = [];
|
|
33
|
+
const importManager = new project_tsconfig_paths.ImportManager();
|
|
34
|
+
for (const sourceFile of info.sourceFiles) {
|
|
35
|
+
// We need to migration either
|
|
36
|
+
// * `bootstrapApplication(App)
|
|
37
|
+
// * `platformBrowser().bootstrapModule(AppModule)`
|
|
38
|
+
// * `platformBrowserDynamic().bootstrapModule(AppModule)`
|
|
39
|
+
// * `TestBed.initTestEnvironment([AppModule], platformBrowserTesting())`
|
|
40
|
+
// * `getTestBed.initTestEnvironment([AppModule], platformBrowserTesting())`
|
|
41
|
+
const specifiers = getSpecifiers(sourceFile);
|
|
42
|
+
// If none of the imports related to bootstraping are present, we can skip the file.
|
|
43
|
+
if (specifiers === null)
|
|
44
|
+
continue;
|
|
45
|
+
const { bootstrapAppSpecifier, platformBrowserDynamicSpecifier, platformBrowserSpecifier, testBedSpecifier, createApplicationSpecifier, getTestBedSpecifier, } = specifiers;
|
|
46
|
+
const typeChecker = info.program.getTypeChecker();
|
|
47
|
+
const isCreateApplicationNode = (node) => {
|
|
48
|
+
return (ts.isCallExpression(node) &&
|
|
49
|
+
createApplicationSpecifier !== null &&
|
|
50
|
+
symbol.isReferenceToImport(typeChecker, node.expression, createApplicationSpecifier));
|
|
51
|
+
};
|
|
52
|
+
const isBootstrapAppNode = (node) => {
|
|
53
|
+
return (ts.isCallExpression(node) &&
|
|
54
|
+
bootstrapAppSpecifier !== null &&
|
|
55
|
+
symbol.isReferenceToImport(typeChecker, node.expression, bootstrapAppSpecifier));
|
|
56
|
+
};
|
|
57
|
+
const isBootstrapModuleNode = (node) => {
|
|
58
|
+
return (ts.isCallExpression(node) &&
|
|
59
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
60
|
+
node.expression.name.text === 'bootstrapModule' &&
|
|
61
|
+
ts.isCallExpression(node.expression.expression) &&
|
|
62
|
+
(symbol.isReferenceToImport(typeChecker, node.expression.expression.expression, platformBrowserSpecifier) ||
|
|
63
|
+
symbol.isReferenceToImport(typeChecker, node.expression.expression.expression, platformBrowserDynamicSpecifier)));
|
|
64
|
+
};
|
|
65
|
+
const isTestBedInitEnvironmentNode = (node) => {
|
|
66
|
+
return (ts.isCallExpression(node) &&
|
|
67
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
68
|
+
node.expression.name.text === 'initTestEnvironment' &&
|
|
69
|
+
(symbol.isReferenceToImport(typeChecker, node.expression.expression, testBedSpecifier) ||
|
|
70
|
+
symbol.isReferenceToImport(typeChecker, node.expression.expression, getTestBedSpecifier)));
|
|
71
|
+
};
|
|
72
|
+
const reflector = new project_tsconfig_paths.TypeScriptReflectionHost(typeChecker);
|
|
73
|
+
const evaluator = new index.PartialEvaluator(reflector, typeChecker, null);
|
|
74
|
+
const walk = (node) => {
|
|
75
|
+
if (isBootstrapAppNode(node)) {
|
|
76
|
+
this.analyzeBootstrapApplication(node, sourceFile, info, typeChecker, importManager, replacements);
|
|
77
|
+
}
|
|
78
|
+
else if (isCreateApplicationNode(node)) {
|
|
79
|
+
this.analyzeCreateApplication(node, sourceFile, info, typeChecker, importManager, replacements);
|
|
80
|
+
}
|
|
81
|
+
else if (isBootstrapModuleNode(node)) {
|
|
82
|
+
this.analyzeBootstrapModule(node, sourceFile, reflector, evaluator, info, typeChecker, importManager, replacements);
|
|
83
|
+
}
|
|
84
|
+
else if (isTestBedInitEnvironmentNode(node)) {
|
|
85
|
+
this.analyzeTestBedInitEnvironment(node, sourceFile, info, typeChecker, importManager, replacements);
|
|
86
|
+
}
|
|
87
|
+
node.forEachChild(walk);
|
|
88
|
+
};
|
|
89
|
+
sourceFile.forEachChild(walk);
|
|
90
|
+
}
|
|
91
|
+
// The combine method might not run when there is a single target.
|
|
92
|
+
// So we deduplicate here
|
|
93
|
+
replacements = deduplicateReplacements(replacements);
|
|
94
|
+
apply_import_manager.applyImportManagerChanges(importManager, replacements, info.sourceFiles, info);
|
|
95
|
+
return project_paths.confirmAsSerializable({ replacements });
|
|
96
|
+
}
|
|
97
|
+
async combine(unitA, unitB) {
|
|
98
|
+
const combined = [...unitA.replacements, ...unitB.replacements];
|
|
99
|
+
return project_paths.confirmAsSerializable({ replacements: deduplicateReplacements(combined) });
|
|
100
|
+
}
|
|
101
|
+
async globalMeta(data) {
|
|
102
|
+
return project_paths.confirmAsSerializable(data);
|
|
103
|
+
}
|
|
104
|
+
async stats(data) {
|
|
105
|
+
return project_paths.confirmAsSerializable({});
|
|
106
|
+
}
|
|
107
|
+
async migrate(data) {
|
|
108
|
+
return { replacements: data.replacements };
|
|
109
|
+
}
|
|
110
|
+
analyzeBootstrapApplication(node, sourceFile, info, typeChecker, importManager, replacements) {
|
|
111
|
+
const hasExistingChangeDetectionProvider = hasChangeDetectionProvider(node, typeChecker);
|
|
112
|
+
if (hasExistingChangeDetectionProvider)
|
|
113
|
+
return;
|
|
114
|
+
const providerFn = 'provideZoneChangeDetection()';
|
|
115
|
+
const optionsNode = node.arguments[1];
|
|
116
|
+
const currentProjectFile = project_paths.projectFile(sourceFile, info);
|
|
117
|
+
if (optionsNode) {
|
|
118
|
+
let optionProjectFile = currentProjectFile;
|
|
119
|
+
let optionLiteral;
|
|
120
|
+
if (ts.isObjectLiteralExpression(optionsNode)) {
|
|
121
|
+
optionLiteral = optionsNode;
|
|
122
|
+
addProvidersToBootstrapOption(optionProjectFile, optionLiteral, providerFn, replacements);
|
|
123
|
+
}
|
|
124
|
+
else if (ts.isIdentifier(optionsNode)) {
|
|
125
|
+
// This case handled both `bootstrapApplication(App, appConfig)` and the server () => bootstrapApplication(App, appConfig)
|
|
126
|
+
// where appConfig is the result of a `mergeApplicationConfig` call.
|
|
127
|
+
// This is tricky case to handle, in G3 we're might not be able to resolve the identifier's value
|
|
128
|
+
// Our best alternative is to assume there is not CD providers set and add the ZoneChangeDetection provider
|
|
129
|
+
// In the cases where it is, we'll just override the zone provider we just set by re-used inthe appConfig providers
|
|
130
|
+
// TODO: Should we insert a TODO to clean this up ?
|
|
131
|
+
const text = `{...${optionsNode.getText()}, providers: [${providerFn}, ...${optionsNode.getText()}.providers]}`;
|
|
132
|
+
replacements.push(new project_paths.Replacement(currentProjectFile, new project_paths.TextUpdate({
|
|
133
|
+
position: optionsNode.getStart(),
|
|
134
|
+
end: optionsNode.getEnd(),
|
|
135
|
+
toInsert: text,
|
|
136
|
+
})));
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
throw new Error('unsupported optionsNode: ' + optionsNode.getText());
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// No options object, add it.
|
|
144
|
+
const text = `, {providers: [${providerFn}]}`;
|
|
145
|
+
const component = node.arguments[0];
|
|
146
|
+
replacements.push(new project_paths.Replacement(currentProjectFile, new project_paths.TextUpdate({ position: component.getEnd(), end: component.getEnd(), toInsert: text })));
|
|
147
|
+
}
|
|
148
|
+
importManager.addImport({
|
|
149
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
150
|
+
exportSymbolName: 'provideZoneChangeDetection',
|
|
151
|
+
requestedFile: sourceFile,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
analyzeCreateApplication(node, sourceFile, info, typeChecker, importManager, replacements) {
|
|
155
|
+
const hasExistingChangeDetectionProvider = hasChangeDetectionProvider(node, typeChecker);
|
|
156
|
+
if (hasExistingChangeDetectionProvider)
|
|
157
|
+
return;
|
|
158
|
+
const providerFn = 'provideZoneChangeDetection()';
|
|
159
|
+
const optionsNode = node.arguments[0];
|
|
160
|
+
const currentProjectFile = project_paths.projectFile(sourceFile, info);
|
|
161
|
+
if (optionsNode) {
|
|
162
|
+
let optionProjectFile = currentProjectFile;
|
|
163
|
+
let optionLiteral;
|
|
164
|
+
if (ts.isObjectLiteralExpression(optionsNode)) {
|
|
165
|
+
optionLiteral = optionsNode;
|
|
166
|
+
addProvidersToBootstrapOption(optionProjectFile, optionLiteral, providerFn, replacements);
|
|
167
|
+
}
|
|
168
|
+
else if (ts.isIdentifier(optionsNode) ||
|
|
169
|
+
ts.isCallExpression(optionsNode) ||
|
|
170
|
+
ts.isPropertyAccessExpression(optionsNode)) {
|
|
171
|
+
// This is tricky case to handle, in G3 we're might not be able to resolve the identifier's value
|
|
172
|
+
// Our best alternative is to assume there is no CD providers set and add the ZoneChangeDetection provider
|
|
173
|
+
// In the cases where it is, we'll just override the zone provider we just set by re-used inthe appConfig providers
|
|
174
|
+
// TODO: Should we insert a TODO to clean this up ?
|
|
175
|
+
const text = `{...${optionsNode.getText()}, providers: [${providerFn}, ...${optionsNode.getText()}.providers]}`;
|
|
176
|
+
replacements.push(new project_paths.Replacement(currentProjectFile, new project_paths.TextUpdate({
|
|
177
|
+
position: optionsNode.getStart(),
|
|
178
|
+
end: optionsNode.getEnd(),
|
|
179
|
+
toInsert: text,
|
|
180
|
+
})));
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
throw new Error('unsupported optionsNode: ' + optionsNode.getText());
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
// No options object, add it.
|
|
188
|
+
const text = `{providers: [${providerFn}]}`;
|
|
189
|
+
replacements.push(new project_paths.Replacement(currentProjectFile, new project_paths.TextUpdate({
|
|
190
|
+
position: node.expression.getEnd() + 1,
|
|
191
|
+
end: node.expression.getEnd() + 1,
|
|
192
|
+
toInsert: text,
|
|
193
|
+
})));
|
|
194
|
+
}
|
|
195
|
+
importManager.addImport({
|
|
196
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
197
|
+
exportSymbolName: 'provideZoneChangeDetection',
|
|
198
|
+
requestedFile: sourceFile,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
analyzeBootstrapModule(node, sourceFile, reflector, evaluator, info, typeChecker, importManager, replacements) {
|
|
202
|
+
const moduleIdentifier = node.arguments[0];
|
|
203
|
+
const moduleType = evaluator.evaluate(moduleIdentifier);
|
|
204
|
+
if (!(moduleType instanceof project_tsconfig_paths.Reference) || !ts.isClassDeclaration(moduleType.node)) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const moduleClass = moduleType.node;
|
|
208
|
+
const ngModule = findNgModule(moduleClass, reflector);
|
|
209
|
+
if (!ngModule) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const moduleSourceFile = moduleClass.getSourceFile();
|
|
213
|
+
const moduleProjectFile = project_paths.projectFile(moduleSourceFile, info);
|
|
214
|
+
if (moduleSourceFile.getText().includes('ZoneChangeDetectionModule')) {
|
|
215
|
+
// If the file already contains the ZoneChangeDetectionModule, we can skip it.
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
// Always remove the options argument
|
|
219
|
+
replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({ position: moduleIdentifier.getEnd(), end: node.getEnd() - 1, toInsert: '' })));
|
|
220
|
+
const hasExistingChangeDetectionProvider = hasChangeDetectionProvider(ngModule, typeChecker);
|
|
221
|
+
if (hasExistingChangeDetectionProvider) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
// Let's try to understand the bootstrap options.
|
|
225
|
+
const optionsNode = node.arguments[1];
|
|
226
|
+
const options = optionsNode && ts.isObjectLiteralExpression(optionsNode)
|
|
227
|
+
? evaluator.evaluate(optionsNode)
|
|
228
|
+
: null;
|
|
229
|
+
let zoneCdProvider = ZONE_CD_PROVIDER;
|
|
230
|
+
let zoneInstanceProvider = null;
|
|
231
|
+
if (options instanceof Map) {
|
|
232
|
+
const ngZoneOption = options.get('ngZone');
|
|
233
|
+
if (options.has('ngZoneRunCoalescing') || options.has('ngZoneEventCoalescing')) {
|
|
234
|
+
const config = [];
|
|
235
|
+
if (options.get('ngZoneRunCoalescing')) {
|
|
236
|
+
config.push('runCoalescing: true');
|
|
237
|
+
}
|
|
238
|
+
if (options.get('ngZoneEventCoalescing')) {
|
|
239
|
+
config.push('eventCoalescing: true');
|
|
240
|
+
}
|
|
241
|
+
zoneCdProvider = `${PROVIDE_ZONE_CHANGE_DETECTION}(${config.length > 0 ? `{ ${config.join(', ')} }` : ''})`;
|
|
242
|
+
}
|
|
243
|
+
if (ngZoneOption instanceof project_tsconfig_paths.Reference) {
|
|
244
|
+
importManager.addImport({
|
|
245
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
246
|
+
exportSymbolName: 'NgZone',
|
|
247
|
+
requestedFile: moduleSourceFile,
|
|
248
|
+
});
|
|
249
|
+
const clazz = ngZoneOption.node;
|
|
250
|
+
if (ts.isClassDeclaration(clazz) && clazz.name) {
|
|
251
|
+
const customZoneSourceFile = clazz.getSourceFile();
|
|
252
|
+
const exportModuleSpecifier = ngZoneOption.bestGuessOwningModule?.specifier ??
|
|
253
|
+
imports.getRelativePath(moduleSourceFile.fileName, customZoneSourceFile.fileName);
|
|
254
|
+
importManager.addImport({
|
|
255
|
+
exportModuleSpecifier,
|
|
256
|
+
exportSymbolName: clazz.name.text,
|
|
257
|
+
requestedFile: moduleSourceFile,
|
|
258
|
+
});
|
|
259
|
+
zoneInstanceProvider = `{provide: NgZone, useClass: ${clazz.name.text}}`;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else if (typeof ngZoneOption === 'string' && ngZoneOption === 'noop') {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
else if (ngZoneOption && typeof ngZoneOption !== 'string') {
|
|
266
|
+
// This is a case where we're not able to migrate automatically
|
|
267
|
+
// The migration fails gracefully, keeps the ngZone option and adds a TODO.
|
|
268
|
+
let ngZoneValue;
|
|
269
|
+
optionsNode.properties.forEach((p) => {
|
|
270
|
+
if (ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === 'ngZone') {
|
|
271
|
+
ngZoneValue = p.initializer.getText();
|
|
272
|
+
}
|
|
273
|
+
else if (ts.isShorthandPropertyAssignment(p) && p.name.text === 'ngZone') {
|
|
274
|
+
ngZoneValue = p.name.text;
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
if (ngZoneValue) {
|
|
278
|
+
// We re-add the ngZone option
|
|
279
|
+
replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
|
|
280
|
+
position: moduleIdentifier.getEnd(),
|
|
281
|
+
end: node.getEnd() - 1,
|
|
282
|
+
toInsert: `, {ngZone: ${ngZoneValue}}`,
|
|
283
|
+
})));
|
|
284
|
+
}
|
|
285
|
+
// And add the TODO
|
|
286
|
+
replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
|
|
287
|
+
position: node.getStart() - 1,
|
|
288
|
+
end: node.getStart() - 1,
|
|
289
|
+
toInsert: '// TODO: BootstrapOptions are deprecated & ignored. Configure NgZone in the providers array of the application module instead.',
|
|
290
|
+
})));
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const providers = [zoneCdProvider];
|
|
294
|
+
if (zoneInstanceProvider) {
|
|
295
|
+
providers.push(zoneInstanceProvider);
|
|
296
|
+
}
|
|
297
|
+
if (providers.length > 0) {
|
|
298
|
+
importManager.addImport({
|
|
299
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
300
|
+
exportSymbolName: PROVIDE_ZONE_CHANGE_DETECTION,
|
|
301
|
+
requestedFile: moduleSourceFile,
|
|
302
|
+
});
|
|
303
|
+
addProvidersToNgModule(moduleProjectFile, moduleSourceFile, ngModule, providers.join(',\n'), replacements);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
analyzeTestBedInitEnvironment(callExpr, sourceFile, info, typeChecker, importManager, replacements) {
|
|
307
|
+
const hasExistingChangeDetectionProvider = hasChangeDetectionProvider(callExpr, typeChecker);
|
|
308
|
+
if (hasExistingChangeDetectionProvider)
|
|
309
|
+
return;
|
|
310
|
+
const ngModules = callExpr.arguments[0];
|
|
311
|
+
const moduleProjectFile = project_paths.projectFile(sourceFile, info);
|
|
312
|
+
importManager.addImport({
|
|
313
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
314
|
+
exportSymbolName: PROVIDE_ZONE_CHANGE_DETECTION,
|
|
315
|
+
requestedFile: sourceFile,
|
|
316
|
+
});
|
|
317
|
+
let tmpNode = callExpr;
|
|
318
|
+
let insertPosition = 0;
|
|
319
|
+
while (tmpNode.parent.kind !== ts.SyntaxKind.SourceFile) {
|
|
320
|
+
insertPosition = tmpNode.parent.getStart(sourceFile, true) - 1;
|
|
321
|
+
tmpNode = tmpNode.parent;
|
|
322
|
+
}
|
|
323
|
+
importManager.addImport({
|
|
324
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
325
|
+
exportSymbolName: 'NgModule',
|
|
326
|
+
requestedFile: sourceFile,
|
|
327
|
+
});
|
|
328
|
+
addZoneCDModule(ZONE_CD_PROVIDER, moduleProjectFile, insertPosition, replacements);
|
|
329
|
+
insertZoneCDModule(ngModules, moduleProjectFile, replacements, 'ZoneChangeDetectionModule');
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function addProvidersToNgModule(projectFile, moduleSourceFile, ngModule, providersText, replacements) {
|
|
333
|
+
// ObjLiteral => callExp => Decorator => ClassExpression
|
|
334
|
+
const moduleClassDeclaration = ngModule.parent.parent.parent;
|
|
335
|
+
const insertPosition = moduleClassDeclaration.getStart(moduleSourceFile, true) - 1;
|
|
336
|
+
addZoneCDModule(providersText, projectFile, insertPosition, replacements);
|
|
337
|
+
const importsNode = property_name.findLiteralProperty(ngModule, 'imports');
|
|
338
|
+
if (importsNode && ts.isPropertyAssignment(importsNode)) {
|
|
339
|
+
insertZoneCDModule(importsNode.initializer, projectFile, replacements, 'ZoneChangeDetectionModule');
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
const text = `imports: [ZoneChangeDetectionModule]`;
|
|
343
|
+
const toInsert = `${text},\n`;
|
|
344
|
+
let position = ngModule.getStart() + 1;
|
|
345
|
+
if (ngModule.properties.length > 0) {
|
|
346
|
+
const firstProperty = ngModule.properties[0];
|
|
347
|
+
position = firstProperty.getStart();
|
|
348
|
+
}
|
|
349
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
350
|
+
position,
|
|
351
|
+
end: position,
|
|
352
|
+
toInsert,
|
|
353
|
+
})));
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function addZoneCDModule(providersText, projectFile, location, replacements) {
|
|
357
|
+
const newModuleText = `\n@NgModule({ providers: [ ${providersText} ] })
|
|
358
|
+
export class ZoneChangeDetectionModule {}\n\n`;
|
|
359
|
+
if (replacementsHaveZoneCdModule(projectFile.rootRelativePath, replacements, newModuleText)) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
363
|
+
position: location,
|
|
364
|
+
end: location,
|
|
365
|
+
toInsert: newModuleText,
|
|
366
|
+
})));
|
|
367
|
+
}
|
|
368
|
+
function insertZoneCDModule(node, projectFile, replacements, importedModule) {
|
|
369
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
370
|
+
const literal = node;
|
|
371
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
372
|
+
position: literal.elements[0]?.getStart() ?? literal.getEnd() - 1,
|
|
373
|
+
end: literal.elements[0]?.getStart() ?? literal.getEnd() - 1,
|
|
374
|
+
toInsert: importedModule + ',',
|
|
375
|
+
})));
|
|
376
|
+
}
|
|
377
|
+
else if (ts.isIdentifier(node)) {
|
|
378
|
+
// This should be a good enough heuristic to determine if the identifier is not array
|
|
379
|
+
let isArray = !node.text.endsWith('Module');
|
|
380
|
+
// Because if it's an array, we need to spread it
|
|
381
|
+
const newImports = `[${importedModule}, ${isArray ? '...' : ''}${node.text}]`;
|
|
382
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
383
|
+
position: node.getStart(),
|
|
384
|
+
end: node.getEnd(),
|
|
385
|
+
toInsert: newImports,
|
|
386
|
+
})));
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
throw new Error('unsupported importsNode: ' + node.getText());
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
function addProvidersToBootstrapOption(projectFile, optionsNode, providersText, replacements) {
|
|
393
|
+
const providersProp = property_name.findLiteralProperty(optionsNode, 'providers');
|
|
394
|
+
if (providersProp && ts.isPropertyAssignment(providersProp)) {
|
|
395
|
+
// Can be bootstrap(App, {providers: [...]}), bootstrap(App, {providers}), bootstrap(App, {...appConfig, providers}) etc.
|
|
396
|
+
if (ts.isArrayLiteralExpression(providersProp.initializer)) {
|
|
397
|
+
const initializer = providersProp.initializer;
|
|
398
|
+
const text = `${providersText},`;
|
|
399
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
400
|
+
position: initializer.elements[0]?.getStart() ?? initializer.getEnd() - 1,
|
|
401
|
+
end: initializer.elements[0]?.getStart() ?? initializer.getEnd() - 1,
|
|
402
|
+
toInsert: text,
|
|
403
|
+
})));
|
|
404
|
+
}
|
|
405
|
+
else if (ts.isIdentifier(providersProp.initializer)) {
|
|
406
|
+
const newProviders = `[${providersText}, ...${providersProp.initializer.text}]`;
|
|
407
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
408
|
+
position: providersProp.initializer.getStart(),
|
|
409
|
+
end: providersProp.initializer.getEnd(),
|
|
410
|
+
toInsert: newProviders,
|
|
411
|
+
})));
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
const newProviders = `[${providersText}, ...`;
|
|
415
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
416
|
+
position: providersProp.initializer.getStart(),
|
|
417
|
+
end: providersProp.initializer.getStart(),
|
|
418
|
+
toInsert: newProviders,
|
|
419
|
+
})));
|
|
420
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
421
|
+
position: providersProp.initializer.getEnd(),
|
|
422
|
+
end: providersProp.initializer.getEnd(),
|
|
423
|
+
toInsert: ']',
|
|
424
|
+
})));
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
else if (providersProp && ts.isShorthandPropertyAssignment(providersProp)) {
|
|
428
|
+
const newProviders = `providers: [${providersText}, ...${providersProp.name.text}]`;
|
|
429
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
430
|
+
position: providersProp.getStart(),
|
|
431
|
+
end: providersProp.getEnd(),
|
|
432
|
+
toInsert: newProviders,
|
|
433
|
+
})));
|
|
434
|
+
}
|
|
435
|
+
else if (optionsNode.properties.length === 1 &&
|
|
436
|
+
ts.isSpreadAssignment(optionsNode.properties[0])) {
|
|
437
|
+
const spread = optionsNode.properties[0];
|
|
438
|
+
const newProviders = `, providers: [${providersText}, ...${spread.expression.getText()}.providers]`;
|
|
439
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
440
|
+
position: spread.getEnd(),
|
|
441
|
+
end: spread.getEnd(),
|
|
442
|
+
toInsert: newProviders,
|
|
443
|
+
})));
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
const text = `providers: [${providersText}]`;
|
|
447
|
+
let toInsert;
|
|
448
|
+
let position;
|
|
449
|
+
if (optionsNode.properties.length > 0) {
|
|
450
|
+
const lastProperty = optionsNode.properties[optionsNode.properties.length - 1];
|
|
451
|
+
toInsert = `,\n ${text}`;
|
|
452
|
+
position = lastProperty.getEnd();
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
toInsert = `\n ${text}\n`;
|
|
456
|
+
position = optionsNode.getStart() + 1;
|
|
457
|
+
}
|
|
458
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
459
|
+
position,
|
|
460
|
+
end: position,
|
|
461
|
+
toInsert,
|
|
462
|
+
})));
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function findNgModule(node, reflector) {
|
|
466
|
+
const decorators = reflector.getDecoratorsOfDeclaration(node);
|
|
467
|
+
if (decorators) {
|
|
468
|
+
const ngModuleDecorator = project_tsconfig_paths.getAngularDecorators(decorators, ['NgModule'], true)[0];
|
|
469
|
+
if (ngModuleDecorator &&
|
|
470
|
+
ngModuleDecorator.args &&
|
|
471
|
+
ngModuleDecorator.args.length > 0 &&
|
|
472
|
+
ts.isObjectLiteralExpression(ngModuleDecorator.args[0])) {
|
|
473
|
+
return ngModuleDecorator.args[0];
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
function hasChangeDetectionProvider(expression, // either the bootstrapApplication or platformBrowserDynamic().bootstrapModule()
|
|
479
|
+
typeChecker) {
|
|
480
|
+
let literal;
|
|
481
|
+
if (ts.isCallExpression(expression)) {
|
|
482
|
+
let optionsNode = expression.arguments[1];
|
|
483
|
+
if (!optionsNode &&
|
|
484
|
+
symbol.isReferenceToImport(typeChecker, expression.expression, imports.getImportSpecifier(expression.getSourceFile(), '@angular/core', 'createApplication'))) {
|
|
485
|
+
optionsNode = expression.arguments[0];
|
|
486
|
+
}
|
|
487
|
+
if (!optionsNode)
|
|
488
|
+
return false;
|
|
489
|
+
if (ts.isIdentifier(optionsNode)) {
|
|
490
|
+
literal = getObjectLiteralFromIdentifier(optionsNode, typeChecker);
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
literal = optionsNode;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
literal = expression;
|
|
498
|
+
}
|
|
499
|
+
if (!literal) {
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
const provideZoneCdSpecifier = imports.getImportSpecifier(literal.getSourceFile(), '@angular/core', 'provideZoneChangeDetection');
|
|
503
|
+
const provideZonelessCdSpecifier = imports.getImportSpecifier(literal.getSourceFile(), '@angular/core', 'provideZonelessChangeDetection');
|
|
504
|
+
if (provideZoneCdSpecifier === null && provideZonelessCdSpecifier === null) {
|
|
505
|
+
return false;
|
|
506
|
+
}
|
|
507
|
+
const found = ts.forEachChild(literal, function walk(node) {
|
|
508
|
+
if (ts.isCallExpression(node)) {
|
|
509
|
+
if (provideZonelessCdSpecifier &&
|
|
510
|
+
node.getText().includes(provideZonelessCdSpecifier.getText())) {
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
513
|
+
if (provideZoneCdSpecifier && node.getText().includes(provideZoneCdSpecifier.getText())) {
|
|
514
|
+
return true;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return ts.forEachChild(node, walk);
|
|
518
|
+
});
|
|
519
|
+
return !!found;
|
|
520
|
+
}
|
|
521
|
+
function getObjectLiteralFromIdentifier(identifier, typeChecker) {
|
|
522
|
+
let symbol = typeChecker.getSymbolAtLocation(identifier);
|
|
523
|
+
if (!symbol)
|
|
524
|
+
return;
|
|
525
|
+
// Follow aliases (for imported symbols)
|
|
526
|
+
if ((symbol.flags & ts.SymbolFlags.Alias) !== 0) {
|
|
527
|
+
symbol = typeChecker.getAliasedSymbol(symbol);
|
|
528
|
+
}
|
|
529
|
+
const declarations = symbol.getDeclarations();
|
|
530
|
+
if (!declarations)
|
|
531
|
+
return;
|
|
532
|
+
for (const decl of declarations) {
|
|
533
|
+
if (ts.isVariableDeclaration(decl) &&
|
|
534
|
+
decl.initializer &&
|
|
535
|
+
ts.isObjectLiteralExpression(decl.initializer)) {
|
|
536
|
+
return decl.initializer;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Extracts the import specifiers related to bootstraping from the source file.
|
|
543
|
+
* Returns null if no relevant specifiers are found.
|
|
544
|
+
*/
|
|
545
|
+
function getSpecifiers(sourceFile) {
|
|
546
|
+
const createApplicationSpecifier = imports.getImportSpecifier(sourceFile, '@angular/core', 'createApplication');
|
|
547
|
+
const bootstrapAppSpecifier = imports.getImportSpecifier(sourceFile, '@angular/platform-browser', 'bootstrapApplication');
|
|
548
|
+
const platformBrowserDynamicSpecifier = imports.getImportSpecifier(sourceFile, '@angular/platform-browser-dynamic', 'platformBrowserDynamic');
|
|
549
|
+
const platformBrowserSpecifier = imports.getImportSpecifier(sourceFile, '@angular/platform-browser', 'platformBrowser');
|
|
550
|
+
const testBedSpecifier = imports.getImportSpecifier(sourceFile, '@angular/core/testing', 'TestBed');
|
|
551
|
+
const getTestBedSpecifier = imports.getImportSpecifier(sourceFile, '@angular/core/testing', 'getTestBed');
|
|
552
|
+
const ngModuleSpecifier = imports.getImportSpecifier(sourceFile, '@angular/core', 'NgModule');
|
|
553
|
+
if (!createApplicationSpecifier &&
|
|
554
|
+
!bootstrapAppSpecifier &&
|
|
555
|
+
!platformBrowserDynamicSpecifier &&
|
|
556
|
+
!platformBrowserSpecifier &&
|
|
557
|
+
!testBedSpecifier &&
|
|
558
|
+
!ngModuleSpecifier &&
|
|
559
|
+
!getTestBedSpecifier) {
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
562
|
+
return {
|
|
563
|
+
createApplicationSpecifier,
|
|
564
|
+
bootstrapAppSpecifier,
|
|
565
|
+
platformBrowserDynamicSpecifier,
|
|
566
|
+
platformBrowserSpecifier,
|
|
567
|
+
testBedSpecifier,
|
|
568
|
+
ngModuleSpecifier,
|
|
569
|
+
getTestBedSpecifier,
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Removes duplicate replacements and for replacements at the same position, takes the longest one.
|
|
574
|
+
*/
|
|
575
|
+
function deduplicateReplacements(replacements) {
|
|
576
|
+
if (replacements.length <= 1) {
|
|
577
|
+
return replacements;
|
|
578
|
+
}
|
|
579
|
+
// Group replacements by file and position
|
|
580
|
+
const groupedByFileAndPosition = new Map();
|
|
581
|
+
for (const replacement of replacements) {
|
|
582
|
+
const fileKey = replacement.projectFile.id;
|
|
583
|
+
const position = replacement.update.data.position;
|
|
584
|
+
if (!groupedByFileAndPosition.has(fileKey)) {
|
|
585
|
+
groupedByFileAndPosition.set(fileKey, new Map());
|
|
586
|
+
}
|
|
587
|
+
const fileReplacements = groupedByFileAndPosition.get(fileKey);
|
|
588
|
+
if (!fileReplacements.has(position)) {
|
|
589
|
+
fileReplacements.set(position, []);
|
|
590
|
+
}
|
|
591
|
+
fileReplacements.get(position).push(replacement);
|
|
592
|
+
}
|
|
593
|
+
const result = [];
|
|
594
|
+
for (const fileReplacements of groupedByFileAndPosition.values()) {
|
|
595
|
+
for (const positionReplacements of fileReplacements.values()) {
|
|
596
|
+
if (positionReplacements.length === 1) {
|
|
597
|
+
result.push(positionReplacements[0]);
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
// For multiple replacements at the same position, take the one with the longest content
|
|
601
|
+
const longestReplacement = positionReplacements.reduce((longest, current) => {
|
|
602
|
+
const longestLength = longest.update.data.toInsert.length;
|
|
603
|
+
const currentLength = current.update.data.toInsert.length;
|
|
604
|
+
return currentLength > longestLength ? current : longest;
|
|
605
|
+
});
|
|
606
|
+
result.push(longestReplacement);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return result;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* In the case we're looking to insert a new ZoneChangeDetectionModule, we need to check if we already inserted one.
|
|
614
|
+
*
|
|
615
|
+
* This function also checks if the existing one has fewer options (shorter text length), which means the previous migration strategy inserted one
|
|
616
|
+
* but the following one is more complete and we should still add it (the dedup function will take care of the cleanup).
|
|
617
|
+
*/
|
|
618
|
+
function replacementsHaveZoneCdModule(rootRelativePath, replacements, text) {
|
|
619
|
+
return replacements.some((replacement) => {
|
|
620
|
+
const exisitingText = replacement.update.data.toInsert;
|
|
621
|
+
const isSameFile = replacement.projectFile.rootRelativePath === rootRelativePath;
|
|
622
|
+
return (isSameFile &&
|
|
623
|
+
text.includes('ZoneChangeDetectionModule') &&
|
|
624
|
+
exisitingText.length >= text.length);
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
function migrate() {
|
|
629
|
+
return async (tree) => {
|
|
630
|
+
await project_paths.runMigrationInDevkit({
|
|
631
|
+
tree,
|
|
632
|
+
getMigration: () => new BootstrapOptionsMigration(),
|
|
633
|
+
});
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
exports.migrate = migrate;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v21.0.0-next.
|
|
3
|
+
* @license Angular v21.0.0-next.5
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -8,14 +8,14 @@
|
|
|
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-Dr2s3Pq3.cjs');
|
|
12
12
|
var ts = require('typescript');
|
|
13
13
|
require('os');
|
|
14
|
-
var project_tsconfig_paths = require('./project_tsconfig_paths-
|
|
15
|
-
var index = require('./index-
|
|
14
|
+
var project_tsconfig_paths = require('./project_tsconfig_paths-DX9KHLn9.cjs');
|
|
15
|
+
var index = require('./index-Bb6iejCd.cjs');
|
|
16
16
|
require('path');
|
|
17
17
|
require('node:path');
|
|
18
|
-
var apply_import_manager = require('./apply_import_manager-
|
|
18
|
+
var apply_import_manager = require('./apply_import_manager-Bx60Uquz.cjs');
|
|
19
19
|
require('@angular-devkit/schematics');
|
|
20
20
|
require('fs');
|
|
21
21
|
require('module');
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v21.0.0-next.
|
|
3
|
+
* @license Angular v21.0.0-next.5
|
|
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
|
-
var project_tsconfig_paths = require('./project_tsconfig_paths-
|
|
10
|
+
var project_tsconfig_paths = require('./project_tsconfig_paths-DX9KHLn9.cjs');
|
|
11
11
|
require('os');
|
|
12
12
|
var p = require('path');
|
|
13
13
|
|