@angular/core 20.0.0-next.0 → 20.0.0-next.2

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 (52) hide show
  1. package/fesm2022/core.mjs +3307 -4479
  2. package/fesm2022/core.mjs.map +1 -1
  3. package/fesm2022/primitives/di.mjs +45 -0
  4. package/fesm2022/primitives/di.mjs.map +1 -0
  5. package/fesm2022/primitives/event-dispatch.mjs +3 -590
  6. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  7. package/fesm2022/primitives/signals.mjs +19 -9
  8. package/fesm2022/primitives/signals.mjs.map +1 -1
  9. package/fesm2022/rxjs-interop.mjs +8 -33
  10. package/fesm2022/rxjs-interop.mjs.map +1 -1
  11. package/fesm2022/testing.mjs +392 -250
  12. package/fesm2022/testing.mjs.map +1 -1
  13. package/fesm2022/weak_ref-DrMdAIDh.mjs +12 -0
  14. package/fesm2022/weak_ref-DrMdAIDh.mjs.map +1 -0
  15. package/index.d.ts +14339 -15134
  16. package/navigation_types.d-u4EOrrdZ.d.ts +121 -0
  17. package/package.json +11 -1
  18. package/primitives/di/index.d.ts +91 -0
  19. package/primitives/event-dispatch/index.d.ts +206 -310
  20. package/primitives/signals/index.d.ts +159 -196
  21. package/rxjs-interop/index.d.ts +72 -92
  22. package/schematics/bundles/{apply_import_manager-0959b78c.js → apply_import_manager-CyRT0UvU.js} +13 -17
  23. package/schematics/bundles/{checker-cf6f7980.js → checker-DF8ZaFW5.js} +3363 -1289
  24. package/schematics/bundles/cleanup-unused-imports.js +22 -28
  25. package/schematics/bundles/{compiler_host-cc1379e9.js → compiler_host-Da636uJ8.js} +20 -24
  26. package/schematics/bundles/control-flow-migration.js +82 -39
  27. package/schematics/bundles/{imports-31a38653.js → imports-CIX-JgAN.js} +10 -15
  28. package/schematics/bundles/{index-42d84d69.js → index-DnkWgagp.js} +56 -60
  29. package/schematics/bundles/{index-6675d6bc.js → index-vGJcp5M7.js} +5 -5
  30. package/schematics/bundles/inject-flags.js +181 -0
  31. package/schematics/bundles/inject-migration.js +122 -128
  32. package/schematics/bundles/{leading_space-6e7a8ec6.js → leading_space-D9nQ8UQC.js} +2 -2
  33. package/schematics/bundles/{migrate_ts_type_references-5089e4ef.js → migrate_ts_type_references-DtkOnnv0.js} +113 -120
  34. package/schematics/bundles/{ng_decorators-6878e227.js → ng_decorators-DznZ5jMl.js} +5 -9
  35. package/schematics/bundles/{nodes-ffdce442.js → nodes-B16H9JUd.js} +3 -7
  36. package/schematics/bundles/output-migration.js +40 -46
  37. package/schematics/bundles/{program-362689f0.js → program-BZk27Ndu.js} +846 -2653
  38. package/schematics/bundles/{project_paths-7d2daa1e.js → project_paths-Jtbi76Bs.js} +26 -24
  39. package/schematics/bundles/{project_tsconfig_paths-6c9cde78.js → project_tsconfig_paths-CDVxT6Ov.js} +2 -2
  40. package/schematics/bundles/{property_name-42030525.js → property_name-BBwFuqMe.js} +4 -8
  41. package/schematics/bundles/route-lazy-loading.js +36 -42
  42. package/schematics/bundles/self-closing-tags-migration.js +55 -45
  43. package/schematics/bundles/signal-input-migration.js +61 -68
  44. package/schematics/bundles/signal-queries-migration.js +48 -55
  45. package/schematics/bundles/signals.js +10 -12
  46. package/schematics/bundles/standalone-migration.js +179 -185
  47. package/schematics/migrations.json +4 -15
  48. package/testing/index.d.ts +309 -478
  49. package/weak_ref.d-ttyj86RV.d.ts +9 -0
  50. package/schematics/bundles/explicit-standalone-flag.js +0 -184
  51. package/schematics/bundles/pending-tasks.js +0 -103
  52. package/schematics/bundles/provide-initializer.js +0 -186
