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

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 (56) hide show
  1. package/event_dispatcher.d-pVP0-wST.d.ts +345 -0
  2. package/fesm2022/core.mjs +614 -428
  3. package/fesm2022/core.mjs.map +1 -1
  4. package/fesm2022/injector-BlLwZ2sr.mjs +24 -0
  5. package/fesm2022/injector-BlLwZ2sr.mjs.map +1 -0
  6. package/fesm2022/primitives/di.mjs +5 -18
  7. package/fesm2022/primitives/di.mjs.map +1 -1
  8. package/fesm2022/primitives/event-dispatch.mjs +1 -1
  9. package/fesm2022/primitives/signals.mjs +4 -589
  10. package/fesm2022/primitives/signals.mjs.map +1 -1
  11. package/fesm2022/rxjs-interop.mjs +1 -8
  12. package/fesm2022/rxjs-interop.mjs.map +1 -1
  13. package/fesm2022/testing.mjs +2 -10
  14. package/fesm2022/testing.mjs.map +1 -1
  15. package/fesm2022/untracked-DkcXpNb_.mjs +620 -0
  16. package/fesm2022/untracked-DkcXpNb_.mjs.map +1 -0
  17. package/index.d.ts +7589 -7510
  18. package/{navigation_types.d-u4EOrrdZ.d.ts → navigation_types.d-DgDrF5rp.d.ts} +2 -2
  19. package/package.json +2 -2
  20. package/primitives/di/index.d.ts +25 -10
  21. package/primitives/event-dispatch/index.d.ts +5 -340
  22. package/primitives/signals/index.d.ts +5 -208
  23. package/rxjs-interop/index.d.ts +1 -10
  24. package/schematics/bundles/{apply_import_manager-CyRT0UvU.js → apply_import_manager-CeNv8GIG.js} +6 -6
  25. package/schematics/bundles/{checker-DF8ZaFW5.js → checker-k591b6WQ.js} +856 -180
  26. package/schematics/bundles/cleanup-unused-imports.js +42 -69
  27. package/schematics/bundles/{compiler_host-Da636uJ8.js → compiler_host-DwM3ugW3.js} +2 -2
  28. package/schematics/bundles/control-flow-migration.js +34 -13
  29. package/schematics/bundles/imports-CIX-JgAN.js +1 -1
  30. package/schematics/bundles/{program-BZk27Ndu.js → index-B4OAlHh8.js} +2234 -2097
  31. package/schematics/bundles/{index-DnkWgagp.js → index-BhELUmYx.js} +11 -11
  32. package/schematics/bundles/inject-flags.js +18 -52
  33. package/schematics/bundles/inject-migration.js +3 -3
  34. package/schematics/bundles/leading_space-D9nQ8UQC.js +1 -1
  35. package/schematics/bundles/{migrate_ts_type_references-DtkOnnv0.js → migrate_ts_type_references-Be0TNYen.js} +20 -20
  36. package/schematics/bundles/ng_decorators-DznZ5jMl.js +1 -1
  37. package/schematics/bundles/nodes-B16H9JUd.js +1 -1
  38. package/schematics/bundles/output-migration.js +62 -90
  39. package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.js +1 -1
  40. package/schematics/bundles/property_name-BBwFuqMe.js +1 -1
  41. package/schematics/bundles/route-lazy-loading.js +3 -3
  42. package/schematics/bundles/{project_paths-Jtbi76Bs.js → run_in_devkit-CkvEksWP.js} +262 -197
  43. package/schematics/bundles/self-closing-tags-migration.js +41 -71
  44. package/schematics/bundles/signal-input-migration.js +69 -97
  45. package/schematics/bundles/signal-queries-migration.js +80 -108
  46. package/schematics/bundles/signals.js +11 -11
  47. package/schematics/bundles/standalone-migration.js +8 -22
  48. package/schematics/bundles/symbol-VPWguRxr.js +25 -0
  49. package/schematics/bundles/test-bed-get.js +98 -0
  50. package/schematics/migrations.json +5 -0
  51. package/testing/index.d.ts +2 -4
  52. package/weak_ref.d-BZ7gyRag.d.ts +216 -0
  53. package/fesm2022/weak_ref-DrMdAIDh.mjs +0 -12
  54. package/fesm2022/weak_ref-DrMdAIDh.mjs.map +0 -1
  55. package/schematics/bundles/index-vGJcp5M7.js +0 -30
  56. package/weak_ref.d-ttyj86RV.d.ts +0 -9
