@angular/core 19.2.0-next.2 → 19.2.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 (42) hide show
  1. package/fesm2022/core.mjs +1094 -1064
  2. package/fesm2022/core.mjs.map +1 -1
  3. package/fesm2022/primitives/event-dispatch.mjs +1 -1
  4. package/fesm2022/primitives/signals.mjs +5 -5
  5. package/fesm2022/primitives/signals.mjs.map +1 -1
  6. package/fesm2022/rxjs-interop.mjs +1 -1
  7. package/fesm2022/testing.mjs +5 -5
  8. package/index.d.ts +92 -44
  9. package/package.json +1 -1
  10. package/primitives/event-dispatch/index.d.ts +1 -1
  11. package/primitives/signals/index.d.ts +2 -2
  12. package/rxjs-interop/index.d.ts +1 -1
  13. package/schematics/bundles/apply_import_manager-a930fcf1.js +71 -0
  14. package/schematics/bundles/{checker-9af84be9.js → checker-2eecc677.js} +101 -63
  15. package/schematics/bundles/cleanup-unused-imports.js +17 -16
  16. package/schematics/bundles/{compiler_host-dbff2781.js → compiler_host-c280a924.js} +2 -2
  17. package/schematics/bundles/control-flow-migration.js +10 -3
  18. package/schematics/bundles/explicit-standalone-flag.js +5 -5
  19. package/schematics/bundles/{imports-31a38653.js → imports-abe29092.js} +1 -1
  20. package/schematics/bundles/{index-23b503a4.js → index-24a2ad1e.js} +9 -9
  21. package/schematics/bundles/{index-93e324de.js → index-3891dd55.js} +4 -4
  22. package/schematics/bundles/inject-migration.js +10 -9
  23. package/schematics/bundles/{leading_space-6e7a8ec6.js → leading_space-d190b83b.js} +1 -1
  24. package/schematics/bundles/{migrate_ts_type_references-c6615b87.js → migrate_ts_type_references-71b3a951.js} +21 -21
  25. package/schematics/bundles/{nodes-88c2157f.js → ng_decorators-e699c081.js} +2 -15
  26. package/schematics/bundles/nodes-a535b2be.js +27 -0
  27. package/schematics/bundles/output-migration.js +22 -21
  28. package/schematics/bundles/pending-tasks.js +5 -5
  29. package/schematics/bundles/{program-66386e72.js → program-24da9092.js} +113 -54
  30. package/schematics/bundles/{apply_import_manager-d8ea426b.js → project_paths-b073c4d6.js} +3 -57
  31. package/schematics/bundles/{project_tsconfig_paths-6c9cde78.js → project_tsconfig_paths-e9ccccbf.js} +1 -1
  32. package/schematics/bundles/property_name-7c8433f5.js +31 -0
  33. package/schematics/bundles/provide-initializer.js +5 -5
  34. package/schematics/bundles/route-lazy-loading.js +9 -13
  35. package/schematics/bundles/self-closing-tags-migration.js +448 -0
  36. package/schematics/bundles/signal-input-migration.js +22 -21
  37. package/schematics/bundles/signal-queries-migration.js +28 -27
  38. package/schematics/bundles/signals.js +9 -8
  39. package/schematics/bundles/standalone-migration.js +14 -13
  40. package/schematics/collection.json +6 -0
  41. package/schematics/ng-generate/self-closing-tags-migration/schema.json +14 -0
  42. package/testing/index.d.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v19.2.0-next.2
2
+ * @license Angular v19.2.0-rc.0
3
3
  * (c) 2010-2024 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -280,7 +280,7 @@ export declare function setAlternateWeakRefImpl(impl: unknown): void;
280
280
 
281
281
  export declare function setPostSignalSetFn(fn: (() => void) | null): (() => void) | null;
282
282
 
283
- export declare function setThrowInvalidWriteToSignalError(fn: () => never): void;
283
+ export declare function setThrowInvalidWriteToSignalError(fn: <T>(node: SignalNode<T>) => never): void;
284
284
 
