@angular/core 15.1.1 → 15.1.3
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.
- package/esm2020/src/application_ref.mjs +1 -1
- package/esm2020/src/version.mjs +1 -1
- package/esm2020/testing/src/logger.mjs +3 -3
- package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
- package/fesm2015/core.mjs +2 -2
- package/fesm2015/core.mjs.map +1 -1
- package/fesm2015/testing.mjs +2 -2
- package/fesm2015/testing.mjs.map +1 -1
- package/fesm2020/core.mjs +2 -2
- package/fesm2020/core.mjs.map +1 -1
- package/fesm2020/testing.mjs +2 -2
- package/fesm2020/testing.mjs.map +1 -1
- package/index.d.ts +5 -2
- package/package.json +1 -1
- package/schematics/migrations/relative-link-resolution/bundle.js +9 -9
- package/schematics/migrations/relative-link-resolution/bundle.js.map +2 -2
- package/schematics/migrations/router-link-with-href/bundle.js +12 -12
- package/schematics/migrations/router-link-with-href/bundle.js.map +2 -2
- package/testing/index.d.ts +1 -1
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v15.1.
|
|
2
|
+
* @license Angular v15.1.3
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -628,9 +628,11 @@ export declare interface BootstrapOptions {
|
|
|
628
628
|
* Optionally specify coalescing event change detections or not.
|
|
629
629
|
* Consider the following case.
|
|
630
630
|
*
|
|
631
|
+
* ```
|
|
631
632
|
* <div (click)="doSomething()">
|
|
632
633
|
* <button (click)="doSomethingElse()"></button>
|
|
633
634
|
* </div>
|
|
635
|
+
* ```
|
|
634
636
|
*
|
|
635
637
|
* When button is clicked, because of the event bubbling, both
|
|
636
638
|
* event handlers will be called and 2 change detections will be
|
|
@@ -649,12 +651,13 @@ export declare interface BootstrapOptions {
|
|
|
649
651
|
* into a single change detection.
|
|
650
652
|
*
|
|
651
653
|
* Consider the following case.
|
|
652
|
-
*
|
|
654
|
+
* ```
|
|
653
655
|
* for (let i = 0; i < 10; i ++) {
|
|
654
656
|
* ngZone.run(() => {
|
|
655
657
|
* // do something
|
|
656
658
|
* });
|
|
657
659
|
* }
|
|
660
|
+
* ```
|
|
658
661
|
*
|
|
659
662
|
* This case triggers the change detection multiple times.
|
|
660
663
|
* With ngZoneRunCoalescing options, all change detections in an event loop trigger only once.
|
package/package.json
CHANGED
|
@@ -42,7 +42,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
// bazel-out/
|
|
45
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/migrations/relative-link-resolution/index.mjs
|
|
46
46
|
var relative_link_resolution_exports = {};
|
|
47
47
|
__export(relative_link_resolution_exports, {
|
|
48
48
|
default: () => relative_link_resolution_default
|
|
@@ -51,7 +51,7 @@ module.exports = __toCommonJS(relative_link_resolution_exports);
|
|
|
51
51
|
var import_schematics = require("@angular-devkit/schematics");
|
|
52
52
|
var import_path2 = require("path");
|
|
53
53
|
|
|
54
|
-
// bazel-out/
|
|
54
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/project_tsconfig_paths.mjs
|
|
55
55
|
var import_core = require("@angular-devkit/core");
|
|
56
56
|
function getProjectTsConfigPaths(tree) {
|
|
57
57
|
return __async(this, null, function* () {
|
|
@@ -131,11 +131,11 @@ function getWorkspace(tree) {
|
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
// bazel-out/
|
|
134
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
|
|
135
135
|
var import_path = require("path");
|
|
136
136
|
var import_typescript2 = __toESM(require("typescript"), 1);
|
|
137
137
|
|
|
138
|
-
// bazel-out/
|
|
138
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/typescript/parse_tsconfig.mjs
|
|
139
139
|
var path = __toESM(require("path"), 1);
|
|
140
140
|
var import_typescript = __toESM(require("typescript"), 1);
|
|
141
141
|
function parseTsconfigFile(tsconfigPath, basePath) {
|
|
@@ -152,7 +152,7 @@ function parseTsconfigFile(tsconfigPath, basePath) {
|
|
|
152
152
|
return import_typescript.default.parseJsonConfigFileContent(config, parseConfigHost, basePath, {});
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
// bazel-out/
|
|
155
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
|
|
156
156
|
function createMigrationProgram(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles) {
|
|
157
157
|
tsconfigPath = (0, import_path.resolve)(basePath, tsconfigPath);
|
|
158
158
|
const parsed = parseTsconfigFile(tsconfigPath, (0, import_path.dirname)(tsconfigPath));
|
|
@@ -167,10 +167,10 @@ function createMigrationCompilerHost(tree, options, basePath, fakeRead) {
|
|
|
167
167
|
var _a;
|
|
168
168
|
const treeRelativePath = (0, import_path.relative)(basePath, fileName);
|
|
169
169
|
let result = fakeRead == null ? void 0 : fakeRead(treeRelativePath);
|
|
170
|
-
if (result
|
|
170
|
+
if (typeof result !== "string") {
|
|
171
171
|
result = treeRelativePath.startsWith("..") ? defaultReadFile.call(host, fileName) : (_a = tree.read(treeRelativePath)) == null ? void 0 : _a.toString();
|
|
172
172
|
}
|
|
173
|
-
return result ? result.replace(/^\uFEFF/, "") : void 0;
|
|
173
|
+
return typeof result === "string" ? result.replace(/^\uFEFF/, "") : void 0;
|
|
174
174
|
};
|
|
175
175
|
return host;
|
|
176
176
|
}
|
|
@@ -181,7 +181,7 @@ function canMigrateFile(basePath, sourceFile, program) {
|
|
|
181
181
|
return !(0, import_path.relative)(basePath, sourceFile.fileName).startsWith("..");
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
// bazel-out/
|
|
184
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/migrations/relative-link-resolution/util.mjs
|
|
185
185
|
var import_typescript3 = __toESM(require("typescript"), 1);
|
|
186
186
|
var relativeLinkResolution = "relativeLinkResolution";
|
|
187
187
|
var knownConfigValues = /* @__PURE__ */ new Set([`'legacy'`, `'corrected'`]);
|
|
@@ -221,7 +221,7 @@ function sortByStartPosDescending(rewrites) {
|
|
|
221
221
|
return rewrites.sort((entityA, entityB) => entityB.startPos - entityA.startPos);
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
// bazel-out/
|
|
224
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/migrations/relative-link-resolution/index.mjs
|
|
225
225
|
function relative_link_resolution_default() {
|
|
226
226
|
return (tree) => __async(this, null, function* () {
|
|
227
227
|
const { buildPaths, testPaths } = yield getProjectTsConfigPaths(tree);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../../packages/core/schematics/migrations/relative-link-resolution/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/relative-link-resolution/util.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. ' +\n 'Cannot run a migration to cleanup the deprecated `relativeLinkResolution` config option.');\n }\n\n for (const tsconfigPath of allPaths) {\n runRelativeLinkResolutionMigration(tree, tsconfigPath, basePath);\n }\n };\n}\n\nfunction runRelativeLinkResolutionMigration(tree: Tree, tsconfigPath: string, basePath: string) {\n const {program} = createMigrationProgram(tree, tsconfigPath, basePath);\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, origLength: number, text: string) => {\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, origLength);\n update.insertLeft(startPos, text);\n };\n\n migrateFile(sourceFile, 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';\nimport {parseTsconfigFile} from './parse_tsconfig';\n\nexport type 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 // 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 host = createMigrationCompilerHost(tree, parsed.options, basePath, fakeFileRead);\n const program =\n ts.createProgram(parsed.fileNames.concat(additionalFiles || []), parsed.options, host);\n return {parsed, host, program};\n}\n\nexport function 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 (result === undefined) {\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 result ? 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 or files from an external library.\n if (sourceFile.isDeclarationFile || 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\nconst relativeLinkResolution = 'relativeLinkResolution';\nconst knownConfigValues = new Set([`'legacy'`, `'corrected'`]);\n\nexport interface RewriteEntity {\n startPos: number;\n width: number;\n replacement: string;\n}\n\nexport interface MigratableNode {\n objectLiteral: ts.ObjectLiteralExpression;\n property: ts.ObjectLiteralElementLike;\n}\n\nexport type RewriteFn = (startPos: number, origLength: number, text: string) => void;\n\nexport function migrateFile(sourceFile: ts.SourceFile, rewriteFn: RewriteFn) {\n let rewrites: RewriteEntity[] = [];\n const usages = getUsages(sourceFile);\n for (const {objectLiteral, property} of usages) {\n const replacementNode = ts.factory.updateObjectLiteralExpression(\n objectLiteral, objectLiteral.properties.filter(prop => prop !== property));\n const printer = ts.createPrinter();\n const replacementText = printer.printNode(ts.EmitHint.Unspecified, replacementNode, sourceFile);\n rewrites.push({\n startPos: objectLiteral.getStart(),\n width: objectLiteral.getWidth(),\n replacement: replacementText,\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 rewrite of rewrites) {\n rewriteFn(rewrite.startPos, rewrite.width, rewrite.replacement);\n }\n}\n\nfunction getUsages(sourceFile: ts.SourceFile): MigratableNode[] {\n const usages: MigratableNode[] = [];\n const visitNode = (node: ts.Node) => {\n if (ts.isObjectLiteralExpression(node)) {\n // Look for patterns like the following:\n // ```\n // { ... relativeLinkResolution: 'legacy', ... }\n // ```\n // or:\n // ```\n // { ... relativeLinkResolution: 'corrected', ... }\n // ```\n // If the value is unknown (i.e. not 'legacy' or 'corrected'),\n // do not attempt to rewrite (this might be an application-specific\n // configuration, not a part of Router).\n const property = node.properties.find(\n prop => ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) &&\n prop.name.text === relativeLinkResolution &&\n knownConfigValues.has(prop.initializer.getText()));\n if (property) {\n usages.push({objectLiteral: node, property});\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"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAQA,wBAA8D;AAC9D,IAAAA,eAAuB;;;ACDvB,kBAAqD;AAOrD,SAAsB,wBAAwB,MAAU;;AAItD,UAAM,aAAa,oBAAI,IAAG;AAC1B,UAAM,YAAY,oBAAI,IAAG;AAEzB,UAAM,YAAY,MAAM,aAAa,IAAI;AACzC,eAAW,CAAC,EAAE,OAAO,KAAK,UAAU,UAAU;AAC5C,iBAAW,CAAC,MAAM,MAAM,KAAK,QAAQ,SAAS;AAC5C,YAAI,SAAS,WAAW,SAAS,QAAQ;AACvC;;AAGF,mBAAW,CAAC,EAAE,OAAO,KAAK,iBAAiB,MAAM,GAAG;AAClD,gBAAM,WAAW,QAAQ;AAEzB,cAAI,OAAO,aAAa,YAAY,CAAC,KAAK,OAAO,QAAQ,GAAG;AAC1D;;AAGF,cAAI,SAAS,SAAS;AACpB,uBAAW,QAAI,uBAAU,QAAQ,CAAC;iBAC7B;AACL,sBAAU,QAAI,uBAAU,QAAQ,CAAC;;;;;AAMzC,WAAO;MACL,YAAY,CAAC,GAAG,UAAU;MAC1B,WAAW,CAAC,GAAG,SAAS;;EAE5B;;AAGA,UACI,iBAAiB,QAAmC;AAEtD,MAAI,OAAO,SAAS;AAClB,UAAM,CAAC,QAAW,OAAO,OAAO;;AAGlC,MAAI,CAAC,OAAO,gBAAgB;AAC1B;;AAGF,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,OAAO,cAAc,GAAG;AACnE,QAAI,SAAS;AACX,YAAM,CAAC,MAAM,OAAO;;;AAG1B;AAEA,SAAS,WAAW,MAAU;AAC5B,SAAO;IACC,SAASC,OAAY;;AACzB,cAAM,OAAO,KAAK,KAAKA,KAAI;AAC3B,YAAI,CAAC,MAAM;AACT,gBAAM,IAAI,MAAM,iBAAiB;;AAGnC,eAAO,sBAAU,mBAAmB,IAAI;MAC1C;;IACM,UAAUA,OAAc,MAAY;;AACxC,eAAO,KAAK,UAAUA,OAAM,IAAI;MAClC;;IACM,YAAYA,OAAY;;AAK5B,eAAO,CAAC,KAAK,OAAOA,KAAI,KAAK,KAAK,OAAOA,KAAI,EAAE,SAAS,SAAS;MACnE;;IACM,OAAOA,OAAY;;AACvB,eAAO,KAAK,OAAOA,KAAI;MACzB;;;AAEJ;AAEA,SAAe,aAAa,MAAU;;AACpC,UAAM,OAAO,WAAW,IAAI;AAC5B,UAAM,EAAC,UAAS,IAAI,MAAM,uBAAW,cAAc,KAAK,IAAI;AAE5D,WAAO;EACT;;;;AC7FA,kBAAyC;AACzC,IAAAC,qBAAe;;;ACDf,WAAsB;AACtB,wBAAe;AAET,SAAU,kBAAkB,cAAsB,UAAgB;AACtE,QAAM,EAAC,OAAM,IAAI,kBAAAC,QAAG,eAAe,cAAc,kBAAAA,QAAG,IAAI,QAAQ;AAChE,QAAM,kBAAkB;IACtB,2BAA2B,kBAAAA,QAAG,IAAI;IAClC,YAAY,kBAAAA,QAAG,IAAI;IACnB,eAAe,kBAAAA,QAAG,IAAI;IACtB,UAAU,kBAAAA,QAAG,IAAI;;AAMnB,MAAI,CAAM,gBAAW,QAAQ,GAAG;AAC9B,UAAM,MAAM,mDAAmD;;AAGjE,SAAO,kBAAAA,QAAG,2BAA2B,QAAQ,iBAAiB,UAAU,CAAA,CAAE;AAC5E;;;
|
|
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. ' +\n 'Cannot run a migration to cleanup the deprecated `relativeLinkResolution` config option.');\n }\n\n for (const tsconfigPath of allPaths) {\n runRelativeLinkResolutionMigration(tree, tsconfigPath, basePath);\n }\n };\n}\n\nfunction runRelativeLinkResolutionMigration(tree: Tree, tsconfigPath: string, basePath: string) {\n const {program} = createMigrationProgram(tree, tsconfigPath, basePath);\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, origLength: number, text: string) => {\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, origLength);\n update.insertLeft(startPos, text);\n };\n\n migrateFile(sourceFile, 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\nexport type 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 // 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 host = createMigrationCompilerHost(tree, parsed.options, basePath, fakeFileRead);\n const program =\n ts.createProgram(parsed.fileNames.concat(additionalFiles || []), parsed.options, host);\n return {parsed, host, program};\n}\n\nexport function 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 or files from an external library.\n if (sourceFile.isDeclarationFile || 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\nconst relativeLinkResolution = 'relativeLinkResolution';\nconst knownConfigValues = new Set([`'legacy'`, `'corrected'`]);\n\nexport interface RewriteEntity {\n startPos: number;\n width: number;\n replacement: string;\n}\n\nexport interface MigratableNode {\n objectLiteral: ts.ObjectLiteralExpression;\n property: ts.ObjectLiteralElementLike;\n}\n\nexport type RewriteFn = (startPos: number, origLength: number, text: string) => void;\n\nexport function migrateFile(sourceFile: ts.SourceFile, rewriteFn: RewriteFn) {\n let rewrites: RewriteEntity[] = [];\n const usages = getUsages(sourceFile);\n for (const {objectLiteral, property} of usages) {\n const replacementNode = ts.factory.updateObjectLiteralExpression(\n objectLiteral, objectLiteral.properties.filter(prop => prop !== property));\n const printer = ts.createPrinter();\n const replacementText = printer.printNode(ts.EmitHint.Unspecified, replacementNode, sourceFile);\n rewrites.push({\n startPos: objectLiteral.getStart(),\n width: objectLiteral.getWidth(),\n replacement: replacementText,\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 rewrite of rewrites) {\n rewriteFn(rewrite.startPos, rewrite.width, rewrite.replacement);\n }\n}\n\nfunction getUsages(sourceFile: ts.SourceFile): MigratableNode[] {\n const usages: MigratableNode[] = [];\n const visitNode = (node: ts.Node) => {\n if (ts.isObjectLiteralExpression(node)) {\n // Look for patterns like the following:\n // ```\n // { ... relativeLinkResolution: 'legacy', ... }\n // ```\n // or:\n // ```\n // { ... relativeLinkResolution: 'corrected', ... }\n // ```\n // If the value is unknown (i.e. not 'legacy' or 'corrected'),\n // do not attempt to rewrite (this might be an application-specific\n // configuration, not a part of Router).\n const property = node.properties.find(\n prop => ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) &&\n prop.name.text === relativeLinkResolution &&\n knownConfigValues.has(prop.initializer.getText()));\n if (property) {\n usages.push({objectLiteral: node, property});\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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_path", "path", "import_typescript", "ts", "ts", "import_typescript", "ts"]
|
|
7
7
|
}
|
|
@@ -42,7 +42,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
// bazel-out/
|
|
45
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/index.mjs
|
|
46
46
|
var router_link_with_href_exports = {};
|
|
47
47
|
__export(router_link_with_href_exports, {
|
|
48
48
|
default: () => router_link_with_href_default
|
|
@@ -51,7 +51,7 @@ module.exports = __toCommonJS(router_link_with_href_exports);
|
|
|
51
51
|
var import_schematics = require("@angular-devkit/schematics");
|
|
52
52
|
var import_path2 = require("path");
|
|
53
53
|
|
|
54
|
-
// bazel-out/
|
|
54
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/project_tsconfig_paths.mjs
|
|
55
55
|
var import_core = require("@angular-devkit/core");
|
|
56
56
|
function getProjectTsConfigPaths(tree) {
|
|
57
57
|
return __async(this, null, function* () {
|
|
@@ -131,11 +131,11 @@ function getWorkspace(tree) {
|
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
// bazel-out/
|
|
134
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
|
|
135
135
|
var import_path = require("path");
|
|
136
136
|
var import_typescript2 = __toESM(require("typescript"), 1);
|
|
137
137
|
|
|
138
|
-
// bazel-out/
|
|
138
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/typescript/parse_tsconfig.mjs
|
|
139
139
|
var path = __toESM(require("path"), 1);
|
|
140
140
|
var import_typescript = __toESM(require("typescript"), 1);
|
|
141
141
|
function parseTsconfigFile(tsconfigPath, basePath) {
|
|
@@ -152,7 +152,7 @@ function parseTsconfigFile(tsconfigPath, basePath) {
|
|
|
152
152
|
return import_typescript.default.parseJsonConfigFileContent(config, parseConfigHost, basePath, {});
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
// bazel-out/
|
|
155
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/typescript/compiler_host.mjs
|
|
156
156
|
function createMigrationProgram(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles) {
|
|
157
157
|
tsconfigPath = (0, import_path.resolve)(basePath, tsconfigPath);
|
|
158
158
|
const parsed = parseTsconfigFile(tsconfigPath, (0, import_path.dirname)(tsconfigPath));
|
|
@@ -167,10 +167,10 @@ function createMigrationCompilerHost(tree, options, basePath, fakeRead) {
|
|
|
167
167
|
var _a;
|
|
168
168
|
const treeRelativePath = (0, import_path.relative)(basePath, fileName);
|
|
169
169
|
let result = fakeRead == null ? void 0 : fakeRead(treeRelativePath);
|
|
170
|
-
if (result
|
|
170
|
+
if (typeof result !== "string") {
|
|
171
171
|
result = treeRelativePath.startsWith("..") ? defaultReadFile.call(host, fileName) : (_a = tree.read(treeRelativePath)) == null ? void 0 : _a.toString();
|
|
172
172
|
}
|
|
173
|
-
return result ? result.replace(/^\uFEFF/, "") : void 0;
|
|
173
|
+
return typeof result === "string" ? result.replace(/^\uFEFF/, "") : void 0;
|
|
174
174
|
};
|
|
175
175
|
return host;
|
|
176
176
|
}
|
|
@@ -181,10 +181,10 @@ function canMigrateFile(basePath, sourceFile, program) {
|
|
|
181
181
|
return !(0, import_path.relative)(basePath, sourceFile.fileName).startsWith("..");
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
// bazel-out/
|
|
184
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/util.mjs
|
|
185
185
|
var import_typescript5 = __toESM(require("typescript"), 1);
|
|
186
186
|
|
|
187
|
-
// bazel-out/
|
|
187
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/typescript/imports.mjs
|
|
188
188
|
var import_typescript3 = __toESM(require("typescript"), 1);
|
|
189
189
|
function getImportOfIdentifier(typeChecker, node) {
|
|
190
190
|
const symbol = typeChecker.getSymbolAtLocation(node);
|
|
@@ -231,7 +231,7 @@ function findImportSpecifier(nodes, specifierName) {
|
|
|
231
231
|
});
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
// bazel-out/
|
|
234
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/utils/typescript/nodes.mjs
|
|
235
235
|
var import_typescript4 = __toESM(require("typescript"), 1);
|
|
236
236
|
function closestNode(node, kind) {
|
|
237
237
|
let current = node;
|
|
@@ -244,7 +244,7 @@ function closestNode(node, kind) {
|
|
|
244
244
|
return null;
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
// bazel-out/
|
|
247
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/util.mjs
|
|
248
248
|
var routerLink = "RouterLink";
|
|
249
249
|
var routerLinkWithHref = "RouterLinkWithHref";
|
|
250
250
|
var routerModule = "@angular/router";
|
|
@@ -303,7 +303,7 @@ function sortByStartPosDescending(rewrites) {
|
|
|
303
303
|
return rewrites.sort((entityA, entityB) => entityB.startPos - entityA.startPos);
|
|
304
304
|
}
|
|
305
305
|
|
|
306
|
-
// bazel-out/
|
|
306
|
+
// bazel-out/darwin-fastbuild/bin/packages/core/schematics/migrations/router-link-with-href/index.mjs
|
|
307
307
|
function router_link_with_href_default() {
|
|
308
308
|
return (tree) => __async(this, null, function* () {
|
|
309
309
|
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';\nimport {parseTsconfigFile} from './parse_tsconfig';\n\nexport type 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 // 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 host = createMigrationCompilerHost(tree, parsed.options, basePath, fakeFileRead);\n const program =\n ts.createProgram(parsed.fileNames.concat(additionalFiles || []), parsed.options, host);\n return {parsed, host, program};\n}\n\nexport function 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 (result === undefined) {\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 result ? 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 or files from an external library.\n if (sourceFile.isDeclarationFile || 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 = routerLinkWithHrefSpec ?\n closestNode<ts.NamedImports>(routerLinkWithHrefSpec, ts.SyntaxKind.NamedImports) :\n 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, specifierName: string): ts.ImportSpecifier|null {\n for (const node of sourceFile.statements) {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) &&\n node.moduleSpecifier.text === moduleName) {\n const namedBindings = node.importClause && node.importClause.namedBindings;\n if (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, kind: ts.SyntaxKind): T|null {\n let current: ts.Node = node;\n\n while (current && !ts.isSourceFile(current)) {\n if (current.kind === kind) {\n return current as T;\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": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAQA,wBAA8D;AAC9D,IAAAA,eAAuB;;;ACDvB,kBAAqD;AAOrD,SAAsB,wBAAwB,MAAU;;AAItD,UAAM,aAAa,oBAAI,IAAG;AAC1B,UAAM,YAAY,oBAAI,IAAG;AAEzB,UAAM,YAAY,MAAM,aAAa,IAAI;AACzC,eAAW,CAAC,EAAE,OAAO,KAAK,UAAU,UAAU;AAC5C,iBAAW,CAAC,MAAM,MAAM,KAAK,QAAQ,SAAS;AAC5C,YAAI,SAAS,WAAW,SAAS,QAAQ;AACvC;;AAGF,mBAAW,CAAC,EAAE,OAAO,KAAK,iBAAiB,MAAM,GAAG;AAClD,gBAAM,WAAW,QAAQ;AAEzB,cAAI,OAAO,aAAa,YAAY,CAAC,KAAK,OAAO,QAAQ,GAAG;AAC1D;;AAGF,cAAI,SAAS,SAAS;AACpB,uBAAW,QAAI,uBAAU,QAAQ,CAAC;iBAC7B;AACL,sBAAU,QAAI,uBAAU,QAAQ,CAAC;;;;;AAMzC,WAAO;MACL,YAAY,CAAC,GAAG,UAAU;MAC1B,WAAW,CAAC,GAAG,SAAS;;EAE5B;;AAGA,UACI,iBAAiB,QAAmC;AAEtD,MAAI,OAAO,SAAS;AAClB,UAAM,CAAC,QAAW,OAAO,OAAO;;AAGlC,MAAI,CAAC,OAAO,gBAAgB;AAC1B;;AAGF,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,OAAO,cAAc,GAAG;AACnE,QAAI,SAAS;AACX,YAAM,CAAC,MAAM,OAAO;;;AAG1B;AAEA,SAAS,WAAW,MAAU;AAC5B,SAAO;IACC,SAASC,OAAY;;AACzB,cAAM,OAAO,KAAK,KAAKA,KAAI;AAC3B,YAAI,CAAC,MAAM;AACT,gBAAM,IAAI,MAAM,iBAAiB;;AAGnC,eAAO,sBAAU,mBAAmB,IAAI;MAC1C;;IACM,UAAUA,OAAc,MAAY;;AACxC,eAAO,KAAK,UAAUA,OAAM,IAAI;MAClC;;IACM,YAAYA,OAAY;;AAK5B,eAAO,CAAC,KAAK,OAAOA,KAAI,KAAK,KAAK,OAAOA,KAAI,EAAE,SAAS,SAAS;MACnE;;IACM,OAAOA,OAAY;;AACvB,eAAO,KAAK,OAAOA,KAAI;MACzB;;;AAEJ;AAEA,SAAe,aAAa,MAAU;;AACpC,UAAM,OAAO,WAAW,IAAI;AAC5B,UAAM,EAAC,UAAS,IAAI,MAAM,uBAAW,cAAc,KAAK,IAAI;AAE5D,WAAO;EACT;;;;AC7FA,kBAAyC;AACzC,IAAAC,qBAAe;;;ACDf,WAAsB;AACtB,wBAAe;AAET,SAAU,kBAAkB,cAAsB,UAAgB;AACtE,QAAM,EAAC,OAAM,IAAI,kBAAAC,QAAG,eAAe,cAAc,kBAAAA,QAAG,IAAI,QAAQ;AAChE,QAAM,kBAAkB;IACtB,2BAA2B,kBAAAA,QAAG,IAAI;IAClC,YAAY,kBAAAA,QAAG,IAAI;IACnB,eAAe,kBAAAA,QAAG,IAAI;IACtB,UAAU,kBAAAA,QAAG,IAAI;;AAMnB,MAAI,CAAM,gBAAW,QAAQ,GAAG;AAC9B,UAAM,MAAM,mDAAmD;;AAGjE,SAAO,kBAAAA,QAAG,2BAA2B,QAAQ,iBAAiB,UAAU,CAAA,CAAE;AAC5E;;;
|
|
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\nexport type 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 // 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 host = createMigrationCompilerHost(tree, parsed.options, basePath, fakeFileRead);\n const program =\n ts.createProgram(parsed.fileNames.concat(additionalFiles || []), parsed.options, host);\n return {parsed, host, program};\n}\n\nexport function 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 or files from an external library.\n if (sourceFile.isDeclarationFile || 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 = routerLinkWithHrefSpec ?\n closestNode<ts.NamedImports>(routerLinkWithHrefSpec, ts.SyntaxKind.NamedImports) :\n 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, specifierName: string): ts.ImportSpecifier|null {\n for (const node of sourceFile.statements) {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) &&\n node.moduleSpecifier.text === moduleName) {\n const namedBindings = node.importClause && node.importClause.namedBindings;\n if (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, kind: ts.SyntaxKind): T|null {\n let current: ts.Node = node;\n\n while (current && !ts.isSourceFile(current)) {\n if (current.kind === kind) {\n return current as T;\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
|
}
|
package/testing/index.d.ts
CHANGED