@angular/core 21.0.0-next.0 → 21.0.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/fesm2022/_attribute-chunk.mjs +12 -0
  2. package/fesm2022/_attribute-chunk.mjs.map +1 -0
  3. package/fesm2022/_debug_node-chunk.mjs +18469 -0
  4. package/fesm2022/_debug_node-chunk.mjs.map +1 -0
  5. package/fesm2022/_effect-chunk.mjs +423 -0
  6. package/fesm2022/_effect-chunk.mjs.map +1 -0
  7. package/fesm2022/_effect-chunk2.mjs +2951 -0
  8. package/fesm2022/_effect-chunk2.mjs.map +1 -0
  9. package/fesm2022/_not_found-chunk.mjs +39 -0
  10. package/fesm2022/_not_found-chunk.mjs.map +1 -0
  11. package/fesm2022/_resource-chunk.mjs +378 -0
  12. package/fesm2022/_resource-chunk.mjs.map +1 -0
  13. package/fesm2022/_untracked-chunk.mjs +96 -0
  14. package/fesm2022/_untracked-chunk.mjs.map +1 -0
  15. package/fesm2022/_weak_ref-chunk.mjs +10 -0
  16. package/fesm2022/_weak_ref-chunk.mjs.map +1 -0
  17. package/fesm2022/core.mjs +2499 -4185
  18. package/fesm2022/core.mjs.map +1 -1
  19. package/fesm2022/primitives-di.mjs +23 -0
  20. package/fesm2022/primitives-di.mjs.map +1 -0
  21. package/fesm2022/primitives-event-dispatch.mjs +788 -0
  22. package/fesm2022/primitives-event-dispatch.mjs.map +1 -0
  23. package/fesm2022/primitives-signals.mjs +187 -0
  24. package/fesm2022/primitives-signals.mjs.map +1 -0
  25. package/fesm2022/rxjs-interop.mjs +210 -308
  26. package/fesm2022/rxjs-interop.mjs.map +1 -1
  27. package/fesm2022/testing.mjs +2309 -3170
  28. package/fesm2022/testing.mjs.map +1 -1
  29. package/package.json +18 -12
  30. package/resources/best-practices.md +56 -0
  31. package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +117 -0
  32. package/schematics/bundles/application-config-core.cjs +84 -0
  33. package/schematics/bundles/{apply_import_manager-DR9xXCle.cjs → apply_import_manager-1Zs_gpB6.cjs} +4 -5
  34. package/schematics/bundles/bootstrap-options-migration.cjs +598 -0
  35. package/schematics/bundles/cleanup-unused-imports.cjs +9 -13
  36. package/schematics/bundles/common-to-standalone-migration.cjs +381 -0
  37. package/schematics/bundles/{compiler_host-BXBP7CE2.cjs → compiler_host-DBwYMlTo.cjs} +10 -11
  38. package/schematics/bundles/control-flow-migration.cjs +122 -119
  39. package/schematics/bundles/{imports-CIX-JgAN.cjs → imports-DP72APSx.cjs} +6 -1
  40. package/schematics/bundles/{index-CfTQUOiz.cjs → index-B7I9sIUx.cjs} +36 -39
  41. package/schematics/bundles/inject-migration.cjs +148 -70
  42. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  43. package/schematics/bundles/{migrate_ts_type_references-6NtAj-Wk.cjs → migrate_ts_type_references-UGIUl7En.cjs} +500 -24
  44. package/schematics/bundles/ng_component_template-Dsuq1Lw7.cjs +185 -0
  45. package/schematics/bundles/{ng_decorators-B5HCqr20.cjs → ng_decorators-DSFlWYQY.cjs} +2 -2
  46. package/schematics/bundles/ngclass-to-class-migration.cjs +542 -0
  47. package/schematics/bundles/ngstyle-to-style-migration.cjs +487 -0
  48. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  49. package/schematics/bundles/output-migration.cjs +16 -19
  50. package/schematics/bundles/parse_html-8VLCL37B.cjs +132 -0
  51. package/schematics/bundles/{project_paths-DcaODbky.cjs → project_paths-DvD50ouC.cjs} +14 -247
  52. package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +90 -0
  53. package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
  54. package/schematics/bundles/route-lazy-loading.cjs +54 -26
  55. package/schematics/bundles/router-current-navigation.cjs +7 -18
  56. package/schematics/bundles/router-last-successful-navigation.cjs +7 -18
  57. package/schematics/bundles/router-testing-module-migration.cjs +502 -0
  58. package/schematics/bundles/self-closing-tags-migration.cjs +17 -216
  59. package/schematics/bundles/signal-input-migration.cjs +93 -29
  60. package/schematics/bundles/signal-queries-migration.cjs +22 -25
  61. package/schematics/bundles/signals.cjs +10 -13
  62. package/schematics/bundles/standalone-migration.cjs +135 -102
  63. package/schematics/bundles/{symbol-VPWguRxr.cjs → symbol-BObKoqes.cjs} +3 -2
  64. package/schematics/collection.json +23 -0
  65. package/schematics/migrations/common-to-standalone-migration/schema.json +14 -0
  66. package/schematics/migrations/ngclass-to-class-migration/schema.json +20 -0
  67. package/schematics/migrations/ngstyle-to-style-migration/schema.json +20 -0
  68. package/schematics/migrations/router-testing-module-migration/schema.json +14 -0
  69. package/schematics/migrations.json +16 -2
  70. package/{api.d.d.ts → types/_api-chunk.d.ts} +9 -6
  71. package/{chrome_dev_tools_performance.d.d.ts → types/_chrome_dev_tools_performance-chunk.d.ts} +26 -31
  72. package/{discovery.d.d.ts → types/_discovery-chunk.d.ts} +135 -98
  73. package/{signal.d.d.ts → types/_effect-chunk.d.ts} +14 -5
  74. package/{event_dispatcher.d.d.ts → types/_event_dispatcher-chunk.d.ts} +2 -2
  75. package/{graph.d.d.ts → types/_formatter-chunk.d.ts} +40 -7
  76. package/{weak_ref.d.d.ts → types/_weak_ref-chunk.d.ts} +2 -2
  77. package/{index.d.ts → types/core.d.ts} +233 -305
  78. package/{primitives/di/index.d.ts → types/primitives-di.d.ts} +2 -2
  79. package/{primitives/event-dispatch/index.d.ts → types/primitives-event-dispatch.d.ts} +4 -4
  80. package/{primitives/signals/index.d.ts → types/primitives-signals.d.ts} +7 -8
  81. package/{rxjs-interop/index.d.ts → types/rxjs-interop.d.ts} +8 -6
  82. package/{testing/index.d.ts → types/testing.d.ts} +7 -7
  83. package/fesm2022/attribute.mjs +0 -24
  84. package/fesm2022/attribute.mjs.map +0 -1
  85. package/fesm2022/debug_node.mjs +0 -31833
  86. package/fesm2022/debug_node.mjs.map +0 -1
  87. package/fesm2022/not_found.mjs +0 -56
  88. package/fesm2022/not_found.mjs.map +0 -1
  89. package/fesm2022/primitives/di.mjs +0 -23
  90. package/fesm2022/primitives/di.mjs.map +0 -1
  91. package/fesm2022/primitives/event-dispatch.mjs +0 -1622
  92. package/fesm2022/primitives/event-dispatch.mjs.map +0 -1
  93. package/fesm2022/primitives/signals.mjs +0 -89
  94. package/fesm2022/primitives/signals.mjs.map +0 -1
  95. package/fesm2022/resource.mjs +0 -633
  96. package/fesm2022/resource.mjs.map +0 -1
  97. package/fesm2022/root_effect_scheduler.mjs +0 -4007
  98. package/fesm2022/root_effect_scheduler.mjs.map +0 -1
  99. package/fesm2022/signal.mjs +0 -560
  100. package/fesm2022/signal.mjs.map +0 -1
  101. package/fesm2022/untracked.mjs +0 -117
  102. package/fesm2022/untracked.mjs.map +0 -1
  103. package/fesm2022/weak_ref.mjs +0 -12
  104. package/fesm2022/weak_ref.mjs.map +0 -1
  105. package/schematics/bundles/index-esqfDjNB.cjs +0 -22074
  106. package/schematics/bundles/project_tsconfig_paths-CS-eSeHC.cjs +0 -51062