285
285
  /**
286
286
  * Symbol used to tell `Signal`s apart from other functions.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v19.2.0-next.2
2
+ * @license Angular v19.2.0-rc.0
3
3
  * (c) 2010-2024 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+ /**
3
+ * @license Angular v19.2.0-rc.0
4
+ * (c) 2010-2024 Google LLC. https://angular.io/
5
+ * License: MIT
6
+ */
7
+ 'use strict';
8
+
9
+ var ts = require('typescript');
10
+ require('os');
11
+ var checker = require('./checker-2eecc677.js');
12
+ var project_paths = require('./project_paths-b073c4d6.js');
13
+
14
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
15
+
16
+ var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
17
+
18
+ /**
19
+ * Applies import manager changes, and writes them as replacements the
20
+ * given result array.
21
+ */
22
+ function applyImportManagerChanges(importManager, replacements, sourceFiles, info) {
23
+ const { newImports, updatedImports, deletedImports } = importManager.finalize();
24
+ const printer = ts__default["default"].createPrinter({});
25
+ const pathToFile = new Map(sourceFiles.map((s) => [s.fileName, s]));
26
+ // Capture new imports
27
+ newImports.forEach((newImports, fileName) => {
28
+ newImports.forEach((newImport) => {
29
+ const printedImport = printer.printNode(ts__default["default"].EmitHint.Unspecified, newImport, pathToFile.get(fileName));
30
+ replacements.push(new project_paths.Replacement(project_paths.projectFile(checker.absoluteFrom(fileName), info), new project_paths.TextUpdate({ position: 0, end: 0, toInsert: `${printedImport}\n` })));
31
+ });
32
+ });
33
+ // Capture updated imports
34
+ for (const [oldBindings, newBindings] of updatedImports.entries()) {
35
+ // The import will be generated as multi-line if it already is multi-line,
36
+ // or if the number of elements significantly increased and it previously
37
+ // consisted of very few specifiers.
38
+ const isMultiline = oldBindings.getText().includes('\n') ||
39
+ (newBindings.elements.length >= 6 && oldBindings.elements.length <= 3);
40
+ const hasSpaceBetweenBraces = oldBindings.getText().startsWith('{ ');
41
+ let formatFlags = ts__default["default"].ListFormat.NamedImportsOrExportsElements |
42
+ ts__default["default"].ListFormat.Indented |
43
+ ts__default["default"].ListFormat.Braces |
44
+ ts__default["default"].ListFormat.PreserveLines |
45
+ (isMultiline ? ts__default["default"].ListFormat.MultiLine : ts__default["default"].ListFormat.SingleLine);
46
+ if (hasSpaceBetweenBraces) {
47
+ formatFlags |= ts__default["default"].ListFormat.SpaceBetweenBraces;
48
+ }
49
+ else {
50
+ formatFlags &= ~ts__default["default"].ListFormat.SpaceBetweenBraces;
51
+ }
52
+ const printedBindings = printer.printList(formatFlags, newBindings.elements, oldBindings.getSourceFile());
53
+ replacements.push(new project_paths.Replacement(project_paths.projectFile(oldBindings.getSourceFile(), info), new project_paths.TextUpdate({
54
+ position: oldBindings.getStart(),
55
+ end: oldBindings.getEnd(),
56
+ // TS uses four spaces as indent. We migrate to two spaces as we
57
+ // assume this to be more common.
58
+ toInsert: printedBindings.replace(/^ {4}/gm, ' '),
59
+ })));
60
+ }
61
+ // Update removed imports
62
+ for (const removedImport of deletedImports) {
63
+ replacements.push(new project_paths.Replacement(project_paths.projectFile(removedImport.getSourceFile(), info), new project_paths.TextUpdate({
64
+ position: removedImport.getStart(),
65
+ end: removedImport.getEnd(),
66
+ toInsert: '',
67
+ })));
68
+ }
69
+ }
70
+
71
+ exports.applyImportManagerChanges = applyImportManagerChanges;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v19.2.0-next.2
3
+ * @license Angular v19.2.0-rc.0
4
4
  * (c) 2010-2024 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -2942,10 +2942,6 @@ class Identifiers {
2942
2942
  name: 'ɵɵHostDirectivesFeature',
2943
2943
  moduleName: CORE,
2944
2944
  };
