@angular/core 21.0.0-next.7 → 21.0.0-next.9

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 (82) hide show
  1. package/fesm2022/_attribute-chunk.mjs +1 -1
  2. package/fesm2022/_attribute-chunk.mjs.map +1 -1
  3. package/fesm2022/_debug_node-chunk.mjs +722 -569
  4. package/fesm2022/_debug_node-chunk.mjs.map +1 -1
  5. package/fesm2022/_effect-chunk.mjs +512 -48
  6. package/fesm2022/_effect-chunk.mjs.map +1 -1
  7. package/fesm2022/{_root_effect_scheduler-chunk.mjs → _effect-chunk2.mjs} +202 -19
  8. package/fesm2022/_effect-chunk2.mjs.map +1 -0
  9. package/fesm2022/_not_found-chunk.mjs +1 -1
  10. package/fesm2022/_not_found-chunk.mjs.map +1 -1
  11. package/fesm2022/_resource-chunk.mjs +5 -173
  12. package/fesm2022/_resource-chunk.mjs.map +1 -1
  13. package/fesm2022/_untracked-chunk.mjs +117 -0
  14. package/fesm2022/_untracked-chunk.mjs.map +1 -0
  15. package/fesm2022/_weak_ref-chunk.mjs +1 -1
  16. package/fesm2022/_weak_ref-chunk.mjs.map +1 -1
  17. package/fesm2022/core.mjs +15 -18
  18. package/fesm2022/core.mjs.map +1 -1
  19. package/fesm2022/primitives-di.mjs +1 -1
  20. package/fesm2022/primitives-di.mjs.map +1 -1
  21. package/fesm2022/primitives-event-dispatch.mjs +1 -1
  22. package/fesm2022/primitives-event-dispatch.mjs.map +1 -1
  23. package/fesm2022/primitives-signals.mjs +4 -4
  24. package/fesm2022/primitives-signals.mjs.map +1 -1
  25. package/fesm2022/rxjs-interop.mjs +5 -5
  26. package/fesm2022/rxjs-interop.mjs.map +1 -1
  27. package/fesm2022/testing.mjs +3 -3
  28. package/fesm2022/testing.mjs.map +1 -1
  29. package/package.json +2 -2
  30. package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +5 -5
  31. package/schematics/bundles/application-config-core.cjs +5 -5
  32. package/schematics/bundles/{apply_import_manager-D_4NSuRa.cjs → apply_import_manager-CoeTX_Ob.cjs} +3 -3
  33. package/schematics/bundles/bootstrap-options-migration.cjs +5 -5
  34. package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
  35. package/schematics/bundles/common-to-standalone-migration.cjs +385 -0
  36. package/schematics/bundles/{compiler_host-C1KRWoxv.cjs → compiler_host-emLDwK2U.cjs} +2 -2
  37. package/schematics/bundles/control-flow-migration.cjs +4 -4
  38. package/schematics/bundles/imports-DwPXlGFl.cjs +1 -1
  39. package/schematics/bundles/{index-DYqR8Lpq.cjs → index-CLxYZ09c.cjs} +4 -4
  40. package/schematics/bundles/{index-BFENxhdR.cjs → index-Dvqnp6JS.cjs} +391 -152
  41. package/schematics/bundles/inject-migration.cjs +3 -3
  42. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  43. package/schematics/bundles/{migrate_ts_type_references-CemH7A8e.cjs → migrate_ts_type_references-CpM5FPGa.cjs} +47 -5
  44. package/schematics/bundles/{ng_component_template-AYs8YXuT.cjs → ng_component_template-BRbBIAUX.cjs} +2 -2
  45. package/schematics/bundles/ng_decorators-BI0uV7KI.cjs +1 -1
  46. package/schematics/bundles/ngclass-to-class-migration.cjs +7 -7
  47. package/schematics/bundles/ngstyle-to-style-migration.cjs +7 -7
  48. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  49. package/schematics/bundles/output-migration.cjs +6 -6
  50. package/schematics/bundles/{parse_html-6-AB4O-A.cjs → parse_html-CPWfkfhR.cjs} +2 -2
  51. package/schematics/bundles/{project_paths-EiOrjlNS.cjs → project_paths-C8H7KDJ3.cjs} +3 -3
  52. package/schematics/bundles/{project_tsconfig_paths-BbVhi4fG.cjs → project_tsconfig_paths-CiBzGSIa.cjs} +335 -47
  53. package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
  54. package/schematics/bundles/route-lazy-loading.cjs +3 -3
  55. package/schematics/bundles/router-current-navigation.cjs +4 -4
  56. package/schematics/bundles/router-last-successful-navigation.cjs +4 -4
  57. package/schematics/bundles/router-testing-module-migration.cjs +513 -0
  58. package/schematics/bundles/self-closing-tags-migration.cjs +6 -6
  59. package/schematics/bundles/signal-input-migration.cjs +7 -7
  60. package/schematics/bundles/signal-queries-migration.cjs +7 -7
  61. package/schematics/bundles/signals.cjs +7 -7
  62. package/schematics/bundles/standalone-migration.cjs +4 -4
  63. package/schematics/bundles/symbol-BObKoqes.cjs +1 -1
  64. package/schematics/collection.json +11 -0
  65. package/schematics/migrations/common-to-standalone-migration/schema.json +14 -0
  66. package/schematics/migrations/router-testing-module-migration/schema.json +14 -0
  67. package/types/_api-chunk.d.ts +1 -1
  68. package/types/_chrome_dev_tools_performance-chunk.d.ts +22 -12
  69. package/types/_discovery-chunk.d.ts +58 -10
  70. package/types/_effect-chunk.d.ts +1 -1
  71. package/types/_event_dispatcher-chunk.d.ts +1 -1
  72. package/types/_formatter-chunk.d.ts +4 -3
  73. package/types/_weak_ref-chunk.d.ts +1 -1
  74. package/types/core.d.ts +68 -33
  75. package/types/primitives-di.d.ts +1 -1
  76. package/types/primitives-event-dispatch.d.ts +1 -1
  77. package/types/primitives-signals.d.ts +2 -2
  78. package/types/rxjs-interop.d.ts +1 -1
  79. package/types/testing.d.ts +1 -1
  80. package/fesm2022/_root_effect_scheduler-chunk.mjs.map +0 -1
  81. package/fesm2022/_signal-chunk.mjs +0 -581
  82. package/fesm2022/_signal-chunk.mjs.map +0 -1
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v21.0.0-next.7
3
+ * @license Angular v21.0.0-next.9
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-BbVhi4fG.cjs');
9
+ var project_tsconfig_paths = require('./project_tsconfig_paths-CiBzGSIa.cjs');
10
10
  var ts = require('typescript');
11
11
  var p = require('path');
12
12
  require('os');
@@ -888,7 +888,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
888
888
  function compileDeclareClassMetadata(metadata) {
889
889
  const definitionMap = new project_tsconfig_paths.DefinitionMap();
890
890
  definitionMap.set('minVersion', project_tsconfig_paths.literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
891
- definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.7'));
891
+ definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.9'));
892
892
  definitionMap.set('ngImport', project_tsconfig_paths.importExpr(project_tsconfig_paths.Identifiers.core));
893
893
  definitionMap.set('type', metadata.type);
894
894
  definitionMap.set('decorators', metadata.decorators);
@@ -906,7 +906,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
906
906
  callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? project_tsconfig_paths.literal(null));
907
907
  callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? project_tsconfig_paths.literal(null));