@@ -0,0 +1,487 @@
1
+ 'use strict';
2
+ /**
3
+ * @license Angular v21.0.0-next.10
4
+ * (c) 2010-2025 Google LLC. https://angular.io/
5
+ * License: MIT
6
+ */
7
+ 'use strict';
8
+
9
+ var ts = require('typescript');
10
+ require('@angular/compiler-cli');
11
+ var migrations = require('@angular/compiler-cli/private/migrations');
12
+ require('node:path');
13
+ var project_paths = require('./project_paths-DvD50ouC.cjs');
14
+ var compiler = require('@angular/compiler');
15
+ var apply_import_manager = require('./apply_import_manager-1Zs_gpB6.cjs');
16
+ var imports = require('./imports-DP72APSx.cjs');
17
+ var parse_html = require('./parse_html-8VLCL37B.cjs');
18
+ var ng_component_template = require('./ng_component_template-Dsuq1Lw7.cjs');
19
+ require('@angular-devkit/core');
20
+ require('node:path/posix');
21
+ require('@angular-devkit/schematics');
22
+ require('./project_tsconfig_paths-CDVxT6Ov.cjs');
23
+ require('./ng_decorators-DSFlWYQY.cjs');
24
+ require('./property_name-BBwFuqMe.cjs');
25
+
26
+ const ngStyleStr = 'NgStyle';
27
+ const commonModuleStr = '@angular/common';
28
+ const commonModuleImportsStr = 'CommonModule';
29
+ function migrateNgStyleBindings(template, config, componentNode, typeChecker) {
30
+ const parsed = parse_html.parseTemplate(template);
31
+ if (!parsed.tree || !parsed.tree.rootNodes.length) {
32
+ return { migrated: template, changed: false, replacementCount: 0, canRemoveCommonModule: false };
33
+ }
34
+ const visitor = new NgStyleCollector(template, componentNode, typeChecker);
35
+ compiler.visitAll(visitor, parsed.tree.rootNodes, config);
36
+ let newTemplate = template;
37
+ let changedOffset = 0;
38
+ let replacementCount = 0;
39
+ for (const { start, end, replacement } of visitor.replacements) {
40
+ const currentLength = newTemplate.length;
41
+ newTemplate = replaceTemplate(newTemplate, replacement, start, end, changedOffset);
42
+ changedOffset += newTemplate.length - currentLength;
43
+ replacementCount++;
44
+ }
45
+ const changed = newTemplate !== template;
46
+ return {
47
+ migrated: newTemplate,
48
+ changed,
49
+ replacementCount,
50
+ canRemoveCommonModule: changed ? parse_html.canRemoveCommonModule(newTemplate) : false,
51
+ };
52
+ }
53
+ /**
54
+ * Creates a Replacement to remove `NgStyle` from a component's `imports` array.
55
+ * Uses ReflectionHost + PartialEvaluator for robust AST analysis.
56
+ */
57
+ function createNgStyleImportsArrayRemoval(classNode, file, typeChecker, removeCommonModule) {
58
+ const reflector = new migrations.TypeScriptReflectionHost(typeChecker);
59
+ const decorators = reflector.getDecoratorsOfDeclaration(classNode);
60
+ if (!decorators) {
61
+ return null;
62
+ }
63
+ const componentDecorator = decorators.find((decorator) => decorator.name === 'Component');
64
+ if (!componentDecorator?.node) {
65
+ return null;
66
+ }
67
+ const decoratorNode = componentDecorator.node;
68
+ if (!ts.isDecorator(decoratorNode) ||
69
+ !ts.isCallExpression(decoratorNode.expression) ||
70
+ decoratorNode.expression.arguments.length === 0 ||
71
+ !ts.isObjectLiteralExpression(decoratorNode.expression.arguments[0])) {
72
+ return null;
73
+ }
74
+ const metadata = decoratorNode.expression.arguments[0];
75
+ const importsProperty = metadata.properties.find((p) => ts.isPropertyAssignment(p) && p.name?.getText() === 'imports');
76
+ if (!importsProperty || !ts.isArrayLiteralExpression(importsProperty.initializer)) {
77
+ return null;
78
+ }
79
+ const importsArray = importsProperty.initializer;
80
+ const elementsToRemove = new Set([ngStyleStr]);
81
+ if (removeCommonModule) {
82
+ elementsToRemove.add(commonModuleImportsStr);
83
+ }
84
+ const originalElements = importsArray.elements;
85
+ const filteredElements = originalElements.filter((el) => !ts.isIdentifier(el) || !elementsToRemove.has(el.text));
86
+ if (filteredElements.length === originalElements.length) {
87
+ return null; // No changes needed.
88
+ }
89
+ // If the array becomes empty, remove the entire `imports` property.
90
+ if (filteredElements.length === 0) {
91
+ const removalRange = getPropertyRemovalRange(importsProperty);
92
+ return new project_paths.Replacement(file, new project_paths.TextUpdate({
93
+ position: removalRange.start,
94
+ end: removalRange.end,
95
+ toInsert: '',
96
+ }));
97
+ }
98
+ const printer = ts.createPrinter();
99
+ const newArray = ts.factory.updateArrayLiteralExpression(importsArray, filteredElements);
100
+ const newText = printer.printNode(ts.EmitHint.Unspecified, newArray, classNode.getSourceFile());
101
+ return new project_paths.Replacement(file, new project_paths.TextUpdate({
102
+ position: importsArray.getStart(),
103
+ end: importsArray.getEnd(),
104
+ toInsert: newText,
105
+ }));
106
+ }
107
+ /**
108
+ * Calculates the removal range for a property in an object literal,
109
+ * including the trailing comma if it's not the last property.
110
+ */
111
+ function getPropertyRemovalRange(property) {
112
+ const parent = property.parent;
113
+ if (!ts.isObjectLiteralExpression(parent)) {
114
+ return { start: property.getStart(), end: property.getEnd() };
115
+ }
116
+ const properties = parent.properties;
117
+ const propertyIndex = properties.indexOf(property);
118
+ const end = property.getEnd();
119
+ if (propertyIndex < properties.length - 1) {
120
+ const nextProperty = properties[propertyIndex + 1];
121
+ return { start: property.getStart(), end: nextProperty.getStart() };
122
+ }
123
+ return { start: property.getStart(), end };
124
+ }
125
+ function calculateImportReplacements(info, sourceFiles, filesToRemoveCommonModule) {
126
+ const importReplacements = {};
127
+ const importManager = new migrations.ImportManager();
128
+ for (const sf of sourceFiles) {
129
+ const file = project_paths.projectFile(sf, info);
130
+ // Always remove NgStyle if it's imported directly.
131
+ importManager.removeImport(sf, ngStyleStr, commonModuleStr);
132
+ // Conditionally remove CommonModule if it's no longer needed.
133
+ if (filesToRemoveCommonModule.has(file.id)) {
134
+ importManager.removeImport(sf, commonModuleImportsStr, commonModuleStr);
135
+ }
136
+ const addRemove = [];
137
+ apply_import_manager.applyImportManagerChanges(importManager, addRemove, [sf], info);
138
+ if (addRemove.length > 0) {
139
+ importReplacements[file.id] = {
140
+ add: [],
141
+ addAndRemove: addRemove,
142
+ };
143
+ }
144
+ }
145
+ return importReplacements;
146
+ }
147
+ function replaceTemplate(template, replaceValue, start, end, offset) {
148
+ return template.slice(0, start + offset) + replaceValue + template.slice(end + offset);
149
+ }
150
+ /**
151
+ * Visitor class that scans Angular templates and collects replacements
152
+ * for [ngStyle] bindings that use static object literals.
153
+ */
154
+ class NgStyleCollector extends compiler.RecursiveVisitor {
155
+ originalTemplate;
156
+ replacements = [];
157
+ isNgStyleImported = true; // Default to true (permissive)
158
+ constructor(originalTemplate, componentNode, typeChecker) {
159
+ super();
160
+ this.originalTemplate = originalTemplate;
161
+ // If we have enough information, check if NgStyle is actually imported.
162
+ // If not, we can confidently disable the migration for this component.
163
+ if (componentNode && typeChecker) {
164
+ const imports$1 = imports.getImportSpecifiers(componentNode.getSourceFile(), commonModuleStr, [
165
+ ngStyleStr,
166
+ commonModuleImportsStr,
167
+ ]);
168
+ if (imports$1.length === 0) {
169
+ this.isNgStyleImported = false;
170
+ }
171
+ }
172
+ }
173
+ visitElement(element, config) {
174
+ // If NgStyle is not imported, do not attempt to migrate.
175
+ if (!this.isNgStyleImported) {
176
+ return;
177
+ }
178
+ for (const attr of element.attrs) {
179
+ if (attr.name !== '[ngStyle]' && attr.name !== 'ngStyle') {
180
+ continue;
181
+ }
182
+ if (attr.name === '[ngStyle]' && attr.valueSpan) {
183
+ const expr = this.originalTemplate.slice(attr.valueSpan.start.offset, attr.valueSpan.end.offset);
184
+ const staticMatch = parseStaticObjectLiteral(expr);
185
+ if (staticMatch === null) {
186
+ if (config.bestEffortMode && !isObjectLiteralSyntax(expr.trim())) {
187
+ const keyReplacement = this.originalTemplate
188
+ .slice(attr.sourceSpan.start.offset, attr.valueSpan.start.offset)
189
+ .replace('[ngStyle]', '[style]');
190
+ this.replacements.push({
191
+ start: attr.sourceSpan.start.offset,
192
+ end: attr.valueSpan.start.offset,
193
+ replacement: keyReplacement,
194
+ });
195
+ }
196
+ continue;
197
+ }
198
+ let replacement;
199
+ if (staticMatch.length === 0) {
200
+ replacement = '';
201
+ }
202
+ else if (staticMatch.length === 1) {
203
+ const { key, value } = staticMatch[0];
204
+ // Special case: If the key is an empty string, use [style]=""
205
+ if (key === '') {
206
+ replacement = '';
207
+ }
208
+ else {
209
+ // Normal single condition: use [style.styleName]="condition"
210
+ replacement = `[style.${key}]="${value}"`;
211
+ }
212
+ }
213
+ else {
214
+ replacement = `[style]="${expr}"`;
215
+ }
216
+ this.replacements.push({
217
+ start: attr.sourceSpan.start.offset,
218
+ end: attr.sourceSpan.end.offset,
219
+ replacement,
220
+ });
221
+ continue;
222
+ }
223
+ if (attr.name === 'ngStyle' && attr.value) {
224
+ this.replacements.push({
225
+ start: attr.sourceSpan.start.offset,
226
+ end: attr.sourceSpan.end.offset,
227
+ replacement: `style="${attr.value}"`,
228
+ });
229
+ }
230
+ }
231
+ return super.visitElement(element, config);
232
+ }
233
+ }
234
+ function parseStaticObjectLiteral(expr) {
235
+ const trimmedExpr = expr.trim();
236
+ if (trimmedExpr === '{}' || trimmedExpr === '[]') {
237
+ return [];
238
+ }
239
+ if (!isObjectLiteralSyntax(trimmedExpr)) {
240
+ return null;
241
+ }
242
+ const objectLiteral = parseAsObjectLiteral(trimmedExpr);
243
+ if (!objectLiteral) {
244
+ return null;
245
+ }
246
+ return extractStyleBindings(objectLiteral);
247
+ }
248
+ /**
249
+ * Validates basic object literal syntax
250
+ */
251
+ function isObjectLiteralSyntax(expr) {
252
+ return expr.startsWith('{') && expr.endsWith('}');
253
+ }
254
+ /**
255
+ * Parses expression as TypeScript object literal
256
+ */
257
+ function parseAsObjectLiteral(expr) {
258
+ const sourceFile = ts.createSourceFile('temp.ts', `const obj = ${expr}`, ts.ScriptTarget.Latest, true);
259
+ const variableStatement = sourceFile.statements[0];
260
+ if (!ts.isVariableStatement(variableStatement)) {
261
+ return null;
262
+ }
263
+ const declaration = variableStatement.declarationList.declarations[0];
264
+ if (!declaration.initializer || !ts.isObjectLiteralExpression(declaration.initializer)) {
265
+ return null;
266
+ }
267
+ return declaration.initializer;
268
+ }
269
+ function extractStyleBindings(objectLiteral) {
270
+ const result = [];
271
+ for (const property of objectLiteral.properties) {
272
+ if (ts.isShorthandPropertyAssignment(property)) {
273
+ return null;
274
+ }
275
+ else if (ts.isPropertyAssignment(property)) {
276
+ const keyText = extractPropertyKey(property.name);
277
+ const valueText = extractPropertyValue(property.initializer);
278
+ if (keyText === '' && valueText) {
279
+ result.push({ key: '', value: valueText });
280
+ continue;
281
+ }
282
+ if (!keyText || !valueText) {
283
+ return null;
284
+ }
285
+ result.push({ key: keyText, value: valueText });
286
+ }
287
+ else {
288
+ return null;
289
+ }
290
+ }
291
+ return result;
292
+ }
293
+ /**
294
+ * Extracts text from property key (name)
295
+ */
296
+ function extractPropertyKey(name) {
297
+ if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) {
298
+ return name.text;
299
+ }
300
+ return null;
301
+ }
302
+ /**
303
+ * Extracts text from property value
304
+ */
305
+ function extractPropertyValue(initializer) {
306
+ // String literals: 'value' or "value"
307
+ if (ts.isStringLiteral(initializer)) {
308
+ return `'${initializer.text}'`;
309
+ }
310
+ // Numeric literals: 42, 3.14
311
+ if (ts.isNumericLiteral(initializer) || ts.isIdentifier(initializer)) {
312
+ return initializer.text;
313
+ }
314
+ // Boolean and null keywords
315
+ if (initializer.kind === ts.SyntaxKind.TrueKeyword) {
316
+ return 'true';
317
+ }
318
+ if (initializer.kind === ts.SyntaxKind.FalseKeyword) {
319
+ return 'false';
320
+ }
321
+ if (initializer.kind === ts.SyntaxKind.NullKeyword) {
322
+ return 'null';
323
+ }
324
+ return initializer.getText();
325
+ }
326
+
327
+ class NgStyleMigration extends project_paths.TsurgeFunnelMigration {
328
+ config;
329
+ constructor(config = {}) {
330
+ super();
331
+ this.config = config;
332
+ }
333
+ processTemplate(template, node, file, info, typeChecker) {
334
+ const { migrated, changed, replacementCount, canRemoveCommonModule } = migrateNgStyleBindings(template.content, this.config, node, typeChecker);
335
+ if (!changed) {
336
+ return null;
337
+ }
338
+ const fileToMigrate = template.inline
339
+ ? file
340
+ : project_paths.projectFile(template.filePath, info);
341
+ const end = template.start + template.content.length;
342
+ return {
343
+ replacements: [prepareTextReplacement(fileToMigrate, migrated, template.start, end)],
344
+ replacementCount,
345
+ canRemoveCommonModule,
346
+ };
347
+ }
348
+ async analyze(info) {
349
+ const { sourceFiles, program } = info;
350
+ const typeChecker = program.getTypeChecker();
351
+ const ngStyleReplacements = [];
352
+ const filesWithNgStyleDeclarations = new Set();
353
+ const filesToRemoveCommonModule = new Set();
354
+ for (const sf of sourceFiles) {
355
+ ts.forEachChild(sf, (node) => {
356
+ if (!ts.isClassDeclaration(node)) {
357
+ return;
358
+ }
359
+ const file = project_paths.projectFile(sf, info);
360
+ if (this.config.shouldMigrate && !this.config.shouldMigrate(file)) {
361
+ return;
362
+ }
363
+ const templateVisitor = new ng_component_template.NgComponentTemplateVisitor(typeChecker);
364
+ templateVisitor.visitNode(node);
365
+ const replacementsForStyle = [];
366
+ let replacementCountForStyle = 0;
367
+ let canRemoveCommonModuleForFile = true;
368
+ for (const template of templateVisitor.resolvedTemplates) {
369
+ const result = this.processTemplate(template, node, file, info, typeChecker);
370
+ if (result) {
371
+ replacementsForStyle.push(...result.replacements);
372
+ replacementCountForStyle += result.replacementCount;
373
+ if (!result.canRemoveCommonModule) {
374
+ canRemoveCommonModuleForFile = false;
375
+ }
376
+ }
377
+ }
378
+ if (replacementsForStyle.length > 0) {
379
+ if (canRemoveCommonModuleForFile) {
380
+ filesToRemoveCommonModule.add(file.id);
381
+ }
382
+ // Handle the `@Component({ imports: [...] })` array.
383
+ const importsRemoval = createNgStyleImportsArrayRemoval(node, file, typeChecker, canRemoveCommonModuleForFile);
384
+ if (importsRemoval) {
385
+ replacementsForStyle.push(importsRemoval);
386
+ }
387
+ ngStyleReplacements.push({
388
+ file,
389
+ replacementCount: replacementCountForStyle,
390
+ replacements: replacementsForStyle,
391
+ });
392
+ filesWithNgStyleDeclarations.add(sf);
393
+ }
394
+ });
395
+ }
396
+ const importReplacements = calculateImportReplacements(info, filesWithNgStyleDeclarations, filesToRemoveCommonModule);
397
+ return project_paths.confirmAsSerializable({
398
+ ngStyleReplacements,
399
+ importReplacements,
400
+ });
401
+ }
402
+ async combine(unitA, unitB) {
403
+ const importReplacements = {};
404
+ for (const unit of [unitA, unitB]) {
405
+ for (const fileIDStr of Object.keys(unit.importReplacements)) {
406
+ const fileID = fileIDStr;
407
+ importReplacements[fileID] = unit.importReplacements[fileID];
408
+ }
409
+ }
410
+ return project_paths.confirmAsSerializable({
411
+ ngStyleReplacements: [...unitA.ngStyleReplacements, ...unitB.ngStyleReplacements],
412
+ importReplacements,
413
+ });
414
+ }
415
+ async globalMeta(combinedData) {
416
+ return project_paths.confirmAsSerializable({
417
+ ngStyleReplacements: combinedData.ngStyleReplacements,
418
+ importReplacements: combinedData.importReplacements,
419
+ });
420
+ }
421
+ async stats(globalMetadata) {
422
+ const touchedFilesCount = globalMetadata.ngStyleReplacements.length;
423
+ const replacementCount = globalMetadata.ngStyleReplacements.reduce((acc, cur) => acc + cur.replacementCount, 0);
424
+ return project_paths.confirmAsSerializable({
425
+ touchedFilesCount,
426
+ replacementCount,
427
+ });
428
+ }
429
+ async migrate(globalData) {
430
+ const replacements = [];
431
+ replacements.push(...globalData.ngStyleReplacements.flatMap(({ replacements }) => replacements));
432
+ for (const fileIDStr of Object.keys(globalData.importReplacements)) {
433
+ const fileID = fileIDStr;
434
+ const importReplacements = globalData.importReplacements[fileID];
435
+ replacements.push(...importReplacements.addAndRemove);
436
+ }
437
+ return { replacements };
438
+ }
439
+ }
440
+ function prepareTextReplacement(file, replacement, start, end) {
441
+ return new project_paths.Replacement(file, new project_paths.TextUpdate({
442
+ position: start,
443
+ end: end,
444
+ toInsert: replacement,
445
+ }));
446
+ }
447
+
448
+ function migrate(options) {
449
+ return async (tree, context) => {
450
+ await project_paths.runMigrationInDevkit({
451
+ tree,
452
+ getMigration: (fs) => new NgStyleMigration({
453
+ bestEffortMode: options.bestEffortMode,
454
+ shouldMigrate: (file) => {
455
+ return (file.rootRelativePath.startsWith(fs.normalize(options.path)) &&
456
+ !/(^|\/)node_modules\//.test(file.rootRelativePath));
457
+ },
458
+ }),
459
+ beforeProgramCreation: (tsconfigPath, stage) => {
460
+ if (stage === project_paths.MigrationStage.Analysis) {
461
+ context.logger.info(`Preparing analysis for: ${tsconfigPath}...`);
462
+ }
463
+ else {
464
+ context.logger.info(`Running migration for: ${tsconfigPath}...`);
465
+ }
466
+ },
467
+ beforeUnitAnalysis: (tsconfigPath) => {
468
+ context.logger.info(`Scanning for component tags: ${tsconfigPath}...`);
469
+ },
470
+ afterAllAnalyzed: () => {
471
+ context.logger.info(``);
472
+ context.logger.info(`Processing analysis data between targets...`);
473
+ context.logger.info(``);
474
+ },
475
+ afterAnalysisFailure: () => {
476
+ context.logger.error('Migration failed unexpectedly with no analysis data');
477
+ },
478
+ whenDone: ({ touchedFilesCount, replacementCount, }) => {
479
+ context.logger.info('');
480
+ context.logger.info(`Successfully migrated to style bindings from ngStyle 🎉`);
481
+ context.logger.info(` -> Migrated ${replacementCount} ngStyle to style bindings in ${touchedFilesCount} files.`);
482
+ },
483
+ });
484
+ };
485
+ }
486
+
487
+ exports.migrate = migrate;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v21.0.0-next.0
3
+ * @license Angular v21.0.0-next.10
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -1,26 +1,23 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v21.0.0-next.0
3
+ * @license Angular v21.0.0-next.10
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
8
 
9
9
  var ts = require('typescript');
10
- require('os');
11
- var project_tsconfig_paths = require('./project_tsconfig_paths-CS-eSeHC.cjs');
12
- var index$1 = require('./index-esqfDjNB.cjs');
13
- require('path');
10
+ require('@angular/compiler-cli');
11
+ var migrations = require('@angular/compiler-cli/private/migrations');
14
12
  require('node:path');
15
- var project_paths = require('./project_paths-DcaODbky.cjs');
16
- var apply_import_manager = require('./apply_import_manager-DR9xXCle.cjs');
17
- var index = require('./index-CfTQUOiz.cjs');
13
+ var project_paths = require('./project_paths-DvD50ouC.cjs');
14
+ var compiler = require('@angular/compiler');
15
+ var apply_import_manager = require('./apply_import_manager-1Zs_gpB6.cjs');
16
+ var index = require('./index-B7I9sIUx.cjs');
18
17
  require('@angular-devkit/core');
19
18
  require('node:path/posix');
20
- require('fs');
21
- require('module');
22
- require('url');
23
19
  require('@angular-devkit/schematics');
20
+ require('./project_tsconfig_paths-CDVxT6Ov.cjs');
24
21
 
25
22
  function isOutputDeclarationEligibleForMigration(node) {
26
23
  return (node.initializer !== undefined &&
@@ -67,7 +64,7 @@ function isOutputDeclaration(node, reflector, dtsReader) {
67
64
  node.parent.name === undefined) {
68
65
  return false;
69
66
  }
70
- const ref = new project_tsconfig_paths.Reference(node.parent);
67
+ const ref = new migrations.Reference(node.parent);
71
68
  const directiveMeta = dtsReader.getDirectiveMetadata(ref);
72
69
  return !!directiveMeta?.outputs.getByClassPropertyName(node.name.text);
73
70
  }
@@ -84,7 +81,7 @@ function getTargetPropertyDeclaration(targetSymbol) {
84
81
  /** Returns Angular `@Output` decorator or null when a given property declaration is not an @Output */
85
82
  function getOutputDecorator(node, reflector) {
86
83
  const decorators = reflector.getDecoratorsOfDeclaration(node);
87
- const ngDecorators = decorators !== null ? project_tsconfig_paths.getAngularDecorators(decorators, ['Output'], /* isCore */ false) : [];
84
+ const ngDecorators = decorators !== null ? migrations.getAngularDecorators(decorators, ['Output'], /* isCore */ false) : [];
88
85
  return ngDecorators.length > 0 ? ngDecorators[0] : null;
89
86
  }
90
87
  // THINK: this utility + type is not specific to @Output, really, maybe move it to tsurge?
@@ -114,7 +111,7 @@ function checkNonTsReferenceAccessesField(ref, fieldName) {
114
111
  if (ref.from.read !== readFromPath) {
115
112
  return null;
116
113
  }
117
- if (!(parentRead instanceof project_tsconfig_paths.PropertyRead) || parentRead.name !== fieldName) {
114
+ if (!(parentRead instanceof compiler.PropertyRead) || parentRead.name !== fieldName) {
118
115
  return null;
119
116
  }
120
117
  return parentRead;
@@ -170,7 +167,7 @@ function calculateDeclarationReplacement(info, node, aliasParam) {
170
167
  function calculateImportReplacements(info, sourceFiles) {
171
168
  const importReplacements = {};
172
169
  for (const sf of sourceFiles) {
173
- const importManager = new project_tsconfig_paths.ImportManager();
170
+ const importManager = new migrations.ImportManager();
174
171
  const addOnly = [];
175
172
  const addRemove = [];
176
173
  const file = project_paths.projectFile(sf, info);
@@ -205,7 +202,7 @@ function calculateCompleteCallReplacement(info, node) {
205
202
  function calculatePipeCallReplacement(info, node) {
206
203
  if (ts.isPropertyAccessExpression(node.expression)) {
207
204
  const sf = node.getSourceFile();
208
- const importManager = new project_tsconfig_paths.ImportManager();
205
+ const importManager = new migrations.ImportManager();
209
206
  const outputToObservableIdent = importManager.addImport({
210
207
  requestedFile: sf,
211
208
  exportModuleSpecifier: '@angular/core/rxjs-interop',
@@ -256,9 +253,9 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
256
253
  let problematicDeclarationCount = 0;
257
254
  const filesWithOutputDeclarations = new Set();
258
255
  const checker = program.getTypeChecker();
259
- const reflector = new project_tsconfig_paths.TypeScriptReflectionHost(checker);
260
- const dtsReader = new index$1.DtsMetadataReader(checker, reflector);
261
- const evaluator = new index$1.PartialEvaluator(reflector, checker, null);
256
+ const reflector = new migrations.TypeScriptReflectionHost(checker);
257
+ const dtsReader = new migrations.DtsMetadataReader(checker, reflector);
258
+ const evaluator = new migrations.PartialEvaluator(reflector, checker, null);
262
259
  const resourceLoader = info.ngCompiler?.['resourceManager'] ?? null;
263
260
  // Pre-analyze the program and get access to the template type checker.
264
261
  // If we are processing a non-Angular target, there is no template info.