2945
- static InputTransformsFeatureFeature = {
2946
- name: 'ɵɵInputTransformsFeature',
2947
- moduleName: CORE,
2948
- };
2949
2945
  static ExternalStylesFeature = {
2950
2946
  name: 'ɵɵExternalStylesFeature',
2951
2947
  moduleName: CORE,
@@ -10118,7 +10114,14 @@ function transformExpressionsInOp(op, transform, flags) {
10118
10114
  op.trustedValueFn && transformExpressionsInExpression(op.trustedValueFn, transform, flags);
10119
10115
  break;
10120
10116
  case OpKind.RepeaterCreate:
10121
- op.track = transformExpressionsInExpression(op.track, transform, flags);
10117
+ if (op.trackByOps === null) {
10118
+ op.track = transformExpressionsInExpression(op.track, transform, flags);
10119
+ }
10120
+ else {
10121
+ for (const innerOp of op.trackByOps) {
10122
+ transformExpressionsInOp(innerOp, transform, flags | VisitorContextFlag.InChildOperation);
10123
+ }
10124
+ }
10122
10125
  if (op.trackByFn !== null) {
10123
10126
  op.trackByFn = transformExpressionsInExpression(op.trackByFn, transform, flags);
10124
10127
  }
@@ -10647,6 +10650,7 @@ function createRepeaterCreateOp(primaryView, emptyView, tag, track, varNames, em
10647
10650
  emptyView,
10648
10651
  track,
10649
10652
  trackByFn: null,
10653
+ trackByOps: null,
10650
10654
  tag,
10651
10655
  emptyTag,
10652
10656
  emptyAttributes: null,
@@ -11147,6 +11151,11 @@ class CompilationUnit {
11147
11151
  yield listenerOp;
11148
11152
  }
11149
11153
  }
11154
+ else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
11155
+ for (const trackOp of op.trackByOps) {
11156
+ yield trackOp;
11157
+ }
11158
+ }
11150
11159
  }
