@angular/core 21.0.0-next.9 → 21.0.0-rc.0

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 (78) hide show
  1. package/fesm2022/_attribute-chunk.mjs +2 -14
  2. package/fesm2022/_attribute-chunk.mjs.map +1 -1
  3. package/fesm2022/_debug_node-chunk.mjs +15164 -28368
  4. package/fesm2022/_debug_node-chunk.mjs.map +1 -1
  5. package/fesm2022/_effect-chunk.mjs +322 -504
  6. package/fesm2022/_effect-chunk.mjs.map +1 -1
  7. package/fesm2022/_effect-chunk2.mjs +2204 -4061
  8. package/fesm2022/_effect-chunk2.mjs.map +1 -1
  9. package/fesm2022/_not_found-chunk.mjs +18 -35
  10. package/fesm2022/_not_found-chunk.mjs.map +1 -1
  11. package/fesm2022/_resource-chunk.mjs +312 -391
  12. package/fesm2022/_resource-chunk.mjs.map +1 -1
  13. package/fesm2022/_untracked-chunk.mjs +75 -96
  14. package/fesm2022/_untracked-chunk.mjs.map +1 -1
  15. package/fesm2022/_weak_ref-chunk.mjs +2 -4
  16. package/fesm2022/_weak_ref-chunk.mjs.map +1 -1
  17. package/fesm2022/core.mjs +2461 -4305
  18. package/fesm2022/core.mjs.map +1 -1
  19. package/fesm2022/primitives-di.mjs +9 -9
  20. package/fesm2022/primitives-di.mjs.map +1 -1
  21. package/fesm2022/primitives-event-dispatch.mjs +626 -1460
  22. package/fesm2022/primitives-event-dispatch.mjs.map +1 -1
  23. package/fesm2022/primitives-signals.mjs +154 -188
  24. package/fesm2022/primitives-signals.mjs.map +1 -1
  25. package/fesm2022/rxjs-interop.mjs +204 -304
  26. package/fesm2022/rxjs-interop.mjs.map +1 -1
  27. package/fesm2022/testing.mjs +2303 -3162
  28. package/fesm2022/testing.mjs.map +1 -1
  29. package/package.json +8 -2
  30. package/resources/best-practices.md +56 -0
  31. package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +7 -25
  32. package/schematics/bundles/application-config-core.cjs +8 -19
  33. package/schematics/bundles/{apply_import_manager-CoeTX_Ob.cjs → apply_import_manager-1Zs_gpB6.cjs} +4 -5
  34. package/schematics/bundles/bootstrap-options-migration.cjs +93 -132
  35. package/schematics/bundles/cleanup-unused-imports.cjs +9 -13
  36. package/schematics/bundles/common-to-standalone-migration.cjs +12 -16
  37. package/schematics/bundles/{compiler_host-emLDwK2U.cjs → compiler_host-DBwYMlTo.cjs} +10 -11
  38. package/schematics/bundles/control-flow-migration.cjs +29 -31
  39. package/schematics/bundles/{imports-DwPXlGFl.cjs → imports-DP72APSx.cjs} +1 -23
  40. package/schematics/bundles/{index-CLxYZ09c.cjs → index-B7I9sIUx.cjs} +36 -37
  41. package/schematics/bundles/inject-migration.cjs +9 -26
  42. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  43. package/schematics/bundles/{migrate_ts_type_references-CpM5FPGa.cjs → migrate_ts_type_references-UGIUl7En.cjs} +458 -24
  44. package/schematics/bundles/{ng_component_template-BRbBIAUX.cjs → ng_component_template-Dsuq1Lw7.cjs} +4 -5
  45. package/schematics/bundles/{ng_decorators-BI0uV7KI.cjs → ng_decorators-DSFlWYQY.cjs} +2 -2
  46. package/schematics/bundles/ngclass-to-class-migration.cjs +16 -19
  47. package/schematics/bundles/ngstyle-to-style-migration.cjs +15 -18
  48. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  49. package/schematics/bundles/output-migration.cjs +16 -19
  50. package/schematics/bundles/{parse_html-CPWfkfhR.cjs → parse_html-8VLCL37B.cjs} +5 -5
  51. package/schematics/bundles/{project_paths-C8H7KDJ3.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 +9 -25
  55. package/schematics/bundles/router-current-navigation.cjs +6 -17
  56. package/schematics/bundles/router-last-successful-navigation.cjs +6 -17
  57. package/schematics/bundles/router-testing-module-migration.cjs +7 -18
  58. package/schematics/bundles/self-closing-tags-migration.cjs +14 -17
  59. package/schematics/bundles/signal-input-migration.cjs +23 -26
  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 +22 -56
  63. package/schematics/bundles/symbol-BObKoqes.cjs +1 -1
  64. package/types/_api-chunk.d.ts +1 -1
  65. package/types/_chrome_dev_tools_performance-chunk.d.ts +1 -1
  66. package/types/_discovery-chunk.d.ts +7 -9
  67. package/types/_effect-chunk.d.ts +1 -1
  68. package/types/_event_dispatcher-chunk.d.ts +1 -1
  69. package/types/_formatter-chunk.d.ts +1 -1
  70. package/types/_weak_ref-chunk.d.ts +1 -1
  71. package/types/core.d.ts +1 -81
  72. package/types/primitives-di.d.ts +1 -1
  73. package/types/primitives-event-dispatch.d.ts +1 -1
  74. package/types/primitives-signals.d.ts +1 -1
  75. package/types/rxjs-interop.d.ts +1 -1
  76. package/types/testing.d.ts +1 -1
  77. package/schematics/bundles/index-Dvqnp6JS.cjs +0 -22419
  78. package/schematics/bundles/project_tsconfig_paths-CiBzGSIa.cjs +0 -51591
@@ -1,29 +1,26 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v21.0.0-next.9
3
+ * @license Angular v21.0.0-rc.0
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-CiBzGSIa.cjs');
12
- var index = require('./index-Dvqnp6JS.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-C8H7KDJ3.cjs');
16
- var apply_import_manager = require('./apply_import_manager-CoeTX_Ob.cjs');
17
- var imports = require('./imports-DwPXlGFl.cjs');
18
- var parse_html = require('./parse_html-CPWfkfhR.cjs');
19
- var ng_component_template = require('./ng_component_template-BRbBIAUX.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 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');
20
19
  require('@angular-devkit/core');
21
20
  require('node:path/posix');
22
- require('fs');
23
- require('module');
24
- require('url');
25
21
  require('@angular-devkit/schematics');
26
- require('./ng_decorators-BI0uV7KI.cjs');
22
+ require('./project_tsconfig_paths-CDVxT6Ov.cjs');
23
+ require('./ng_decorators-DSFlWYQY.cjs');
27
24
  require('./property_name-BBwFuqMe.cjs');
28
25
 
29
26
  const ngClassStr = 'NgClass';
@@ -35,7 +32,7 @@ function migrateNgClassBindings(template, config, componentNode, typeChecker) {
35
32
  return { migrated: template, changed: false, replacementCount: 0, canRemoveCommonModule: false };
36
33
  }
37
34
  const visitor = new NgClassCollector(template, componentNode, typeChecker);
38
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes, config);
35
+ compiler.visitAll(visitor, parsed.tree.rootNodes, config);
39
36
  let newTemplate = template;