@@ -1,36 +1,35 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.2
3
+ * @license Angular v20.0.0-next.4
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
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
9
  var ts = require('typescript');
14
- var checker = require('./checker-DF8ZaFW5.js');
15
- var program = require('./program-BZk27Ndu.js');
10
+ require('os');
11
+ var checker = require('./checker-k591b6WQ.js');
12
+ var index = require('./index-B4OAlHh8.js');
16
13
  require('path');
17
- require('./index-vGJcp5M7.js');
18
- var apply_import_manager = require('./apply_import_manager-CyRT0UvU.js');
14
+ var run_in_devkit = require('./run_in_devkit-CkvEksWP.js');
15
+ var apply_import_manager = require('./apply_import_manager-CeNv8GIG.js');
19
16
  require('@angular-devkit/core');
20
17
  require('node:path/posix');
21
18
  require('fs');
22
19
  require('module');
23
20
  require('url');
21
+ require('@angular-devkit/schematics');
22
+ require('./project_tsconfig_paths-CDVxT6Ov.js');
24
23
 
25
24
  /** Migration that cleans up unused imports from a project. */
26
- class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
25
+ class UnusedImportsMigration extends run_in_devkit.TsurgeFunnelMigration {
27
26
  printer = ts.createPrinter();
28
27
  createProgram(tsconfigAbsPath, fs) {
29
28
  return super.createProgram(tsconfigAbsPath, fs, {
30
29
  extendedDiagnostics: {
31
30
  checks: {
32
31
  // Ensure that the diagnostic is enabled.
33
- unusedStandaloneImports: program.DiagnosticCategoryLabel.Warning,
32
+ unusedStandaloneImports: index.DiagnosticCategoryLabel.Warning,
34
33
  },
35
34
  },
36
35
  });
@@ -62,10 +61,10 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
62
61
  }
63
62
  this.generateReplacements(sourceFile, resolvedLocations, usageAnalysis, info, replacements);
64
63
  });
65
- return project_paths.confirmAsSerializable({ replacements, removedIdentifiers, changedFiles });
64
+ return run_in_devkit.confirmAsSerializable({ replacements, removedIdentifiers, changedFiles });
66
65
  }
67
66
  async migrate(globalData) {
68
- return project_paths.confirmAsSerializable(globalData);
67
+ return run_in_devkit.confirmAsSerializable(globalData);
69
68
  }
70
69
  async combine(unitA, unitB) {
71
70
  const combinedReplacements = [];
@@ -89,14 +88,14 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
89
88
  }
90
89
  }
91
90
  });