11151
11160
  for (const op of this.update) {
11152
11161
  yield op;
@@ -12874,6 +12883,9 @@ function recursivelyProcessView(view, parentScope) {
12874
12883
  if (op.emptyView) {
12875
12884
  recursivelyProcessView(view.job.views.get(op.emptyView), scope);
12876
12885
  }
12886
+ if (op.trackByOps !== null) {
12887
+ op.trackByOps.prepend(generateVariablesInScopeForView(view, scope, false));
12888
+ }
12877
12889
  break;
12878
12890
  case OpKind.Listener:
12879
12891
  case OpKind.TwoWayListener:
@@ -23103,7 +23115,7 @@ function reifyCreateOperations(unit, ops) {
23103
23115
  emptyDecls = emptyView.decls;
23104
23116
  emptyVars = emptyView.vars;
23105
23117
  }
23106
- OpList.replace(op, repeaterCreate(op.handle.slot, repeaterView.fnName, op.decls, op.vars, op.tag, op.attributes, op.trackByFn, op.usesComponentInstance, emptyViewFnName, emptyDecls, emptyVars, op.emptyTag, op.emptyAttributes, op.wholeSourceSpan));
23118
+ OpList.replace(op, repeaterCreate(op.handle.slot, repeaterView.fnName, op.decls, op.vars, op.tag, op.attributes, reifyTrackBy(unit, op), op.usesComponentInstance, emptyViewFnName, emptyDecls, emptyVars, op.emptyTag, op.emptyAttributes, op.wholeSourceSpan));
23107
23119
  break;
23108
23120
  case OpKind.SourceLocation:
23109
23121
  const locationsLiteral = literalArr(op.locations.map(({ targetSlot, offset, line, column }) => {
@@ -23284,6 +23296,8 @@ function reifyIrExpression(expr) {
23284
23296
  return readContextLet(expr.targetSlot.slot);
23285
23297
  case ExpressionKind.StoreLet:
23286
23298
  return storeLet(expr.value, expr.sourceSpan);
23299
+ case ExpressionKind.TrackContext:
23300
+ return variable('this');
23287
23301
  default:
23288
23302
  throw new Error(`AssertionError: Unsupported reification of ir.Expression kind: ${ExpressionKind[expr.kind]}`);
23289
23303
  }
@@ -23312,6 +23326,42 @@ function reifyListenerHandler(unit, name, handlerOps, consumesDollarEvent) {
23312
23326
  }
23313
23327
  return fn(params, handlerStmts, undefined, undefined, name);
23314
23328
  }
23329
+ /** Reifies the tracking expression of a `RepeaterCreateOp`. */
23330
+ function reifyTrackBy(unit, op) {
23331
+ // If the tracking function was created already, there's nothing left to do.
23332
+ if (op.trackByFn !== null) {
23333
+ return op.trackByFn;
23334
+ }
23335
+ const params = [new FnParam('$index'), new FnParam('$item')];
23336
+ let fn$1;
23337
+ if (op.trackByOps === null) {
23338
+ // If there are no additional ops related to the tracking function, we just need
23339
+ // to turn it into a function that returns the result of the expression.
23340
+ fn$1 = op.usesComponentInstance
23341
+ ? fn(params, [new ReturnStatement(op.track)])
23342
+ : arrowFn(params, op.track);
23343
+ }
23344
+ else {
23345
+ // Otherwise first we need to reify the track-related ops.
23346
+ reifyUpdateOperations(unit, op.trackByOps);
23347
+ const statements = [];
23348
+ for (const trackOp of op.trackByOps) {
23349
+ if (trackOp.kind !== OpKind.Statement) {
23350
+ throw new Error(`AssertionError: expected reified statements, but found op ${OpKind[trackOp.kind]}`);
23351
+ }
23352
+ statements.push(trackOp.statement);
23353
+ }
23354
+ // Afterwards we can create the function from those ops.
23355
+ fn$1 =
23356
+ op.usesComponentInstance ||
23357
+ statements.length !== 1 ||
23358
+ !(statements[0] instanceof ReturnStatement)
23359
+ ? fn(params, statements)
23360
+ : arrowFn(params, statements[0].value);
23361
+ }
23362
+ op.trackByFn = unit.job.pool.getSharedFunctionReference(fn$1, '_forTrack');
23363
+ return op.trackByFn;
23364
+ }
23315
23365
 
23316
23366
  /**
23317
23367
  * Binding with no content can be safely deleted.
@@ -23410,6 +23460,11 @@ function processLexicalScope$1(view, ops) {
23410
23460
  case OpKind.TwoWayListener:
23411
23461
  processLexicalScope$1(view, op.handlerOps);
23412
23462
  break;
23463
+ case OpKind.RepeaterCreate:
23464
+ if (op.trackByOps !== null) {
23465
+ processLexicalScope$1(view, op.trackByOps);
23466
+ }
23467
+ break;
23413
23468
  }
23414
23469
  }
23415
23470
  if (view === view.job.root) {
@@ -23842,6 +23897,11 @@ function processLexicalScope(unit, ops, savedView) {
23842
23897
  // lexical scope.
23843
23898
  processLexicalScope(unit, op.handlerOps, savedView);
23844
23899
  break;
23900
+ case OpKind.RepeaterCreate:
23901
+ if (op.trackByOps !== null) {
23902
+ processLexicalScope(unit, op.trackByOps, savedView);
23903
+ }
23904
+ break;
23845
23905
  }
23846
23906
  }
23847
23907
  // Next, use the `scope` mapping to match `ir.LexicalReadExpr` with defined names in the lexical
@@ -24242,6 +24302,9 @@ function generateTemporaries(ops) {
24242
24302
  if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
24243
24303
  op.handlerOps.prepend(generateTemporaries(op.handlerOps));
24244
24304
  }
24305
+ else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
24306
+ op.trackByOps.prepend(generateTemporaries(op.trackByOps));
24307
+ }
24245
24308
  }
24246
24309
  return generatedStatements;
24247
24310
  }
@@ -24256,49 +24319,6 @@ function assignName(names, expr) {
24256
24319
  expr.name = name;
24257
24320
  }
24258
24321
 
24259
- /**
24260
- * Generate track functions that need to be extracted to the constant pool. This entails wrapping
24261
- * them in an arrow (or traditional) function, replacing context reads with `this.`, and storing
24262
- * them in the constant pool.
24263
- *
24264
- * Note that, if a track function was previously optimized, it will not need to be extracted, and
24265
- * this phase is a no-op.
24266
- */
24267
- function generateTrackFns(job) {
24268
- for (const unit of job.units) {
24269
- for (const op of unit.create) {
24270
- if (op.kind !== OpKind.RepeaterCreate) {
24271
- continue;
24272
- }
24273
- if (op.trackByFn !== null) {
24274
- // The final track function was already set, probably because it was optimized.
24275
- continue;
24276
- }
24277
- // Find all component context reads.
24278
- let usesComponentContext = false;
24279
- op.track = transformExpressionsInExpression(op.track, (expr) => {
24280
- if (expr instanceof PipeBindingExpr || expr instanceof PipeBindingVariadicExpr) {
24281
- throw new Error(`Illegal State: Pipes are not allowed in this context`);
24282
- }
24283
- if (expr instanceof TrackContextExpr) {
24284
- usesComponentContext = true;
24285
- return variable('this');
24286
- }
24287
- return expr;
24288
- }, VisitorContextFlag.None);
24289
- let fn;
24290
- const fnParams = [new FnParam('$index'), new FnParam('$item')];
24291
- if (usesComponentContext) {
24292
- fn = new FunctionExpr(fnParams, [new ReturnStatement(op.track)]);
24293
- }
24294
- else {
24295
- fn = arrowFn(fnParams, op.track);
24296
- }
24297
- op.trackByFn = job.pool.getSharedFunctionReference(fn, '_forTrack');
24298
- }
24299
- }
24300
- }
24301
-
24302
24322
  /**
24303
24323
  * `track` functions in `for` repeaters can sometimes be "optimized," i.e. transformed into inline
24304
24324
  * expressions, in lieu of an external function call. For example, tracking by `$index` can be be
@@ -24345,12 +24365,20 @@ function optimizeTrackFns(job) {
24345
24365
  // Replace context reads with a special IR expression, since context reads in a track
24346
24366
  // function are emitted specially.
24347
24367
  op.track = transformExpressionsInExpression(op.track, (expr) => {
24348
- if (expr instanceof ContextExpr) {
24368
+ if (expr instanceof PipeBindingExpr || expr instanceof PipeBindingVariadicExpr) {
24369
+ throw new Error(`Illegal State: Pipes are not allowed in this context`);
24370
+ }
24371
+ else if (expr instanceof ContextExpr) {
24349
24372
  op.usesComponentInstance = true;
24350
24373
  return new TrackContextExpr(expr.view);
24351
24374
  }
24352
24375
  return expr;
24353
24376
  }, VisitorContextFlag.None);
24377
+ // Also create an OpList for the tracking expression since it may need
24378
+ // additional ops when generating the final code (e.g. temporary variables).
24379
+ const trackOpList = new OpList();
24380
+ trackOpList.push(createStatementOp(new ReturnStatement(op.track, op.track.sourceSpan)));
24381
+ op.trackByOps = trackOpList;
24354
24382
  }
24355
24383
  }
24356
24384
  }
@@ -24575,6 +24603,9 @@ function optimizeVariables(job) {
24575
24603
  if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
24576
24604
  inlineAlwaysInlineVariables(op.handlerOps);
24577
24605
  }
24606
+ else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
24607
+ inlineAlwaysInlineVariables(op.trackByOps);
24608
+ }
24578
24609
  }
24579
24610
  optimizeVariablesInOpList(unit.create, job.compatibility);
24580
24611
  optimizeVariablesInOpList(unit.update, job.compatibility);
@@ -24582,6 +24613,9 @@ function optimizeVariables(job) {
24582
24613
  if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
24583
24614
  optimizeVariablesInOpList(op.handlerOps, job.compatibility);
24584
24615
  }
24616
+ else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
24617
+ optimizeVariablesInOpList(op.trackByOps, job.compatibility);
24618
+ }
24585
24619
  }
24586
24620
  }
24587
24621
  }
@@ -25162,7 +25196,6 @@ const phases = [
25162
25196
  { kind: CompilationJobKind.Tmpl, fn: resolveI18nElementPlaceholders },
25163
25197
  { kind: CompilationJobKind.Tmpl, fn: resolveI18nExpressionPlaceholders },
25164
25198
  { kind: CompilationJobKind.Tmpl, fn: extractI18nMessages },
25165
- { kind: CompilationJobKind.Tmpl, fn: generateTrackFns },
25166
25199
  { kind: CompilationJobKind.Tmpl, fn: collectI18nConsts },
25167
25200
  { kind: CompilationJobKind.Tmpl, fn: collectConstExpressions },
25168
25201
  { kind: CompilationJobKind.Both, fn: collectElementConsts },
@@ -28710,7 +28743,6 @@ function addFeatures(definitionMap, meta) {
28710
28743
  const features = [];
28711
28744
  const providers = meta.providers;
28712
28745
  const viewProviders = meta.viewProviders;
28713
- const inputKeys = Object.keys(meta.inputs);
28714
28746
  if (providers || viewProviders) {
28715
28747
  const args = [providers || new LiteralArrayExpr([])];
28716
28748
  if (viewProviders) {
@@ -28718,12 +28750,6 @@ function addFeatures(definitionMap, meta) {
28718
28750
  }
28719
28751
  features.push(importExpr(Identifiers.ProvidersFeature).callFn(args));
28720
28752
  }
28721
- for (const key of inputKeys) {
28722
- if (meta.inputs[key].transformFunction !== null) {
28723
- features.push(importExpr(Identifiers.InputTransformsFeatureFeature));
28724
- break;
28725
- }
28726
- }
28727
28753
  // Note: host directives feature needs to be inserted before the
28728
28754
  // inheritance feature to ensure the correct execution order.
28729
28755
  if (meta.hostDirectives?.length) {
@@ -30696,7 +30722,7 @@ function publishFacade(global) {
30696
30722
  * @description
30697
30723
  * Entry point for all public APIs of the compiler package.
30698
30724
  */
30699
- new Version('19.2.0-next.2');
30725
+ new Version('19.2.0-rc.0');
30700
30726
 
30701
30727
  const _I18N_ATTR = 'i18n';
30702
30728
  const _I18N_ATTR_PREFIX = 'i18n-';
@@ -32104,7 +32130,7 @@ class NodeJSPathManipulation {
32104
32130
  // G3-ESM-MARKER: G3 uses CommonJS, but externally everything in ESM.
32105
32131
  // CommonJS/ESM interop for determining the current file name and containing dir.
32106
32132
  const isCommonJS = typeof __filename !== 'undefined';
32107
- const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.src || new URL('checker-9af84be9.js', document.baseURI).href));
32133
+ const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.src || new URL('checker-2eecc677.js', document.baseURI).href));
32108
32134
  const currentFileName = isCommonJS ? __filename : url.fileURLToPath(currentFileUrl);
32109
32135
  /**
32110
32136
  * A wrapper around the Node.js file-system that supports readonly operations and path manipulation.
@@ -32734,6 +32760,11 @@ const patchedReferencedAliasesSymbol = Symbol('patchedReferencedAliases');
32734
32760
  * that have been referenced in a value-position by the transform, such the installed patch can
32735
32761
  * ensure that those import declarations are not elided.
32736
32762
  *
32763
+ * If `null` is returned then the transform operates in an isolated context, i.e. using the
32764
+ * `ts.transform` API. In such scenario there is no information whether an alias declaration
32765
+ * is referenced, so all alias declarations are naturally preserved and explicitly registering
32766
+ * an alias declaration as used isn't necessary.
32767
+ *
32737
32768
  * See below. Note that this uses sourcegraph as the TypeScript checker file doesn't display on
32738
32769
  * Github.
32739
32770
  * https://sourcegraph.com/github.com/microsoft/TypeScript@3eaa7c65f6f076a08a5f7f1946fd0df7c7430259/-/blob/src/compiler/checker.ts#L31219-31257
@@ -32745,6 +32776,11 @@ function loadIsReferencedAliasDeclarationPatch(context) {
32745
32776
  throwIncompatibleTransformationContextError();
32746
32777
  }
32747
32778
  const emitResolver = context.getEmitResolver();
32779
+ if (emitResolver === undefined) {
32780
+ // In isolated `ts.transform` operations no emit resolver is present, return null as `isReferencedAliasDeclaration`
32781
+ // will never be invoked.
32782
+ return null;
32783
+ }
32748
32784
  // The emit resolver may have been patched already, in which case we return the set of referenced
32749
32785
  // aliases that was created when the patch was first applied.
32750
32786
  // See https://github.com/angular/angular/issues/40276.
@@ -32870,7 +32906,7 @@ class DefaultImportTracker {
32870
32906
  if (clausesToPreserve === null) {
32871
32907
  clausesToPreserve = loadIsReferencedAliasDeclarationPatch(context);
32872
32908
  }
32873
- clausesToPreserve.add(clause);
32909
+ clausesToPreserve?.add(clause);
32874
32910
  }
32875
32911
  }
32876
32912
  return sourceFile;
@@ -36067,7 +36103,9 @@ function createTsTransformForImportManager(manager, extraStatementsForFiles) {
36067
36103
  // doesn't drop these thinking they are unused.
36068
36104
  if (reusedOriginalAliasDeclarations.size > 0) {
36069
36105
  const referencedAliasDeclarations = loadIsReferencedAliasDeclarationPatch(ctx);
36070
- reusedOriginalAliasDeclarations.forEach((aliasDecl) => referencedAliasDeclarations.add(aliasDecl));
36106
+ if (referencedAliasDeclarations !== null) {
36107
+ reusedOriginalAliasDeclarations.forEach((aliasDecl) => referencedAliasDeclarations.add(aliasDecl));
36108
+ }
36071
36109
  }
36072
36110
  // Update the set of affected files to include files that need extra statements to be inserted.
36073
36111
  if (extraStatementsForFiles !== undefined) {
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v19.2.0-next.2
3
+ * @license Angular v19.2.0-rc.0
4
4
  * (c) 2010-2024 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -9,14 +9,15 @@
9
9
  Object.defineProperty(exports, '__esModule', { value: true });
10
10
 
11
11
  var schematics = require('@angular-devkit/schematics');
12
- var project_tsconfig_paths = require('./project_tsconfig_paths-6c9cde78.js');
13
- var apply_import_manager = require('./apply_import_manager-d8ea426b.js');
12
+ var project_tsconfig_paths = require('./project_tsconfig_paths-e9ccccbf.js');
13
+ var project_paths = require('./project_paths-b073c4d6.js');
14
14
  require('os');
15
15
  var ts = require('typescript');
16
- var checker = require('./checker-9af84be9.js');
17
- var program = require('./program-66386e72.js');
16
+ var checker = require('./checker-2eecc677.js');
17
+ var program = require('./program-24da9092.js');
18
18
  require('path');
19
- require('./index-93e324de.js');
19
+ require('./index-3891dd55.js');
20
+ var apply_import_manager = require('./apply_import_manager-a930fcf1.js');
20
21
  require('@angular-devkit/core');
21
22
  require('node:path/posix');
22
23
  require('fs');
@@ -28,7 +29,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
28
29
  var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
29
30
 
30
31
  /** Migration that cleans up unused imports from a project. */
31
- class UnusedImportsMigration extends apply_import_manager.TsurgeFunnelMigration {
32
+ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
32
33
  printer = ts__default["default"].createPrinter();
33
34
  createProgram(tsconfigAbsPath, fs) {
34
35
  return super.createProgram(tsconfigAbsPath, fs, {
@@ -67,10 +68,10 @@ class UnusedImportsMigration extends apply_import_manager.TsurgeFunnelMigration
67
68
  }
68
69
  this.generateReplacements(sourceFile, resolvedLocations, usageAnalysis, info, replacements);
69
70
  });
70
- return apply_import_manager.confirmAsSerializable({ replacements, removedIdentifiers, changedFiles });
71
+ return project_paths.confirmAsSerializable({ replacements, removedIdentifiers, changedFiles });
71
72
  }
72
73
  async migrate(globalData) {
73
- return apply_import_manager.confirmAsSerializable(globalData);
74
+ return project_paths.confirmAsSerializable(globalData);
74
75
  }
75
76
  async combine(unitA, unitB) {
76
77
  const combinedReplacements = [];
@@ -94,14 +95,14 @@ class UnusedImportsMigration extends apply_import_manager.TsurgeFunnelMigration
94
95
  }
95
96
  }