908
908
  definitionMap.set('minVersion', project_tsconfig_paths.literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
909
- definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.7'));
909
+ definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.9'));
910
910
  definitionMap.set('ngImport', project_tsconfig_paths.importExpr(project_tsconfig_paths.Identifiers.core));
911
911
  definitionMap.set('type', metadata.type);
912
912
  definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
@@ -1001,7 +1001,7 @@ function createDirectiveDefinitionMap(meta) {
1001
1001
  const definitionMap = new project_tsconfig_paths.DefinitionMap();
1002
1002
  const minVersion = getMinimumVersionForPartialOutput(meta);
1003
1003
  definitionMap.set('minVersion', project_tsconfig_paths.literal(minVersion));
1004
- definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.7'));
1004
+ definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.9'));
1005
1005
  // e.g. `type: MyDirective`
1006
1006
  definitionMap.set('type', meta.type.value);
1007
1007
  if (meta.isStandalone !== undefined) {
@@ -1414,7 +1414,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
1414
1414
  function compileDeclareFactoryFunction(meta) {
1415
1415
  const definitionMap = new project_tsconfig_paths.DefinitionMap();
1416
1416
  definitionMap.set('minVersion', project_tsconfig_paths.literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
1417
- definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.7'));
1417
+ definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.9'));
1418
1418
  definitionMap.set('ngImport', project_tsconfig_paths.importExpr(project_tsconfig_paths.Identifiers.core));
1419
1419
  definitionMap.set('type', meta.type.value);
1420
1420
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -1449,7 +1449,7 @@ function compileDeclareInjectableFromMetadata(meta) {
1449
1449
  function createInjectableDefinitionMap(meta) {
1450
1450
  const definitionMap = new project_tsconfig_paths.DefinitionMap();
1451
1451
  definitionMap.set('minVersion', project_tsconfig_paths.literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
1452
- definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.7'));
1452
+ definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.9'));
1453
1453
  definitionMap.set('ngImport', project_tsconfig_paths.importExpr(project_tsconfig_paths.Identifiers.core));
1454
1454
  definitionMap.set('type', meta.type.value);
1455
1455
  // Only generate providedIn property if it has a non-null value
@@ -1500,7 +1500,7 @@ function compileDeclareInjectorFromMetadata(meta) {
1500
1500
  function createInjectorDefinitionMap(meta) {
1501
1501
  const definitionMap = new project_tsconfig_paths.DefinitionMap();
1502
1502
  definitionMap.set('minVersion', project_tsconfig_paths.literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
1503
- definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.7'));
1503
+ definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.9'));
1504
1504
  definitionMap.set('ngImport', project_tsconfig_paths.importExpr(project_tsconfig_paths.Identifiers.core));
1505
1505
  definitionMap.set('type', meta.type.value);
1506
1506
  definitionMap.set('providers', meta.providers);
@@ -1533,7 +1533,7 @@ function createNgModuleDefinitionMap(meta) {
1533
1533
  throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
1534
1534
  }
1535
1535
  definitionMap.set('minVersion', project_tsconfig_paths.literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
1536
- definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.7'));
1536
+ definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.9'));
1537
1537
  definitionMap.set('ngImport', project_tsconfig_paths.importExpr(project_tsconfig_paths.Identifiers.core));
1538
1538
  definitionMap.set('type', meta.type.value);
1539
1539
  // We only generate the keys in the metadata if the arrays contain values.
@@ -1584,7 +1584,7 @@ function compileDeclarePipeFromMetadata(meta) {
1584
1584
  function createPipeDefinitionMap(meta) {
1585
1585
  const definitionMap = new project_tsconfig_paths.DefinitionMap();
1586
1586
  definitionMap.set('minVersion', project_tsconfig_paths.literal(MINIMUM_PARTIAL_LINKER_VERSION));
1587
- definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.7'));
1587
+ definitionMap.set('version', project_tsconfig_paths.literal('21.0.0-next.9'));
1588
1588
  definitionMap.set('ngImport', project_tsconfig_paths.importExpr(project_tsconfig_paths.Identifiers.core));
1589
1589
  // e.g. `type: MyPipe`
1590
1590
  definitionMap.set('type', meta.type.value);
@@ -5617,7 +5617,7 @@ class InjectableClassRegistry {
5617
5617
  * If no such metadata is present, this function returns `null`. Otherwise, the call is returned
5618
5618
  * as a `Statement` for inclusion along with the class.
5619
5619
  */
5620
- function extractClassMetadata(clazz, reflection, isCore, annotateForClosureCompiler, angularDecoratorTransform = (dec) => dec) {
5620
+ function extractClassMetadata(clazz, reflection, isCore, annotateForClosureCompiler, angularDecoratorTransform = (dec) => dec, undecoratedMetadataExtractor = () => null) {
5621
5621
  if (!reflection.isClass(clazz)) {
5622
5622
  return null;
5623
5623
  }
@@ -5651,21 +5651,47 @@ function extractClassMetadata(clazz, reflection, isCore, annotateForClosureCompi
5651
5651
  // Do the same for property decorators.
5652
5652
  let metaPropDecorators = null;
5653
5653
  const classMembers = reflection.getMembersOfClass(clazz).filter((member) => !member.isStatic &&
5654
- member.decorators !== null &&
5655
- member.decorators.length > 0 &&
5656
5654
  // Private fields are not supported in the metadata emit
5657
5655
  member.accessLevel !== project_tsconfig_paths.ClassMemberAccessLevel.EcmaScriptPrivate);
5658
- const duplicateDecoratedMembers = classMembers.filter((member, i, arr) => arr.findIndex((arrayMember) => arrayMember.name === member.name) < i);
5659
- if (duplicateDecoratedMembers.length > 0) {
5656
+ const decoratedMembers = [];
5657
+ const seenMemberNames = new Set();
5658
+ let duplicateDecoratedMembers = null;
5659
+ for (const member of classMembers) {
5660
+ const shouldQuoteName = member.nameNode !== null && ts.isStringLiteralLike(member.nameNode);
5661
+ if (member.decorators !== null && member.decorators.length > 0) {
5662
+ decoratedMembers.push({
5663
+ key: member.name,
5664
+ quoted: shouldQuoteName,
5665
+ value: decoratedClassMemberToMetadata(member.decorators, isCore),
5666
+ });
5667
+ if (seenMemberNames.has(member.name)) {
5668
+ duplicateDecoratedMembers ??= [];
5669
+ duplicateDecoratedMembers.push(member);
5670
+ }
5671
+ else {
5672
+ seenMemberNames.add(member.name);
5673
+ }
5674
+ }
5675
+ else {
5676
+ const undecoratedMetadata = undecoratedMetadataExtractor(member);
5677
+ if (undecoratedMetadata !== null) {
5678
+ decoratedMembers.push({
5679
+ key: member.name,
5680
+ quoted: shouldQuoteName,
5681
+ value: undecoratedMetadata,
5682
+ });
5683
+ }
5684
+ }
5685
+ }
5686
+ if (duplicateDecoratedMembers !== null) {
5660
5687
  // This should theoretically never happen, because the only way to have duplicate instance
5661
5688
  // member names is getter/setter pairs and decorators cannot appear in both a getter and the
5662
5689
  // corresponding setter.
5663
5690
  throw new project_tsconfig_paths.FatalDiagnosticError(project_tsconfig_paths.ErrorCode.DUPLICATE_DECORATED_PROPERTIES, duplicateDecoratedMembers[0].nameNode ?? clazz, `Duplicate decorated properties found on class '${clazz.name.text}': ` +
5664
5691
  duplicateDecoratedMembers.map((member) => member.name).join(', '));
5665
5692
  }
5666
- const decoratedMembers = classMembers.map((member) => classMemberToMetadata(member.nameNode ?? member.name, member.decorators, isCore));
5667
5693
  if (decoratedMembers.length > 0) {
5668
- metaPropDecorators = new project_tsconfig_paths.WrappedNodeExpr(ts.factory.createObjectLiteralExpression(decoratedMembers));
5694
+ metaPropDecorators = project_tsconfig_paths.literalMap(decoratedMembers);
5669
5695
  }
5670
5696
  return {
5671
5697
  type: new project_tsconfig_paths.WrappedNodeExpr(id),
@@ -5699,12 +5725,11 @@ function ctorParameterToMetadata(param, isCore) {
5699
5725
  /**
5700
5726
  * Convert a reflected class member to metadata.
5701
5727
  */
5702
- function classMemberToMetadata(name, decorators, isCore) {
5728
+ function decoratedClassMemberToMetadata(decorators, isCore) {
5703
5729
  const ngDecorators = decorators
5704
5730
  .filter((dec) => isAngularDecorator$1(dec, isCore))
5705
- .map((decorator) => decoratorToMetadata(decorator));
5706
- const decoratorMeta = ts.factory.createArrayLiteralExpression(ngDecorators);
5707
- return ts.factory.createPropertyAssignment(name, decoratorMeta);
5731
+ .map((decorator) => new project_tsconfig_paths.WrappedNodeExpr(decoratorToMetadata(decorator)));
5732
+ return new project_tsconfig_paths.LiteralArrayExpr(ngDecorators);
5708
5733
  }
5709
5734
  /**
5710
5735
  * Convert a reflected decorator to metadata.
@@ -7879,9 +7904,11 @@ class DirectiveDecoratorHandler {
7879
7904
  this.usePoisonedData = usePoisonedData;
7880
7905
  this.typeCheckHostBindings = typeCheckHostBindings;
7881
7906
  this.emitDeclarationOnly = emitDeclarationOnly;
7907
+ this.undecoratedMetadataExtractor = project_tsconfig_paths.getDirectiveUndecoratedMetadataExtractor(reflector, importTracker);
7882
7908
  }
7883
7909
  precedence = project_tsconfig_paths.HandlerPrecedence.PRIMARY;
7884
7910
  name = 'DirectiveDecoratorHandler';
7911
+ undecoratedMetadataExtractor;
7885
7912
  detect(node, decorators) {
7886
7913
  // If a class is undecorated but uses Angular features, we detect it as an
7887
7914
  // abstract directive. This is an unsupported pattern as of v10, but we want
@@ -7934,7 +7961,7 @@ class DirectiveDecoratorHandler {
7934
7961
  hostDirectives: directiveResult.hostDirectives,
7935
7962
  rawHostDirectives: directiveResult.rawHostDirectives,
7936
7963
  classMetadata: this.includeClassMetadata
7937
- ? extractClassMetadata(node, this.reflector, this.isCore, this.annotateForClosureCompiler)
7964
+ ? extractClassMetadata(node, this.reflector, this.isCore, this.annotateForClosureCompiler, undefined, this.undecoratedMetadataExtractor)
7938
7965
  : null,
7939
7966
  baseClass: project_tsconfig_paths.readBaseClass(node, this.reflector, this.evaluator),
7940
7967
  typeCheckMeta: project_tsconfig_paths.extractDirectiveTypeCheckMeta(node, directiveResult.inputs, this.reflector),
@@ -10156,6 +10183,45 @@ class SelectorlessDirectivesAnalyzer extends project_tsconfig_paths.CombinedRecu
10156
10183
  }
10157
10184
  }
10158
10185
 
10186
+ /*!
10187
+ * @license
10188
+ * Copyright Google LLC All Rights Reserved.
10189
+ *
10190
+ * Use of this source code is governed by an MIT-style license that can be
10191
+ * found in the LICENSE file at https://angular.dev/license
10192
+ */
10193
+ const ANIMATE_ENTER = 'animate.enter';
10194
+ const ANIMATE_LEAVE = `animate.leave`;
10195
+ /**
10196
+ * Analyzes a component's template to determine if it's using animate.enter
10197
+ * or animate.leave syntax.
10198
+ */
10199
+ function analyzeTemplateForAnimations(template) {
10200
+ const analyzer = new AnimationsAnalyzer();
10201
+ project_tsconfig_paths.visitAll(analyzer, template);
10202
+ return { hasAnimations: analyzer.hasAnimations };
10203
+ }
10204
+ /**
10205
+ * Visitor that traverses all the template nodes and
10206
+ * expressions to look for animation references.
10207
+ */
10208
+ class AnimationsAnalyzer extends project_tsconfig_paths.CombinedRecursiveAstVisitor {
10209
+ hasAnimations = false;
10210
+ visitElement(element) {
10211
+ for (const attr of element.attributes) {
10212
+ if (attr.name === ANIMATE_LEAVE || attr.name === ANIMATE_ENTER) {
10213
+ this.hasAnimations = true;
10214
+ }
10215
+ }
10216
+ for (const input of element.inputs) {
10217
+ if (input.name === ANIMATE_LEAVE || input.name === ANIMATE_ENTER) {
10218
+ this.hasAnimations = true;
10219
+ }
10220
+ }
10221
+ super.visitElement(element);
10222
+ }
10223
+ }
10224
+
10159
10225
  const EMPTY_ARRAY = [];
10160
10226
  const isUsedDirective = (decl) => decl.kind === project_tsconfig_paths.R3TemplateDependencyKind.Directive;
10161
10227
  const isUsedPipe = (decl) => decl.kind === project_tsconfig_paths.R3TemplateDependencyKind.Pipe;
@@ -10265,6 +10331,7 @@ class ComponentDecoratorHandler {
10265
10331
  enableSelectorless: this.enableSelectorless,
10266
10332
  preserveSignificantWhitespace: this.i18nPreserveSignificantWhitespace,
10267
10333
  };
10334
+ this.undecoratedMetadataExtractor = project_tsconfig_paths.getDirectiveUndecoratedMetadataExtractor(reflector, importTracker);
10268
10335
  // Dependencies can't be deferred during HMR, because the HMR update module can't have
10269
10336
  // dynamic imports and its dependencies need to be passed in directly. If dependencies
10270
10337
  // are deferred, their imports will be deleted so we may lose the reference to them.
@@ -10272,6 +10339,7 @@ class ComponentDecoratorHandler {
10272
10339
  }
10273
10340
  literalCache = new Map();
10274
10341
  elementSchemaRegistry = new project_tsconfig_paths.DomElementSchemaRegistry();
10342
+ undecoratedMetadataExtractor;
10275
10343
  /**
10276
10344
  * During the asynchronous preanalyze phase, it's necessary to parse the template to extract
10277
10345
  * any potential <link> tags which might need to be loaded. This cache ensures that work is not
@@ -10566,6 +10634,16 @@ class ComponentDecoratorHandler {
10566
10634
  }
10567
10635
  }
10568
10636
  }
10637
+ if (component.has('animations')) {
10638
+ const { hasAnimations } = analyzeTemplateForAnimations(template.nodes);
10639
+ if (hasAnimations) {
10640
+ if (diagnostics === undefined) {
10641
+ diagnostics = [];
10642
+ }
10643
+ diagnostics.push(project_tsconfig_paths.makeDiagnostic(project_tsconfig_paths.ErrorCode.COMPONENT_ANIMATIONS_CONFLICT, component.get('animations'), `A component cannot have both the '@Component.animations' property (legacy animations) and use 'animate.enter' or 'animate.leave' in the template.`));
10644
+ isPoisoned = true;
10645
+ }
10646
+ }
10569
10647
  const templateResource = template.declaration.isInline
10570
10648
  ? { path: null, node: component.get('template') }
10571
10649
  : {
@@ -10731,7 +10809,7 @@ class ComponentDecoratorHandler {
10731
10809
  },
10732
10810
  typeCheckMeta: project_tsconfig_paths.extractDirectiveTypeCheckMeta(node, inputs, this.reflector),
10733
10811
  classMetadata: this.includeClassMetadata
10734
- ? extractClassMetadata(node, this.reflector, this.isCore, this.annotateForClosureCompiler, (dec) => transformDecoratorResources(dec, component, styles, template))
10812
+ ? extractClassMetadata(node, this.reflector, this.isCore, this.annotateForClosureCompiler, (dec) => transformDecoratorResources(dec, component, styles, template), this.undecoratedMetadataExtractor)
10735
10813
  : null,
10736
10814
  classDebugInfo: extractClassDebugInfo(node, this.reflector, this.compilerHost, this.rootDirs,
10737
10815
  /* forbidOrphanRenderering */ this.forbidOrphanRendering),
@@ -12321,7 +12399,7 @@ class PipeDecoratorHandler {
12321
12399
  * @description
12322
12400
  * Entry point for all public APIs of the compiler-cli package.
12323
12401
  */
12324
- new project_tsconfig_paths.Version('21.0.0-next.7');
12402
+ new project_tsconfig_paths.Version('21.0.0-next.9');
12325
12403
 
12326
12404
  /**
12327
12405
  * Whether a given decorator should be treated as an Angular decorator.
@@ -13511,21 +13589,6 @@ var MemberTags;
13511
13589
  MemberTags["Inherited"] = "override";
13512
13590
  })(MemberTags || (MemberTags = {}));
13513
13591
 
13514
- /** Gets whether a symbol's name indicates it is an Angular-private API. */
13515
- function isAngularPrivateName(name) {
13516
- const firstChar = name[0] ?? '';
13517
- return firstChar === 'ɵ' || firstChar === '_';
13518
- }
13519
-
13520
- /** Gets a list of all the generic type parameters for a declaration. */
13521
- function extractGenerics(declaration) {
13522
- return (declaration.typeParameters?.map((typeParam) => ({
13523
- name: typeParam.name.getText(),
13524
- constraint: typeParam.constraint?.getText(),
13525
- default: typeParam.default?.getText(),
13526
- })) ?? []);
13527
- }
13528
-
13529
13592
  /**
13530
13593
  * RegExp to match the `@` character follow by any Angular decorator, used to escape Angular
13531
13594
  * decorators in JsDoc blocks so that they're not parsed as JsDoc tags.
@@ -13592,6 +13655,21 @@ function unescapeAngularDecorators(comment) {
13592
13655
  return comment.replace(/_NG_AT_/g, '@');
13593
13656
  }
13594
13657
 
13658
+ /** Gets whether a symbol's name indicates it is an Angular-private API. */
13659
+ function isAngularPrivateName(name) {
13660
+ const firstChar = name[0] ?? '';
13661
+ return firstChar === 'ɵ' || firstChar === '_';
13662
+ }
13663
+
13664
+ /** Gets a list of all the generic type parameters for a declaration. */
13665
+ function extractGenerics(declaration) {
13666
+ return (declaration.typeParameters?.map((typeParam) => ({
13667
+ name: typeParam.name.getText(),
13668
+ constraint: typeParam.constraint?.getText(),
13669
+ default: typeParam.default?.getText(),
13670
+ })) ?? []);
13671
+ }
13672
+
13595
13673
  /** Gets the string representation of a node's resolved type. */
13596
13674
  function extractResolvedTypeString(node, checker) {
13597
13675
  return checker.typeToString(checker.getTypeAtLocation(node), undefined, ts.TypeFormatFlags.NoTruncation);
@@ -13736,7 +13814,7 @@ function hasLeadingInternalComment(member) {
13736
13814
  }
13737
13815
 
13738
13816
  /** Extractor to pull info for API reference documentation for a TypeScript class or interface. */
13739
- class ClassExtractor {
13817
+ class PropertiesExtractor {
13740
13818
  declaration;
13741
13819
  typeChecker;
13742
13820
  constructor(declaration, typeChecker) {
@@ -13746,18 +13824,8 @@ class ClassExtractor {
13746
13824
  /** Extract docs info specific to classes. */
13747
13825
  extract() {
13748
13826
  return {
13749
- name: this.declaration.name.text,
13750
- isAbstract: this.isAbstract(),
13751
- entryType: ts.isInterfaceDeclaration(this.declaration)
13752
- ? EntryType.Interface
13753
- : EntryType.UndecoratedClass,
13754
13827
  members: this.extractSignatures().concat(this.extractAllClassMembers()),
13755
13828
  generics: extractGenerics(this.declaration),
13756
- description: extractJsDocDescription(this.declaration),
13757
- jsdocTags: extractJsDocTags(this.declaration),
13758
- rawComment: extractRawJsDoc(this.declaration),
13759
- extends: this.extractInheritance(this.declaration),
13760
- implements: this.extractInterfaceConformance(this.declaration),
13761
13829
  };
13762
13830
  }
13763
13831
  /** Extracts doc info for a class's members. */
@@ -13844,22 +13912,6 @@ class ClassExtractor {
13844
13912
  memberTags: this.getMemberTags(constructorDeclaration),
13845
13913
  };
13846
13914
  }
13847
- extractInheritance(declaration) {
13848
- if (!declaration.heritageClauses) {
13849
- return undefined;
13850
- }
13851
- for (const clause of declaration.heritageClauses) {
13852
- if (clause.token === ts.SyntaxKind.ExtendsKeyword) {
13853
- // We are assuming a single class can only extend one class.
13854
- const types = clause.types;
13855
- if (types.length > 0) {
13856
- const baseClass = types[0];
13857
- return baseClass.getText();
13858
- }
13859
- }
13860
- }
13861
- return undefined;
13862
- }
13863
13915
  extractInterfaceConformance(declaration) {
13864
13916
  const implementClause = declaration.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ImplementsKeyword);
13865
13917
  return implementClause?.types.map((m) => m.getText()) ?? [];
@@ -14013,11 +14065,6 @@ class ClassExtractor {
14013
14065
  isDocumentableSignature(signature) {
14014
14066
  return (ts.isConstructSignatureDeclaration(signature) || ts.isCallSignatureDeclaration(signature));
14015
14067
  }
14016
- /** Gets whether the declaration for this extractor is abstract. */
14017
- isAbstract() {
14018
- const modifiers = this.declaration.modifiers ?? [];
14019
- return modifiers.some((mod) => mod.kind === ts.SyntaxKind.AbstractKeyword);
14020
- }
14021
14068
  /**
14022
14069
  * Check wether a member has a private computed property name like [ɵWRITABLE_SIGNAL]
14023
14070
  *
@@ -14027,6 +14074,48 @@ class ClassExtractor {
14027
14074
  return (ts.isComputedPropertyName(property.name) && property.name.expression.getText().startsWith('ɵ'));
14028
14075
  }
14029
14076
  }
14077
+
14078
+ /** Extractor to pull info for API reference documentation for a TypeScript class or interface. */
14079
+ class ClassExtractor extends PropertiesExtractor {
14080
+ constructor(declaration, typeChecker) {
14081
+ super(declaration, typeChecker);
14082
+ }
14083
+ /** Extract docs info specific to classes. */
14084
+ extract() {
14085
+ return {
14086
+ name: this.declaration.name.text,
14087
+ isAbstract: this.isAbstract(),
14088
+ entryType: EntryType.UndecoratedClass,
14089
+ ...super.extract(),
14090
+ description: extractJsDocDescription(this.declaration),
14091
+ jsdocTags: extractJsDocTags(this.declaration),
14092
+ rawComment: extractRawJsDoc(this.declaration),
14093
+ extends: this.extractInheritance(this.declaration),
14094
+ implements: this.extractInterfaceConformance(this.declaration),
14095
+ };
14096
+ }
14097
+ /** Gets whether the declaration for this extractor is abstract. */
14098
+ isAbstract() {
14099
+ const modifiers = this.declaration.modifiers ?? [];
14100
+ return modifiers.some((mod) => mod.kind === ts.SyntaxKind.AbstractKeyword);
14101
+ }
14102
+ extractInheritance(declaration) {
14103
+ if (!declaration.heritageClauses) {
14104
+ return undefined;
14105
+ }
14106
+ for (const clause of declaration.heritageClauses) {
14107
+ if (clause.token === ts.SyntaxKind.ExtendsKeyword) {
14108
+ // We are assuming a single class can only extend one class.
14109
+ const types = clause.types;
14110
+ if (types.length > 0) {
14111
+ const baseClass = types[0];
14112
+ return baseClass.getText();
14113
+ }
14114
+ }
14115
+ }
14116
+ return undefined;
14117
+ }
14118
+ }
14030
14119
  /** Extractor to pull info for API reference documentation for an Angular directive. */
14031
14120
  class DirectiveExtractor extends ClassExtractor {
14032
14121
  reference;
@@ -14130,11 +14219,6 @@ function extractClass(classDeclaration, metadataReader, typeChecker) {
14130
14219
  }
14131
14220
  return extractor.extract();
14132
14221
  }
14133
- /** Extracts documentation info for an interface. */
14134
- function extractInterface(declaration, typeChecker) {
14135
- const extractor = new ClassExtractor(declaration, typeChecker);
14136
- return extractor.extract();
14137
- }
14138
14222
  function extractPipeSyntax(metadata, classDeclaration) {
14139
14223
  const transformParams = classDeclaration.members.find((member) => {
14140
14224
  return (ts.isMethodDeclaration(member) &&
@@ -14226,6 +14310,46 @@ function extractLiteralPropertiesAsEnumMembers(declaration) {
14226
14310
  });
14227
14311
  }
14228
14312
 
14313
+ /** Extractor to pull info for API reference documentation for a TypeScript class or interface. */
14314
+ class InterfaceExtractor extends PropertiesExtractor {
14315
+ constructor(declaration, typeChecker) {
14316
+ super(declaration, typeChecker);
14317
+ }
14318
+ /** Extract docs info specific to classes. */
14319
+ extract() {
14320
+ return {
14321
+ name: this.declaration.name.text,
14322
+ entryType: EntryType.Interface,
14323
+ ...super.extract(),
14324
+ description: extractJsDocDescription(this.declaration),
14325
+ jsdocTags: extractJsDocTags(this.declaration),
14326
+ rawComment: extractRawJsDoc(this.declaration),
14327
+ extends: this.extractInheritance(this.declaration),
14328
+ implements: this.extractInterfaceConformance(this.declaration),
14329
+ };
14330
+ }
14331
+ extractInheritance(declaration) {
14332
+ if (!declaration.heritageClauses) {
14333
+ return [];
14334
+ }
14335
+ for (const clause of declaration.heritageClauses) {
14336
+ if (clause.token === ts.SyntaxKind.ExtendsKeyword) {
14337
+ // We are assuming a single class can only extend one class.
14338
+ const types = clause.types;
14339
+ if (types.length > 0) {
14340
+ return types.map((t) => t.getText());
14341
+ }
14342
+ }
14343
+ }
14344
+ return [];
14345
+ }
14346
+ }
14347
+ /** Extracts documentation info for an interface. */
14348
+ function extractInterface(declaration, typeChecker) {
14349
+ const extractor = new InterfaceExtractor(declaration, typeChecker);
14350
+ return extractor.extract();
14351
+ }
14352
+
14229
14353
  /** Extracts an API documentation entry for an Angular decorator. */
14230
14354
  function extractorDecorator(declaration, typeChecker) {
14231
14355
  const documentedNode = getDecoratorJsDocNode(declaration, typeChecker);
@@ -16358,16 +16482,6 @@ function isSignalSymbol(symbol) {
16358
16482
  * This abstract class provides a base implementation for the run method.
16359
16483
  */
16360
16484
  class TemplateCheckWithVisitor {
16361
- /**
16362
- * When extended diagnostics were first introduced, the visitor wasn't implemented correctly
16363
- * which meant that it wasn't visiting the `templateAttrs` of structural directives (e.g.
16364
- * the expression of `*ngIf`). Fixing the issue causes a lot of internal breakages and will likely
16365
- * need to be done in a major version to avoid external breakages. This flag is used to opt out
16366
- * pre-existing diagnostics from the correct behavior until the breakages have been fixed while
16367
- * ensuring that newly-written diagnostics are correct from the beginning.
16368
- * TODO(crisbeto): remove this flag and fix the internal brekages.
16369
- */
16370
- canVisitStructuralAttributes = true;
16371
16485
  /**
16372
16486
  * Base implementation for run function, visits all nodes in template and calls
16373
16487
  * `visitNode()` for each one.
@@ -16406,11 +16520,8 @@ class TemplateVisitor extends project_tsconfig_paths.CombinedRecursiveAstVisitor
16406
16520
  this.visitAllTemplateNodes(template.outputs);
16407
16521
  }
16408
16522
  this.visitAllTemplateNodes(template.directives);
16409
- // TODO(crisbeto): remove this condition when deleting `canVisitStructuralAttributes`.
16410
- if (this.check.canVisitStructuralAttributes || isInlineTemplate) {
16411
- // `templateAttrs` aren't transferred over to the inner element so we always have to visit them.
16412
- this.visitAllTemplateNodes(template.templateAttrs);
16413
- }
16523
+ // `templateAttrs` aren't transferred over to the inner element so we always have to visit them.
16524
+ this.visitAllTemplateNodes(template.templateAttrs);
16414
16525
  this.visitAllTemplateNodes(template.variables);
16415
16526
  this.visitAllTemplateNodes(template.references);
16416
16527
  this.visitAllTemplateNodes(template.children);
@@ -16442,32 +16553,23 @@ class InterpolatedSignalCheck extends TemplateCheckWithVisitor {
16442
16553
  .filter((item) => item instanceof project_tsconfig_paths.PropertyRead)
16443
16554
  .flatMap((item) => buildDiagnosticForSignal(ctx, item, component));
16444
16555
  }
16445
- // bound properties like `[prop]="mySignal"`
16446
- else if (node instanceof project_tsconfig_paths.BoundAttribute) {
16447
- const symbol = ctx.templateTypeChecker.getSymbolOfNode(node, component);
16448
- if (symbol?.kind === project_tsconfig_paths.SymbolKind.Input &&
16449
- symbol.bindings.length > 0 &&
16450
- symbol.bindings.some((binding) => binding.target.kind === project_tsconfig_paths.SymbolKind.Directive)) {
16451
- return [];
16452
- }
16453
- // otherwise, we check if the node is
16454
- const nodeAst = isPropertyReadNodeAst(node);
16455
- if (
16456
- // a bound property like `[prop]="mySignal"`
16457
- (node.type === project_tsconfig_paths.BindingType.Property ||
16458
- // or a class binding like `[class.myClass]="mySignal"`
16459
- node.type === project_tsconfig_paths.BindingType.Class ||
16460
- // or a style binding like `[style.width]="mySignal"`
16461
- node.type === project_tsconfig_paths.BindingType.Style ||
16462
- // or an attribute binding like `[attr.role]="mySignal"`
16463
- node.type === project_tsconfig_paths.BindingType.Attribute ||
16464
- // or an animation binding like `[animate.enter]="mySignal"`
16465
- node.type === project_tsconfig_paths.BindingType.Animation ||
16466
- // or an animation binding like `[@myAnimation]="mySignal"`
16467
- node.type === project_tsconfig_paths.BindingType.LegacyAnimation) &&
16468
- nodeAst) {
16469
- return buildDiagnosticForSignal(ctx, nodeAst, component);
16470
- }
16556
+ // check bound inputs like `[prop]="mySignal"` on an element or inline template
16557
+ else if (node instanceof project_tsconfig_paths.Element$1 && node.inputs.length > 0) {
16558
+ const directivesOfElement = ctx.templateTypeChecker.getDirectivesOfNode(component, node);
16559
+ return node.inputs.flatMap((input) => checkBoundAttribute(ctx, component, directivesOfElement, input));
16560
+ }
16561
+ else if (node instanceof project_tsconfig_paths.Template && node.tagName === 'ng-template') {
16562
+ const directivesOfElement = ctx.templateTypeChecker.getDirectivesOfNode(component, node);
16563
+ const inputDiagnostics = node.inputs.flatMap((input) => {
16564
+ return checkBoundAttribute(ctx, component, directivesOfElement, input);
16565
+ });
16566
+ const templateAttrDiagnostics = node.templateAttrs.flatMap((attr) => {
16567
+ if (!(attr instanceof project_tsconfig_paths.BoundAttribute)) {
16568
+ return [];
16569
+ }
16570
+ return checkBoundAttribute(ctx, component, directivesOfElement, attr);
16571
+ });
16572
+ return inputDiagnostics.concat(templateAttrDiagnostics);
16471
16573
  }
16472
16574
  // if blocks like `@if(mySignal) { ... }`
16473
16575
  else if (node instanceof project_tsconfig_paths.IfBlock) {
@@ -16493,6 +16595,32 @@ class InterpolatedSignalCheck extends TemplateCheckWithVisitor {
16493
16595
  return [];
16494
16596
  }
16495
16597
  }
16598
+ function checkBoundAttribute(ctx, component, directivesOfElement, node) {
16599
+ // we skip the check if the node is an input binding
16600
+ if (directivesOfElement !== null &&
16601
+ directivesOfElement.some((dir) => dir.inputs.getByBindingPropertyName(node.name) !== null)) {
16602
+ return [];
16603
+ }
16604
+ // otherwise, we check if the node is
16605
+ const nodeAst = isPropertyReadNodeAst(node);
16606
+ if (
16607
+ // a bound property like `[prop]="mySignal"`
16608
+ (node.type === project_tsconfig_paths.BindingType.Property ||
16609
+ // or a class binding like `[class.myClass]="mySignal"`
16610
+ node.type === project_tsconfig_paths.BindingType.Class ||
16611
+ // or a style binding like `[style.width]="mySignal"`
16612
+ node.type === project_tsconfig_paths.BindingType.Style ||
16613
+ // or an attribute binding like `[attr.role]="mySignal"`
16614
+ node.type === project_tsconfig_paths.BindingType.Attribute ||
16615
+ // or an animation binding like `[animate.enter]="mySignal"`
16616
+ node.type === project_tsconfig_paths.BindingType.Animation ||
16617
+ // or an animation binding like `[@myAnimation]="mySignal"`
16618
+ node.type === project_tsconfig_paths.BindingType.LegacyAnimation) &&
16619
+ nodeAst) {
16620
+ return buildDiagnosticForSignal(ctx, nodeAst, component);
16621
+ }
16622
+ return [];
16623
+ }
16496
16624
  function isPropertyReadNodeAst(node) {
16497
16625
  if (node.value instanceof project_tsconfig_paths.ASTWithSource === false) {
16498
16626
  return undefined;
@@ -16525,9 +16653,11 @@ function buildDiagnosticForSignal(ctx, node, component) {
16525
16653
  // error.
16526
16654
  // We also check for `{{ mySignal.set }}` or `{{ mySignal.update }}` or
16527
16655
  // `{{ mySignal.asReadonly }}` as these are the names of instance properties of Signal
16656
+ if (!isFunctionInstanceProperty(node.name) && !isSignalInstanceProperty(node.name)) {
16657
+ return [];
16658
+ }
16528
16659
  const symbolOfReceiver = ctx.templateTypeChecker.getSymbolOfNode(node.receiver, component);
16529
- if ((isFunctionInstanceProperty(node.name) || isSignalInstanceProperty(node.name)) &&
16530
- symbolOfReceiver !== null &&
16660
+ if (symbolOfReceiver !== null &&
16531
16661
  symbolOfReceiver.kind === project_tsconfig_paths.SymbolKind.Expression &&
16532
16662
  isSignalReference(symbolOfReceiver)) {
16533
16663
  const templateMapping = ctx.templateTypeChecker.getSourceMappingAtTcbLocation(symbolOfReceiver.tcbLocation);
@@ -16537,7 +16667,7 @@ function buildDiagnosticForSignal(ctx, node, component) {
16537
16667
  }
16538
16668
  return [];
16539
16669
  }
16540
- const factory$e = {
16670
+ const factory$f = {
16541
16671
  code: project_tsconfig_paths.ErrorCode.INTERPOLATED_SIGNAL_NOT_INVOKED,
16542
16672
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.INTERPOLATED_SIGNAL_NOT_INVOKED,
16543
16673
  create: () => new InterpolatedSignalCheck(),
@@ -16563,7 +16693,7 @@ class InvalidBananaInBoxCheck extends TemplateCheckWithVisitor {
16563
16693
  return [diagnostic];
16564
16694
  }
16565
16695
  }
16566
- const factory$d = {
16696
+ const factory$e = {
16567
16697
  code: project_tsconfig_paths.ErrorCode.INVALID_BANANA_IN_BOX,
16568
16698
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.INVALID_BANANA_IN_BOX,
16569
16699
  create: () => new InvalidBananaInBoxCheck(),
@@ -16624,7 +16754,7 @@ class MissingControlFlowDirectiveCheck extends TemplateCheckWithVisitor {
16624
16754
  return [diagnostic];
16625
16755
  }
16626
16756
  }
16627
- const factory$c = {
16757
+ const factory$d = {
16628
16758
  code: project_tsconfig_paths.ErrorCode.MISSING_CONTROL_FLOW_DIRECTIVE,
16629
16759
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.MISSING_CONTROL_FLOW_DIRECTIVE,
16630
16760
  create: (options) => {
@@ -16657,7 +16787,7 @@ class MissingNgForOfLetCheck extends TemplateCheckWithVisitor {
16657
16787
  return [diagnostic];
16658
16788
  }
16659
16789
  }
16660
- const factory$b = {
16790
+ const factory$c = {
16661
16791
  code: project_tsconfig_paths.ErrorCode.MISSING_NGFOROF_LET,
16662
16792
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.MISSING_NGFOROF_LET,
16663
16793
  create: () => new MissingNgForOfLetCheck(),
@@ -16675,6 +16805,8 @@ const KNOWN_CONTROL_FLOW_DIRECTIVES = new Set([
16675
16805
  'ngForTrackBy',
16676
16806
  'ngSwitchCase',
16677
16807
  'ngSwitchDefault',
16808
+ 'ngIfThen',
16809
+ 'ngIfElse',
16678
16810
  ]);
16679
16811
  /**
16680
16812
  * Ensures that there are no structural directives (something like *select or *featureFlag)
@@ -16702,9 +16834,12 @@ class MissingStructuralDirectiveCheck extends TemplateCheckWithVisitor {
16702
16834
  if (!customStructuralDirective)
16703
16835
  return [];
16704
16836
  const symbol = ctx.templateTypeChecker.getSymbolOfNode(node, component);
16705
- if (symbol?.directives.length) {
16837
+ // Check if there's a directive that matches the structural directive we're checking.
16838
+ // The structural directive *foo desugars to [foo], so we need to check if any
16839
+ // directive's selector would match the attribute [foo].
16840
+ const hasStructuralDirective = symbol?.directives.some((dir) => dir.selector?.includes(`[${customStructuralDirective.name}]`));
16841
+ if (hasStructuralDirective)
16706
16842
  return [];
16707
- }
16708
16843
  const sourceSpan = customStructuralDirective.keySpan || customStructuralDirective.sourceSpan;
16709
16844
  const errorMessage = `A structural directive \`${customStructuralDirective.name}\` was used in the template ` +
16710
16845
  `without a corresponding import in the component. ` +
@@ -16712,7 +16847,7 @@ class MissingStructuralDirectiveCheck extends TemplateCheckWithVisitor {
16712
16847
  return [ctx.makeTemplateDiagnostic(sourceSpan, errorMessage)];
16713
16848
  }
16714
16849
  }
16715
- const factory$a = {
16850
+ const factory$b = {
16716
16851
  code: project_tsconfig_paths.ErrorCode.MISSING_STRUCTURAL_DIRECTIVE,
16717
16852
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.MISSING_STRUCTURAL_DIRECTIVE,
16718
16853
  create: () => new MissingStructuralDirectiveCheck(),
@@ -16725,7 +16860,6 @@ const factory$a = {
16725
16860
  * otherwise it would produce inaccurate results.
16726
16861
  */
16727
16862
  class NullishCoalescingNotNullableCheck extends TemplateCheckWithVisitor {
16728
- canVisitStructuralAttributes = false;
16729
16863
  code = project_tsconfig_paths.ErrorCode.NULLISH_COALESCING_NOT_NULLABLE;
16730
16864
  visitNode(ctx, component, node) {
16731
16865
  if (!(node instanceof project_tsconfig_paths.Binary) || node.operation !== '??')
@@ -16757,7 +16891,7 @@ class NullishCoalescingNotNullableCheck extends TemplateCheckWithVisitor {
16757
16891
  return [diagnostic];
16758
16892
  }
16759
16893
  }
16760
- const factory$9 = {
16894
+ const factory$a = {
16761
16895
  code: project_tsconfig_paths.ErrorCode.NULLISH_COALESCING_NOT_NULLABLE,
16762
16896
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.NULLISH_COALESCING_NOT_NULLABLE,
16763
16897
  create: (options) => {
@@ -16778,7 +16912,6 @@ const factory$9 = {
16778
16912
  */
16779
16913
  class OptionalChainNotNullableCheck extends TemplateCheckWithVisitor {
16780
16914
  noUncheckedIndexedAccess;
16781
- canVisitStructuralAttributes = false;
16782
16915
  code = project_tsconfig_paths.ErrorCode.OPTIONAL_CHAIN_NOT_NULLABLE;
16783
16916
  constructor(noUncheckedIndexedAccess) {
16784
16917
  super();
@@ -16825,7 +16958,7 @@ class OptionalChainNotNullableCheck extends TemplateCheckWithVisitor {
16825
16958
  return [diagnostic];
16826
16959
  }
16827
16960
  }
16828
- const factory$8 = {
16961
+ const factory$9 = {
16829
16962
  code: project_tsconfig_paths.ErrorCode.OPTIONAL_CHAIN_NOT_NULLABLE,
16830
16963
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.OPTIONAL_CHAIN_NOT_NULLABLE,
16831
16964
  create: (options) => {
@@ -16866,7 +16999,7 @@ class NgSkipHydrationSpec extends TemplateCheckWithVisitor {
16866
16999
  return [];
16867
17000
  }
16868
17001
  }
16869
- const factory$7 = {
17002
+ const factory$8 = {
16870
17003
  code: project_tsconfig_paths.ErrorCode.SKIP_HYDRATION_NOT_STATIC,
16871
17004
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.SKIP_HYDRATION_NOT_STATIC,
16872
17005
  create: () => new NgSkipHydrationSpec(),
@@ -16890,7 +17023,7 @@ class SuffixNotSupportedCheck extends TemplateCheckWithVisitor {
16890
17023
  return [diagnostic];
16891
17024
  }
16892
17025
  }
16893
- const factory$6 = {
17026
+ const factory$7 = {
16894
17027
  code: project_tsconfig_paths.ErrorCode.SUFFIX_NOT_SUPPORTED,
16895
17028
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.SUFFIX_NOT_SUPPORTED,
16896
17029
  create: () => new SuffixNotSupportedCheck(),
@@ -16935,7 +17068,7 @@ class TextAttributeNotBindingSpec extends TemplateCheckWithVisitor {
16935
17068
  return [diagnostic];
16936
17069
  }
16937
17070
  }
16938
- const factory$5 = {
17071
+ const factory$6 = {
16939
17072
  code: project_tsconfig_paths.ErrorCode.TEXT_ATTRIBUTE_NOT_BINDING,
16940
17073
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.TEXT_ATTRIBUTE_NOT_BINDING,
16941
17074
  create: () => new TextAttributeNotBindingSpec(),
@@ -16995,7 +17128,7 @@ function assertExpressionInvoked$1(expression, component, node, expressionText,
16995
17128
  function generateStringFromExpression$1(expression, source) {
16996
17129
  return source.substring(expression.span.start, expression.span.end);
16997
17130
  }
16998
- const factory$4 = {
17131
+ const factory$5 = {
16999
17132
  code: project_tsconfig_paths.ErrorCode.UNINVOKED_FUNCTION_IN_EVENT_BINDING,
17000
17133
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.UNINVOKED_FUNCTION_IN_EVENT_BINDING,
17001
17134
  create: () => new UninvokedFunctionInEventBindingSpec(),
@@ -17028,7 +17161,7 @@ class UnparenthesizedNullishCoalescing extends TemplateCheckWithVisitor {
17028
17161
  return [];
17029
17162
  }
17030
17163
  }
17031
- const factory$3 = {
17164
+ const factory$4 = {
17032
17165
  code: project_tsconfig_paths.ErrorCode.UNPARENTHESIZED_NULLISH_COALESCING,
17033
17166
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.UNPARENTHESIZED_NULLISH_COALESCING,
17034
17167
  create: () => new UnparenthesizedNullishCoalescing(),
@@ -17072,7 +17205,7 @@ class UnusedLetDeclarationCheck extends TemplateCheckWithVisitor {
17072
17205
  return this.analysis.get(node);
17073
17206
  }
17074
17207
  }
17075
- const factory$2 = {
17208
+ const factory$3 = {
17076
17209
  code: project_tsconfig_paths.ErrorCode.UNUSED_LET_DECLARATION,
17077
17210
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.UNUSED_LET_DECLARATION,
17078
17211
  create: () => new UnusedLetDeclarationCheck(),
@@ -17110,7 +17243,7 @@ class UninvokedTrackFunctionCheck extends TemplateCheckWithVisitor {
17110
17243
  function generateStringFromExpression(expression, source) {
17111
17244
  return source.substring(expression.span.start, expression.span.end);
17112
17245
  }
17113
- const factory$1 = {
17246
+ const factory$2 = {
17114
17247
  code: project_tsconfig_paths.ErrorCode.UNINVOKED_TRACK_FUNCTION,
17115
17248
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.UNINVOKED_TRACK_FUNCTION,
17116
17249
  create: () => new UninvokedTrackFunctionCheck(),
@@ -17140,12 +17273,98 @@ function assertExpressionInvoked(expression, component, ctx) {
17140
17273
  }
17141
17274
  return [];
17142
17275
  }
17143
- const factory = {
17276
+ const factory$1 = {
17144
17277
  code: project_tsconfig_paths.ErrorCode.UNINVOKED_FUNCTION_IN_TEXT_INTERPOLATION,
17145
17278
  name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.UNINVOKED_FUNCTION_IN_TEXT_INTERPOLATION,
17146
17279
  create: () => new UninvokedFunctionInTextInterpolation(),
17147
17280
  };
17148
17281
 
17282
+ /**
17283
+ * This check implements warnings for unreachable or redundant @defer triggers.
17284
+ * Emits ErrorCode.DEFER_TRIGGER_MISCONFIGURATION with messages matching the project's
17285
+ * expected text.
17286
+ */
17287
+ class DeferTriggerMisconfiguration extends TemplateCheckWithVisitor {
17288
+ code = project_tsconfig_paths.ErrorCode.DEFER_TRIGGER_MISCONFIGURATION;
17289
+ visitNode(ctx, component, node) {
17290
+ if (!(node instanceof project_tsconfig_paths.DeferredBlock))
17291
+ return [];
17292
+ const mainKeys = Object.keys(node.triggers);
17293
+ const prefetchKeys = Object.keys(node.prefetchTriggers);
17294
+ // Gather actual trigger objects for mains and prefetch (only defined ones)
17295
+ const mains = mainKeys
17296
+ .map((k) => node.triggers[k])
17297
+ .filter((t) => t !== undefined && t !== null);
17298
+ const prefetches = prefetchKeys
17299
+ .map((k) => node.prefetchTriggers[k])
17300
+ .filter((t) => t !== undefined && t !== null);
17301
+ const diags = [];
17302
+ // 'on immediate' dominance
17303
+ const hasImmediateMain = mains.some((t) => t instanceof project_tsconfig_paths.ImmediateDeferredTrigger);
17304
+ if (hasImmediateMain) {
17305
+ if (mains.length > 1) {
17306
+ const msg = `The 'immediate' trigger makes additional triggers redundant.`;
17307
+ diags.push(ctx.makeTemplateDiagnostic(node.sourceSpan, msg));
17308
+ }
17309
+ if (prefetches.length > 0) {
17310
+ const msg = `Prefetch triggers have no effect because 'immediate' executes earlier.`;
17311
+ diags.push(ctx.makeTemplateDiagnostic(node.sourceSpan, msg));
17312
+ }
17313
+ }
17314
+ // If there is exactly one main and at least one prefetch, compare them.
17315
+ if (mains.length === 1 && prefetches.length > 0) {
17316
+ const main = mains[0];
17317
+ for (const pre of prefetches) {
17318
+ // Timer vs Timer: warn when prefetch delay >= main delay
17319
+ const isTimerTriggger = main instanceof project_tsconfig_paths.TimerDeferredTrigger && pre instanceof project_tsconfig_paths.TimerDeferredTrigger;
17320
+ if (isTimerTriggger) {
17321
+ const mainDelay = main.delay;
17322
+ const preDelay = pre.delay;
17323
+ if (preDelay >= mainDelay) {
17324
+ const msg = `The Prefetch 'timer(${preDelay}ms)' is not scheduled before the main 'timer(${mainDelay}ms)', so it won’t run prior to rendering. Lower the prefetch delay or remove it.`;
17325
+ diags.push(ctx.makeTemplateDiagnostic(pre.sourceSpan ?? node.sourceSpan, msg));
17326
+ }
17327
+ }
17328
+ // Reference-based triggers (hover/interaction/viewport): only warn if both
17329
+ // have a reference and the references are identical. If references differ
17330
+ // (or one is missing), the prefetch targets a different element and
17331
+ // provides potential value.
17332
+ const isHoverTrigger = main instanceof project_tsconfig_paths.HoverDeferredTrigger && pre instanceof project_tsconfig_paths.HoverDeferredTrigger;
17333
+ const isInteractionTrigger = main instanceof project_tsconfig_paths.InteractionDeferredTrigger &&
17334
+ pre instanceof project_tsconfig_paths.InteractionDeferredTrigger;
17335
+ const isViewportTrigger = main instanceof project_tsconfig_paths.ViewportDeferredTrigger &&
17336
+ pre instanceof project_tsconfig_paths.ViewportDeferredTrigger;
17337
+ if (isHoverTrigger || isInteractionTrigger || isViewportTrigger) {
17338
+ const mainRef = main.reference;
17339
+ const preRef = pre.reference;
17340
+ if (mainRef && preRef && mainRef === preRef) {
17341
+ const kindName = main.constructor.name.replace('DeferredTrigger', '').toLowerCase();
17342
+ const msg = `Prefetch '${kindName}' matches the main trigger and provides no benefit. Remove the prefetch modifier.`;
17343
+ diags.push(ctx.makeTemplateDiagnostic(pre.sourceSpan ?? node.sourceSpan, msg));
17344
+ }
17345
+ // otherwise, different references or missing reference => no warning
17346
+ continue;
17347
+ }
17348
+ // Syntactic identical: same class for immediate/idle/never etc. (timers handled above)
17349
+ if (main.constructor === pre.constructor &&
17350
+ !(main instanceof project_tsconfig_paths.TimerDeferredTrigger)) {
17351
+ const kind = main instanceof project_tsconfig_paths.ImmediateDeferredTrigger
17352
+ ? 'immediate'
17353
+ : main.constructor.name.replace('DeferredTrigger', '').toLowerCase();
17354
+ const msg = `Prefetch '${kind}' matches the main trigger and provides no benefit. Remove the prefetch modifier.`;
17355
+ diags.push(ctx.makeTemplateDiagnostic(pre.sourceSpan ?? node.sourceSpan, msg));
17356
+ }
17357
+ }
17358
+ }
17359
+ return diags;
17360
+ }
17361
+ }
17362
+ const factory = {
17363
+ code: project_tsconfig_paths.ErrorCode.DEFER_TRIGGER_MISCONFIGURATION,
17364
+ name: project_tsconfig_paths.ExtendedTemplateDiagnosticName.DEFER_TRIGGER_MISCONFIGURATION,
17365
+ create: () => new DeferTriggerMisconfiguration(),
17366
+ };
17367
+
17149
17368
  /**
17150
17369
  * A label referring to a `ts.DiagnosticCategory` or `'suppress'`, meaning the associated diagnostic
17151
17370
  * should not be displayed at all.
@@ -17233,19 +17452,20 @@ function assertNever(value) {
17233
17452
  }
17234
17453
 
17235
17454
  const ALL_DIAGNOSTIC_FACTORIES = [
17236
- factory$d,
17455
+ factory$e,
17456
+ factory$a,
17237
17457
  factory$9,
17238
- factory$8,
17458
+ factory$d,
17459
+ factory$6,
17239
17460
  factory$c,
17240
- factory$5,
17241
17461
  factory$b,
17242
- factory$a,
17243
- factory$6,
17244
- factory$e,
17245
- factory$4,
17246
- factory$2,
17247
17462
  factory$7,
17463
+ factory$f,
17464
+ factory$5,
17248
17465
  factory$3,
17466
+ factory$8,
17467
+ factory$4,
17468
+ factory$2,
17249
17469
  factory$1,
17250
17470
  factory,
17251
17471
  ];
@@ -18040,6 +18260,10 @@ function requireIdentifiers () {
18040
18260
 
18041
18261
  const numeric = /^[0-9]+$/;
18042
18262
  const compareIdentifiers = (a, b) => {
18263
+ if (typeof a === 'number' && typeof b === 'number') {
18264
+ return a === b ? 0 : a < b ? -1 : 1
18265
+ }
18266
+
18043
18267
  const anum = numeric.test(a);
18044
18268
  const bnum = numeric.test(b);
18045
18269
 
@@ -18182,11 +18406,25 @@ function requireSemver$1 () {
18182
18406
  other = new SemVer(other, this.options);
18183
18407
  }
18184
18408
 
18185
- return (
18186
- compareIdentifiers(this.major, other.major) ||
18187
- compareIdentifiers(this.minor, other.minor) ||
18188
- compareIdentifiers(this.patch, other.patch)
18189
- )
18409
+ if (this.major < other.major) {
18410
+ return -1
18411
+ }
18412
+ if (this.major > other.major) {
18413
+ return 1
18414
+ }
18415
+ if (this.minor < other.minor) {
18416
+ return -1
18417
+ }
18418
+ if (this.minor > other.minor) {
18419
+ return 1
18420
+ }
18421
+ if (this.patch < other.patch) {
18422
+ return -1
18423
+ }
18424
+ if (this.patch > other.patch) {
18425
+ return 1
18426
+ }
18427
+ return 0
18190
18428
  }
18191
18429
 
18192
18430
  comparePre (other) {
@@ -19207,6 +19445,7 @@ function requireRange () {
19207
19445
  // already replaced the hyphen ranges
19208
19446
  // turn into a set of JUST comparators.
19209
19447
  const parseComparator = (comp, options) => {
19448
+ comp = comp.replace(re[t.BUILD], '');
19210
19449
  debug('comp', comp, options);
19211
19450
  comp = replaceCarets(comp, options);
19212
19451
  debug('caret', comp);
@@ -20425,7 +20664,7 @@ var semver = /*@__PURE__*/getDefaultExportFromCjs(semverExports);
20425
20664
  * @param minVersion Minimum required version for the feature.
20426
20665
  */
20427
20666
  function coreVersionSupportsFeature(coreVersion, minVersion) {
20428
- // A version of `21.0.0-next.7` usually means that core is at head so it supports
20667
+ // A version of `21.0.0-next.9` usually means that core is at head so it supports
20429
20668
  // all features. Use string interpolation prevent the placeholder from being replaced
20430
20669
  // with the current version during build time.
20431
20670
  if (coreVersion === `0.0.0-${'PLACEHOLDER'}`) {