@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
@@ -1,20 +1,19 @@
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 schematics = require('@angular-devkit/schematics');
10
- var p = require('path');
11
- var compiler_host = require('./compiler_host-BXBP7CE2.cjs');
12
- var project_tsconfig_paths = require('./project_tsconfig_paths-CS-eSeHC.cjs');
10
+ var path = require('path');
11
+ var compiler_host = require('./compiler_host-DBwYMlTo.cjs');
12
+ var compiler = require('@angular/compiler');
13
13
  var ts = require('typescript');
14
- require('os');
15
- require('fs');
16
- require('module');
17
- require('url');
14
+ var parse_html = require('./parse_html-8VLCL37B.cjs');
15
+ var project_tsconfig_paths = require('./project_tsconfig_paths-CDVxT6Ov.cjs');
16
+ require('@angular/compiler-cli/private/migrations');
18
17
  require('@angular-devkit/core');
19
18
 
20
19
  function lookupIdentifiersInSourceFile(sourceFile, names) {
@@ -274,7 +273,7 @@ class AnalyzedFile {
274
273
  }
275
274
  }
276
275
  /** Finds all non-control flow elements from common module. */
277
- class CommonCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
276
+ class CommonCollector extends compiler.RecursiveVisitor {
278
277
  count = 0;
279
278
  visitElement(el) {
280
279
  if (el.attrs.length > 0) {
@@ -313,7 +312,7 @@ class CommonCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
313
312
  }
314
313
  }
315
314
  /** Finds all elements that represent i18n blocks. */
316
- class i18nCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
315
+ class i18nCollector extends compiler.RecursiveVisitor {
317
316
  elements = [];
318
317
  visitElement(el) {
319
318
  if (el.attrs.find((a) => a.name === 'i18n') !== undefined) {
@@ -323,7 +322,7 @@ class i18nCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
323
322
  }
324
323
  }
325
324
  /** Finds all elements with ngif structural directives. */
326
- class ElementCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
325
+ class ElementCollector extends compiler.RecursiveVisitor {
327
326
  _attributes;
328
327
  elements = [];
329
328
  constructor(_attributes = []) {
@@ -376,7 +375,7 @@ class ElementCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
376
375
  }
377
376
  }
378
377
  /** Finds all elements with ngif structural directives. */
379
- class TemplateCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
378
+ class TemplateCollector extends compiler.RecursiveVisitor {
380
379
  elements = [];
381
380
  templates = new Map();
382
381
  visitElement(el) {
@@ -409,6 +408,7 @@ const endMarkerRegex = new RegExp(endMarker, 'gm');
409
408
  const startI18nMarkerRegex = new RegExp(startI18nMarker, 'gm');
410
409
  const endI18nMarkerRegex = new RegExp(endI18nMarker, 'gm');
411
410
  const replaceMarkerRegex = new RegExp(`${startMarker}|${endMarker}`, 'gm');
411
+ const PRIORITY_WEIGHT_TEMPLATE_REFERENCE_BY_OUTLET = 2;
412
412
  /**
413
413
  * Analyzes a source file to find file that need to be migrated and the text ranges within them.
414
414
  * @param sourceFile File to be analyzed.
@@ -548,8 +548,8 @@ function analyzeDecorators(node, sourceFile, analyzedFiles) {
548
548
  case 'templateUrl':
549
549
  // Leave the end as undefined which means that the range is until the end of the file.
550
550
  if (ts.isStringLiteralLike(prop.initializer)) {
551
- const path = p.join(p.dirname(sourceFile.fileName), prop.initializer.text);
552
- AnalyzedFile.addRange(path, sourceFile, analyzedFiles, {
551
+ const path$1 = path.join(path.dirname(sourceFile.fileName), prop.initializer.text);
552
+ AnalyzedFile.addRange(path$1, sourceFile, analyzedFiles, {
553
553
  start: 0,
554
554
  node: prop,
555
555
  type: 'templateUrl',
@@ -579,37 +579,8 @@ function getNestedCount(etm, aggregator) {
579
579
  return getNestedCount(etm, aggregator);
580
580
  }
581
581
  }
582
- /**
583
- * parses the template string into the Html AST
584
- */
585
- function parseTemplate(template) {
586
- let parsed;
587
- try {
588
- // Note: we use the HtmlParser here, instead of the `parseTemplate` function, because the
589
- // latter returns an Ivy AST, not an HTML AST. The HTML AST has the advantage of preserving
590
- // interpolated text as text nodes containing a mixture of interpolation tokens and text tokens,
591
- // rather than turning them into `BoundText` nodes like the Ivy AST does. This allows us to
592
- // easily get the text-only ranges without having to reconstruct the original text.
593
- parsed = new project_tsconfig_paths.HtmlParser().parse(template, '', {
594
- // Allows for ICUs to be parsed.
595
- tokenizeExpansionForms: true,
596
- // Explicitly disable blocks so that their characters are treated as plain text.
597
- tokenizeBlocks: true,
598
- preserveLineEndings: true,
599
- });
600
- // Don't migrate invalid templates.
601
- if (parsed.errors && parsed.errors.length > 0) {
602
- const errors = parsed.errors.map((e) => ({ type: 'parse', error: e }));
603
- return { tree: undefined, errors };
604
- }
605
- }
606
- catch (e) {
607
- return { tree: undefined, errors: [{ type: 'parse', error: e }] };
608
- }
609
- return { tree: parsed, errors: [] };
610
- }
611
582
  function validateMigratedTemplate(migrated, fileName) {
612
- const parsed = parseTemplate(migrated);
583
+ const parsed = parse_html.parseTemplate(migrated);
613
584
  let errors = [];
614
585
  if (parsed.errors.length > 0) {
615
586
  errors.push({
@@ -628,7 +599,7 @@ function validateMigratedTemplate(migrated, fileName) {
628
599
  }
629
600
  function validateI18nStructure(parsed, fileName) {
630
601
  const visitor = new i18nCollector();
631
- project_tsconfig_paths.visitAll$1(visitor, parsed.rootNodes);
602
+ compiler.visitAll(visitor, parsed.rootNodes);
632
603
  const parents = visitor.elements.filter((el) => el.children.length > 0);
633
604
  for (const p of parents) {
634
605
  for (const el of visitor.elements) {
@@ -705,10 +676,10 @@ function reduceNestingOffset(el, nestLevel, offset, postOffsets) {
705
676
  * Returns null if the migration failed (e.g. there was a syntax error).
706
677
  */
707
678
  function getTemplates(template) {
708
- const parsed = parseTemplate(template);
679
+ const parsed = parse_html.parseTemplate(template);
709
680
  if (parsed.tree !== undefined) {
710
681
  const visitor = new TemplateCollector();
711
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes);
682
+ compiler.visitAll(visitor, parsed.tree.rootNodes);
712
683
  for (let [key, tmpl] of visitor.templates) {
713
684
  tmpl.count = countTemplateUsage(parsed.tree.rootNodes, key);
714
685
  tmpl.generateContents(template);
@@ -717,34 +688,6 @@ function getTemplates(template) {
717
688
  }
718
689
  return new Map();
719
690
  }
720
- function countTemplateUsage(nodes, templateName) {
721
- let count = 0;
722
- let isReferencedInTemplateOutlet = false;
723
- for (const node of nodes) {
724
- if (node.attrs) {
725
- for (const attr of node.attrs) {
726
- if (attr.name === '*ngTemplateOutlet' && attr.value === templateName.slice(1)) {
727
- isReferencedInTemplateOutlet = true;
728
- break;
729
- }
730
- if (attr.name.trim() === templateName) {
731
- count++;
732
- }
733
- }
734
- }
735
- if (node.children) {
736
- if (node.name === 'for') {
737
- for (const child of node.children) {
738
- if (child.value?.includes(templateName.slice(1))) {
739
- count++;
740
- }
741
- }
742
- }
743
- count += countTemplateUsage(node.children, templateName);
744
- }
745
- }
746
- return isReferencedInTemplateOutlet ? count + 2 : count;
747
- }
748
691
  function updateTemplates(template, templates) {
749
692
  const updatedTemplates = getTemplates(template);
750
693
  for (let [key, tmpl] of updatedTemplates) {
@@ -768,9 +711,10 @@ function processNgTemplates(template, sourceFile) {
768
711
  try {
769
712
  const templates = getTemplates(template);
770
713
  // swap placeholders and remove
771
- for (const [name, t] of templates) {
772
- const replaceRegex = new RegExp(getPlaceholder(name.slice(1)), 'g');
773
- const forRegex = new RegExp(getPlaceholder(name.slice(1), PlaceholderKind.Alternate), 'g');
714
+ for (const [nameWithHash, t] of templates) {
715
+ const name = nameWithHash.slice(1);
716
+ const replaceRegex = new RegExp(getPlaceholder(name), 'g');
717
+ const forRegex = new RegExp(getPlaceholder(nameWithHash.slice(1), PlaceholderKind.Alternate), 'g');
774
718
  const forMatches = [...template.matchAll(forRegex)];
775
719
  const matches = [...forMatches, ...template.matchAll(replaceRegex)];
776
720
  let safeToRemove = true;
@@ -795,7 +739,12 @@ function processNgTemplates(template, sourceFile) {
795
739
  template = template.replace(replaceRegex, t.children);
796
740
  }
797
741
  const dist = matches.filter((obj, index, self) => index === self.findIndex((t) => t.input === obj.input));
798
- if ((t.count === dist.length || t.count - matches.length === 1) && safeToRemove) {
742
+ // Check if template is used by ngTemplateOutlet in addition to control flow
743
+ const hasTemplateOutletUsage = checkForTemplateOutletUsage(template, nameWithHash.slice(1));
744
+ // Only remove template if it's safe to do so AND not used by ngTemplateOutlet
745
+ if ((t.count === dist.length || t.count - matches.length === 1) &&
746
+ safeToRemove &&
747
+ !hasTemplateOutletUsage) {
799
748
  const refsInComponentFile = getViewChildOrViewChildrenNames(sourceFile);
800
749
  if (refsInComponentFile?.length > 0) {
801
750
  const templateRefs = getTemplateReferences(template);
@@ -825,6 +774,59 @@ function processNgTemplates(template, sourceFile) {
825
774
  return { migrated: template, err: err };
826
775
  }
827
776
  }
777
+ function analyzeTemplateUsage(nodes, templateName) {
778
+ let count = 0;
779
+ let isReferencedInTemplateOutlet = false;
780
+ const templateNameWithHash = `#${templateName}`;
781
+ function traverseNodes(nodeList) {
782
+ for (const node of nodeList) {
783
+ if (node.attrs) {
784
+ for (const attr of node.attrs) {
785
+ if ((attr.name === '*ngTemplateOutlet' || attr.name === '[ngTemplateOutlet]') &&
786
+ attr.value?.split(';')[0] === templateName) {
787
+ isReferencedInTemplateOutlet = true;
788
+ }
789
+ if (attr.name.trim() === templateNameWithHash) {
790
+ count++;
791
+ }
792
+ }
793
+ }
794
+ if (node.children) {
795
+ if (node.name === 'for') {
796
+ for (const child of node.children) {
797
+ if (child.value?.includes(templateName)) {
798
+ count++;
799
+ }
800
+ }
801
+ }
802
+ traverseNodes(node.children);
803
+ }
804
+ }
805
+ }
806
+ traverseNodes(nodes);
807
+ return {
808
+ isReferencedInTemplateOutlet,
809
+ totalCount: isReferencedInTemplateOutlet
810
+ ? count + PRIORITY_WEIGHT_TEMPLATE_REFERENCE_BY_OUTLET
811
+ : count,
812
+ };
813
+ }
814
+ /**
815
+ * Checks if a template is used by ngTemplateOutlet directive
816
+ */
817
+ function checkForTemplateOutletUsage(template, templateName) {
818
+ const parsed = parse_html.parseTemplate(template);
819
+ if (parsed.tree === undefined) {
820
+ return false;
821
+ }
822
+ const result = analyzeTemplateUsage(parsed.tree.rootNodes, templateName);
823
+ return result.isReferencedInTemplateOutlet;
824
+ }
825
+ function countTemplateUsage(nodes, templateNameWithHash) {
826
+ const templateName = templateNameWithHash.slice(1);
827
+ const result = analyzeTemplateUsage(nodes, templateName);
828
+ return result.totalCount;
829
+ }
828
830
  function getViewChildOrViewChildrenNames(sourceFile) {
829
831
  const names = [];
830
832
  function visit(node) {
@@ -845,15 +847,15 @@ function getViewChildOrViewChildrenNames(sourceFile) {
845
847
  return names;
846
848
  }
847
849
  function getTemplateReferences(template) {
848
- const parsed = parseTemplate(template);
850
+ const parsed = parse_html.parseTemplate(template);
849
851
  if (parsed.tree === undefined) {
850
852
  return [];
851
853
  }
852
- const references = [];
854
+ const templateNameRefWithoutHash = [];
853
855
  function visitNodes(nodes) {
854
856
  for (const node of nodes) {
855
857
  if (node?.name === 'ng-template') {
856
- references.push(...node.attrs?.map((ref) => ref?.name?.slice(1)));
858
+ templateNameRefWithoutHash.push(...node.attrs?.map((ref) => ref?.name?.slice(1)));
857
859
  }
858
860
  if (node.children) {
859
861
  visitNodes(node.children);
@@ -861,7 +863,7 @@ function getTemplateReferences(template) {
861
863
  }
862
864
  }
863
865
  visitNodes(parsed.tree.rootNodes);
864
- return references;
866
+ return templateNameRefWithoutHash;
865
867
  }
866
868
  function replaceRemainingPlaceholders(template) {
867
869
  const pattern = '.*';
@@ -880,11 +882,11 @@ function replaceRemainingPlaceholders(template) {
880
882
  * determines if the CommonModule can be safely removed from imports
881
883
  */
882
884
  function canRemoveCommonModule(template) {
883
- const parsed = parseTemplate(template);
885
+ const parsed = parse_html.parseTemplate(template);
884
886
  let removeCommonModule = false;
885
887
  if (parsed.tree !== undefined) {
886
888
  const visitor = new CommonCollector();
887
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes);
889
+ compiler.visitAll(visitor, parsed.tree.rootNodes);
888
890
  removeCommonModule = visitor.count === 0;
889
891
  }
890
892
  return removeCommonModule;
@@ -1004,10 +1006,10 @@ function getMainBlock(etm, tmpl, offset) {
1004
1006
  return { start, middle, end };
1005
1007
  }
1006
1008
  function generateI18nMarkers(tmpl) {
1007
- let parsed = parseTemplate(tmpl);
1009
+ let parsed = parse_html.parseTemplate(tmpl);
1008
1010
  if (parsed.tree !== undefined) {
1009
1011
  const visitor = new i18nCollector();
1010
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes);
1012
+ compiler.visitAll(visitor, parsed.tree.rootNodes);
1011
1013
  for (const [ix, el] of visitor.elements.entries()) {
1012
1014
  // we only care about elements with children and i18n tags
1013
1015
  // elements without children have nothing to translate
@@ -1203,13 +1205,13 @@ const cases = [boundcase, switchcase, nakedcase, switchdefault, nakeddefault];
1203
1205
  */
1204
1206
  function migrateCase(template) {
1205
1207
  let errors = [];
1206
- let parsed = parseTemplate(template);
1208
+ let parsed = parse_html.parseTemplate(template);
1207
1209
  if (parsed.tree === undefined) {
1208
1210
  return { migrated: template, errors, changed: false };
1209
1211
  }
1210
1212
  let result = template;
1211
1213
  const visitor = new ElementCollector(cases);
1212
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes);
1214
+ compiler.visitAll(visitor, parsed.tree.rootNodes);
1213
1215
  calculateNesting(visitor, hasLineBreaks(template));
1214
1216
  // this tracks the character shift from different lengths of blocks from
1215
1217
  // the prior directives so as to adjust for nested block replacement during
@@ -1300,13 +1302,13 @@ const stringPairs = new Map([
1300
1302
  */
1301
1303
  function migrateFor(template) {
1302
1304
  let errors = [];
1303
- let parsed = parseTemplate(template);
1305
+ let parsed = parse_html.parseTemplate(template);
1304
1306
  if (parsed.tree === undefined) {
1305
1307
  return { migrated: template, errors, changed: false };
1306
1308
  }
1307
1309
  let result = template;
1308
1310
  const visitor = new ElementCollector(fors);
1309
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes);
1311
+ compiler.visitAll(visitor, parsed.tree.rootNodes);
1310
1312
  calculateNesting(visitor, hasLineBreaks(template));
1311
1313
  // this tracks the character shift from different lengths of blocks from
1312
1314
  // the prior directives so as to adjust for nested block replacement during
@@ -1505,13 +1507,13 @@ const ifs = [ngif, nakedngif, boundngif];
1505
1507
  */
1506
1508
  function migrateIf(template) {
1507
1509
  let errors = [];
1508
- let parsed = parseTemplate(template);
1510
+ let parsed = parse_html.parseTemplate(template);
1509
1511
  if (parsed.tree === undefined) {
1510
1512
  return { migrated: template, errors, changed: false };
1511
1513
  }
1512
1514
  let result = template;
1513
1515
  const visitor = new ElementCollector(ifs);
1514
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes);
1516
+ compiler.visitAll(visitor, parsed.tree.rootNodes);
1515
1517
  calculateNesting(visitor, hasLineBreaks(template));
1516
1518
  // this tracks the character shift from different lengths of blocks from
1517
1519
  // the prior directives so as to adjust for nested block replacement during
@@ -1698,13 +1700,13 @@ const switches = [ngswitch];
1698
1700
  */
1699
1701
  function migrateSwitch(template) {
1700
1702
  let errors = [];
1701
- let parsed = parseTemplate(template);
1703
+ let parsed = parse_html.parseTemplate(template);
1702
1704
  if (parsed.tree === undefined) {
1703
1705
  return { migrated: template, errors, changed: false };
1704
1706
  }
1705
1707
  let result = template;
1706
1708
  const visitor = new ElementCollector(switches);
1707
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes);
1709
+ compiler.visitAll(visitor, parsed.tree.rootNodes);
1708
1710
  calculateNesting(visitor, hasLineBreaks(template));
1709
1711
  // this tracks the character shift from different lengths of blocks from
1710
1712
  // the prior directives so as to adjust for nested block replacement during
@@ -1735,11 +1737,11 @@ function migrateSwitch(template) {
1735
1737
  }
1736
1738
  function assertValidSwitchStructure(children) {
1737
1739
  for (const child of children) {
1738
- if (child instanceof project_tsconfig_paths.Text && child.value.trim() !== '') {
1740
+ if (child instanceof compiler.Text && child.value.trim() !== '') {
1739
1741
  throw new Error(`Text node: "${child.value}" would result in invalid migrated @switch block structure. ` +
1740
1742
  `@switch can only have @case or @default as children.`);
1741
1743
  }
1742
- else if (child instanceof project_tsconfig_paths.Element) {
1744
+ else if (child instanceof compiler.Element) {
1743
1745
  let hasCase = false;
1744
1746
  for (const attr of child.attrs) {
1745
1747
  if (cases.includes(attr.name)) {
@@ -1843,7 +1845,10 @@ function migrate(options) {
1843
1845
  const basePath = process.cwd();
1844
1846
  let pathToMigrate;
1845
1847
  if (options.path) {
1846
- pathToMigrate = compiler_host.normalizePath(p.join(basePath, options.path));
1848
+ if (options.path.startsWith('..')) {
1849
+ throw new schematics.SchematicsException('Cannot run control flow migration outside of the current project.');
1850
+ }
1851
+ pathToMigrate = compiler_host.normalizePath(path.join(basePath, options.path));
1847
1852
  if (pathToMigrate.trim() !== '') {
1848
1853
  allPaths.push(pathToMigrate);
1849
1854
  }
@@ -1853,33 +1858,31 @@ function migrate(options) {
1853
1858
  allPaths = [...buildPaths, ...testPaths];
1854
1859
  }
1855
1860
  if (!allPaths.length) {
1856
- throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the http providers migration.');
1861
+ context.logger.warn('Could not find any tsconfig file. Cannot run the control flow migration.');
1862
+ return;
1857
1863
  }
1858
1864
  let errors = [];
1865
+ let sourceFilesCount = 0;
1859
1866
  for (const tsconfigPath of allPaths) {
1860
- const migrateErrors = runControlFlowMigration(tree, tsconfigPath, basePath, pathToMigrate, options);
1867
+ const program = compiler_host.createMigrationProgram(tree, tsconfigPath, basePath);
1868
+ const sourceFiles = program
1869
+ .getSourceFiles()
1870
+ .filter((sourceFile) => (pathToMigrate ? sourceFile.fileName.startsWith(pathToMigrate) : true) &&
1871
+ compiler_host.canMigrateFile(basePath, sourceFile, program));
1872
+ const migrateErrors = runControlFlowMigration(tree, sourceFiles, basePath, options);
1861
1873
  errors = [...errors, ...migrateErrors];
1874
+ sourceFilesCount += sourceFiles.length;
1862
1875
  }
1863
1876
  if (errors.length > 0) {
1864
1877
  context.logger.warn(`WARNING: ${errors.length} errors occurred during your migration:\n`);
1865
- errors.forEach((err) => {
1866
- context.logger.warn(err);
1867
- });
1878
+ errors.forEach((err) => context.logger.warn(err));
1879
+ }
1880
+ else if (sourceFilesCount === 0) {
1881
+ context.logger.warn('Control flow migration did not find any files to migrate');
1868
1882
  }
1869
1883
  };
1870
1884
  }
1871
- function runControlFlowMigration(tree, tsconfigPath, basePath, pathToMigrate, schematicOptions) {
1872
- if (schematicOptions?.path?.startsWith('..')) {
1873
- throw new schematics.SchematicsException('Cannot run control flow migration outside of the current project.');
1874
- }
1875
- const program = compiler_host.createMigrationProgram(tree, tsconfigPath, basePath);
1876
- const sourceFiles = program
1877
- .getSourceFiles()
1878
- .filter((sourceFile) => (pathToMigrate ? sourceFile.fileName.startsWith(pathToMigrate) : true) &&
1879
- compiler_host.canMigrateFile(basePath, sourceFile, program));
1880
- if (sourceFiles.length === 0) {
1881
- throw new schematics.SchematicsException(`Could not find any files to migrate under the path ${pathToMigrate}. Cannot run the control flow migration.`);
1882
- }
1885
+ function runControlFlowMigration(tree, sourceFiles, basePath, schematicOptions) {
1883
1886
  const analysis = new Map();
1884
1887
  const migrateErrors = new Map();
1885
1888
  for (const sourceFile of sourceFiles) {
@@ -1888,10 +1891,10 @@ function runControlFlowMigration(tree, tsconfigPath, basePath, pathToMigrate, sc
1888
1891
  // sort files with .html files first
1889
1892
  // this ensures class files know if it's safe to remove CommonModule
1890
1893
  const paths = sortFilePaths([...analysis.keys()]);
1891
- for (const path of paths) {
1892
- const file = analysis.get(path);
1894
+ for (const path$1 of paths) {
1895
+ const file = analysis.get(path$1);
1893
1896
  const ranges = file.getSortedRanges();
1894
- const relativePath = p.relative(basePath, path);
1897
+ const relativePath = path.relative(basePath, path$1);
1895
1898
  const content = tree.readText(relativePath);
1896
1899
  const update = tree.beginUpdate(relativePath);
1897
1900
  for (const { start, end, node, type } of ranges) {
@@ -1903,7 +1906,7 @@ function runControlFlowMigration(tree, tsconfigPath, basePath, pathToMigrate, sc
1903
1906
  update.insertLeft(start, migrated);
1904
1907
  }
1905
1908
  if (errors.length > 0) {
1906
- migrateErrors.set(path, errors);
1909
+ migrateErrors.set(path$1, errors);
1907
1910
  }
1908
1911
  }
1909
1912
  tree.commitUpdate(update);
@@ -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
  */
@@ -49,6 +49,10 @@ function getImportOfIdentifier(typeChecker, node) {
49
49
  function getImportSpecifier(sourceFile, moduleName, specifierName) {
50
50
  return getImportSpecifiers(sourceFile, moduleName, specifierName)[0] ?? null;
51
51
  }
52
+ /**
53
+ * Note: returns only matching imports specifiers,
54
+ * Unmatched imports will be ignored (you won't get undefined), but a shorter array.
55
+ */
52
56
  function getImportSpecifiers(sourceFile, moduleName, specifierOrSpecifiers) {
53
57
  const matches = [];
54
58
  for (const node of sourceFile.statements) {
@@ -102,4 +106,5 @@ function findImportSpecifier(nodes, specifierName) {
102
106
 
103
107
  exports.getImportOfIdentifier = getImportOfIdentifier;
104
108
  exports.getImportSpecifier = getImportSpecifier;
109
+ exports.getImportSpecifiers = getImportSpecifiers;
105
110
  exports.getNamedImports = getNamedImports;