92
- return project_paths.confirmAsSerializable({
91
+ return run_in_devkit.confirmAsSerializable({
93
92
  replacements: combinedReplacements,
94
93
  removedIdentifiers: combinedRemovedIdentifiers,
95
94
  changedFiles: changedFileIds.size,
96
95
  });
97
96
  }
98
97
  async globalMeta(combinedData) {
99
- return project_paths.confirmAsSerializable(combinedData);
98
+ return run_in_devkit.confirmAsSerializable(combinedData);
100
99
  }
101
100
  async stats(globalMetadata) {
102
101
  return {
@@ -223,7 +222,7 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
223
222
  const importManager = new checker.ImportManager();
224
223
  // Replace full arrays with empty ones. This allows preserves more of the user's formatting.
225
224
  fullRemovals.forEach((node) => {
226
- replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
225
+ replacements.push(new run_in_devkit.Replacement(run_in_devkit.projectFile(sourceFile, info), new run_in_devkit.TextUpdate({
227
226
  position: node.getStart(),
228
227
  end: node.getEnd(),
229
228
  toInsert: '[]',
@@ -232,7 +231,7 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
232
231
  // Filter out the unused identifiers from an array.
233
232
  partialRemovals.forEach((toRemove, node) => {
234
233
  const newNode = ts.factory.updateArrayLiteralExpression(node, node.elements.filter((el) => !toRemove.has(el)));
235
- replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
234
+ replacements.push(new run_in_devkit.Replacement(run_in_devkit.projectFile(sourceFile, info), new run_in_devkit.TextUpdate({
236
235
  position: node.getStart(),
237
236
  end: node.getEnd(),
238
237
  toInsert: this.printer.printNode(ts.EmitHint.Unspecified, newNode, sourceFile),
@@ -264,59 +263,33 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
264
263
 
265
264
  function migrate() {
266
265
  return async (tree, context) => {
267
- const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
268
- if (!buildPaths.length && !testPaths.length) {
269
- throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot clean up unused imports.');
270
- }
271
- const fs = new project_paths.DevkitMigrationFilesystem(tree);
272
- checker.setFileSystem(fs);
273
- const migration = new UnusedImportsMigration();
274
- const unitResults = [];
275
- const programInfos = [...buildPaths, ...testPaths].map((tsconfigPath) => {
276
- context.logger.info(`Preparing analysis for ${tsconfigPath}`);
277
- const baseInfo = migration.createProgram(tsconfigPath, fs);
278
- const info = migration.prepareProgram(baseInfo);
279
- return { info, tsconfigPath };
266
+ await run_in_devkit.runMigrationInDevkit({
267
+ getMigration: () => new UnusedImportsMigration(),
268
+ tree,
269
+ beforeProgramCreation: (tsconfigPath) => {
270
+ context.logger.info(`Preparing analysis for ${tsconfigPath}`);
271
+ },
272
+ beforeUnitAnalysis: (tsconfigPath) => {
273
+ context.logger.info(`Scanning for unused imports using ${tsconfigPath}`);
274
+ },
275
+ afterAnalysisFailure: () => {
276
+ context.logger.error('Schematic failed unexpectedly with no analysis data');
277
+ },
278
+ whenDone: (stats) => {
279
+ const { removedImports, changedFiles } = stats.counters;
280
+ let statsMessage;
281
+ if (removedImports === 0) {
282
+ statsMessage = 'Schematic could not find unused imports in the project';
283
+ }
284
+ else {
285
+ statsMessage =
286
+ `Removed ${removedImports} import${removedImports !== 1 ? 's' : ''} ` +
287
+ `in ${changedFiles} file${changedFiles !== 1 ? 's' : ''}`;
288
+ }
289
+ context.logger.info('');
290
+ context.logger.info(statsMessage);
291
+ },
280
292
  });
281
- for (const { info, tsconfigPath } of programInfos) {
282
- context.logger.info(`Scanning for unused imports using ${tsconfigPath}`);
283
- unitResults.push(await migration.analyze(info));
284
- }
285
- const combined = await project_paths.synchronouslyCombineUnitData(migration, unitResults);
286
- if (combined === null) {
287
- context.logger.error('Schematic failed unexpectedly with no analysis data');
288
- return;
289
- }
290
- const globalMeta = await migration.globalMeta(combined);
291
- const replacementsPerFile = new Map();
292
- const { replacements } = await migration.migrate(globalMeta);
293
- const changesPerFile = project_paths.groupReplacementsByFile(replacements);
294
- for (const [file, changes] of changesPerFile) {
295
- if (!replacementsPerFile.has(file)) {
296
- replacementsPerFile.set(file, changes);
297
- }
298
- }
299
- for (const [file, changes] of replacementsPerFile) {
300
- const recorder = tree.beginUpdate(file);
301
- for (const c of changes) {
302
- recorder
303
- .remove(c.data.position, c.data.end - c.data.position)
304
- .insertRight(c.data.position, c.data.toInsert);
305
- }
306
- tree.commitUpdate(recorder);
307
- }
308
- const { counters: { removedImports, changedFiles }, } = await migration.stats(globalMeta);
309
- let statsMessage;
310
- if (removedImports === 0) {
311
- statsMessage = 'Schematic could not find unused imports in the project';
312
- }
313
- else {
314
- statsMessage =
315
- `Removed ${removedImports} import${removedImports !== 1 ? 's' : ''} ` +
316
- `in ${changedFiles} file${changedFiles !== 1 ? 's' : ''}`;
317
- }
318
- context.logger.info('');
319
- context.logger.info(statsMessage);
320
293
  };
321
294
  }
322
295
 
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.2
3
+ * @license Angular v20.0.0-next.4
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
8
 
9
9
  var ts = require('typescript');
10
- var checker = require('./checker-DF8ZaFW5.js');
10
+ var checker = require('./checker-k591b6WQ.js');
11
11
  require('os');
12
12
  var p = require('path');
13
13
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.2
3
+ * @license Angular v20.0.0-next.4
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -8,8 +8,8 @@
8
8
 
9
9
  var schematics = require('@angular-devkit/schematics');
10
10
  var p = require('path');
11
- var compiler_host = require('./compiler_host-Da636uJ8.js');
12
- var checker = require('./checker-DF8ZaFW5.js');
11
+ var compiler_host = require('./compiler_host-DwM3ugW3.js');
12
+ var checker = require('./checker-k591b6WQ.js');
13
13
  var ts = require('typescript');
14
14
  require('os');
15
15
  require('fs');
@@ -680,9 +680,6 @@ function calculateNesting(visitor, hasLineBreaks) {
680
680
  }
681
681
  }
682
682
  }
683
- function escapeRegExp(val) {
684
- return val.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
685
- }
686
683
  /**
687
684
  * determines if a given template string contains line breaks
688
685
  */
@@ -711,18 +708,42 @@ function getTemplates(template) {
711
708
  if (parsed.tree !== undefined) {
712
709
  const visitor = new TemplateCollector();
713
710
  checker.visitAll(visitor, parsed.tree.rootNodes);
714
- // count usages of each ng-template
715
711
  for (let [key, tmpl] of visitor.templates) {
716
- const escapeKey = escapeRegExp(key.slice(1));
717
- const regex = new RegExp(`[^a-zA-Z0-9-<(\']${escapeKey}\\W`, 'gm');
718
- const matches = template.match(regex);
719
- tmpl.count = matches?.length ?? 0;
712
+ tmpl.count = countTemplateUsage(parsed.tree.rootNodes, key);
720
713
  tmpl.generateContents(template);
721
714
  }
722
715
  return visitor.templates;
723
716
  }
724
717
  return new Map();
725
718
  }
719
+ function countTemplateUsage(nodes, templateName) {
720
+ let count = 0;
721
+ let isReferencedInTemplateOutlet = false;
722
+ for (const node of nodes) {
723
+ if (node.attrs) {
724
+ for (const attr of node.attrs) {
725
+ if (attr.name === '*ngTemplateOutlet' && attr.value === templateName.slice(1)) {
726
+ isReferencedInTemplateOutlet = true;
727
+ break;
728
+ }
729
+ if (attr.name.trim() === templateName) {
730
+ count++;
731
+ }
732
+ }
733
+ }
734
+ if (node.children) {
735
+ if (node.name === 'for') {
736
+ for (const child of node.children) {
737
+ if (child.value?.includes(templateName.slice(1))) {
738
+ count++;
739
+ }
740
+ }
741
+ }
742
+ count += countTemplateUsage(node.children, templateName);
743
+ }
744
+ }
745
+ return isReferencedInTemplateOutlet ? count + 2 : count;
746
+ }
726
747
  function updateTemplates(template, templates) {
727
748
  const updatedTemplates = getTemplates(template);
728
749
  for (let [key, tmpl] of updatedTemplates) {
@@ -772,8 +793,8 @@ function processNgTemplates(template, sourceFile) {
772
793
  else {
773
794
  template = template.replace(replaceRegex, t.children);
774
795
  }
775
- // the +1 accounts for the t.count's counting of the original template
776
- if (t.count === matches.length + 1 && safeToRemove) {
796
+ const dist = matches.filter((obj, index, self) => index === self.findIndex((t) => t.input === obj.input));
797
+ if ((t.count === dist.length || t.count - matches.length === 1) && safeToRemove) {
777
798
  const refsInComponentFile = getViewChildOrViewChildrenNames(sourceFile);
778
799
  if (refsInComponentFile?.length > 0) {
779
800
  const templateRefs = getTemplateReferences(template);
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.2
3
+ * @license Angular v20.0.0-next.4
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */