@angular/core 16.0.0-next.0 → 16.0.0-next.1

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 (57) hide show
  1. package/esm2020/src/application_init.mjs +3 -2
  2. package/esm2020/src/application_module.mjs +3 -2
  3. package/esm2020/src/application_ref.mjs +5 -3
  4. package/esm2020/src/change_detection/change_detector_ref.mjs +3 -2
  5. package/esm2020/src/change_detection/differs/iterable_differs.mjs +3 -2
  6. package/esm2020/src/change_detection/differs/keyvalue_differs.mjs +3 -2
  7. package/esm2020/src/console.mjs +3 -2
  8. package/esm2020/src/core_private_export.mjs +2 -1
  9. package/esm2020/src/core_render3_private_export.mjs +2 -1
  10. package/esm2020/src/di/injector.mjs +3 -2
  11. package/esm2020/src/di/r3_injector.mjs +5 -1
  12. package/esm2020/src/di/reflective_injector.mjs +3 -2
  13. package/esm2020/src/linker/compiler.mjs +3 -2
  14. package/esm2020/src/linker/component_factory_resolver.mjs +3 -2
  15. package/esm2020/src/linker/destroy_ref.mjs +41 -0
  16. package/esm2020/src/linker/element_ref.mjs +3 -2
  17. package/esm2020/src/linker/query_list.mjs +6 -7
  18. package/esm2020/src/linker/template_ref.mjs +3 -2
  19. package/esm2020/src/linker/view_container_ref.mjs +3 -2
  20. package/esm2020/src/linker.mjs +2 -1
  21. package/esm2020/src/render/api.mjs +3 -2
  22. package/esm2020/src/render3/features/standalone_feature.mjs +1 -1
  23. package/esm2020/src/render3/fields.mjs +10 -1
  24. package/esm2020/src/render3/hooks.mjs +3 -2
  25. package/esm2020/src/render3/instructions/element.mjs +10 -9
  26. package/esm2020/src/render3/instructions/shared.mjs +16 -17
  27. package/esm2020/src/render3/interfaces/definition.mjs +1 -1
  28. package/esm2020/src/render3/interfaces/node.mjs +1 -1
  29. package/esm2020/src/render3/interfaces/view.mjs +3 -2
  30. package/esm2020/src/render3/node_manipulation.mjs +14 -14
  31. package/esm2020/src/render3/util/view_utils.mjs +11 -2
  32. package/esm2020/src/render3/view_ref.mjs +4 -3
  33. package/esm2020/src/sanitization/sanitizer.mjs +3 -2
  34. package/esm2020/src/testability/testability.mjs +5 -3
  35. package/esm2020/src/transfer_state.mjs +148 -0
  36. package/esm2020/src/util/iterable.mjs +6 -7
  37. package/esm2020/src/version.mjs +1 -1
  38. package/esm2020/testing/src/logger.mjs +6 -5
  39. package/esm2020/testing/src/ng_zone_mock.mjs +6 -5
  40. package/esm2020/testing/src/test_bed.mjs +3 -2
  41. package/fesm2015/core.mjs +243 -74
  42. package/fesm2015/core.mjs.map +1 -1
  43. package/fesm2015/testing.mjs +74 -73
  44. package/fesm2015/testing.mjs.map +1 -1
  45. package/fesm2020/core.mjs +241 -74
  46. package/fesm2020/core.mjs.map +1 -1
  47. package/fesm2020/testing.mjs +74 -73
  48. package/fesm2020/testing.mjs.map +1 -1
  49. package/index.d.ts +122 -1
  50. package/package.json +3 -3
  51. package/schematics/migrations/relative-link-resolution/bundle.js +7 -7
  52. package/schematics/migrations/router-link-with-href/bundle.js +10 -10
  53. package/schematics/migrations/router-link-with-href/bundle.js.map +2 -2
  54. package/schematics/ng-generate/standalone-migration/bundle.js +1150 -1155
  55. package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
  56. package/testing/index.d.ts +1 -1
  57. package/esm2020/src/util/symbol.mjs +0 -30
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v16.0.0-next.0
2
+ * @license Angular v16.0.0-next.1
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -2204,6 +2204,20 @@ declare type DestroyHookData = (HookEntry | HookData)[];
2204
2204
  */
2205
2205
  export declare function destroyPlatform(): void;
2206
2206
 
2207
+
2208
+ /**
2209
+ * `DestroyRef` lets you set callbacks to run for any cleanup or destruction behavior.
2210
+ * The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
2211
+ * is injected in a component or directive, the callbacks run when that component or
2212
+ * directive is destroyed. Otherwise the callbacks run when a corresponding injector is destroyed.
2213
+ */
2214
+ export declare abstract class DestroyRef {
2215
+ /**
2216
+ * Registers a destroy callback in a given lifecycle scope.
2217
+ */
2218
+ abstract onDestroy(callback: () => void): void;
2219
+ }
2220
+
2207
2221
  /**
2208
2222
  * Directive decorator and metadata.
2209
2223
  *
@@ -5078,6 +5092,12 @@ declare interface LView<T = unknown> extends Array<any> {
5078
5092
  * precedence over the element and module injectors.
5079
5093
  */
5080
5094
  readonly [EMBEDDED_VIEW_INJECTOR]: Injector | null;
5095
+ /**
5096
+ * A collection of callbacks functions that are executed when a given LView is destroyed. Those
5097
+ * are user defined, LView-specific destroy callbacks that don't have any corresponding TView
5098
+ * entries.
5099
+ */
5100
+ [ON_DESTROY_HOOKS]: Array<() => void> | null;
5081
5101
  }
5082
5102
 
5083
5103
  /** Flags associated with an LView (saved in LView[FLAGS]) */