@@ -1,30 +1,26 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.0
4
- * (c) 2010-2024 Google LLC. https://angular.io/
3
+ * @license Angular v20.0.0-next.2
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
10
  require('os');
11
- var checker = require('./checker-cf6f7980.js');
12
- var program = require('./program-362689f0.js');
11
+ var checker = require('./checker-DF8ZaFW5.js');
12
+ var program = require('./program-BZk27Ndu.js');
13
13
  require('path');
14
- var project_paths = require('./project_paths-7d2daa1e.js');
15
-
16
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
17
-
18
- var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
14
+ var project_paths = require('./project_paths-Jtbi76Bs.js');
19
15
 
20
16
  function getMemberName(member) {
21
17
  if (member.name === undefined) {
22
18
  return null;
23
19
  }
24
- if (ts__default["default"].isIdentifier(member.name) || ts__default["default"].isStringLiteralLike(member.name)) {
20
+ if (ts.isIdentifier(member.name) || ts.isStringLiteralLike(member.name)) {
25
21
  return member.name.text;
26
22
  }
27
- if (ts__default["default"].isPrivateIdentifier(member.name)) {
23
+ if (ts.isPrivateIdentifier(member.name)) {
28
24
  return `#${member.name.text}`;
29
25
  }
30
26
  return null;
@@ -32,8 +28,8 @@ function getMemberName(member) {
32
28
 
33
29
  /** Checks whether the given node can be an `@Input()` declaration node. */
34
30
  function isInputContainerNode(node) {
35
- return (((ts__default["default"].isAccessor(node) && ts__default["default"].isClassDeclaration(node.parent)) ||
36
- ts__default["default"].isPropertyDeclaration(node)) &&
31
+ return (((ts.isAccessor(node) && ts.isClassDeclaration(node.parent)) ||
32
+ ts.isPropertyDeclaration(node)) &&
37
33
  getMemberName(node) !== null);
38
34
  }
39
35
 
@@ -56,17 +52,17 @@ class DebugElementComponentInstance {
56
52
  if (this.cache.has(node)) {
57
53
  return this.cache.get(node);
58
54
  }
59
- if (!ts__default["default"].isPropertyAccessExpression(node)) {
55
+ if (!ts.isPropertyAccessExpression(node)) {
60
56
  return null;
61
57
  }
62
58
  // Check for `<>.componentInstance`.
63
- if (!ts__default["default"].isIdentifier(node.name) || node.name.text !== 'componentInstance') {
59
+ if (!ts.isIdentifier(node.name) || node.name.text !== 'componentInstance') {
64
60
  return null;
65
61
  }
66
62
  // Check for `<>.query(..).<>`.
67
- if (!ts__default["default"].isCallExpression(node.expression) ||
68
- !ts__default["default"].isPropertyAccessExpression(node.expression.expression) ||
69
- !ts__default["default"].isIdentifier(node.expression.expression.name) ||
63
+ if (!ts.isCallExpression(node.expression) ||
64
+ !ts.isPropertyAccessExpression(node.expression.expression) ||
65
+ !ts.isIdentifier(node.expression.expression.name) ||
70
66
  node.expression.expression.name.text !== 'query') {
71
67
  return null;
72
68
  }
@@ -76,13 +72,13 @@ class DebugElementComponentInstance {
76
72
  }
77
73
  const queryArg = queryCall.arguments[0];
78
74
  let typeExpr;
79
- if (ts__default["default"].isCallExpression(queryArg) &&
75
+ if (ts.isCallExpression(queryArg) &&
80
76
  queryArg.arguments.length === 1 &&
81
- ts__default["default"].isIdentifier(queryArg.arguments[0])) {
77
+ ts.isIdentifier(queryArg.arguments[0])) {
82
78
  // Detect references, like: `query(By.directive(T))`.
83
79
  typeExpr = queryArg.arguments[0];
84
80
  }
85
- else if (ts__default["default"].isIdentifier(queryArg)) {
81
+ else if (ts.isIdentifier(queryArg)) {
86
82
  // Detect references, like: `harness.query(T)`.
87
83
  typeExpr = queryArg;
88
84
  }
@@ -91,7 +87,7 @@ class DebugElementComponentInstance {
91
87
  }
92
88
  const symbol = this.checker.getSymbolAtLocation(typeExpr);
93
89
  if (symbol?.valueDeclaration === undefined ||
94
- !ts__default["default"].isClassDeclaration(symbol?.valueDeclaration)) {
90
+ !ts.isClassDeclaration(symbol?.valueDeclaration)) {
95
91
  // Cache this as we use the expensive type checker.
96
92
  this.cache.set(node, null);
97
93
  return null;
@@ -123,8 +119,8 @@ class PartialDirectiveTypeInCatalystTests {
123
119
  }
124
120
  detect(node) {
125
121
  // Detect `Partial<...>`
126
- if (!ts__default["default"].isTypeReferenceNode(node) ||
127
- !ts__default["default"].isIdentifier(node.typeName) ||
122
+ if (!ts.isTypeReferenceNode(node) ||
123
+ !ts.isIdentifier(node.typeName) ||
128
124
  node.typeName.text !== 'Partial') {
129
125
  return null;
130
126
  }
@@ -135,8 +131,8 @@ class PartialDirectiveTypeInCatalystTests {
135
131
  // Extract T of `Partial<T>`.
136
132
  const cmpTypeArg = node.typeArguments?.[0];
137
133
  if (!cmpTypeArg ||
138
- !ts__default["default"].isTypeReferenceNode(cmpTypeArg) ||
139
- !ts__default["default"].isIdentifier(cmpTypeArg.typeName)) {
134
+ !ts.isTypeReferenceNode(cmpTypeArg) ||
135
+ !ts.isIdentifier(cmpTypeArg.typeName)) {
140
136
  return null;
141
137
  }
142
138
  const cmpType = cmpTypeArg.typeName;
@@ -144,7 +140,7 @@ class PartialDirectiveTypeInCatalystTests {
144
140
  // Note: Technically the class might be derived of an input-containing class,
145
141
  // but this is out of scope for now. We can expand if we see it's a common case.
146
142
  if (symbol?.valueDeclaration === undefined ||
147
- !ts__default["default"].isClassDeclaration(symbol.valueDeclaration) ||
143
+ !ts.isClassDeclaration(symbol.valueDeclaration) ||
148
144
  !this.knownFields.shouldTrackClassReference(symbol.valueDeclaration)) {
149
145
  return null;
150
146
  }
@@ -320,7 +316,7 @@ class TemplateReferenceVisitor extends checker.RecursiveVisitor$1 {
320
316
  * This resolution is important to be able to migrate references to inputs
321
317
  * that will be migrated to signal inputs.
322
318
  */
323
- class TemplateExpressionReferenceVisitor extends checker.RecursiveAstVisitor$1 {
319
+ class TemplateExpressionReferenceVisitor extends checker.RecursiveAstVisitor {
324
320
  typeChecker;
325
321
  templateTypeChecker;
326
322
  componentClass;
@@ -547,7 +543,7 @@ function identifyHostBindingReferences(node, programInfo, checker$1, reflector,
547
543
  return;
548
544
  }
549
545
  const metadataNode = checker.unwrapExpression(ngDecorator.args[0]);
550
- if (!ts__default["default"].isObjectLiteralExpression(metadataNode)) {
546
+ if (!ts.isObjectLiteralExpression(metadataNode)) {
551
547
  return;
552
548
  }
553
549
  const metadata = checker.reflectObjectLiteral(metadataNode);
@@ -557,26 +553,26 @@ function identifyHostBindingReferences(node, programInfo, checker$1, reflector,
557
553
  let hostField = checker.unwrapExpression(metadata.get('host'));
558
554
  // Special-case in case host bindings are shared via a variable.
559
555
  // e.g. Material button shares host bindings as a constant in the same target.
560
- if (ts__default["default"].isIdentifier(hostField)) {
556
+ if (ts.isIdentifier(hostField)) {
561
557
  let symbol = checker$1.getSymbolAtLocation(hostField);
562
558
  // Plain identifier references can point to alias symbols (e.g. imports).
563
- if (symbol !== undefined && symbol.flags & ts__default["default"].SymbolFlags.Alias) {
559
+ if (symbol !== undefined && symbol.flags & ts.SymbolFlags.Alias) {
564
560
  symbol = checker$1.getAliasedSymbol(symbol);
565
561
  }
566
562
  if (symbol !== undefined &&
567
563
  symbol.valueDeclaration !== undefined &&
568
- ts__default["default"].isVariableDeclaration(symbol.valueDeclaration)) {
564
+ ts.isVariableDeclaration(symbol.valueDeclaration)) {
569
565
  hostField = symbol?.valueDeclaration.initializer;
570
566
  }
571
567
  }
572
- if (hostField === undefined || !ts__default["default"].isObjectLiteralExpression(hostField)) {
568
+ if (hostField === undefined || !ts.isObjectLiteralExpression(hostField)) {
573
569
  return;
574
570
  }
575
571
  const hostMap = checker.reflectObjectLiteral(hostField);
576
572
  const expressionResult = [];
577
573
  const expressionVisitor = new TemplateExpressionReferenceVisitor(checker$1, null, node, knownFields, fieldNamesToConsiderForReferenceLookup);
578
574
  for (const [rawName, expression] of hostMap.entries()) {
579
- if (!ts__default["default"].isStringLiteralLike(expression)) {
575
+ if (!ts.isStringLiteralLike(expression)) {
580
576
  continue;
581
577
  }
582
578
  const isEventBinding = rawName.startsWith('(');
@@ -639,7 +635,7 @@ function attemptExtractTemplateDefinition(node, checker$1, reflector, resourceLo
639
635
  if (ngDecorators.length === 0 ||
640
636
  ngDecorators[0].args === null ||
641
637
  ngDecorators[0].args.length === 0 ||
642
- !ts__default["default"].isObjectLiteralExpression(ngDecorators[0].args[0])) {
638
+ !ts.isObjectLiteralExpression(ngDecorators[0].args[0])) {
643
639
  return null;
644
640
  }
645
641
  const properties = checker.reflectObjectLiteral(ngDecorators[0].args[0]);
@@ -755,7 +751,7 @@ function extractTemplateWithoutCompilerAnalysis(node, checker$1, reflector, reso
755
751
  function resolveBindingElement(node) {
756
752
  const name = node.propertyName ?? node.name;
757
753
  // If we are discovering a non-analyzable element in the path, abort.
758
- if (!ts__default["default"].isStringLiteralLike(name) && !ts__default["default"].isIdentifier(name)) {
754
+ if (!ts.isStringLiteralLike(name) && !ts.isIdentifier(name)) {
759
755
  return null;
760
756
  }
761
757
  return {
@@ -766,7 +762,7 @@ function resolveBindingElement(node) {
766
762
  /** Gets the declaration node of the given binding element. */
767
763
  function getBindingElementDeclaration(node) {
768
764
  while (true) {
769
- if (ts__default["default"].isBindingElement(node.parent.parent)) {
765
+ if (ts.isBindingElement(node.parent.parent)) {
770
766
  node = node.parent.parent;
771
767
  }
772
768
  else {
@@ -786,10 +782,10 @@ function getBindingElementDeclaration(node) {
786
782
  * variable for narrowing. Replacing just the identifier is wrong.
787
783
  */
788
784
  function traverseAccess(access) {
789
- if (ts__default["default"].isPropertyAccessExpression(access.parent) && access.parent.name === access) {
785
+ if (ts.isPropertyAccessExpression(access.parent) && access.parent.name === access) {
790
786
  return access.parent;
791
787
  }
792
- else if (ts__default["default"].isElementAccessExpression(access.parent) &&
788
+ else if (ts.isElementAccessExpression(access.parent) &&
793
789
  access.parent.argumentExpression === access) {
794
790
  return access.parent;
795
791
  }
@@ -801,10 +797,10 @@ function traverseAccess(access) {
801
797
  * parenthesized expression or `as` expression.
802
798
  */
803
799
  function unwrapParent(node) {
804
- if (ts__default["default"].isParenthesizedExpression(node.parent)) {
800
+ if (ts.isParenthesizedExpression(node.parent)) {
805
801
  return unwrapParent(node.parent);
806
802
  }
807
- else if (ts__default["default"].isAsExpression(node.parent)) {
803
+ else if (ts.isAsExpression(node.parent)) {
808
804
  return unwrapParent(node.parent);
809
805
  }
810
806
  return node;
@@ -817,18 +813,18 @@ function unwrapParent(node) {
817
813
  * something or not.
818
814
  */
819
815
  const writeBinaryOperators = [
820
- ts__default["default"].SyntaxKind.EqualsToken,
821
- ts__default["default"].SyntaxKind.BarBarEqualsToken,
822
- ts__default["default"].SyntaxKind.BarEqualsToken,
823
- ts__default["default"].SyntaxKind.AmpersandEqualsToken,
824
- ts__default["default"].SyntaxKind.AmpersandAmpersandEqualsToken,
825
- ts__default["default"].SyntaxKind.SlashEqualsToken,
826
- ts__default["default"].SyntaxKind.MinusEqualsToken,
827
- ts__default["default"].SyntaxKind.PlusEqualsToken,
828
- ts__default["default"].SyntaxKind.CaretEqualsToken,
829
- ts__default["default"].SyntaxKind.PercentEqualsToken,
830
- ts__default["default"].SyntaxKind.AsteriskEqualsToken,
831
- ts__default["default"].SyntaxKind.ExclamationEqualsToken,
816
+ ts.SyntaxKind.EqualsToken,
817
+ ts.SyntaxKind.BarBarEqualsToken,
818
+ ts.SyntaxKind.BarEqualsToken,
819
+ ts.SyntaxKind.AmpersandEqualsToken,
820
+ ts.SyntaxKind.AmpersandAmpersandEqualsToken,
821
+ ts.SyntaxKind.SlashEqualsToken,
822
+ ts.SyntaxKind.MinusEqualsToken,
823
+ ts.SyntaxKind.PlusEqualsToken,
824
+ ts.SyntaxKind.CaretEqualsToken,
825
+ ts.SyntaxKind.PercentEqualsToken,
826
+ ts.SyntaxKind.AsteriskEqualsToken,
827
+ ts.SyntaxKind.ExclamationEqualsToken,
832
828
  ];
833
829
 
834
830
  /**
@@ -849,7 +845,7 @@ function identifyPotentialTypeScriptReference(node, programInfo, checker, knownF
849
845
  let target = undefined;
850
846
  // Resolve binding elements to their declaration symbol.
851
847
  // Commonly inputs are accessed via object expansion. e.g. `const {input} = this;`.
852
- if (ts__default["default"].isBindingElement(node.parent)) {
848
+ if (ts.isBindingElement(node.parent)) {
853
849
  // Skip binding elements that are using spread.
854
850
  if (node.parent.dotDotDotToken !== undefined) {
855
851
  return;
@@ -867,11 +863,11 @@ function identifyPotentialTypeScriptReference(node, programInfo, checker, knownF
867
863
  target = checker.getSymbolAtLocation(node);
868
864
  }
869
865
  noTargetSymbolCheck: if (target === undefined) {
870
- if (ts__default["default"].isPropertyAccessExpression(node.parent) && node.parent.name === node) {
866
+ if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {
871
867
  const propAccessSymbol = checker.getSymbolAtLocation(node.parent.expression);
872
868
  if (propAccessSymbol !== undefined &&
873
869
  propAccessSymbol.valueDeclaration !== undefined &&
874
- ts__default["default"].isVariableDeclaration(propAccessSymbol.valueDeclaration) &&
870
+ ts.isVariableDeclaration(propAccessSymbol.valueDeclaration) &&
875
871
  propAccessSymbol.valueDeclaration.initializer !== undefined) {
876
872
  target = advisors.debugElComponentInstanceTracker
877
873
  .detect(propAccessSymbol.valueDeclaration.initializer)
@@ -890,7 +886,7 @@ function identifyPotentialTypeScriptReference(node, programInfo, checker, knownF
890
886
  }
891
887
  const access = unwrapParent(traverseAccess(node));
892
888
  const accessParent = access.parent;
893
- const isWriteReference = ts__default["default"].isBinaryExpression(accessParent) &&
889
+ const isWriteReference = ts.isBinaryExpression(accessParent) &&
894
890
  accessParent.left === access &&
895
891
  writeBinaryOperators.includes(accessParent.operatorToken.kind);
896
892
  // track accesses from source files to known fields.
@@ -900,7 +896,7 @@ function identifyPotentialTypeScriptReference(node, programInfo, checker, knownF
900
896
  node,
901
897
  file: project_paths.projectFile(node.getSourceFile(), programInfo),
902
898
  isWrite: isWriteReference,
903
- isPartOfElementBinding: ts__default["default"].isBindingElement(node.parent),
899
+ isPartOfElementBinding: ts.isBindingElement(node.parent),
904
900
  },
905
901
  target: targetInput,
906
902
  });
@@ -935,7 +931,7 @@ function createFindAllSourceFileReferencesVisitor(programInfo, checker, reflecto
935
931
  let lastTime = currentTimeInMs();
936
932
  // Note: If there is no template type checker and resource loader, we aren't processing
937
933
  // an Angular program, and can skip template detection.
938
- if (ts__default["default"].isClassDeclaration(node) && templateTypeChecker !== null && resourceLoader !== null) {
934
+ if (ts.isClassDeclaration(node) && templateTypeChecker !== null && resourceLoader !== null) {
939
935
  identifyTemplateReferences(programInfo, node, reflector, checker, evaluator, templateTypeChecker, resourceLoader, programInfo.userOptions, result, knownFields, fieldNamesToConsiderForReferenceLookup);
940
936
  perfCounters.template += (currentTimeInMs() - lastTime) / 1000;
941
937
  lastTime = currentTimeInMs();
@@ -945,7 +941,7 @@ function createFindAllSourceFileReferencesVisitor(programInfo, checker, reflecto
945
941
  }
946
942
  lastTime = currentTimeInMs();
947
943
  // find references, but do not capture input declarations itself.
948
- if (ts__default["default"].isIdentifier(node) &&
944
+ if (ts.isIdentifier(node) &&
949
945
  !(isInputContainerNode(node.parent) && node.parent.name === node)) {
950
946
  identifyPotentialTypeScriptReference(node, programInfo, checker, knownFields, result, fieldNamesToConsiderForReferenceLookup, {
951
947
  debugElComponentInstanceTracker,
@@ -1,15 +1,15 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.0
4
- * (c) 2010-2024 Google LLC. https://angular.io/
3
+ * @license Angular v20.0.0-next.2
4
+ * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
8
 
9
9
  require('os');
10
10
  require('typescript');
11
- var checker = require('./checker-cf6f7980.js');
12
- require('./program-362689f0.js');
11
+ var checker = require('./checker-DF8ZaFW5.js');
12
+ require('./program-BZk27Ndu.js');
13
13
  require('path');
14
14
 
15
15
  /**
@@ -17,7 +17,7 @@ require('path');
17
17
  * @description
18
18
  * Entry point for all public APIs of the compiler-cli package.
19
19
  */
20
- new checker.Version('20.0.0-next.0');
20
+ new checker.Version('20.0.0-next.2');
21
21
 
22
22
  var LogLevel;
23
23
  (function (LogLevel) {
@@ -0,0 +1,181 @@
1
+ 'use strict';
2
+ /**
3
+ * @license Angular v20.0.0-next.2
4
+ * (c) 2010-2025 Google LLC. https://angular.io/
5
+ * License: MIT
6
+ */
7
+ 'use strict';
8
+
9
+ var schematics = require('@angular-devkit/schematics');
10
+ var project_tsconfig_paths = require('./project_tsconfig_paths-CDVxT6Ov.js');
11
+ var project_paths = require('./project_paths-Jtbi76Bs.js');
12
+ require('os');
13
+ var ts = require('typescript');
14
+ var checker = require('./checker-DF8ZaFW5.js');
15
+ require('./program-BZk27Ndu.js');
16
+ require('path');
17
+ var apply_import_manager = require('./apply_import_manager-CyRT0UvU.js');
18
+ var imports = require('./imports-CIX-JgAN.js');
19
+ require('@angular-devkit/core');
20
+ require('node:path/posix');
21
+ require('fs');
22
+ require('module');
23
+ require('url');
24
+
25
+ /** Mapping between `InjectFlag` enum members to their object literal equvalients. */
26
+ const FLAGS_TO_FIELDS = {
27
+ 'Default': 'default',
28
+ 'Host': 'host',
29
+ 'Optional': 'optional',
30
+ 'Self': 'self',
31
+ 'SkipSelf': 'skipSelf',
32
+ };
33
+ /** Migration that replaces `InjectFlags` usages with object literals. */
34
+ class InjectFlagsMigration extends project_paths.TsurgeFunnelMigration {
35
+ async analyze(info) {
36
+ const locations = {};
37
+ const importRemovals = {};
38
+ for (const sourceFile of info.sourceFiles) {
39
+ const specifier = imports.getImportSpecifier(sourceFile, '@angular/core', 'InjectFlags');
40
+ if (specifier === null) {
41
+ continue;
42
+ }
43
+ const file = project_paths.projectFile(sourceFile, info);
44
+ const importManager = new checker.ImportManager();
45
+ const importReplacements = [];
46
+ // Always remove the `InjectFlags` since it has been removed from Angular.
47
+ // Note that it be better to do this inside of `migrate`, but we don't have AST access there.
48
+ importManager.removeImport(sourceFile, 'InjectFlags', '@angular/core');
49
+ apply_import_manager.applyImportManagerChanges(importManager, importReplacements, [sourceFile], info);
50
+ importRemovals[file.id] = importReplacements;
51
+ sourceFile.forEachChild(function walk(node) {
52
+ if (
53
+ // Note: we don't use the type checker for matching here, because
54
+ // the `InjectFlags` will be removed which can break the lookup.
55
+ ts.isPropertyAccessExpression(node) &&
56
+ ts.isIdentifier(node.expression) &&
57
+ node.expression.text === specifier.name.text &&
58
+ FLAGS_TO_FIELDS.hasOwnProperty(node.name.text)) {
59
+ const root = getInjectFlagsRootExpression(node);
60
+ if (root !== null) {
61
+ const flagName = FLAGS_TO_FIELDS[node.name.text];
62
+ const id = getNodeID(file, root);
63
+ locations[id] ??= { file, flags: [], position: root.getStart(), end: root.getEnd() };
64
+ // The flags can't be a set here, because they need to be serializable.
65
+ if (!locations[id].flags.includes(flagName)) {
66
+ locations[id].flags.push(flagName);
67
+ }
68
+ }
69
+ }
70
+ else {
71
+ node.forEachChild(walk);
72
+ }
73
+ });
74
+ }
75
+ return project_paths.confirmAsSerializable({ locations, importRemovals });
76
+ }
77
+ async migrate(globalData) {
78
+ const replacements = [];
79
+ for (const removals of Object.values(globalData.importRemovals)) {
80
+ replacements.push(...removals);
81
+ }
82
+ for (const { file, position, end, flags } of Object.values(globalData.locations)) {
83
+ // Declare a property for each flag, except for `default` which does not have a flag.
84
+ const properties = flags.filter((flag) => flag !== 'default').map((flag) => `${flag}: true`);
85
+ const toInsert = properties.length ? `{ ${properties.join(', ')} }` : '{}';
86
+ replacements.push(new project_paths.Replacement(file, new project_paths.TextUpdate({ position, end, toInsert })));
87
+ }
88
+ return project_paths.confirmAsSerializable({ replacements });
89
+ }
90
+ async combine(unitA, unitB) {
91
+ return project_paths.confirmAsSerializable({
92
+ locations: {
93
+ ...unitA.locations,
94
+ ...unitB.locations,
95
+ },
96
+ importRemovals: {
97
+ ...unitA.importRemovals,
98
+ ...unitB.importRemovals,
99
+ },
100
+ });
101
+ }
102
+ async globalMeta(combinedData) {
103
+ return project_paths.confirmAsSerializable(combinedData);
104
+ }
105
+ async stats() {
106
+ return { counters: {} };
107
+ }
108
+ }
109
+ /** Gets an ID that can be used to look up a node based on its location. */
110
+ function getNodeID(file, node) {
111
+ return `${file.id}/${node.getStart()}/${node.getWidth()}`;
112
+ }
113
+ /**
114
+ * Gets the root expression of an `InjectFlags` usage. For example given `InjectFlags.Optional`.
115
+ * in `InjectFlags.Host | InjectFlags.Optional | InjectFlags.SkipSelf`, the function will return
116
+ * the top-level binary expression.
117
+ * @param start Node from which to start searching.
118
+ */
119
+ function getInjectFlagsRootExpression(start) {
120
+ let current = start;
121
+ let parent = current?.parent;
122
+ while (parent && (ts.isBinaryExpression(parent) || ts.isParenthesizedExpression(parent))) {
123
+ current = parent;
124
+ parent = current.parent;
125
+ }
126
+ // Only allow allow expressions that are call parameters, variable initializer or parameter
127
+ // initializers which are the only officially supported usages of `InjectFlags`.
128
+ if (current &&
129
+ parent &&
130
+ ((ts.isCallExpression(parent) && parent.arguments.includes(current)) ||
131
+ (ts.isVariableDeclaration(parent) && parent.initializer === current) ||
132
+ (ts.isParameter(parent) && parent.initializer === current))) {
133
+ return current;
134
+ }
135
+ return null;
136
+ }
137
+
138
+ function migrate() {
139
+ return async (tree) => {
140
+ const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
141
+ if (!buildPaths.length && !testPaths.length) {
142
+ throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot replace `InjectFlags` usages.');
143
+ }
144
+ const fs = new project_paths.DevkitMigrationFilesystem(tree);
145
+ checker.setFileSystem(fs);
146
+ const migration = new InjectFlagsMigration();
147
+ const unitResults = [];
148
+ const programInfos = [...buildPaths, ...testPaths].map((tsconfigPath) => {
149
+ const baseInfo = migration.createProgram(tsconfigPath, fs);
150
+ const info = migration.prepareProgram(baseInfo);
151
+ return { info, tsconfigPath };
152
+ });
153
+ for (const { info } of programInfos) {
154
+ unitResults.push(await migration.analyze(info));
155
+ }
156
+ const combined = await project_paths.synchronouslyCombineUnitData(migration, unitResults);
157
+ if (combined === null) {
158
+ return;
159
+ }
160
+ const globalMeta = await migration.globalMeta(combined);
161
+ const replacementsPerFile = new Map();
162
+ const { replacements } = await migration.migrate(globalMeta);
163
+ const changesPerFile = project_paths.groupReplacementsByFile(replacements);
164
+ for (const [file, changes] of changesPerFile) {
165
+ if (!replacementsPerFile.has(file)) {
166
+ replacementsPerFile.set(file, changes);
167
+ }
168
+ }
169
+ for (const [file, changes] of replacementsPerFile) {
170
+ const recorder = tree.beginUpdate(file);
171
+ for (const c of changes) {
172
+ recorder
173
+ .remove(c.data.position, c.data.end - c.data.position)
174
+ .insertRight(c.data.position, c.data.toInsert);
175
+ }
176
+ tree.commitUpdate(recorder);
177
+ }
178
+ };
179
+ }
180
+
181
+ exports.migrate = migrate;