40
37
  let changedOffset = 0;
41
38
  let replacementCount = 0;
@@ -58,8 +55,8 @@ function migrateNgClassBindings(template, config, componentNode, typeChecker) {
58
55
  * Uses ReflectionHost + PartialEvaluator for robust AST analysis.
59
56
  */
60
57
  function createNgClassImportsArrayRemoval(classNode, file, typeChecker, removeCommonModule) {
61
- const reflector = new project_tsconfig_paths.TypeScriptReflectionHost(typeChecker);
62
- const evaluator = new index.PartialEvaluator(reflector, typeChecker, null);
58
+ const reflector = new migrations.TypeScriptReflectionHost(typeChecker);
59
+ const evaluator = new migrations.PartialEvaluator(reflector, typeChecker, null);
63
60
  // Use ReflectionHost to get decorators instead of manual AST traversal
64
61
  const decorators = reflector.getDecoratorsOfDeclaration(classNode);
65
62
  if (!decorators) {
@@ -133,7 +130,7 @@ function getPropertyRemovalRange(property) {
133
130
  }
134
131
  function calculateImportReplacements(info, sourceFiles, filesToRemoveCommonModule) {
135
132
  const importReplacements = {};
136
- const importManager = new project_tsconfig_paths.ImportManager();
133
+ const importManager = new migrations.ImportManager();
137
134
  for (const sf of sourceFiles) {
138
135
  const file = project_paths.projectFile(sf, info);
139
136
  // Always remove NgClass if it's imported directly.
@@ -160,7 +157,7 @@ function replaceTemplate(template, replaceValue, start, end, offset) {
160
157
  * Visitor class that scans Angular templates and collects replacements
161
158
  * for [ngClass] bindings that use static object literals.
162
159
  */
163
- class NgClassCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
160
+ class NgClassCollector extends compiler.RecursiveVisitor {
164
161
  componentNode;
165
162
  typeChecker;
166
163
  replacements = [];
@@ -1,29 +1,26 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v21.0.0-next.9
3
+ * @license Angular v21.0.0-rc.0
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-CiBzGSIa.cjs');
12
- require('./index-Dvqnp6JS.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-C8H7KDJ3.cjs');
16
- var apply_import_manager = require('./apply_import_manager-CoeTX_Ob.cjs');
17
- var imports = require('./imports-DwPXlGFl.cjs');
18
- var parse_html = require('./parse_html-CPWfkfhR.cjs');
19
- var ng_component_template = require('./ng_component_template-BRbBIAUX.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 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');
20
19
  require('@angular-devkit/core');
21
20
  require('node:path/posix');
22
- require('fs');
23
- require('module');
24
- require('url');
25
21
  require('@angular-devkit/schematics');
26
- require('./ng_decorators-BI0uV7KI.cjs');
22
+ require('./project_tsconfig_paths-CDVxT6Ov.cjs');
23
+ require('./ng_decorators-DSFlWYQY.cjs');
27
24
  require('./property_name-BBwFuqMe.cjs');
28
25
 
29
26
  const ngStyleStr = 'NgStyle';
@@ -35,7 +32,7 @@ function migrateNgStyleBindings(template, config, componentNode, typeChecker) {
35
32
  return { migrated: template, changed: false, replacementCount: 0, canRemoveCommonModule: false };
36
33
  }
37
34
  const visitor = new NgStyleCollector(template, componentNode, typeChecker);
38
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes, config);
35
+ compiler.visitAll(visitor, parsed.tree.rootNodes, config);
39
36
  let newTemplate = template;
40
37
  let changedOffset = 0;
41
38
  let replacementCount = 0;
@@ -58,7 +55,7 @@ function migrateNgStyleBindings(template, config, componentNode, typeChecker) {
58
55
  * Uses ReflectionHost + PartialEvaluator for robust AST analysis.
59
56
  */
60
57
  function createNgStyleImportsArrayRemoval(classNode, file, typeChecker, removeCommonModule) {
61
- const reflector = new project_tsconfig_paths.TypeScriptReflectionHost(typeChecker);
58
+ const reflector = new migrations.TypeScriptReflectionHost(typeChecker);
62
59
  const decorators = reflector.getDecoratorsOfDeclaration(classNode);
63
60
  if (!decorators) {
64
61
  return null;
@@ -127,7 +124,7 @@ function getPropertyRemovalRange(property) {
127
124
  }
128
125
  function calculateImportReplacements(info, sourceFiles, filesToRemoveCommonModule) {
129
126
  const importReplacements = {};
130
- const importManager = new project_tsconfig_paths.ImportManager();
127
+ const importManager = new migrations.ImportManager();
131
128
  for (const sf of sourceFiles) {
132
129
  const file = project_paths.projectFile(sf, info);
133
130
  // Always remove NgStyle if it's imported directly.
@@ -154,7 +151,7 @@ function replaceTemplate(template, replaceValue, start, end, offset) {
154
151
  * Visitor class that scans Angular templates and collects replacements
155
152
  * for [ngStyle] bindings that use static object literals.
156
153
  */
157
- class NgStyleCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
154
+ class NgStyleCollector extends compiler.RecursiveVisitor {
158
155
  originalTemplate;
159
156
  replacements = [];
160
157
  isNgStyleImported = true; // Default to true (permissive)
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v21.0.0-next.9
3
+ * @license Angular v21.0.0-rc.0
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.9
3
+ * @license Angular v21.0.0-rc.0
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-CiBzGSIa.cjs');
12
- var index$1 = require('./index-Dvqnp6JS.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-C8H7KDJ3.cjs');
16
- var apply_import_manager = require('./apply_import_manager-CoeTX_Ob.cjs');
17
- var index = require('./index-CLxYZ09c.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.
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v21.0.0-next.9
3
+ * @license Angular v21.0.0-rc.0
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
8
 
9
- var project_tsconfig_paths = require('./project_tsconfig_paths-CiBzGSIa.cjs');
9
+ var compiler = require('@angular/compiler');
10
10
 
11
11
  /**
12
12
  * parses the template string into the Html AST
@@ -19,7 +19,7 @@ function parseTemplate(template) {
19
19
  // interpolated text as text nodes containing a mixture of interpolation tokens and text tokens,
20
20
  // rather than turning them into `BoundText` nodes like the Ivy AST does. This allows us to
21
21
  // easily get the text-only ranges without having to reconstruct the original text.
22
- parsed = new project_tsconfig_paths.HtmlParser().parse(template, '', {
22
+ parsed = new compiler.HtmlParser().parse(template, '', {
23
23
  // Allows for ICUs to be parsed.
24
24
  tokenizeExpansionForms: true,
25
25
  // Explicitly disable blocks so that their characters are treated as plain text.
@@ -83,13 +83,13 @@ function canRemoveCommonModule(template) {
83
83
  let removeCommonModule = false;
84
84
  if (parsed.tree !== undefined) {
85
85
  const visitor = new CommonCollector();
86
- project_tsconfig_paths.visitAll$1(visitor, parsed.tree.rootNodes);
86
+ compiler.visitAll(visitor, parsed.tree.rootNodes);
87
87
  removeCommonModule = visitor.count === 0;
88
88
  }
89
89
  return removeCommonModule;
90
90
  }
91
91
  /** Finds all non-control flow elements from common module. */
92
- class CommonCollector extends project_tsconfig_paths.RecursiveVisitor$1 {
92
+ class CommonCollector extends compiler.RecursiveVisitor {
93
93
  count = 0;
94
94
  visitElement(el) {
95
95
  if (el.attrs.length > 0) {
@@ -1,20 +1,19 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v21.0.0-next.9
3
+ * @license Angular v21.0.0-rc.0
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
8
 
9
- var index = require('./index-Dvqnp6JS.cjs');
9
+ var compilerCli = require('@angular/compiler-cli');
10
10
  var schematics = require('@angular-devkit/schematics');
11
11
  var core = require('@angular-devkit/core');
12
12
  var posixPath = require('node:path/posix');
13
- var os = require('os');
13
+ var migrations = require('@angular/compiler-cli/private/migrations');
14
14
  var ts = require('typescript');
15
- var project_tsconfig_paths = require('./project_tsconfig_paths-CiBzGSIa.cjs');
16
- require('path');
17
15
  var path = require('node:path');
16
+ var project_tsconfig_paths = require('./project_tsconfig_paths-CDVxT6Ov.cjs');
18
17
 
19
18
  function _interopNamespaceDefault(e) {
20
19
  var n = Object.create(null);
@@ -34,233 +33,8 @@ function _interopNamespaceDefault(e) {
34
33
  }
35
34
 
36
35
  var posixPath__namespace = /*#__PURE__*/_interopNamespaceDefault(posixPath);
37
- var os__namespace = /*#__PURE__*/_interopNamespaceDefault(os);
38
36
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
39
37
 
40
- /// <reference types="node" />
41
- class NgtscCompilerHost {
42
- fs;
43
- options;
44
- constructor(fs, options = {}) {
45
- this.fs = fs;
46
- this.options = options;
47
- }
48
- getSourceFile(fileName, languageVersion) {
49
- const text = this.readFile(fileName);
50
- return text !== undefined
51
- ? ts.createSourceFile(fileName, text, languageVersion, true)
52
- : undefined;
53
- }
54
- getDefaultLibFileName(options) {
55
- return this.fs.join(this.getDefaultLibLocation(), ts.getDefaultLibFileName(options));
56
- }
57
- getDefaultLibLocation() {
58
- return this.fs.getDefaultLibLocation();
59
- }
60
- writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles) {
61
- const path = project_tsconfig_paths.absoluteFrom(fileName);
62
- this.fs.ensureDir(this.fs.dirname(path));
63
- this.fs.writeFile(path, data);
64
- }
65
- getCurrentDirectory() {
66
- return this.fs.pwd();
67
- }
68
- getCanonicalFileName(fileName) {
69
- return this.useCaseSensitiveFileNames() ? fileName : fileName.toLowerCase();
70
- }
71
- useCaseSensitiveFileNames() {
72
- return this.fs.isCaseSensitive();
73
- }
74
- getNewLine() {
75
- switch (this.options.newLine) {
76
- case ts.NewLineKind.CarriageReturnLineFeed:
77
- return '\r\n';
78
- case ts.NewLineKind.LineFeed:
79
- return '\n';
80
- default:
81
- return os__namespace.EOL;
82
- }
83
- }
84
- fileExists(fileName) {
85
- const absPath = this.fs.resolve(fileName);
86
- return this.fs.exists(absPath) && this.fs.stat(absPath).isFile();
87
- }
88
- readFile(fileName) {
89
- const absPath = this.fs.resolve(fileName);
90
- if (!this.fileExists(absPath)) {
91
- return undefined;
92
- }
93
- return this.fs.readFile(absPath);
94
- }
95
- realpath(path) {
96
- return this.fs.realpath(this.fs.resolve(path));
97
- }
98
- }
99
-
100
- // We use TypeScript's native `ts.matchFiles` utility for the virtual file systems
101
- // and their TypeScript compiler host `readDirectory` implementation. TypeScript's
102
- // function implements complex logic for matching files with respect to root
103
- // directory, extensions, excludes, includes etc. The function is currently
104
- // internal but we can use it as the API most likely will not change any time soon,
105
- // nor does it seem like this is being made public any time soon.
106
- // Related issue for tracking: https://github.com/microsoft/TypeScript/issues/13793.
107
- /**
108
- * Creates a {@link ts.CompilerHost#readDirectory} implementation function,
109
- * that leverages the specified file system (that may be e.g. virtual).
110
- */
111
- function createFileSystemTsReadDirectoryFn(fs) {
112
- if (ts.matchFiles === undefined) {
113
- throw Error('Unable to read directory in configured file system. This means that ' +
114
- 'TypeScript changed its file matching internals.\n\nPlease consider downgrading your ' +
115
- 'TypeScript version, and report an issue in the Angular framework repository.');
116
- }
117
- const matchFilesFn = ts.matchFiles.bind(ts);
118
- return (rootDir, extensions, excludes, includes, depth) => {
119
- const directoryExists = (p) => {
120
- const resolvedPath = fs.resolve(p);
121
- return fs.exists(resolvedPath) && fs.stat(resolvedPath).isDirectory();
122
- };
123
- return matchFilesFn(rootDir, extensions, excludes, includes, fs.isCaseSensitive(), fs.pwd(), depth, (p) => {
124
- const resolvedPath = fs.resolve(p);
125
- // TS also gracefully returns an empty file set.
126
- if (!directoryExists(resolvedPath)) {
127
- return { directories: [], files: [] };
128
- }
129
- const children = fs.readdir(resolvedPath);
130
- const files = [];
131
- const directories = [];
132
- for (const child of children) {
133
- if (fs.stat(fs.join(resolvedPath, child))?.isDirectory()) {
134
- directories.push(child);
135
- }
136
- else {
137
- files.push(child);
138
- }
139
- }
140
- return { files, directories };
141
- }, (p) => fs.resolve(p), (p) => directoryExists(p));
142
- };
143
- }
144
-
145
- function calcProjectFileAndBasePath(project, host = project_tsconfig_paths.getFileSystem()) {
146
- const absProject = host.resolve(project);
147
- const projectIsDir = host.lstat(absProject).isDirectory();
148
- const projectFile = projectIsDir ? host.join(absProject, 'tsconfig.json') : absProject;
149
- const projectDir = projectIsDir ? absProject : host.dirname(absProject);
150
- const basePath = host.resolve(projectDir);
151
- return { projectFile, basePath };
152
- }
153
- function readConfiguration(project, existingOptions, host = project_tsconfig_paths.getFileSystem()) {
154
- try {
155
- const fs = project_tsconfig_paths.getFileSystem();
156
- const readConfigFile = (configFile) => ts.readConfigFile(configFile, (file) => host.readFile(host.resolve(file)));
157
- const readAngularCompilerOptions = (configFile, parentOptions = {}) => {
158
- const { config, error } = readConfigFile(configFile);
159
- if (error) {
160
- // Errors are handled later on by 'parseJsonConfigFileContent'
161
- return parentOptions;
162
- }
163
- // Note: In Google, `angularCompilerOptions` are stored in `bazelOptions`.
164
- // This function typically doesn't run for actual Angular compilations, but
165
- // tooling like Tsurge, or schematics may leverage this helper, so we account
166
- // for this here.
167
- const angularCompilerOptions = config.angularCompilerOptions ?? config.bazelOptions?.angularCompilerOptions;
168
- // we are only interested into merging 'angularCompilerOptions' as
169
- // other options like 'compilerOptions' are merged by TS
170
- let existingNgCompilerOptions = { ...angularCompilerOptions, ...parentOptions };
171
- if (!config.extends) {
172
- return existingNgCompilerOptions;
173
- }
174
- const extendsPaths = typeof config.extends === 'string' ? [config.extends] : config.extends;
175
- // Call readAngularCompilerOptions recursively to merge NG Compiler options
176
- // Reverse the array so the overrides happen from right to left.
177
- return [...extendsPaths].reverse().reduce((prevOptions, extendsPath) => {
178
- const extendedConfigPath = getExtendedConfigPath(configFile, extendsPath, host, fs);
179
- return extendedConfigPath === null
180
- ? prevOptions
181
- : readAngularCompilerOptions(extendedConfigPath, prevOptions);
182
- }, existingNgCompilerOptions);
183
- };
184
- const { projectFile, basePath } = calcProjectFileAndBasePath(project, host);
185
- const configFileName = host.resolve(host.pwd(), projectFile);
186
- const { config, error } = readConfigFile(projectFile);
187
- if (error) {
188
- return {
189
- project,
190
- errors: [error],
191
- rootNames: [],
192
- options: {},
193
- emitFlags: index.EmitFlags.Default,
194
- };
195
- }
196
- const existingCompilerOptions = {
197
- genDir: basePath,
198
- basePath,
199
- ...readAngularCompilerOptions(configFileName),
200
- ...existingOptions,
201
- };
202
- const parseConfigHost = createParseConfigHost(host, fs);
203
- const { options, errors, fileNames: rootNames, projectReferences, } = ts.parseJsonConfigFileContent(config, parseConfigHost, basePath, existingCompilerOptions, configFileName);
204
- let emitFlags = index.EmitFlags.Default;
205
- if (!(options['skipMetadataEmit'] || options['flatModuleOutFile'])) {
206
- emitFlags |= index.EmitFlags.Metadata;
207
- }
208
- if (options['skipTemplateCodegen']) {
209
- emitFlags = emitFlags & ~index.EmitFlags.Codegen;
210
- }
211
- return { project: projectFile, rootNames, projectReferences, options, errors, emitFlags };
212
- }
213
- catch (e) {
214
- const errors = [
215
- {
216
- category: ts.DiagnosticCategory.Error,
217
- messageText: e.stack ?? e.message,
218
- file: undefined,
219
- start: undefined,
220
- length: undefined,
221
- source: 'angular',
222
- code: index.UNKNOWN_ERROR_CODE,
223
- },
224
- ];
225
- return { project: '', errors, rootNames: [], options: {}, emitFlags: index.EmitFlags.Default };
226
- }
227
- }
228
- function createParseConfigHost(host, fs = project_tsconfig_paths.getFileSystem()) {
229
- return {
230
- fileExists: host.exists.bind(host),
231
- readDirectory: createFileSystemTsReadDirectoryFn(fs),
232
- readFile: host.readFile.bind(host),
233
- useCaseSensitiveFileNames: fs.isCaseSensitive(),
234
- };
235
- }
236
- function getExtendedConfigPath(configFile, extendsValue, host, fs) {
237
- const result = getExtendedConfigPathWorker(configFile, extendsValue, host, fs);
238
- if (result !== null) {
239
- return result;
240
- }
241
- // Try to resolve the paths with a json extension append a json extension to the file in case if
242
- // it is missing and the resolution failed. This is to replicate TypeScript behaviour, see:
243
- // https://github.com/microsoft/TypeScript/blob/294a5a7d784a5a95a8048ee990400979a6bc3a1c/src/compiler/commandLineParser.ts#L2806
244
- return getExtendedConfigPathWorker(configFile, `${extendsValue}.json`, host, fs);
245
- }
246
- function getExtendedConfigPathWorker(configFile, extendsValue, host, fs) {
247
- if (extendsValue.startsWith('.') || fs.isRooted(extendsValue)) {
248
- const extendedConfigPath = host.resolve(host.dirname(configFile), extendsValue);
249
- if (host.exists(extendedConfigPath)) {
250
- return extendedConfigPath;
251
- }
252
- }
253
- else {
254
- const parseConfigHost = createParseConfigHost(host, fs);
255
- // Path isn't a rooted or relative path, resolve like a module.
256
- const { resolvedModule } = ts.nodeModuleNameResolver(extendsValue, configFile, { moduleResolution: ts.ModuleResolutionKind.Node10, resolveJsonModule: true }, parseConfigHost);
257
- if (resolvedModule) {
258
- return project_tsconfig_paths.absoluteFrom(resolvedModule.resolvedFileName);
259
- }
260
- }
261
- return null;
262
- }
263
-
264
38
  /**
265
39
  * Angular compiler file system implementation that leverages an
266
40
  * CLI schematic virtual file tree.
@@ -495,7 +269,7 @@ function createPlainTsProgram(tsHost, tsconfig, optionOverrides) {
495
269
  * an instance of the Angular compiler for the project.
496
270
  */
497
271
  function createNgtscProgram(tsHost, tsconfig, optionOverrides) {
498
- const ngtscProgram = new index.NgtscProgram(tsconfig.rootNames, {
272
+ const ngtscProgram = new compilerCli.NgtscProgram(tsconfig.rootNames, {
499
273
  ...tsconfig.options,
500
274
  ...defaultMigrationTsOptions,
501
275
  ...optionOverrides,
@@ -517,7 +291,7 @@ function createNgtscProgram(tsHost, tsconfig, optionOverrides) {
517
291
  const NO_INPUTS_ERROR_CODE = 18003;
518
292
  /** Parses the given tsconfig file, supporting Angular compiler options. */
519
293
  function parseTsconfigOrDie(absoluteTsconfigPath, fs) {
520
- const tsconfig = readConfiguration(absoluteTsconfigPath, {}, fs);
294
+ const tsconfig = compilerCli.readConfiguration(absoluteTsconfigPath, {}, fs);
521
295
  // Skip the "No inputs found..." error since we don't want to interrupt the migration if a
522
296
  // tsconfig doesn't match a file. This will result in an empty `Program` which is still valid.
523
297
  const errors = tsconfig.errors.filter((diag) => diag.code !== NO_INPUTS_ERROR_CODE);
@@ -555,9 +329,9 @@ function createBaseProgramInfo(absoluteTsconfigPath, fs, optionOverrides = {}) {
555
329
  // Make sure the FS becomes globally available. Some code paths
556
330
  // of the Angular compiler, or tsconfig parsing aren't leveraging
557
331
  // the specified file system.
558
- project_tsconfig_paths.setFileSystem(fs);
332
+ compilerCli.setFileSystem(fs);
559
333
  const tsconfig = parseTsconfigOrDie(absoluteTsconfigPath, fs);
560
- const tsHost = new NgtscCompilerHost(fs, tsconfig.options);
334
+ const tsHost = new compilerCli.NgtscCompilerHost(fs, tsconfig.options);
561
335
  // When enabled, use a plain TS program if we are sure it's not
562
336
  // an Angular project based on the `tsconfig.json`.
563
337
  if (google3UsePlainTsProgramIfNoKnownAngularOption() &&
@@ -584,14 +358,14 @@ function getProgramInfoFromBaseInfo(baseInfo) {
584
358
  const fullProgramSourceFiles = [...baseInfo.program.getSourceFiles()];
585
359
  const sourceFiles = fullProgramSourceFiles.filter((f) => !f.isDeclarationFile &&
586
360
  // Note `isShim` will work for the initial program, but for TCB programs, the shims are no longer annotated.
587
- !project_tsconfig_paths.isShim(f) &&
361
+ !migrations.isShim(f) &&
588
362
  !f.fileName.endsWith('.ngtypecheck.ts'));
589
363
  // Sort it by length in reverse order (longest first). This speeds up lookups,
590
364
  // since there's no need to keep going through the array once a match is found.
591
- const sortedRootDirs = project_tsconfig_paths.getRootDirs(baseInfo.host, baseInfo.userOptions).sort((a, b) => b.length - a.length);
365
+ const sortedRootDirs = migrations.getRootDirs(baseInfo.host, baseInfo.userOptions).sort((a, b) => b.length - a.length);
592
366
  // TODO: Consider also following TS's logic here, finding the common source root.
593
367
  // See: Program#getCommonSourceDirectory.
594
- const primaryRoot = project_tsconfig_paths.absoluteFrom(baseInfo.userOptions.rootDir ?? sortedRootDirs.at(-1) ?? baseInfo.program.getCurrentDirectory());
368
+ const primaryRoot = compilerCli.absoluteFrom(baseInfo.userOptions.rootDir ?? sortedRootDirs.at(-1) ?? baseInfo.program.getCurrentDirectory());
595
369
  return {
596
370
  ...baseInfo,
597
371
  sourceFiles,
@@ -648,13 +422,6 @@ class TsurgeFunnelMigration extends TsurgeBaseMigration {
648
422
  class TsurgeComplexMigration extends TsurgeBaseMigration {
649
423
  }
650
424
 
651
- /*!
652
- * @license
653
- * Copyright Google LLC All Rights Reserved.
654
- *
655
- * Use of this source code is governed by an MIT-style license that can be
656
- * found in the LICENSE file at https://angular.dev/license
657
- */
658
425
  exports.MigrationStage = void 0;
659
426
  (function (MigrationStage) {
660
427
  /** The migration is analyzing an entrypoint */
@@ -670,7 +437,7 @@ async function runMigrationInDevkit(config) {
670
437
  }
671
438
  const tsconfigPaths = [...buildPaths, ...testPaths];
672
439
  const fs = new DevkitMigrationFilesystem(config.tree);
673
- project_tsconfig_paths.setFileSystem(fs);
440
+ compilerCli.setFileSystem(fs);
674
441
  const migration = config.getMigration(fs);
675
442
  const unitResults = [];
676
443
  const isFunnelMigration = migration instanceof TsurgeFunnelMigration;
@@ -780,7 +547,7 @@ function confirmAsSerializable(data) {
780
547
  * See {@link ProjectFile}.
781
548
  */
782
549
  function projectFile(file, { sortedRootDirs, projectRoot }) {
783
- const fs = project_tsconfig_paths.getFileSystem();
550
+ const fs = compilerCli.getFileSystem();
784
551
  const filePath = fs.resolve(typeof file === 'string' ? file : file.fileName);
785
552
  // Sorted root directories are sorted longest to shortest. First match
786
553
  // is the appropriate root directory for ID computation.
@@ -807,7 +574,7 @@ function projectFile(file, { sortedRootDirs, projectRoot }) {
807
574
  * E.g. `a/b/c` is within `a/b` but not within `a/x`.
808
575
  */
809
576
  function isWithinBasePath(fs, base, path) {
810
- return project_tsconfig_paths.isLocalRelativePath(fs.relative(base, path));
577
+ return compilerCli.isLocalRelativePath(fs.relative(base, path));
811
578
  }
812
579
 
813
580
  exports.Replacement = Replacement;