@@ -5643,6 +5663,8 @@ export declare class NgZone {
5643
5663
  */
5644
5664
  export declare const NO_ERRORS_SCHEMA: SchemaMetadata;
5645
5665
 
5666
+ declare const ON_DESTROY_HOOKS = 22;
5667
+
5646
5668
  /**
5647
5669
  * @description
5648
5670
  * A lifecycle hook that is called when any data-bound property of a directive changes.
@@ -8257,6 +8279,11 @@ declare interface TNode {
8257
8279
  * to insert them or remove them from the DOM.
8258
8280
  */
8259
8281
  next: TNode | null;
8282
+ /**
8283
+ * The previous sibling node.
8284
+ * This simplifies operations when we need a pointer to the previous node.
8285
+ */
8286
+ prev: TNode | null;
8260
8287
  /**
8261
8288
  * The next projected sibling. Since in Angular content projection works on the node-by-node
8262
8289
  * basis the act of projecting nodes might change nodes relationship at the insertion point
@@ -10384,6 +10411,8 @@ export declare interface ɵDirectiveType<T> extends Type<T> {
10384
10411
  ɵfac: unknown;
10385
10412
  }
10386
10413
 
10414
+ export declare function ɵescapeTransferStateContent(text: string): string;
10415
+
10387
10416
  /**
10388
10417
  * Index of each type of locale data from the extra locale data array
10389
10418
  */
@@ -10577,6 +10606,10 @@ export declare function ɵisInjectable(type: any): boolean;
10577
10606
 
10578
10607
  export declare function ɵisListLikeIterable(obj: any): boolean;
10579
10608
 
10609
+ export declare function ɵisNgModule<T>(value: Type<T>): value is Type<T> & {
10610
+ ɵmod: ɵNgModuleDef<T>;
10611
+ };
10612
+
10580
10613
  /**
10581
10614
  * Determine if the argument is an Observable
10582
10615
  *
@@ -10707,6 +10740,22 @@ export declare function ɵmakeDecorator<T>(name: string, props?: (...args: any[]
10707
10740
  (...args: any[]): (cls: any) => any;
10708
10741
  };
10709
10742
 
10743
+ /**
10744
+ * Create a `StateKey<T>` that can be used to store value of type T with `TransferState`.
10745
+ *
10746
+ * Example:
10747
+ *
10748
+ * ```
10749
+ * const COUNTER_KEY = makeStateKey<number>('counter');
10750
+ * let value = 10;
10751
+ *
10752
+ * transferState.set(COUNTER_KEY, value);
10753
+ * ```
10754
+ *
10755
+ * @publicApi
10756
+ */
10757
+ export declare function ɵmakeStateKey<T = void>(key: string): ɵStateKey<T>;
10758
+
10710
10759
 
10711
10760
  export declare const ɵNG_COMP_DEF: string;
10712
10761
 
@@ -11218,6 +11267,25 @@ export declare function ɵsetUnknownElementStrictMode(shouldThrow: boolean): voi
11218
11267
  */
11219
11268
  export declare function ɵsetUnknownPropertyStrictMode(shouldThrow: boolean): void;
11220
11269
 
11270
+ /**
11271
+ * A type-safe key to use with `TransferState`.
11272
+ *
11273
+ * Example:
11274
+ *
11275
+ * ```
11276
+ * const COUNTER_KEY = makeStateKey<number>('counter');
11277
+ * let value = 10;
11278
+ *
11279
+ * transferState.set(COUNTER_KEY, value);
11280
+ * ```
11281
+ *
11282
+ * @publicApi
11283
+ */
11284
+ export declare type ɵStateKey<T> = string & {
11285
+ __not_a_string: never;
11286
+ __value_type?: T;
11287
+ };
11288
+
11221
11289
  /** Store a value in the `data` at a given `index`. */
11222
11290
  export declare function ɵstore<T>(tView: TView, lView: LView, index: number, value: T): void;
11223
11291
 
@@ -11240,12 +11308,65 @@ export declare const ɵTESTABILITY: InjectionToken<Testability>;
11240
11308
  */
11241
11309
  export declare const ɵTESTABILITY_GETTER: InjectionToken<GetTestability>;
11242
11310
 
11311
+ /**
11312
+ * A key value store that is transferred from the application on the server side to the application
11313
+ * on the client side.
11314
+ *
11315
+ * The `TransferState` is available as an injectable token.
11316
+ * On the client, just inject this token using DI and use it, it will be lazily initialized.
11317
+ * On the server it's already included if `renderApplication` function is used. Otherwise, import
11318
+ * the `ServerTransferStateModule` module to make the `TransferState` available.
11319
+ *
11320
+ * The values in the store are serialized/deserialized using JSON.stringify/JSON.parse. So only
11321
+ * boolean, number, string, null and non-class objects will be serialized and deserialized in a
11322
+ * non-lossy manner.
11323
+ *
11324
+ * @publicApi
11325
+ */
11326
+ export declare class ɵTransferState {
11327
+ private store;
11328
+ private onSerializeCallbacks;
11329
+ constructor();
11330
+ /**
11331
+ * Get the value corresponding to a key. Return `defaultValue` if key is not found.
11332
+ */
11333
+ get<T>(key: ɵStateKey<T>, defaultValue: T): T;
11334
+ /**
11335
+ * Set the value corresponding to a key.
11336
+ */
11337
+ set<T>(key: ɵStateKey<T>, value: T): void;
11338
+ /**
11339
+ * Remove a key from the store.
11340
+ */
11341
+ remove<T>(key: ɵStateKey<T>): void;
11342
+ /**
11343
+ * Test whether a key exists in the store.
11344
+ */
11345
+ hasKey<T>(key: ɵStateKey<T>): boolean;
11346
+ /**
11347
+ * Indicates whether the state is empty.
11348
+ */
11349
+ get isEmpty(): boolean;
11350
+ /**
11351
+ * Register a callback to provide the value for a key when `toJson` is called.
11352
+ */
11353
+ onSerialize<T>(key: ɵStateKey<T>, callback: () => T): void;
11354
+ /**
11355
+ * Serialize the current state of the store to JSON.
11356
+ */
11357
+ toJson(): string;
11358
+ static ɵfac: i0.ɵɵFactoryDeclaration<ɵTransferState, never>;
11359
+ static ɵprov: i0.ɵɵInjectableDeclaration<ɵTransferState>;
11360
+ }
11361
+
11243
11362
  /**
11244
11363
  * Compute the pair of transitive scopes (compilation scope and exported scope) for a given type
11245
11364
  * (either a NgModule or a standalone component / directive / pipe).
11246
11365
  */
11247
11366
  export declare function ɵtransitiveScopesFor<T>(type: Type<T>): ɵNgModuleTransitiveScopes;
11248
11367
 
11368
+ export declare function ɵunescapeTransferStateContent(text: string): string;
11369
+
11249
11370
  /**
11250
11371
  * Helper function to remove all the locale data from `LOCALE_DATA`.
11251
11372
  */
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@angular/core",
3
- "version": "16.0.0-next.0",
3
+ "version": "16.0.0-next.1",
4
4
  "description": "Angular - the core framework",
5
5
  "author": "angular",
6
6
  "license": "MIT",
7
7
  "engines": {
8
- "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
8
+ "node": "^16.13.0 || >=18.10.0"
9
9
  },
10
10
  "exports": {
11
11
  "./schematics/*": {
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "peerDependencies": {
38
38
  "rxjs": "^6.5.3 || ^7.4.0",
39
- "zone.js": "~0.11.4 || ~0.12.0"
39
+ "zone.js": "~0.11.4 || ~0.12.0 || ~0.13.0"
40
40
  },
41
41
  "repository": {
42
42
  "type": "git",
@@ -56,7 +56,7 @@ var __async = (__this, __arguments, generator) => {
56
56
  });
57
57
  };
58
58
 
59
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/migrations/relative-link-resolution/index.mjs
59
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/migrations/relative-link-resolution/index.mjs
60
60
  var relative_link_resolution_exports = {};
61
61
  __export(relative_link_resolution_exports, {
62
62
  default: () => relative_link_resolution_default
@@ -65,7 +65,7 @@ module.exports = __toCommonJS(relative_link_resolution_exports);
65
65
  var import_schematics = require("@angular-devkit/schematics");
66
66
  var import_path2 = require("path");
67
67
 
68
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/project_tsconfig_paths.mjs
68
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/project_tsconfig_paths.mjs
69
69
  var import_core = require("@angular-devkit/core");
70
70
  function getProjectTsConfigPaths(tree) {
71
71
  return __async(this, null, function* () {
@@ -145,11 +145,11 @@ function getWorkspace(tree) {
145
145
  });
146
146
  }
147
147
 
148
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
148
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
149
149
  var import_path = require("path");
150
150
  var import_typescript2 = __toESM(require("typescript"), 1);
151
151
 
152
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/typescript/parse_tsconfig.mjs
152
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/typescript/parse_tsconfig.mjs
153
153
  var path = __toESM(require("path"), 1);
154
154
  var import_typescript = __toESM(require("typescript"), 1);
155
155
  function parseTsconfigFile(tsconfigPath, basePath) {
@@ -166,7 +166,7 @@ function parseTsconfigFile(tsconfigPath, basePath) {
166
166
  return import_typescript.default.parseJsonConfigFileContent(config, parseConfigHost, basePath, {});
167
167
  }
168
168
 
169
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
169
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
170
170
  function createMigrationProgram(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles) {
171
171
  const { rootNames, options, host } = createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles);
172
172
  return import_typescript2.default.createProgram(rootNames, options, host);
@@ -199,7 +199,7 @@ function canMigrateFile(basePath, sourceFile, program) {
199
199
  return !(0, import_path.relative)(basePath, sourceFile.fileName).startsWith("..");
200
200
  }
201
201
 
202
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/migrations/relative-link-resolution/util.mjs
202
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/migrations/relative-link-resolution/util.mjs
203
203
  var import_typescript3 = __toESM(require("typescript"), 1);
204
204
  var relativeLinkResolution = "relativeLinkResolution";
205
205
  var knownConfigValues = /* @__PURE__ */ new Set([`'legacy'`, `'corrected'`]);
@@ -239,7 +239,7 @@ function sortByStartPosDescending(rewrites) {
239
239
  return rewrites.sort((entityA, entityB) => entityB.startPos - entityA.startPos);
240
240
  }
241
241
 
242
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/migrations/relative-link-resolution/index.mjs
242
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/migrations/relative-link-resolution/index.mjs
243
243
  function relative_link_resolution_default() {
244
244
  return (tree) => __async(this, null, function* () {
245
245
  const { buildPaths, testPaths } = yield getProjectTsConfigPaths(tree);
@@ -56,7 +56,7 @@ var __async = (__this, __arguments, generator) => {
56
56
  });
57
57
  };
58
58
 
59
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/index.mjs
59
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/index.mjs
60
60
  var router_link_with_href_exports = {};
61
61
  __export(router_link_with_href_exports, {
62
62
  default: () => router_link_with_href_default
@@ -65,7 +65,7 @@ module.exports = __toCommonJS(router_link_with_href_exports);
65
65
  var import_schematics = require("@angular-devkit/schematics");
66
66
  var import_path2 = require("path");
67
67
 
68
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/project_tsconfig_paths.mjs
68
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/project_tsconfig_paths.mjs
69
69
  var import_core = require("@angular-devkit/core");
70
70
  function getProjectTsConfigPaths(tree) {
71
71
  return __async(this, null, function* () {
@@ -145,11 +145,11 @@ function getWorkspace(tree) {
145
145
  });
146
146
  }
147
147
 
148
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
148
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
149
149
  var import_path = require("path");
150
150
  var import_typescript2 = __toESM(require("typescript"), 1);
151
151
 
152
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/typescript/parse_tsconfig.mjs
152
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/typescript/parse_tsconfig.mjs
153
153
  var path = __toESM(require("path"), 1);
154
154
  var import_typescript = __toESM(require("typescript"), 1);
155
155
  function parseTsconfigFile(tsconfigPath, basePath) {
@@ -166,7 +166,7 @@ function parseTsconfigFile(tsconfigPath, basePath) {
166
166
  return import_typescript.default.parseJsonConfigFileContent(config, parseConfigHost, basePath, {});
167
167
  }
168
168
 
169
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
169
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
170
170
  function createMigrationProgram(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles) {
171
171
  const { rootNames, options, host } = createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles);
172
172
  return import_typescript2.default.createProgram(rootNames, options, host);
@@ -199,10 +199,10 @@ function canMigrateFile(basePath, sourceFile, program) {
199
199
  return !(0, import_path.relative)(basePath, sourceFile.fileName).startsWith("..");
200
200
  }
201
201
 
202
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/util.mjs
202
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/util.mjs
203
203
  var import_typescript5 = __toESM(require("typescript"), 1);
204
204
 
205
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/typescript/imports.mjs
205
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/typescript/imports.mjs
206
206
  var import_typescript3 = __toESM(require("typescript"), 1);
207
207
  function getImportOfIdentifier(typeChecker, node) {
208
208
  const symbol = typeChecker.getSymbolAtLocation(node);
@@ -251,7 +251,7 @@ function findImportSpecifier(nodes, specifierName) {
251
251
  });
252
252
  }
253
253
 
254
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/utils/typescript/nodes.mjs
254
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/utils/typescript/nodes.mjs
255
255
  var import_typescript4 = __toESM(require("typescript"), 1);
256
256
  function closestNode(node, predicate) {
257
257
  let current = node.parent;
@@ -264,7 +264,7 @@ function closestNode(node, predicate) {
264
264
  return null;
265
265
  }
266
266
 
267
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/util.mjs
267
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/util.mjs
268
268
  var routerLink = "RouterLink";
269
269
  var routerLinkWithHref = "RouterLinkWithHref";
270
270
  var routerModule = "@angular/router";
@@ -323,7 +323,7 @@ function sortByStartPosDescending(rewrites) {
323
323
  return rewrites.sort((entityA, entityB) => entityB.startPos - entityA.startPos);
324
324
  }
325
325
 
326
- // bazel-out/darwin_arm64-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/index.mjs
326
+ // bazel-out/k8-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/index.mjs
327
327
  function router_link_with_href_default() {
328
328
  return (tree) => __async(this, null, function* () {
329
329
  const { buildPaths, testPaths } = yield getProjectTsConfigPaths(tree);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../packages/core/schematics/migrations/router-link-with-href/index.ts", "../../../../../../../../packages/core/schematics/utils/project_tsconfig_paths.ts", "../../../../../../../../packages/core/schematics/utils/typescript/compiler_host.ts", "../../../../../../../../packages/core/schematics/utils/typescript/parse_tsconfig.ts", "../../../../../../../../packages/core/schematics/migrations/router-link-with-href/util.ts", "../../../../../../../../packages/core/schematics/utils/typescript/imports.ts", "../../../../../../../../packages/core/schematics/utils/typescript/nodes.ts"],
4
- "sourcesContent": ["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Rule, SchematicsException, Tree, UpdateRecorder} from '@angular-devkit/schematics';\nimport {relative} from 'path';\n\nimport {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';\nimport {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host';\n\nimport {migrateFile} from './util';\n\nexport default function(): Rule {\n return async (tree: Tree) => {\n const {buildPaths, testPaths} = await getProjectTsConfigPaths(tree);\n const basePath = process.cwd();\n const allPaths = [...buildPaths, ...testPaths];\n\n if (!allPaths.length) {\n throw new SchematicsException(\n 'Could not find any tsconfig file. Cannot run the `RouterLinkWithHref` migration.');\n }\n\n for (const tsconfigPath of allPaths) {\n runRouterLinkWithHrefMigration(tree, tsconfigPath, basePath);\n }\n };\n}\n\nfunction runRouterLinkWithHrefMigration(tree: Tree, tsconfigPath: string, basePath: string) {\n const program = createMigrationProgram(tree, tsconfigPath, basePath);\n const typeChecker = program.getTypeChecker();\n const sourceFiles =\n program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program));\n\n for (const sourceFile of sourceFiles) {\n let update: UpdateRecorder|null = null;\n\n const rewriter = (startPos: number, width: number, text: string|null) => {\n if (update === null) {\n // Lazily initialize update, because most files will not require migration.\n update = tree.beginUpdate(relative(basePath, sourceFile.fileName));\n }\n update.remove(startPos, width);\n if (text !== null) {\n update.insertLeft(startPos, text);\n }\n };\n\n migrateFile(sourceFile, typeChecker, rewriter);\n\n if (update !== null) {\n tree.commitUpdate(update);\n }\n }\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {json, normalize, virtualFs, workspaces} from '@angular-devkit/core';\nimport {Tree} from '@angular-devkit/schematics';\n\n/**\n * Gets all tsconfig paths from a CLI project by reading the workspace configuration\n * and looking for common tsconfig locations.\n */\nexport async function getProjectTsConfigPaths(tree: Tree):\n Promise<{buildPaths: string[]; testPaths: string[];}> {\n // Start with some tsconfig paths that are generally used within CLI projects. Note\n // that we are not interested in IDE-specific tsconfig files (e.g. /tsconfig.json)\n const buildPaths = new Set<string>();\n const testPaths = new Set<string>();\n\n const workspace = await getWorkspace(tree);\n for (const [, project] of workspace.projects) {\n for (const [name, target] of project.targets) {\n if (name !== 'build' && name !== 'test') {\n continue;\n }\n\n for (const [, options] of allTargetOptions(target)) {\n const tsConfig = options.tsConfig;\n // Filter out tsconfig files that don't exist in the CLI project.\n if (typeof tsConfig !== 'string' || !tree.exists(tsConfig)) {\n continue;\n }\n\n if (name === 'build') {\n buildPaths.add(normalize(tsConfig));\n } else {\n testPaths.add(normalize(tsConfig));\n }\n }\n }\n }\n\n return {\n buildPaths: [...buildPaths],\n testPaths: [...testPaths],\n };\n}\n\n/** Get options for all configurations for the passed builder target. */\nfunction*\n allTargetOptions(target: workspaces.TargetDefinition):\n Iterable<[string | undefined, Record<string, json.JsonValue|undefined>]> {\n if (target.options) {\n yield [undefined, target.options];\n }\n\n if (!target.configurations) {\n return;\n }\n\n for (const [name, options] of Object.entries(target.configurations)) {\n if (options) {\n yield [name, options];\n }\n }\n}\n\nfunction createHost(tree: Tree): workspaces.WorkspaceHost {\n return {\n async readFile(path: string): Promise<string> {\n const data = tree.read(path);\n if (!data) {\n throw new Error('File not found.');\n }\n\n return virtualFs.fileBufferToString(data);\n },\n async writeFile(path: string, data: string): Promise<void> {\n return tree.overwrite(path, data);\n },\n async isDirectory(path: string): Promise<boolean> {\n // Approximate a directory check.\n // We don't need to consider empty directories and hence this is a good enough approach.\n // This is also per documentation, see:\n // https://angular.io/guide/schematics-for-libraries#get-the-project-configuration\n return !tree.exists(path) && tree.getDir(path).subfiles.length > 0;\n },\n async isFile(path: string): Promise<boolean> {\n return tree.exists(path);\n },\n };\n}\n\nasync function getWorkspace(tree: Tree): Promise<workspaces.WorkspaceDefinition> {\n const host = createHost(tree);\n const {workspace} = await workspaces.readWorkspace('/', host);\n\n return workspace;\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport {Tree} from '@angular-devkit/schematics';\nimport {dirname, relative, resolve} from 'path';\nimport ts from 'typescript';\n\nimport {parseTsconfigFile} from './parse_tsconfig';\n\ntype FakeReadFileFn = (fileName: string) => string|undefined;\n\n/**\n * Creates a TypeScript program instance for a TypeScript project within\n * the virtual file system tree.\n * @param tree Virtual file system tree that contains the source files.\n * @param tsconfigPath Virtual file system path that resolves to the TypeScript project.\n * @param basePath Base path for the virtual file system tree.\n * @param fakeFileRead Optional file reader function. Can be used to overwrite files in\n * the TypeScript program, or to add in-memory files (e.g. to add global types).\n * @param additionalFiles Additional file paths that should be added to the program.\n */\nexport function createMigrationProgram(\n tree: Tree, tsconfigPath: string, basePath: string, fakeFileRead?: FakeReadFileFn,\n additionalFiles?: string[]) {\n const {rootNames, options, host} =\n createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles);\n return ts.createProgram(rootNames, options, host);\n}\n\n/**\n * Creates the options necessary to instantiate a TypeScript program.\n * @param tree Virtual file system tree that contains the source files.\n * @param tsconfigPath Virtual file system path that resolves to the TypeScript project.\n * @param basePath Base path for the virtual file system tree.\n * @param fakeFileRead Optional file reader function. Can be used to overwrite files in\n * the TypeScript program, or to add in-memory files (e.g. to add global types).\n * @param additionalFiles Additional file paths that should be added to the program.\n * @param optionOverrides Overrides of the parsed compiler options.\n */\nexport function createProgramOptions(\n tree: Tree, tsconfigPath: string, basePath: string, fakeFileRead?: FakeReadFileFn,\n additionalFiles?: string[], optionOverrides?: ts.CompilerOptions) {\n // Resolve the tsconfig path to an absolute path. This is needed as TypeScript otherwise\n // is not able to resolve root directories in the given tsconfig. More details can be found\n // in the following issue: https://github.com/microsoft/TypeScript/issues/37731.\n tsconfigPath = resolve(basePath, tsconfigPath);\n const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));\n const options = optionOverrides ? {...parsed.options, ...optionOverrides} : parsed.options;\n const host = createMigrationCompilerHost(tree, options, basePath, fakeFileRead);\n return {rootNames: parsed.fileNames.concat(additionalFiles || []), options, host};\n}\n\nfunction createMigrationCompilerHost(\n tree: Tree, options: ts.CompilerOptions, basePath: string,\n fakeRead?: FakeReadFileFn): ts.CompilerHost {\n const host = ts.createCompilerHost(options, true);\n const defaultReadFile = host.readFile;\n\n // We need to overwrite the host \"readFile\" method, as we want the TypeScript\n // program to be based on the file contents in the virtual file tree. Otherwise\n // if we run multiple migrations we might have intersecting changes and\n // source files.\n host.readFile = fileName => {\n const treeRelativePath = relative(basePath, fileName);\n let result: string|undefined = fakeRead?.(treeRelativePath);\n\n if (typeof result !== 'string') {\n // If the relative path resolved to somewhere outside of the tree, fall back to\n // TypeScript's default file reading function since the `tree` will throw an error.\n result = treeRelativePath.startsWith('..') ? defaultReadFile.call(host, fileName) :\n tree.read(treeRelativePath)?.toString();\n }\n\n // Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset,\n // which breaks the CLI UpdateRecorder.\n // See: https://github.com/angular/angular/pull/30719\n return typeof result === 'string' ? result.replace(/^\\uFEFF/, '') : undefined;\n };\n\n return host;\n}\n\n/**\n * Checks whether a file can be migrate by our automated migrations.\n * @param basePath Absolute path to the project.\n * @param sourceFile File being checked.\n * @param program Program that includes the source file.\n */\nexport function canMigrateFile(\n basePath: string, sourceFile: ts.SourceFile, program: ts.Program): boolean {\n // We shouldn't migrate .d.ts files, files from an external library or type checking files.\n if (sourceFile.fileName.endsWith('.ngtypecheck.ts') || sourceFile.isDeclarationFile ||\n program.isSourceFileFromExternalLibrary(sourceFile)) {\n return false;\n }\n\n // Our migrations are set up to create a `Program` from the project's tsconfig and to migrate all\n // the files within the program. This can include files that are outside of the Angular CLI\n // project. We can't migrate files outside of the project, because our file system interactions\n // go through the CLI's `Tree` which assumes that all files are within the project. See:\n // https://github.com/angular/angular-cli/blob/0b0961c9c233a825b6e4bb59ab7f0790f9b14676/packages/angular_devkit/schematics/src/tree/host-tree.ts#L131\n return !relative(basePath, sourceFile.fileName).startsWith('..');\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport * as path from 'path';\nimport ts from 'typescript';\n\nexport function parseTsconfigFile(tsconfigPath: string, basePath: string): ts.ParsedCommandLine {\n const {config} = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n const parseConfigHost = {\n useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,\n fileExists: ts.sys.fileExists,\n readDirectory: ts.sys.readDirectory,\n readFile: ts.sys.readFile,\n };\n\n // Throw if incorrect arguments are passed to this function. Passing relative base paths\n // results in root directories not being resolved and in later type checking runtime errors.\n // More details can be found here: https://github.com/microsoft/TypeScript/issues/37731.\n if (!path.isAbsolute(basePath)) {\n throw Error('Unexpected relative base path has been specified.');\n }\n\n return ts.parseJsonConfigFileContent(config, parseConfigHost, basePath, {});\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport ts from 'typescript';\n\nimport {getImportOfIdentifier, getImportSpecifier, removeSymbolFromNamedImports} from '../../utils/typescript/imports';\nimport {closestNode} from '../../utils/typescript/nodes';\n\nexport const routerLink = 'RouterLink';\nexport const routerLinkWithHref = 'RouterLinkWithHref';\nexport const routerModule = '@angular/router';\n\nexport interface RewriteEntity {\n startPos: number;\n width: number;\n replacement: string;\n}\n\nexport type RewriteFn = (startPos: number, width: number, text: string) => void;\n\nexport function migrateFile(\n sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker, rewrite: RewriteFn) {\n const routerLinkWithHrefSpec = getImportSpecifier(sourceFile, routerModule, routerLinkWithHref);\n\n // No `RouterLinkWithHref` found, nothing to migrate, exit early.\n if (routerLinkWithHrefSpec === null) return;\n\n let rewrites = findUsages(sourceFile, typeChecker);\n\n // There are some usages of the `RouterLinkWithHref` symbol, which need to\n // be rewritten to `RouterLink` instead. Let's check if the `RouterLink` is\n // already imported.\n const routerLinkSpec = getImportSpecifier(sourceFile, routerModule, routerLink);\n\n if (routerLinkSpec) {\n // The `RouterLink` symbol is already imported, just drop the `RouterLinkWithHref` one.\n const routerLinkNamedImports =\n routerLinkWithHrefSpec ? closestNode(routerLinkWithHrefSpec, ts.isNamedImports) : null;\n if (routerLinkNamedImports !== null) {\n // Given an original import like this one:\n // ```\n // import {RouterModule, RouterLinkWithHref, RouterLink} from '@angular/router';\n // ```\n // The code below removes the `RouterLinkWithHref` from the named imports section\n // (i.e. `{RouterModule, RouterLinkWithHref, RouterLink}`) and prints an updated\n // version (`{RouterModule, RouterLink}`) to a string, which is used as a\n // replacement.\n const rewrittenNamedImports =\n removeSymbolFromNamedImports(routerLinkNamedImports, routerLinkWithHrefSpec);\n const printer = ts.createPrinter();\n const replacement =\n printer.printNode(ts.EmitHint.Unspecified, rewrittenNamedImports, sourceFile);\n rewrites.push({\n startPos: routerLinkNamedImports.getStart(),\n width: routerLinkNamedImports.getWidth(),\n replacement: replacement,\n });\n }\n } else {\n // The `RouterLink` symbol is not imported, but the `RouterLinkWithHref` is imported,\n // so rewrite `RouterLinkWithHref` -> `RouterLink`.\n rewrites.push({\n startPos: routerLinkWithHrefSpec.getStart(),\n width: routerLinkWithHrefSpec.getWidth(),\n replacement: routerLink,\n });\n }\n\n // Process rewrites last-to-first (based on start pos) to avoid offset shifts during rewrites.\n rewrites = sortByStartPosDescending(rewrites);\n for (const usage of rewrites) {\n rewrite(usage.startPos, usage.width, usage.replacement);\n }\n}\n\nfunction findUsages(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker): RewriteEntity[] {\n const usages: RewriteEntity[] = [];\n const visitNode = (node: ts.Node) => {\n if (ts.isImportSpecifier(node)) {\n // Skip this node and all of its children; imports are a special case.\n return;\n }\n if (ts.isIdentifier(node)) {\n const importIdentifier = getImportOfIdentifier(typeChecker, node);\n if (importIdentifier?.importModule === routerModule &&\n importIdentifier.name === routerLinkWithHref) {\n usages.push({\n startPos: node.getStart(),\n width: node.getWidth(),\n replacement: routerLink,\n });\n }\n }\n ts.forEachChild(node, visitNode);\n };\n ts.forEachChild(sourceFile, visitNode);\n return usages;\n}\n\n/**\n * Sort all found usages based on their start positions in the source file in descending order (i.e.\n * last usage goes first on the list, etc). This is needed to avoid shifting offsets in the source\n * file (in case there are multiple usages) as we rewrite symbols.\n */\nfunction sortByStartPosDescending(rewrites: RewriteEntity[]): RewriteEntity[] {\n return rewrites.sort((entityA, entityB) => entityB.startPos - entityA.startPos);\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport ts from 'typescript';\n\nexport type Import = {\n name: string,\n importModule: string,\n node: ts.ImportDeclaration\n};\n\n/** Gets import information about the specified identifier by using the Type checker. */\nexport function getImportOfIdentifier(typeChecker: ts.TypeChecker, node: ts.Identifier): Import|\n null {\n const symbol = typeChecker.getSymbolAtLocation(node);\n\n if (!symbol || symbol.declarations === undefined || !symbol.declarations.length) {\n return null;\n }\n\n const decl = symbol.declarations[0];\n\n if (!ts.isImportSpecifier(decl)) {\n return null;\n }\n\n const importDecl = decl.parent.parent.parent;\n\n if (!ts.isStringLiteral(importDecl.moduleSpecifier)) {\n return null;\n }\n\n return {\n // Handles aliased imports: e.g. \"import {Component as myComp} from ...\";\n name: decl.propertyName ? decl.propertyName.text : decl.name.text,\n importModule: importDecl.moduleSpecifier.text,\n node: importDecl\n };\n}\n\n\n/**\n * Gets a top-level import specifier with a specific name that is imported from a particular module.\n * E.g. given a file that looks like:\n *\n * ```\n * import { Component, Directive } from '@angular/core';\n * import { Foo } from './foo';\n * ```\n *\n * Calling `getImportSpecifier(sourceFile, '@angular/core', 'Directive')` will yield the node\n * referring to `Directive` in the top import.\n *\n * @param sourceFile File in which to look for imports.\n * @param moduleName Name of the import's module.\n * @param specifierName Original name of the specifier to look for. Aliases will be resolved to\n * their original name.\n */\nexport function getImportSpecifier(\n sourceFile: ts.SourceFile, moduleName: string|RegExp,\n specifierName: string): ts.ImportSpecifier|null {\n for (const node of sourceFile.statements) {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {\n const isMatch = typeof moduleName === 'string' ? node.moduleSpecifier.text === moduleName :\n moduleName.test(node.moduleSpecifier.text);\n const namedBindings = node.importClause?.namedBindings;\n if (isMatch && namedBindings && ts.isNamedImports(namedBindings)) {\n const match = findImportSpecifier(namedBindings.elements, specifierName);\n if (match) {\n return match;\n }\n }\n }\n }\n\n return null;\n}\n\n\n/**\n * Replaces an import inside a named imports node with a different one.\n *\n * @param node Node that contains the imports.\n * @param existingImport Import that should be replaced.\n * @param newImportName Import that should be inserted.\n */\nexport function replaceImport(\n node: ts.NamedImports, existingImport: string, newImportName: string) {\n const isAlreadyImported = findImportSpecifier(node.elements, newImportName);\n if (isAlreadyImported) {\n return node;\n }\n\n const existingImportNode = findImportSpecifier(node.elements, existingImport);\n if (!existingImportNode) {\n return node;\n }\n\n const importPropertyName =\n existingImportNode.propertyName ? ts.factory.createIdentifier(newImportName) : undefined;\n const importName = existingImportNode.propertyName ? existingImportNode.name :\n ts.factory.createIdentifier(newImportName);\n\n return ts.factory.updateNamedImports(node, [\n ...node.elements.filter(current => current !== existingImportNode),\n // Create a new import while trying to preserve the alias of the old one.\n ts.factory.createImportSpecifier(false, importPropertyName, importName)\n ]);\n}\n\n/**\n * Removes a symbol from the named imports and updates a node\n * that represents a given named imports.\n *\n * @param node Node that contains the imports.\n * @param symbol Symbol that should be removed.\n * @returns An updated node (ts.NamedImports).\n */\nexport function removeSymbolFromNamedImports(node: ts.NamedImports, symbol: ts.ImportSpecifier) {\n return ts.factory.updateNamedImports(node, [\n ...node.elements.filter(current => current !== symbol),\n ]);\n}\n\n/** Finds an import specifier with a particular name. */\nexport function findImportSpecifier(\n nodes: ts.NodeArray<ts.ImportSpecifier>, specifierName: string): ts.ImportSpecifier|undefined {\n return nodes.find(element => {\n const {name, propertyName} = element;\n return propertyName ? propertyName.text === specifierName : name.text === specifierName;\n });\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport ts from 'typescript';\n\n/** Checks whether the given TypeScript node has the specified modifier set. */\nexport function hasModifier(node: ts.Node, modifierKind: ts.SyntaxKind) {\n return !!node.modifiers && node.modifiers.some(m => m.kind === modifierKind);\n}\n\n/** Find the closest parent node of a particular kind. */\nexport function closestNode<T extends ts.Node>(node: ts.Node, predicate: (n: ts.Node) => n is T): T|\n null {\n let current = node.parent;\n\n while (current && !ts.isSourceFile(current)) {\n if (predicate(current)) {\n return current;\n }\n current = current.parent;\n }\n\n return null;\n}\n\n/**\n * Checks whether a particular node is part of a null check. E.g. given:\n * `foo.bar ? foo.bar.value : null` the null check would be `foo.bar`.\n */\nexport function isNullCheck(node: ts.Node): boolean {\n if (!node.parent) {\n return false;\n }\n\n // `foo.bar && foo.bar.value` where `node` is `foo.bar`.\n if (ts.isBinaryExpression(node.parent) && node.parent.left === node) {\n return true;\n }\n\n // `foo.bar && foo.bar.parent && foo.bar.parent.value`\n // where `node` is `foo.bar`.\n if (node.parent.parent && ts.isBinaryExpression(node.parent.parent) &&\n node.parent.parent.left === node.parent) {\n return true;\n }\n\n // `if (foo.bar) {...}` where `node` is `foo.bar`.\n if (ts.isIfStatement(node.parent) && node.parent.expression === node) {\n return true;\n }\n\n // `foo.bar ? foo.bar.value : null` where `node` is `foo.bar`.\n if (ts.isConditionalExpression(node.parent) && node.parent.condition === node) {\n return true;\n }\n\n return false;\n}\n\n/** Checks whether a property access is safe (e.g. `foo.parent?.value`). */\nexport function isSafeAccess(node: ts.Node): boolean {\n return node.parent != null && ts.isPropertyAccessExpression(node.parent) &&\n node.parent.expression === node && node.parent.questionDotToken != null;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Rule, SchematicsException, Tree, UpdateRecorder} from '@angular-devkit/schematics';\nimport {relative} from 'path';\n\nimport {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';\nimport {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host';\n\nimport {migrateFile} from './util';\n\nexport default function(): Rule {\n return async (tree: Tree) => {\n const {buildPaths, testPaths} = await getProjectTsConfigPaths(tree);\n const basePath = process.cwd();\n const allPaths = [...buildPaths, ...testPaths];\n\n if (!allPaths.length) {\n throw new SchematicsException(\n 'Could not find any tsconfig file. Cannot run the `RouterLinkWithHref` migration.');\n }\n\n for (const tsconfigPath of allPaths) {\n runRouterLinkWithHrefMigration(tree, tsconfigPath, basePath);\n }\n };\n}\n\nfunction runRouterLinkWithHrefMigration(tree: Tree, tsconfigPath: string, basePath: string) {\n const program = createMigrationProgram(tree, tsconfigPath, basePath);\n const typeChecker = program.getTypeChecker();\n const sourceFiles =\n program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program));\n\n for (const sourceFile of sourceFiles) {\n let update: UpdateRecorder|null = null;\n\n const rewriter = (startPos: number, width: number, text: string|null) => {\n if (update === null) {\n // Lazily initialize update, because most files will not require migration.\n update = tree.beginUpdate(relative(basePath, sourceFile.fileName));\n }\n update.remove(startPos, width);\n if (text !== null) {\n update.insertLeft(startPos, text);\n }\n };\n\n migrateFile(sourceFile, typeChecker, rewriter);\n\n if (update !== null) {\n tree.commitUpdate(update);\n }\n }\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {json, normalize, virtualFs, workspaces} from '@angular-devkit/core';\nimport {Tree} from '@angular-devkit/schematics';\n\n/**\n * Gets all tsconfig paths from a CLI project by reading the workspace configuration\n * and looking for common tsconfig locations.\n */\nexport async function getProjectTsConfigPaths(tree: Tree):\n Promise<{buildPaths: string[]; testPaths: string[];}> {\n // Start with some tsconfig paths that are generally used within CLI projects. Note\n // that we are not interested in IDE-specific tsconfig files (e.g. /tsconfig.json)\n const buildPaths = new Set<string>();\n const testPaths = new Set<string>();\n\n const workspace = await getWorkspace(tree);\n for (const [, project] of workspace.projects) {\n for (const [name, target] of project.targets) {\n if (name !== 'build' && name !== 'test') {\n continue;\n }\n\n for (const [, options] of allTargetOptions(target)) {\n const tsConfig = options.tsConfig;\n // Filter out tsconfig files that don't exist in the CLI project.\n if (typeof tsConfig !== 'string' || !tree.exists(tsConfig)) {\n continue;\n }\n\n if (name === 'build') {\n buildPaths.add(normalize(tsConfig));\n } else {\n testPaths.add(normalize(tsConfig));\n }\n }\n }\n }\n\n return {\n buildPaths: [...buildPaths],\n testPaths: [...testPaths],\n };\n}\n\n/** Get options for all configurations for the passed builder target. */\nfunction*\n allTargetOptions(target: workspaces.TargetDefinition):\n Iterable<[string | undefined, Record<string, json.JsonValue|undefined>]> {\n if (target.options) {\n yield [undefined, target.options];\n }\n\n if (!target.configurations) {\n return;\n }\n\n for (const [name, options] of Object.entries(target.configurations)) {\n if (options) {\n yield [name, options];\n }\n }\n}\n\nfunction createHost(tree: Tree): workspaces.WorkspaceHost {\n return {\n async readFile(path: string): Promise<string> {\n const data = tree.read(path);\n if (!data) {\n throw new Error('File not found.');\n }\n\n return virtualFs.fileBufferToString(data);\n },\n async writeFile(path: string, data: string): Promise<void> {\n return tree.overwrite(path, data);\n },\n async isDirectory(path: string): Promise<boolean> {\n // Approximate a directory check.\n // We don't need to consider empty directories and hence this is a good enough approach.\n // This is also per documentation, see:\n // https://angular.io/guide/schematics-for-libraries#get-the-project-configuration\n return !tree.exists(path) && tree.getDir(path).subfiles.length > 0;\n },\n async isFile(path: string): Promise<boolean> {\n return tree.exists(path);\n },\n };\n}\n\nasync function getWorkspace(tree: Tree): Promise<workspaces.WorkspaceDefinition> {\n const host = createHost(tree);\n const {workspace} = await workspaces.readWorkspace('/', host);\n\n return workspace;\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport {Tree} from '@angular-devkit/schematics';\nimport {dirname, relative, resolve} from 'path';\nimport ts from 'typescript';\n\nimport {parseTsconfigFile} from './parse_tsconfig';\n\ntype FakeReadFileFn = (fileName: string) => string|undefined;\n\n/**\n * Creates a TypeScript program instance for a TypeScript project within\n * the virtual file system tree.\n * @param tree Virtual file system tree that contains the source files.\n * @param tsconfigPath Virtual file system path that resolves to the TypeScript project.\n * @param basePath Base path for the virtual file system tree.\n * @param fakeFileRead Optional file reader function. Can be used to overwrite files in\n * the TypeScript program, or to add in-memory files (e.g. to add global types).\n * @param additionalFiles Additional file paths that should be added to the program.\n */\nexport function createMigrationProgram(\n tree: Tree, tsconfigPath: string, basePath: string, fakeFileRead?: FakeReadFileFn,\n additionalFiles?: string[]) {\n const {rootNames, options, host} =\n createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles);\n return ts.createProgram(rootNames, options, host);\n}\n\n/**\n * Creates the options necessary to instantiate a TypeScript program.\n * @param tree Virtual file system tree that contains the source files.\n * @param tsconfigPath Virtual file system path that resolves to the TypeScript project.\n * @param basePath Base path for the virtual file system tree.\n * @param fakeFileRead Optional file reader function. Can be used to overwrite files in\n * the TypeScript program, or to add in-memory files (e.g. to add global types).\n * @param additionalFiles Additional file paths that should be added to the program.\n * @param optionOverrides Overrides of the parsed compiler options.\n */\nexport function createProgramOptions(\n tree: Tree, tsconfigPath: string, basePath: string, fakeFileRead?: FakeReadFileFn,\n additionalFiles?: string[], optionOverrides?: ts.CompilerOptions) {\n // Resolve the tsconfig path to an absolute path. This is needed as TypeScript otherwise\n // is not able to resolve root directories in the given tsconfig. More details can be found\n // in the following issue: https://github.com/microsoft/TypeScript/issues/37731.\n tsconfigPath = resolve(basePath, tsconfigPath);\n const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));\n const options = optionOverrides ? {...parsed.options, ...optionOverrides} : parsed.options;\n const host = createMigrationCompilerHost(tree, options, basePath, fakeFileRead);\n return {rootNames: parsed.fileNames.concat(additionalFiles || []), options, host};\n}\n\nfunction createMigrationCompilerHost(\n tree: Tree, options: ts.CompilerOptions, basePath: string,\n fakeRead?: FakeReadFileFn): ts.CompilerHost {\n const host = ts.createCompilerHost(options, true);\n const defaultReadFile = host.readFile;\n\n // We need to overwrite the host \"readFile\" method, as we want the TypeScript\n // program to be based on the file contents in the virtual file tree. Otherwise\n // if we run multiple migrations we might have intersecting changes and\n // source files.\n host.readFile = fileName => {\n const treeRelativePath = relative(basePath, fileName);\n let result: string|undefined = fakeRead?.(treeRelativePath);\n\n if (typeof result !== 'string') {\n // If the relative path resolved to somewhere outside of the tree, fall back to\n // TypeScript's default file reading function since the `tree` will throw an error.\n result = treeRelativePath.startsWith('..') ? defaultReadFile.call(host, fileName) :\n tree.read(treeRelativePath)?.toString();\n }\n\n // Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset,\n // which breaks the CLI UpdateRecorder.\n // See: https://github.com/angular/angular/pull/30719\n return typeof result === 'string' ? result.replace(/^\\uFEFF/, '') : undefined;\n };\n\n return host;\n}\n\n/**\n * Checks whether a file can be migrate by our automated migrations.\n * @param basePath Absolute path to the project.\n * @param sourceFile File being checked.\n * @param program Program that includes the source file.\n */\nexport function canMigrateFile(\n basePath: string, sourceFile: ts.SourceFile, program: ts.Program): boolean {\n // We shouldn't migrate .d.ts files, files from an external library or type checking files.\n if (sourceFile.fileName.endsWith('.ngtypecheck.ts') || sourceFile.isDeclarationFile ||\n program.isSourceFileFromExternalLibrary(sourceFile)) {\n return false;\n }\n\n // Our migrations are set up to create a `Program` from the project's tsconfig and to migrate all\n // the files within the program. This can include files that are outside of the Angular CLI\n // project. We can't migrate files outside of the project, because our file system interactions\n // go through the CLI's `Tree` which assumes that all files are within the project. See:\n // https://github.com/angular/angular-cli/blob/0b0961c9c233a825b6e4bb59ab7f0790f9b14676/packages/angular_devkit/schematics/src/tree/host-tree.ts#L131\n return !relative(basePath, sourceFile.fileName).startsWith('..');\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport * as path from 'path';\nimport ts from 'typescript';\n\nexport function parseTsconfigFile(tsconfigPath: string, basePath: string): ts.ParsedCommandLine {\n const {config} = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n const parseConfigHost = {\n useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,\n fileExists: ts.sys.fileExists,\n readDirectory: ts.sys.readDirectory,\n readFile: ts.sys.readFile,\n };\n\n // Throw if incorrect arguments are passed to this function. Passing relative base paths\n // results in root directories not being resolved and in later type checking runtime errors.\n // More details can be found here: https://github.com/microsoft/TypeScript/issues/37731.\n if (!path.isAbsolute(basePath)) {\n throw Error('Unexpected relative base path has been specified.');\n }\n\n return ts.parseJsonConfigFileContent(config, parseConfigHost, basePath, {});\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport ts from 'typescript';\n\nimport {getImportOfIdentifier, getImportSpecifier, removeSymbolFromNamedImports} from '../../utils/typescript/imports';\nimport {closestNode} from '../../utils/typescript/nodes';\n\nexport const routerLink = 'RouterLink';\nexport const routerLinkWithHref = 'RouterLinkWithHref';\nexport const routerModule = '@angular/router';\n\nexport interface RewriteEntity {\n startPos: number;\n width: number;\n replacement: string;\n}\n\nexport type RewriteFn = (startPos: number, width: number, text: string) => void;\n\nexport function migrateFile(\n sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker, rewrite: RewriteFn) {\n const routerLinkWithHrefSpec = getImportSpecifier(sourceFile, routerModule, routerLinkWithHref);\n\n // No `RouterLinkWithHref` found, nothing to migrate, exit early.\n if (routerLinkWithHrefSpec === null) return;\n\n let rewrites = findUsages(sourceFile, typeChecker);\n\n // There are some usages of the `RouterLinkWithHref` symbol, which need to\n // be rewritten to `RouterLink` instead. Let's check if the `RouterLink` is\n // already imported.\n const routerLinkSpec = getImportSpecifier(sourceFile, routerModule, routerLink);\n\n if (routerLinkSpec) {\n // The `RouterLink` symbol is already imported, just drop the `RouterLinkWithHref` one.\n const routerLinkNamedImports =\n routerLinkWithHrefSpec ? closestNode(routerLinkWithHrefSpec, ts.isNamedImports) : null;\n if (routerLinkNamedImports !== null) {\n // Given an original import like this one:\n // ```\n // import {RouterModule, RouterLinkWithHref, RouterLink} from '@angular/router';\n // ```\n // The code below removes the `RouterLinkWithHref` from the named imports section\n // (i.e. `{RouterModule, RouterLinkWithHref, RouterLink}`) and prints an updated\n // version (`{RouterModule, RouterLink}`) to a string, which is used as a\n // replacement.\n const rewrittenNamedImports =\n removeSymbolFromNamedImports(routerLinkNamedImports, routerLinkWithHrefSpec);\n const printer = ts.createPrinter();\n const replacement =\n printer.printNode(ts.EmitHint.Unspecified, rewrittenNamedImports, sourceFile);\n rewrites.push({\n startPos: routerLinkNamedImports.getStart(),\n width: routerLinkNamedImports.getWidth(),\n replacement: replacement,\n });\n }\n } else {\n // The `RouterLink` symbol is not imported, but the `RouterLinkWithHref` is imported,\n // so rewrite `RouterLinkWithHref` -> `RouterLink`.\n rewrites.push({\n startPos: routerLinkWithHrefSpec.getStart(),\n width: routerLinkWithHrefSpec.getWidth(),\n replacement: routerLink,\n });\n }\n\n // Process rewrites last-to-first (based on start pos) to avoid offset shifts during rewrites.\n rewrites = sortByStartPosDescending(rewrites);\n for (const usage of rewrites) {\n rewrite(usage.startPos, usage.width, usage.replacement);\n }\n}\n\nfunction findUsages(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker): RewriteEntity[] {\n const usages: RewriteEntity[] = [];\n const visitNode = (node: ts.Node) => {\n if (ts.isImportSpecifier(node)) {\n // Skip this node and all of its children; imports are a special case.\n return;\n }\n if (ts.isIdentifier(node)) {\n const importIdentifier = getImportOfIdentifier(typeChecker, node);\n if (importIdentifier?.importModule === routerModule &&\n importIdentifier.name === routerLinkWithHref) {\n usages.push({\n startPos: node.getStart(),\n width: node.getWidth(),\n replacement: routerLink,\n });\n }\n }\n ts.forEachChild(node, visitNode);\n };\n ts.forEachChild(sourceFile, visitNode);\n return usages;\n}\n\n/**\n * Sort all found usages based on their start positions in the source file in descending order (i.e.\n * last usage goes first on the list, etc). This is needed to avoid shifting offsets in the source\n * file (in case there are multiple usages) as we rewrite symbols.\n */\nfunction sortByStartPosDescending(rewrites: RewriteEntity[]): RewriteEntity[] {\n return rewrites.sort((entityA, entityB) => entityB.startPos - entityA.startPos);\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport ts from 'typescript';\n\nexport type Import = {\n name: string,\n importModule: string,\n node: ts.ImportDeclaration\n};\n\n/** Gets import information about the specified identifier by using the Type checker. */\nexport function getImportOfIdentifier(typeChecker: ts.TypeChecker, node: ts.Identifier): Import|\n null {\n const symbol = typeChecker.getSymbolAtLocation(node);\n\n if (!symbol || symbol.declarations === undefined || !symbol.declarations.length) {\n return null;\n }\n\n const decl = symbol.declarations[0];\n\n if (!ts.isImportSpecifier(decl)) {\n return null;\n }\n\n const importDecl = decl.parent.parent.parent;\n\n if (!ts.isStringLiteral(importDecl.moduleSpecifier)) {\n return null;\n }\n\n return {\n // Handles aliased imports: e.g. \"import {Component as myComp} from ...\";\n name: decl.propertyName ? decl.propertyName.text : decl.name.text,\n importModule: importDecl.moduleSpecifier.text,\n node: importDecl\n };\n}\n\n\n/**\n * Gets a top-level import specifier with a specific name that is imported from a particular module.\n * E.g. given a file that looks like:\n *\n * ```\n * import { Component, Directive } from '@angular/core';\n * import { Foo } from './foo';\n * ```\n *\n * Calling `getImportSpecifier(sourceFile, '@angular/core', 'Directive')` will yield the node\n * referring to `Directive` in the top import.\n *\n * @param sourceFile File in which to look for imports.\n * @param moduleName Name of the import's module.\n * @param specifierName Original name of the specifier to look for. Aliases will be resolved to\n * their original name.\n */\nexport function getImportSpecifier(\n sourceFile: ts.SourceFile, moduleName: string|RegExp,\n specifierName: string): ts.ImportSpecifier|null {\n for (const node of sourceFile.statements) {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {\n const isMatch = typeof moduleName === 'string' ? node.moduleSpecifier.text === moduleName :\n moduleName.test(node.moduleSpecifier.text);\n const namedBindings = node.importClause?.namedBindings;\n if (isMatch && namedBindings && ts.isNamedImports(namedBindings)) {\n const match = findImportSpecifier(namedBindings.elements, specifierName);\n if (match) {\n return match;\n }\n }\n }\n }\n\n return null;\n}\n\n\n/**\n * Replaces an import inside a named imports node with a different one.\n *\n * @param node Node that contains the imports.\n * @param existingImport Import that should be replaced.\n * @param newImportName Import that should be inserted.\n */\nexport function replaceImport(\n node: ts.NamedImports, existingImport: string, newImportName: string) {\n const isAlreadyImported = findImportSpecifier(node.elements, newImportName);\n if (isAlreadyImported) {\n return node;\n }\n\n const existingImportNode = findImportSpecifier(node.elements, existingImport);\n if (!existingImportNode) {\n return node;\n }\n\n const importPropertyName =\n existingImportNode.propertyName ? ts.factory.createIdentifier(newImportName) : undefined;\n const importName = existingImportNode.propertyName ? existingImportNode.name :\n ts.factory.createIdentifier(newImportName);\n\n return ts.factory.updateNamedImports(node, [\n ...node.elements.filter(current => current !== existingImportNode),\n // Create a new import while trying to preserve the alias of the old one.\n ts.factory.createImportSpecifier(false, importPropertyName, importName)\n ]);\n}\n\n/**\n * Removes a symbol from the named imports and updates a node\n * that represents a given named imports.\n *\n * @param node Node that contains the imports.\n * @param symbol Symbol that should be removed.\n * @returns An updated node (ts.NamedImports).\n */\nexport function removeSymbolFromNamedImports(node: ts.NamedImports, symbol: ts.ImportSpecifier) {\n return ts.factory.updateNamedImports(node, [\n ...node.elements.filter(current => current !== symbol),\n ]);\n}\n\n/** Finds an import specifier with a particular name. */\nexport function findImportSpecifier(\n nodes: ts.NodeArray<ts.ImportSpecifier>, specifierName: string): ts.ImportSpecifier|undefined {\n return nodes.find(element => {\n const {name, propertyName} = element;\n return propertyName ? propertyName.text === specifierName : name.text === specifierName;\n });\n}\n", "/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport ts from 'typescript';\n\n/** Checks whether the given TypeScript node has the specified modifier set. */\nexport function hasModifier(node: ts.Node, modifierKind: ts.SyntaxKind) {\n return ts.canHaveModifiers(node) && !!node.modifiers &&\n node.modifiers.some(m => m.kind === modifierKind);\n}\n\n/** Find the closest parent node of a particular kind. */\nexport function closestNode<T extends ts.Node>(node: ts.Node, predicate: (n: ts.Node) => n is T): T|\n null {\n let current = node.parent;\n\n while (current && !ts.isSourceFile(current)) {\n if (predicate(current)) {\n return current;\n }\n current = current.parent;\n }\n\n return null;\n}\n\n/**\n * Checks whether a particular node is part of a null check. E.g. given:\n * `foo.bar ? foo.bar.value : null` the null check would be `foo.bar`.\n */\nexport function isNullCheck(node: ts.Node): boolean {\n if (!node.parent) {\n return false;\n }\n\n // `foo.bar && foo.bar.value` where `node` is `foo.bar`.\n if (ts.isBinaryExpression(node.parent) && node.parent.left === node) {\n return true;\n }\n\n // `foo.bar && foo.bar.parent && foo.bar.parent.value`\n // where `node` is `foo.bar`.\n if (node.parent.parent && ts.isBinaryExpression(node.parent.parent) &&\n node.parent.parent.left === node.parent) {\n return true;\n }\n\n // `if (foo.bar) {...}` where `node` is `foo.bar`.\n if (ts.isIfStatement(node.parent) && node.parent.expression === node) {\n return true;\n }\n\n // `foo.bar ? foo.bar.value : null` where `node` is `foo.bar`.\n if (ts.isConditionalExpression(node.parent) && node.parent.condition === node) {\n return true;\n }\n\n return false;\n}\n\n/** Checks whether a property access is safe (e.g. `foo.parent?.value`). */\nexport function isSafeAccess(node: ts.Node): boolean {\n return node.parent != null && ts.isPropertyAccessExpression(node.parent) &&\n node.parent.expression === node && node.parent.questionDotToken != null;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_path", "path", "import_typescript", "ts", "ts", "import_typescript", "import_typescript", "ts", "ts", "import_typescript", "ts", "ts"]
7
7
  }