96
97
  });
97
- return apply_import_manager.confirmAsSerializable({
98
+ return project_paths.confirmAsSerializable({
98
99
  replacements: combinedReplacements,
99
100
  removedIdentifiers: combinedRemovedIdentifiers,
100
101
  changedFiles: changedFileIds.size,
101
102
  });
102
103
  }
103
104
  async globalMeta(combinedData) {
104
- return apply_import_manager.confirmAsSerializable(combinedData);
105
+ return project_paths.confirmAsSerializable(combinedData);
105
106
  }
106
107
  async stats(globalMetadata) {
107
108
  return {
@@ -228,7 +229,7 @@ class UnusedImportsMigration extends apply_import_manager.TsurgeFunnelMigration
228
229
  const importManager = new checker.ImportManager();
229
230
  // Replace full arrays with empty ones. This allows preserves more of the user's formatting.
230
231
  fullRemovals.forEach((node) => {
231
- replacements.push(new apply_import_manager.Replacement(apply_import_manager.projectFile(sourceFile, info), new apply_import_manager.TextUpdate({
232
+ replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
232
233
  position: node.getStart(),
233
234
  end: node.getEnd(),
234
235
  toInsert: '[]',
@@ -237,7 +238,7 @@ class UnusedImportsMigration extends apply_import_manager.TsurgeFunnelMigration
237
238
  // Filter out the unused identifiers from an array.
238
239
  partialRemovals.forEach((toRemove, node) => {
239
240
  const newNode = ts__default["default"].factory.updateArrayLiteralExpression(node, node.elements.filter((el) => !toRemove.has(el)));
240
- replacements.push(new apply_import_manager.Replacement(apply_import_manager.projectFile(sourceFile, info), new apply_import_manager.TextUpdate({
241
+ replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
241
242
  position: node.getStart(),
242
243
  end: node.getEnd(),
243
244
  toInsert: this.printer.printNode(ts__default["default"].EmitHint.Unspecified, newNode, sourceFile),
@@ -273,7 +274,7 @@ function migrate() {
273
274
  if (!buildPaths.length && !testPaths.length) {
274
275
  throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot clean up unused imports.');
275
276
  }
276
- const fs = new apply_import_manager.DevkitMigrationFilesystem(tree);
277
+ const fs = new project_paths.DevkitMigrationFilesystem(tree);
277
278
  checker.setFileSystem(fs);
278
279
  const migration = new UnusedImportsMigration();
279
280
  const unitResults = [];
@@ -287,7 +288,7 @@ function migrate() {
287
288
  context.logger.info(`Scanning for unused imports using ${tsconfigPath}`);
288
289
  unitResults.push(await migration.analyze(info));
289
290
  }
290
- const combined = await apply_import_manager.synchronouslyCombineUnitData(migration, unitResults);
291
+ const combined = await project_paths.synchronouslyCombineUnitData(migration, unitResults);
291
292
  if (combined === null) {
292
293
  context.logger.error('Schematic failed unexpectedly with no analysis data');
293
294
  return;
@@ -295,7 +296,7 @@ function migrate() {
295
296
  const globalMeta = await migration.globalMeta(combined);
296
297
  const replacementsPerFile = new Map();
297
298
  const { replacements } = await migration.migrate(globalMeta);
298
- const changesPerFile = apply_import_manager.groupReplacementsByFile(replacements);
299
+ const changesPerFile = project_paths.groupReplacementsByFile(replacements);
299
300
  for (const [file, changes] of changesPerFile) {
300
301
  if (!replacementsPerFile.has(file)) {
301
302
  replacementsPerFile.set(file, changes);
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v19.2.0-next.2
3
+ * @license Angular v19.2.0-rc.0
4
4
  * (c) 2010-2024 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-9af84be9.js');
10
+ var checker = require('./checker-2eecc677.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 v19.2.0-next.2
3
+ * @license Angular v19.2.0-rc.0
4
4
  * (c) 2010-2024 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -10,8 +10,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
10
10
 
11
11
  var schematics = require('@angular-devkit/schematics');
12
12
  var p = require('path');
13
- var compiler_host = require('./compiler_host-dbff2781.js');
14
- var checker = require('./checker-9af84be9.js');
13
+ var compiler_host = require('./compiler_host-c280a924.js');
14
+ var checker = require('./checker-2eecc677.js');
15
15
  var ts = require('typescript');
16
16
  require('os');
17
17
  require('fs');
@@ -297,12 +297,19 @@ class CommonCollector extends checker.RecursiveVisitor {
297
297
  this.count++;
298
298
  }
299
299
  }
300
+ super.visitBlock(ast, null);
300
301
  }
301
302
  visitText(ast) {
302
303
  if (this.hasPipes(ast.value)) {
303
304
  this.count++;
304
305
  }
305
306
  }
307
+ visitLetDeclaration(decl) {
308
+ if (this.hasPipes(decl.value)) {
309
+ this.count++;
310
+ }
311
+ super.visitLetDeclaration(decl, null);
312
+ }
306
313
  hasDirectives(input) {
307
314
  return commonModuleDirectives.has(input);
308
315
  }
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v19.2.0-next.2
3
+ * @license Angular v19.2.0-rc.0
4
4
  * (c) 2010-2024 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -10,12 +10,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
10
10
 
11
11
  var schematics = require('@angular-devkit/schematics');
12
12
  var p = require('path');
13
- var project_tsconfig_paths = require('./project_tsconfig_paths-6c9cde78.js');
14
- var compiler_host = require('./compiler_host-dbff2781.js');
13
+ var project_tsconfig_paths = require('./project_tsconfig_paths-e9ccccbf.js');
14
+ var compiler_host = require('./compiler_host-c280a924.js');
15
15
  var ts = require('typescript');
16
- var imports = require('./imports-31a38653.js');
16
+ var imports = require('./imports-abe29092.js');
17
17
  require('@angular-devkit/core');
18
- require('./checker-9af84be9.js');
18
+ require('./checker-2eecc677.js');
19
19
  require('os');
20
20
  require('fs');
21
21
  require('module');
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v19.2.0-next.2
3
+ * @license Angular v19.2.0-rc.0
4
4
  * (c) 2010-2024 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */