This commit is contained in:
CHEVALLIER Abel
2025-11-13 16:23:22 +01:00
parent de9c515a47
commit cb235644dc
34924 changed files with 3811102 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
import { FileSystem, WorkspacePath } from './file-system';
import { LineAndCharacter } from './utils/line-mappings';
export interface ResolvedResource {
/** Class declaration that contains this resource. */
container: ts.ClassDeclaration | null;
/** File content of the given template. */
content: string;
/** Start offset of the resource content (e.g. in the inline source file) */
start: number;
/** Whether the given resource is inline or not. */
inline: boolean;
/** Path to the file that contains this resource. */
filePath: WorkspacePath;
/**
* Gets the character and line of a given position index in the resource.
* If the resource is declared inline within a TypeScript source file, the line and
* character are based on the full source file content.
*/
getCharacterAndLineOfPosition: (pos: number) => LineAndCharacter;
}
/**
* Collector that can be used to find Angular templates and stylesheets referenced within
* given TypeScript source files (inline or external referenced files)
*/
export declare class ComponentResourceCollector {
typeChecker: ts.TypeChecker;
private _fileSystem;
resolvedTemplates: ResolvedResource[];
resolvedStylesheets: ResolvedResource[];
constructor(typeChecker: ts.TypeChecker, _fileSystem: FileSystem);
visitNode(node: ts.Node): void;
private _visitClassDeclaration;
/** Resolves an external stylesheet by reading its content and computing line mappings. */
resolveExternalStylesheet(filePath: WorkspacePath, container: ts.ClassDeclaration | null): ResolvedResource | null;
private _trackExternalStylesheet;
}

View File

@@ -0,0 +1,164 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ComponentResourceCollector = void 0;
const path_1 = require("path");
const ts = require("typescript");
const decorators_1 = require("./utils/decorators");
const functions_1 = require("./utils/functions");
const line_mappings_1 = require("./utils/line-mappings");
const property_name_1 = require("./utils/property-name");
/**
* Collector that can be used to find Angular templates and stylesheets referenced within
* given TypeScript source files (inline or external referenced files)
*/
class ComponentResourceCollector {
constructor(typeChecker, _fileSystem) {
this.typeChecker = typeChecker;
this._fileSystem = _fileSystem;
this.resolvedTemplates = [];
this.resolvedStylesheets = [];
}
visitNode(node) {
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
this._visitClassDeclaration(node);
}
}
_visitClassDeclaration(node) {
const decorators = ts.getDecorators(node);
if (!decorators || !decorators.length) {
return;
}
const ngDecorators = (0, decorators_1.getAngularDecorators)(this.typeChecker, decorators);
const componentDecorator = ngDecorators.find(dec => dec.name === 'Component');
// In case no "@Component" decorator could be found on the current class, skip.
if (!componentDecorator) {
return;
}
const decoratorCall = componentDecorator.node.expression;
// In case the component decorator call is not valid, skip this class declaration.
if (decoratorCall.arguments.length !== 1) {
return;
}
const componentMetadata = (0, functions_1.unwrapExpression)(decoratorCall.arguments[0]);
// Ensure that the component metadata is an object literal expression.
if (!ts.isObjectLiteralExpression(componentMetadata)) {
return;
}
const sourceFile = node.getSourceFile();
const filePath = this._fileSystem.resolve(sourceFile.fileName);
const sourceFileDirPath = (0, path_1.dirname)(sourceFile.fileName);
// Walk through all component metadata properties and determine the referenced
// HTML templates (either external or inline)
componentMetadata.properties.forEach(property => {
if (!ts.isPropertyAssignment(property)) {
return;
}
const propertyName = (0, property_name_1.getPropertyNameText)(property.name);
if (propertyName === 'styles') {
const elements = ts.isArrayLiteralExpression(property.initializer)
? property.initializer.elements
: [property.initializer];
elements.forEach(el => {
if (ts.isStringLiteralLike(el)) {
// Need to add an offset of one to the start because the template quotes are
// not part of the template content.
const templateStartIdx = el.getStart() + 1;
const content = stripBom(el.text);
this.resolvedStylesheets.push({
filePath,
container: node,
content,
inline: true,
start: templateStartIdx,
getCharacterAndLineOfPosition: pos => ts.getLineAndCharacterOfPosition(sourceFile, pos + templateStartIdx),
});
}
});
}
// In case there is an inline template specified, ensure that the value is statically
// analyzable by checking if the initializer is a string literal-like node.
if (propertyName === 'template' && ts.isStringLiteralLike(property.initializer)) {
// Need to add an offset of one to the start because the template quotes are
// not part of the template content.
const templateStartIdx = property.initializer.getStart() + 1;
this.resolvedTemplates.push({
filePath,
container: node,
content: property.initializer.text,
inline: true,
start: templateStartIdx,
getCharacterAndLineOfPosition: pos => ts.getLineAndCharacterOfPosition(sourceFile, pos + templateStartIdx),
});
}
if (propertyName === 'styleUrls' && ts.isArrayLiteralExpression(property.initializer)) {
property.initializer.elements.forEach(el => {
if (ts.isStringLiteralLike(el)) {
this._trackExternalStylesheet(sourceFileDirPath, el, node);
}
});
}
if (propertyName === 'styleUrl' && ts.isStringLiteralLike(property.initializer)) {
this._trackExternalStylesheet(sourceFileDirPath, property.initializer, node);
}
if (propertyName === 'templateUrl' && ts.isStringLiteralLike(property.initializer)) {
const templateUrl = property.initializer.text;
const templatePath = this._fileSystem.resolve(sourceFileDirPath, templateUrl);
// In case the template does not exist in the file system, skip this
// external template.
if (!this._fileSystem.fileExists(templatePath)) {
return;
}
const fileContent = stripBom(this._fileSystem.read(templatePath) || '');
if (fileContent) {
const lineStartsMap = (0, line_mappings_1.computeLineStartsMap)(fileContent);
this.resolvedTemplates.push({
filePath: templatePath,
container: node,
content: fileContent,
inline: false,
start: 0,
getCharacterAndLineOfPosition: p => (0, line_mappings_1.getLineAndCharacterFromPosition)(lineStartsMap, p),
});
}
}
});
}
/** Resolves an external stylesheet by reading its content and computing line mappings. */
resolveExternalStylesheet(filePath, container) {
// Strip the BOM to avoid issues with the Sass compiler. See:
// https://github.com/angular/components/issues/24227#issuecomment-1200934258
const fileContent = stripBom(this._fileSystem.read(filePath) || '');
if (!fileContent) {
return null;
}
const lineStartsMap = (0, line_mappings_1.computeLineStartsMap)(fileContent);
return {
filePath: filePath,
container: container,
content: fileContent,
inline: false,
start: 0,
getCharacterAndLineOfPosition: pos => (0, line_mappings_1.getLineAndCharacterFromPosition)(lineStartsMap, pos),
};
}
_trackExternalStylesheet(sourceFileDirPath, node, container) {
const stylesheetPath = this._fileSystem.resolve(sourceFileDirPath, node.text);
const stylesheet = this.resolveExternalStylesheet(stylesheetPath, container);
if (stylesheet) {
this.resolvedStylesheets.push(stylesheet);
}
}
}
exports.ComponentResourceCollector = ComponentResourceCollector;
/** Strips the BOM from a string. */
function stripBom(content) {
return content.replace(/\uFEFF/g, '');
}
//# sourceMappingURL=component-resource-collector.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,72 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { UpdateRecorder } from './update-recorder';
/**
* A workspace path semantically is equivalent to the `Path` type provided by the
* Angular devkit. Paths denoted with such a type are guaranteed to be representing
* paths of a given virtual file system. This means that the root of a path can be
* different, and does not necessarily need to match the root in the real file system.
*
* For example: Consider we have a project in `/home/<..>/my-project`. Then a path
* like `/package.json` could actually refer to the `package.json` file in `my-project`.
* Note that in the real file system this would not match though.
*
* One might wonder why another type has been declared for such paths, when there
* already is the `Path` type provided by the devkit. We do this for a couple of reasons:
*
* 1. The update-tool cannot have a dependency on the Angular devkit as that one
* is not synced into g3. We want to be able to run migrations in g3 if needed.
*/
export type WorkspacePath = string & {
__PRIVATE_DEVKIT_PATH: void;
};
/** Interface that describes a directory. */
export interface DirectoryEntry {
/** List of directories inside the directory. */
directories: string[];
/** List of files inside the directory. */
files: string[];
}
/**
* Abstraction of the file system that migrations can use to record and apply
* changes. This is necessary to support virtual file systems as used in the CLI devkit.
*/
export declare abstract class FileSystem {
/** Checks whether the given file exists. */
abstract fileExists(path: WorkspacePath): boolean;
/** Checks whether the given directory exists. */
abstract directoryExists(path: WorkspacePath): boolean;
/** Gets the contents of the given file. */
abstract read(filePath: WorkspacePath): string | null;
/** Reads the given directory to retrieve children. */
abstract readDirectory(dirPath: WorkspacePath): DirectoryEntry;
/**
* Creates an update recorder for the given file. Edits can be recorded and
* committed in batches. Changes are not applied automatically because otherwise
* migrations would need to re-read files, or account for shifted file contents.
*/
abstract edit(filePath: WorkspacePath): UpdateRecorder;
/** Applies all changes which have been recorded in update recorders. */
abstract commitEdits(): void;
/** Creates a new file with the given content. */
abstract create(filePath: WorkspacePath, content: string): void;
/** Overwrites an existing file with the given content. */
abstract overwrite(filePath: WorkspacePath, content: string): void;
/** Deletes the given file. */
abstract delete(filePath: WorkspacePath): void;
/**
* Resolves given paths to a resolved path in the file system. For example, the devkit
* tree considers the actual workspace directory as file system root.
*
* Follows the same semantics as the native path `resolve` method. i.e. segments
* are processed in reverse. The last segment is considered the target and the
* function will iterate from the target through other segments until it finds an
* absolute path segment.
*/
abstract resolve(...segments: string[]): WorkspacePath;
}

View File

@@ -0,0 +1,18 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileSystem = void 0;
/**
* Abstraction of the file system that migrations can use to record and apply
* changes. This is necessary to support virtual file systems as used in the CLI devkit.
*/
class FileSystem {
}
exports.FileSystem = FileSystem;
//# sourceMappingURL=file-system.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"file-system.js","sourceRoot":"","sources":["file-system.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAkCH;;;GAGG;AACH,MAAsB,UAAU;CAiC/B;AAjCD,gCAiCC"}

74
node_modules/@angular/cdk/schematics/update-tool/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,74 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
import { FileSystem, WorkspacePath } from './file-system';
import { UpdateLogger } from './logger';
import { MigrationCtor } from './migration';
import { TargetVersion } from './target-version';
/**
* An update project that can be run against individual migrations. An update project
* accepts a TypeScript program and a context that is provided to all migrations. The
* context is usually not used by migrations, but in some cases migrations rely on
* specifics from the tool that performs the update (e.g. the Angular CLI). In those cases,
* the context can provide the necessary specifics to the migrations in a type-safe way.
*/
export declare class UpdateProject<Context> {
/** Context provided to all migrations. */
private _context;
/** TypeScript program using workspace paths. */
private _program;
/** File system used for reading, writing and editing files. */
private _fileSystem;
/**
* Set of analyzed files. Used for avoiding multiple migration runs if
* files overlap between targets.
*/
private _analyzedFiles;
/** Logger used for printing messages. */
private _logger;
private readonly _typeChecker;
constructor(
/** Context provided to all migrations. */
_context: Context,
/** TypeScript program using workspace paths. */
_program: ts.Program,
/** File system used for reading, writing and editing files. */
_fileSystem: FileSystem,
/**
* Set of analyzed files. Used for avoiding multiple migration runs if
* files overlap between targets.
*/
_analyzedFiles?: Set<WorkspacePath>,
/** Logger used for printing messages. */
_logger?: UpdateLogger);
/**
* Migrates the project to the specified target version.
* @param migrationTypes Migrations that should be run.
* @param target Version the project should be updated to. Can be `null` if the set of
* specified migrations runs regardless of a target version.
* @param data Upgrade data that is passed to all migration rules.
* @param additionalStylesheetPaths Additional stylesheets that should be migrated, if not
* referenced in an Angular component. This is helpful for global stylesheets in a project.
* @param limitToDirectory If specified, changes will be limited to the given directory.
*/
migrate<Data>(migrationTypes: MigrationCtor<Data, Context>[], target: TargetVersion | null, data: Data, additionalStylesheetPaths?: string[], limitToDirectory?: string): {
hasFailures: boolean;
};
/**
* Creates instances of the given migrations with the specified target
* version and data.
*/
private _createMigrations;
/**
* Creates a program from the specified tsconfig and patches the host
* to read files and directories through the given file system.
*
* @throws {TsconfigParseError} If the tsconfig could not be parsed.
*/
static createProgramFromTsconfig(tsconfigPath: WorkspacePath, fs: FileSystem): ts.Program;
}

172
node_modules/@angular/cdk/schematics/update-tool/index.js generated vendored Executable file
View File

@@ -0,0 +1,172 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.UpdateProject = void 0;
const ts = require("typescript");
const component_resource_collector_1 = require("./component-resource-collector");
const logger_1 = require("./logger");
const parse_tsconfig_1 = require("./utils/parse-tsconfig");
const virtual_host_1 = require("./utils/virtual-host");
/**
* An update project that can be run against individual migrations. An update project
* accepts a TypeScript program and a context that is provided to all migrations. The
* context is usually not used by migrations, but in some cases migrations rely on
* specifics from the tool that performs the update (e.g. the Angular CLI). In those cases,
* the context can provide the necessary specifics to the migrations in a type-safe way.
*/
class UpdateProject {
constructor(
/** Context provided to all migrations. */
_context,
/** TypeScript program using workspace paths. */
_program,
/** File system used for reading, writing and editing files. */
_fileSystem,
/**
* Set of analyzed files. Used for avoiding multiple migration runs if
* files overlap between targets.
*/
_analyzedFiles = new Set(),
/** Logger used for printing messages. */
_logger = logger_1.defaultLogger) {
this._context = _context;
this._program = _program;
this._fileSystem = _fileSystem;
this._analyzedFiles = _analyzedFiles;
this._logger = _logger;
this._typeChecker = this._program.getTypeChecker();
}
/**
* Migrates the project to the specified target version.
* @param migrationTypes Migrations that should be run.
* @param target Version the project should be updated to. Can be `null` if the set of
* specified migrations runs regardless of a target version.
* @param data Upgrade data that is passed to all migration rules.
* @param additionalStylesheetPaths Additional stylesheets that should be migrated, if not
* referenced in an Angular component. This is helpful for global stylesheets in a project.
* @param limitToDirectory If specified, changes will be limited to the given directory.
*/
migrate(migrationTypes, target, data, additionalStylesheetPaths, limitToDirectory) {
limitToDirectory && (limitToDirectory = this._fileSystem.resolve(limitToDirectory));
// Create instances of the specified migrations.
const migrations = this._createMigrations(migrationTypes, target, data);
// Creates the component resource collector. The collector can visit arbitrary
// TypeScript nodes and will find Angular component resources. Resources include
// templates and stylesheets. It also captures inline stylesheets and templates.
const resourceCollector = new component_resource_collector_1.ComponentResourceCollector(this._typeChecker, this._fileSystem);
// Collect all of the TypeScript source files we want to migrate. We don't
// migrate type definition files, or source files from external libraries.
const sourceFiles = this._program.getSourceFiles().filter(f => {
return (!f.isDeclarationFile &&
(limitToDirectory == null ||
this._fileSystem.resolve(f.fileName).startsWith(limitToDirectory)) &&
!this._program.isSourceFileFromExternalLibrary(f));
});
// Helper function that visits a given TypeScript node and collects all referenced
// component resources (i.e. stylesheets or templates). Additionally, the helper
// visits the node in each instantiated migration.
const visitNodeAndCollectResources = (node) => {
migrations.forEach(r => r.visitNode(node));
ts.forEachChild(node, visitNodeAndCollectResources);
resourceCollector.visitNode(node);
};
// Walk through all source file, if it has not been visited before, and
// visit found nodes while collecting potential resources.
sourceFiles.forEach(sourceFile => {
const resolvedPath = this._fileSystem.resolve(sourceFile.fileName);
// Do not visit source files which have been checked as part of a
// previously migrated TypeScript project.
if (!this._analyzedFiles.has(resolvedPath)) {
visitNodeAndCollectResources(sourceFile);
this._analyzedFiles.add(resolvedPath);
}
});
// Walk through all resolved templates and visit them in each instantiated
// migration. Note that this can only happen after source files have been
// visited because we find templates through the TypeScript source files.
resourceCollector.resolvedTemplates.forEach(template => {
// Do not visit the template if it has been checked before. Inline
// templates cannot be referenced multiple times.
if (template.inline || !this._analyzedFiles.has(template.filePath)) {
migrations.forEach(m => m.visitTemplate(template));
this._analyzedFiles.add(template.filePath);
}
});
// Walk through all resolved stylesheets and visit them in each instantiated
// migration. Note that this can only happen after source files have been
// visited because we find stylesheets through the TypeScript source files.
resourceCollector.resolvedStylesheets.forEach(stylesheet => {
// Do not visit the stylesheet if it has been checked before. Inline
// stylesheets cannot be referenced multiple times.
if (stylesheet.inline || !this._analyzedFiles.has(stylesheet.filePath)) {
migrations.forEach(r => r.visitStylesheet(stylesheet));
this._analyzedFiles.add(stylesheet.filePath);
}
});
// In some applications, developers will have global stylesheets which are not
// specified in any Angular component. Therefore we allow for additional stylesheets
// being specified. We visit them in each migration unless they have been already
// discovered before as actual component resource.
if (additionalStylesheetPaths) {
additionalStylesheetPaths.forEach(filePath => {
const resolvedPath = this._fileSystem.resolve(filePath);
if (limitToDirectory == null || resolvedPath.startsWith(limitToDirectory)) {
const stylesheet = resourceCollector.resolveExternalStylesheet(resolvedPath, null);
// Do not visit stylesheets which have been referenced from a component.
if (!this._analyzedFiles.has(resolvedPath) && stylesheet) {
migrations.forEach(r => r.visitStylesheet(stylesheet));
this._analyzedFiles.add(resolvedPath);
}
}
});
}
// Call the "postAnalysis" method for each migration.
migrations.forEach(r => r.postAnalysis());
// Collect all failures reported by individual migrations.
const failures = migrations.reduce((res, m) => res.concat(m.failures), []);
// In case there are failures, print these to the CLI logger as warnings.
if (failures.length) {
failures.forEach(({ filePath, message, position }) => {
const lineAndCharacter = position ? `@${position.line + 1}:${position.character + 1}` : '';
this._logger.warn(`${filePath}${lineAndCharacter} - ${message}`);
});
}
return {
hasFailures: !!failures.length,
};
}
/**
* Creates instances of the given migrations with the specified target
* version and data.
*/
_createMigrations(types, target, data) {
const result = [];
for (const ctor of types) {
const instance = new ctor(this._program, this._typeChecker, target, this._context, data, this._fileSystem, this._logger);
instance.init();
if (instance.enabled) {
result.push(instance);
}
}
return result;
}
/**
* Creates a program from the specified tsconfig and patches the host
* to read files and directories through the given file system.
*
* @throws {TsconfigParseError} If the tsconfig could not be parsed.
*/
static createProgramFromTsconfig(tsconfigPath, fs) {
const parsed = (0, parse_tsconfig_1.parseTsconfigFile)(fs.resolve(tsconfigPath), fs);
const host = (0, virtual_host_1.createFileSystemCompilerHost)(parsed.options, fs);
return ts.createProgram(parsed.fileNames, parsed.options, host);
}
}
exports.UpdateProject = UpdateProject;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}

15
node_modules/@angular/cdk/schematics/update-tool/logger.d.ts generated vendored Executable file
View File

@@ -0,0 +1,15 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export interface UpdateLogger {
debug(message: string): void;
error(message: string): void;
fatal(message: string): void;
info(message: string): void;
warn(message: string): void;
}
export declare const defaultLogger: UpdateLogger;

18
node_modules/@angular/cdk/schematics/update-tool/logger.js generated vendored Executable file
View File

@@ -0,0 +1,18 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultLogger = void 0;
exports.defaultLogger = {
debug: m => console.debug(m),
error: m => console.error(m),
fatal: m => console.error(m),
info: m => console.info(m),
warn: m => console.warn(m),
};
//# sourceMappingURL=logger.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"logger.js","sourceRoot":"","sources":["logger.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAUU,QAAA,aAAa,GAAiB;IACzC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CAC3B,CAAC"}

View File

@@ -0,0 +1,87 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
import { ResolvedResource } from './component-resource-collector';
import { FileSystem, WorkspacePath } from './file-system';
import { UpdateLogger } from './logger';
import { TargetVersion } from './target-version';
import { LineAndCharacter } from './utils/line-mappings';
export interface MigrationFailure {
filePath: WorkspacePath;
message: string;
position?: LineAndCharacter;
}
export type PostMigrationAction = void | {
/** Whether the package manager should run upon migration completion. */
runPackageManager: boolean;
};
/** Creates a constructor type for the specified type. */
export type Constructor<T> = new (...args: any[]) => T;
/** Gets a constructor type for the passed migration data. */
export type MigrationCtor<Data, Context = any> = Constructor<Migration<Data, Context>>;
export declare abstract class Migration<Data, Context = any> {
/** TypeScript program for the migration. */
program: ts.Program;
/** TypeChecker instance for the analysis program. */
typeChecker: ts.TypeChecker;
/**
* Version for which the migration rule should run. Null if the migration
* is invoked manually.
*/
targetVersion: TargetVersion | null;
/** Context data for the migration. */
context: Context;
/** Upgrade data passed to the migration. */
upgradeData: Data;
/** File system that can be used for modifying files. */
fileSystem: FileSystem;
/** Logger that can be used to print messages as part of the migration. */
logger: UpdateLogger;
/** List of migration failures that need to be reported. */
failures: MigrationFailure[];
/** Whether the migration is enabled or not. */
abstract enabled: boolean;
constructor(
/** TypeScript program for the migration. */
program: ts.Program,
/** TypeChecker instance for the analysis program. */
typeChecker: ts.TypeChecker,
/**
* Version for which the migration rule should run. Null if the migration
* is invoked manually.
*/
targetVersion: TargetVersion | null,
/** Context data for the migration. */
context: Context,
/** Upgrade data passed to the migration. */
upgradeData: Data,
/** File system that can be used for modifying files. */
fileSystem: FileSystem,
/** Logger that can be used to print messages as part of the migration. */
logger: UpdateLogger);
/** Method can be used to perform global analysis of the program. */
init(): void;
/**
* Method that will be called once all nodes, templates and stylesheets
* have been visited.
*/
postAnalysis(): void;
/**
* Method that will be called for each node in a given source file. Unlike tslint, this
* function will only retrieve TypeScript nodes that need to be casted manually. This
* allows us to only walk the program source files once per program and not per
* migration rule (significant performance boost).
*/
visitNode(node: ts.Node): void;
/** Method that will be called for each Angular template in the program. */
visitTemplate(template: ResolvedResource): void;
/** Method that will be called for each stylesheet in the program. */
visitStylesheet(stylesheet: ResolvedResource): void;
/** Creates a failure with a specified message at the given node location. */
protected createFailureAtNode(node: ts.Node, message: string): void;
}

View File

@@ -0,0 +1,70 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Migration = void 0;
const ts = require("typescript");
class Migration {
constructor(
/** TypeScript program for the migration. */
program,
/** TypeChecker instance for the analysis program. */
typeChecker,
/**
* Version for which the migration rule should run. Null if the migration
* is invoked manually.
*/
targetVersion,
/** Context data for the migration. */
context,
/** Upgrade data passed to the migration. */
upgradeData,
/** File system that can be used for modifying files. */
fileSystem,
/** Logger that can be used to print messages as part of the migration. */
logger) {
this.program = program;
this.typeChecker = typeChecker;
this.targetVersion = targetVersion;
this.context = context;
this.upgradeData = upgradeData;
this.fileSystem = fileSystem;
this.logger = logger;
/** List of migration failures that need to be reported. */
this.failures = [];
}
/** Method can be used to perform global analysis of the program. */
init() { }
/**
* Method that will be called once all nodes, templates and stylesheets
* have been visited.
*/
postAnalysis() { }
/**
* Method that will be called for each node in a given source file. Unlike tslint, this
* function will only retrieve TypeScript nodes that need to be casted manually. This
* allows us to only walk the program source files once per program and not per
* migration rule (significant performance boost).
*/
visitNode(node) { }
/** Method that will be called for each Angular template in the program. */
visitTemplate(template) { }
/** Method that will be called for each stylesheet in the program. */
visitStylesheet(stylesheet) { }
/** Creates a failure with a specified message at the given node location. */
createFailureAtNode(node, message) {
const sourceFile = node.getSourceFile();
this.failures.push({
filePath: this.fileSystem.resolve(sourceFile.fileName),
position: ts.getLineAndCharacterOfPosition(sourceFile, node.getStart()),
message: message,
});
}
}
exports.Migration = Migration;
//# sourceMappingURL=migration.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"migration.js","sourceRoot":"","sources":["migration.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,iCAAiC;AAuBjC,MAAsB,SAAS;IAO7B;IACE,4CAA4C;IACrC,OAAmB;IAC1B,qDAAqD;IAC9C,WAA2B;IAClC;;;OAGG;IACI,aAAmC;IAC1C,sCAAsC;IAC/B,OAAgB;IACvB,4CAA4C;IACrC,WAAiB;IACxB,wDAAwD;IACjD,UAAsB;IAC7B,0EAA0E;IACnE,MAAoB;QAfpB,YAAO,GAAP,OAAO,CAAY;QAEnB,gBAAW,GAAX,WAAW,CAAgB;QAK3B,kBAAa,GAAb,aAAa,CAAsB;QAEnC,YAAO,GAAP,OAAO,CAAS;QAEhB,gBAAW,GAAX,WAAW,CAAM;QAEjB,eAAU,GAAV,UAAU,CAAY;QAEtB,WAAM,GAAN,MAAM,CAAc;QAvB7B,2DAA2D;QAC3D,aAAQ,GAAuB,EAAE,CAAC;IAuB/B,CAAC;IAEJ,oEAAoE;IACpE,IAAI,KAAU,CAAC;IAEf;;;OAGG;IACH,YAAY,KAAU,CAAC;IAEvB;;;;;OAKG;IACH,SAAS,CAAC,IAAa,IAAS,CAAC;IAEjC,2EAA2E;IAC3E,aAAa,CAAC,QAA0B,IAAS,CAAC;IAElD,qEAAqE;IACrE,eAAe,CAAC,UAA4B,IAAS,CAAC;IAEtD,6EAA6E;IACnE,mBAAmB,CAAC,IAAa,EAAE,OAAe;QAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC;YACtD,QAAQ,EAAE,EAAE,CAAC,6BAA6B,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvE,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;IACL,CAAC;CACF;AA3DD,8BA2DC"}

View File

@@ -0,0 +1,16 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export * from './component-resource-collector';
export * from './file-system';
export * from './index';
export * from './migration';
export * from './target-version';
export * from './utils/decorators';
export * from './utils/imports';
export * from './utils/property-name';
export * from './version-changes';

View File

@@ -0,0 +1,33 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./component-resource-collector"), exports);
__exportStar(require("./file-system"), exports);
__exportStar(require("./index"), exports);
__exportStar(require("./migration"), exports);
__exportStar(require("./target-version"), exports);
__exportStar(require("./utils/decorators"), exports);
__exportStar(require("./utils/imports"), exports);
__exportStar(require("./utils/property-name"), exports);
__exportStar(require("./version-changes"), exports);
//# sourceMappingURL=public-api.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["public-api.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;AAEH,iEAA+C;AAC/C,gDAA8B;AAC9B,0CAAwB;AACxB,8CAA4B;AAC5B,mDAAiC;AACjC,qDAAmC;AACnC,kDAAgC;AAChC,wDAAsC;AACtC,oDAAkC"}

View File

@@ -0,0 +1,16 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
/** Possible versions that can be automatically migrated by `ng update`. */
export declare enum TargetVersion {
V20 = "version 20"
}
/**
* Returns all versions that are supported by "ng update". The versions are determined
* based on the "TargetVersion" enum.
*/
export declare function getAllVersionNames(): string[];

View File

@@ -0,0 +1,27 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.TargetVersion = void 0;
exports.getAllVersionNames = getAllVersionNames;
/** Possible versions that can be automatically migrated by `ng update`. */
// tslint:disable-next-line:prefer-const-enum
var TargetVersion;
(function (TargetVersion) {
TargetVersion["V20"] = "version 20";
})(TargetVersion || (exports.TargetVersion = TargetVersion = {}));
/**
* Returns all versions that are supported by "ng update". The versions are determined
* based on the "TargetVersion" enum.
*/
function getAllVersionNames() {
return Object.keys(TargetVersion).filter(enumValue => {
return typeof TargetVersion[enumValue] === 'string';
});
}
//# sourceMappingURL=target-version.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"target-version.js","sourceRoot":"","sources":["target-version.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAaH,gDAIC;AAfD,2EAA2E;AAE3E,6CAA6C;AAC7C,IAAY,aAEX;AAFD,WAAY,aAAa;IACvB,mCAAkB,CAAA;AACpB,CAAC,EAFW,aAAa,6BAAb,aAAa,QAExB;AAED;;;GAGG;AACH,SAAgB,kBAAkB;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;QACnD,OAAO,OAAQ,aAAoD,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC"}

View File

@@ -0,0 +1,13 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
/** Update recorder that can be used to apply changes to a source file. */
export interface UpdateRecorder {
insertLeft(index: number, content: string): UpdateRecorder;
insertRight(index: number, content: string): UpdateRecorder;
remove(index: number, length: number): UpdateRecorder;
}

View File

@@ -0,0 +1,10 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=update-recorder.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"update-recorder.js","sourceRoot":"","sources":["update-recorder.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}

View File

@@ -0,0 +1,22 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
import { Import } from './imports';
export type CallExpressionDecorator = ts.Decorator & {
expression: ts.CallExpression;
};
export interface NgDecorator {
name: string;
node: CallExpressionDecorator;
}
/**
* Gets all decorators which are imported from an Angular package
* (e.g. "@angular/core") from a list of decorators.
*/
export declare function getAngularDecorators(typeChecker: ts.TypeChecker, decorators: readonly ts.Decorator[]): readonly NgDecorator[];
export declare function getCallDecoratorImport(typeChecker: ts.TypeChecker, decorator: ts.Decorator): Import | null;

View File

@@ -0,0 +1,41 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAngularDecorators = getAngularDecorators;
exports.getCallDecoratorImport = getCallDecoratorImport;
const ts = require("typescript");
const imports_1 = require("./imports");
/**
* Gets all decorators which are imported from an Angular package
* (e.g. "@angular/core") from a list of decorators.
*/
function getAngularDecorators(typeChecker, decorators) {
return decorators
.map(node => ({ node, importData: getCallDecoratorImport(typeChecker, node) }))
.filter(({ importData }) => importData && importData.moduleName.startsWith('@angular/'))
.map(({ node, importData }) => ({
node: node,
name: importData.symbolName,
}));
}
function getCallDecoratorImport(typeChecker, decorator) {
if (!ts.isCallExpression(decorator.expression)) {
return null;
}
const valueExpr = decorator.expression.expression;
let identifier = null;
if (ts.isIdentifier(valueExpr)) {
identifier = valueExpr;
}
else if (ts.isPropertyAccessExpression(valueExpr) && ts.isIdentifier(valueExpr.name)) {
identifier = valueExpr.name;
}
return identifier ? (0, imports_1.getImportOfIdentifier)(identifier, typeChecker) : null;
}
//# sourceMappingURL=decorators.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["decorators.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAmBH,oDAWC;AAED,wDAeC;AA7CD,iCAAiC;AAEjC,uCAAwD;AAWxD;;;GAGG;AACH,SAAgB,oBAAoB,CAClC,WAA2B,EAC3B,UAAmC;IAEnC,OAAO,UAAU;SACd,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAC,IAAI,EAAE,UAAU,EAAE,sBAAsB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAC,CAAC,CAAC;SAC5E,MAAM,CAAC,CAAC,EAAC,UAAU,EAAC,EAAE,EAAE,CAAC,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;SACrF,GAAG,CAAC,CAAC,EAAC,IAAI,EAAE,UAAU,EAAC,EAAE,EAAE,CAAC,CAAC;QAC5B,IAAI,EAAE,IAA+B;QACrC,IAAI,EAAE,UAAW,CAAC,UAAU;KAC7B,CAAC,CAAC,CAAC;AACR,CAAC;AAED,SAAgB,sBAAsB,CACpC,WAA2B,EAC3B,SAAuB;IAEvB,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC;IAClD,IAAI,UAAU,GAAyB,IAAI,CAAC;IAC5C,IAAI,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,UAAU,GAAG,SAAS,CAAC;IACzB,CAAC;SAAM,IAAI,EAAE,CAAC,0BAA0B,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACvF,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC;IAC9B,CAAC;IACD,OAAO,UAAU,CAAC,CAAC,CAAC,IAAA,+BAAqB,EAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5E,CAAC"}

View File

@@ -0,0 +1,11 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
import { FileSystem } from '../file-system';
/** Formats the specified diagnostics with respect to the given file system. */
export declare function formatDiagnostics(diagnostics: ts.Diagnostic[], fileSystem: FileSystem): string;

View File

@@ -0,0 +1,18 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatDiagnostics = formatDiagnostics;
const ts = require("typescript");
const virtual_host_1 = require("./virtual-host");
/** Formats the specified diagnostics with respect to the given file system. */
function formatDiagnostics(diagnostics, fileSystem) {
const formatHost = (0, virtual_host_1.createFormatDiagnosticHost)(fileSystem);
return ts.formatDiagnosticsWithColorAndContext(diagnostics, formatHost);
}
//# sourceMappingURL=diagnostics.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["diagnostics.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAOH,8CAGC;AARD,iCAAiC;AAEjC,iDAA0D;AAE1D,+EAA+E;AAC/E,SAAgB,iBAAiB,CAAC,WAA4B,EAAE,UAAsB;IACpF,MAAM,UAAU,GAAG,IAAA,yCAA0B,EAAC,UAAU,CAAC,CAAC;IAC1D,OAAO,EAAE,CAAC,oCAAoC,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AAC1E,CAAC"}

View File

@@ -0,0 +1,14 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
/**
* Unwraps a given expression TypeScript node. Expressions can be wrapped within multiple
* parentheses. e.g. "(((({exp}))))()". The function should return the TypeScript node
* referring to the inner expression. e.g "exp".
*/
export declare function unwrapExpression(node: ts.Expression | ts.ParenthesizedExpression): ts.Expression;

View File

@@ -0,0 +1,20 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.unwrapExpression = unwrapExpression;
const ts = require("typescript");
/**
* Unwraps a given expression TypeScript node. Expressions can be wrapped within multiple
* parentheses. e.g. "(((({exp}))))()". The function should return the TypeScript node
* referring to the inner expression. e.g "exp".
*/
function unwrapExpression(node) {
return ts.isParenthesizedExpression(node) ? unwrapExpression(node.expression) : node;
}
//# sourceMappingURL=functions.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"functions.js","sourceRoot":"","sources":["functions.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AASH,4CAEC;AATD,iCAAiC;AAEjC;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,IAAgD;IAC/E,OAAO,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvF,CAAC"}

View File

@@ -0,0 +1,17 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
/** Interface describing a resolved import. */
export interface Import {
/** Name of the imported symbol. */
symbolName: string;
/** Module name from which the symbol has been imported. */
moduleName: string;
}
/** Resolves the import of the specified identifier. */
export declare function getImportOfIdentifier(node: ts.Identifier, typeChecker: ts.TypeChecker): Import | null;

View File

@@ -0,0 +1,110 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getImportOfIdentifier = getImportOfIdentifier;
const ts = require("typescript");
/** Resolves the import of the specified identifier. */
function getImportOfIdentifier(node, typeChecker) {
// Free standing identifiers which resolve to an import will be handled
// as direct imports. e.g. "@Component()" where "Component" is an identifier
// referring to an import specifier.
const directImport = getSpecificImportOfIdentifier(node, typeChecker);
if (directImport !== null) {
return directImport;
}
else if (ts.isQualifiedName(node.parent) && node.parent.right === node) {
// Determines the import of a qualified name. e.g. "let t: core.Component". In that
// case, the import of the most left identifier will be determined ("core").
const qualifierRoot = getQualifiedNameRoot(node.parent);
if (qualifierRoot) {
const moduleName = getImportOfNamespacedIdentifier(qualifierRoot, typeChecker);
if (moduleName) {
return { moduleName, symbolName: node.text };
}
}
}
else if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {
// Determines the import of a property expression. e.g. "@core.Component". In that
// case, the import of the most left identifier will be determined ("core").
const rootIdentifier = getPropertyAccessRoot(node.parent);
if (rootIdentifier) {
const moduleName = getImportOfNamespacedIdentifier(rootIdentifier, typeChecker);
if (moduleName) {
return { moduleName, symbolName: node.text };
}
}
}
return null;
}
/**
* Resolves the import of the specified identifier. Expects the identifier to resolve
* to a fine-grained import declaration with import specifiers.
*/
function getSpecificImportOfIdentifier(node, typeChecker) {
const symbol = typeChecker.getSymbolAtLocation(node);
if (!symbol || !symbol.declarations || !symbol.declarations.length) {
return null;
}
const declaration = symbol.declarations[0];
if (!ts.isImportSpecifier(declaration)) {
return null;
}
// Since the declaration is an import specifier, we can walk up three times to get a reference
// to the import declaration node (NamedImports -> ImportClause -> ImportDeclaration).
const importDecl = declaration.parent.parent.parent;
if (!ts.isStringLiteral(importDecl.moduleSpecifier)) {
return null;
}
return {
moduleName: importDecl.moduleSpecifier.text,
symbolName: declaration.propertyName ? declaration.propertyName.text : declaration.name.text,
};
}
/**
* Resolves the import of the specified identifier. Expects the identifier to
* resolve to a namespaced import declaration. e.g. "import * as core from ...".
*/
function getImportOfNamespacedIdentifier(node, typeChecker) {
const symbol = typeChecker.getSymbolAtLocation(node);
if (!symbol || !symbol.declarations || !symbol.declarations.length) {
return null;
}
const declaration = symbol.declarations[0];
if (!ts.isNamespaceImport(declaration)) {
return null;
}
// Since the declaration is a namespace import, we can walk up three times to get a reference
// to the import declaration node (NamespaceImport -> ImportClause -> ImportDeclaration).
const importDecl = declaration.parent.parent;
if (!ts.isStringLiteral(importDecl.moduleSpecifier)) {
return null;
}
return importDecl.moduleSpecifier.text;
}
/**
* Gets the root identifier of a qualified type chain. For example: "core.GestureConfig"
* will return the "core" identifier. Allowing us to find the import of "core".
*/
function getQualifiedNameRoot(name) {
while (ts.isQualifiedName(name.left)) {
name = name.left;
}
return ts.isIdentifier(name.left) ? name.left : null;
}
/**
* Gets the root identifier of a property access chain. For example: "core.GestureConfig"
* will return the "core" identifier. Allowing us to find the import of "core".
*/
function getPropertyAccessRoot(node) {
while (ts.isPropertyAccessExpression(node.expression)) {
node = node.expression;
}
return ts.isIdentifier(node.expression) ? node.expression : null;
}
//# sourceMappingURL=imports.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"imports.js","sourceRoot":"","sources":["imports.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,21 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export interface LineAndCharacter {
character: number;
line: number;
}
/** Gets the line and character for the given position from the line starts map. */
export declare function getLineAndCharacterFromPosition(lineStartsMap: number[], position: number): {
character: number;
line: number;
};
/**
* Computes the line start map of the given text. This can be used in order to
* retrieve the line and character of a given text position index.
*/
export declare function computeLineStartsMap(text: string): number[];

View File

@@ -0,0 +1,75 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLineAndCharacterFromPosition = getLineAndCharacterFromPosition;
exports.computeLineStartsMap = computeLineStartsMap;
/*
* Line mapping utilities which can be used to retrieve line and character based
* on an absolute character position in a given file. This functionality is similar
* to TypeScript's "ts.getLineAndCharacterFromPosition" utility, but we cannot leverage
* their logic for line mappings as it's internal and we need to generate line mappings
* for non-TypeScript files such as HTML templates or stylesheets.
*
* Line and character can be retrieved by splitting a given source text based on
* line breaks into line start entries. Later when a specific position is requested,
* the closest line-start position is determined based on the given position.
*/
const LF_CHAR = 10;
const CR_CHAR = 13;
const LINE_SEP_CHAR = 8232;
const PARAGRAPH_CHAR = 8233;
/** Gets the line and character for the given position from the line starts map. */
function getLineAndCharacterFromPosition(lineStartsMap, position) {
const lineIndex = findClosestLineStartPosition(lineStartsMap, position);
return { character: position - lineStartsMap[lineIndex], line: lineIndex };
}
/**
* Computes the line start map of the given text. This can be used in order to
* retrieve the line and character of a given text position index.
*/
function computeLineStartsMap(text) {
const result = [0];
let pos = 0;
while (pos < text.length) {
const char = text.charCodeAt(pos++);
// Handles the "CRLF" line break. In that case we peek the character
// after the "CR" and check if it is a line feed.
if (char === CR_CHAR) {
if (text.charCodeAt(pos) === LF_CHAR) {
pos++;
}
result.push(pos);
}
else if (char === LF_CHAR || char === LINE_SEP_CHAR || char === PARAGRAPH_CHAR) {
result.push(pos);
}
}
result.push(pos);
return result;
}
/** Finds the closest line start for the given position. */
function findClosestLineStartPosition(linesMap, position, low = 0, high = linesMap.length - 1) {
while (low <= high) {
const pivotIndex = Math.floor((low + high) / 2);
const pivotEl = linesMap[pivotIndex];
if (pivotEl === position) {
return pivotIndex;
}
else if (position > pivotEl) {
low = pivotIndex + 1;
}
else {
high = pivotIndex - 1;
}
}
// In case there was no exact match, return the closest "lower" line index. We also
// subtract the index by one because want the index of the previous line start.
return low - 1;
}
//# sourceMappingURL=line-mappings.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"line-mappings.js","sourceRoot":"","sources":["line-mappings.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAyBH,0EAGC;AAMD,oDAkBC;AAlDD;;;;;;;;;;GAUG;AAEH,MAAM,OAAO,GAAG,EAAE,CAAC;AACnB,MAAM,OAAO,GAAG,EAAE,CAAC;AACnB,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,MAAM,cAAc,GAAG,IAAI,CAAC;AAO5B,mFAAmF;AACnF,SAAgB,+BAA+B,CAAC,aAAuB,EAAE,QAAgB;IACvF,MAAM,SAAS,GAAG,4BAA4B,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IACxE,OAAO,EAAC,SAAS,EAAE,QAAQ,GAAG,aAAa,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAC,CAAC;AAC3E,CAAC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,IAAY;IAC/C,MAAM,MAAM,GAAa,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC;QACpC,oEAAoE;QACpE,iDAAiD;QACjD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC;gBACrC,GAAG,EAAE,CAAC;YACR,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;aAAM,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YACjF,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,2DAA2D;AAC3D,SAAS,4BAA4B,CACnC,QAAa,EACb,QAAW,EACX,GAAG,GAAG,CAAC,EACP,IAAI,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC;IAE1B,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;QACnB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAErC,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;YACzB,OAAO,UAAU,CAAC;QACpB,CAAC;aAAM,IAAI,QAAQ,GAAG,OAAO,EAAE,CAAC;YAC9B,GAAG,GAAG,UAAU,GAAG,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,UAAU,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,mFAAmF;IACnF,+EAA+E;IAC/E,OAAO,GAAG,GAAG,CAAC,CAAC;AACjB,CAAC"}

View File

@@ -0,0 +1,18 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
import { FileSystem, WorkspacePath } from '../file-system';
/** Class capturing a tsconfig parse error. */
export declare class TsconfigParseError extends Error {
}
/**
* Attempts to parse the specified tsconfig file.
*
* @throws {TsconfigParseError} If the tsconfig could not be read or parsed.
*/
export declare function parseTsconfigFile(tsconfigPath: WorkspacePath, fileSystem: FileSystem): ts.ParsedCommandLine;

View File

@@ -0,0 +1,45 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.TsconfigParseError = void 0;
exports.parseTsconfigFile = parseTsconfigFile;
const ts = require("typescript");
const virtual_host_1 = require("./virtual-host");
const path_1 = require("path");
const diagnostics_1 = require("./diagnostics");
/** Code of the error raised by TypeScript when a tsconfig doesn't match any files. */
const NO_INPUTS_ERROR_CODE = 18003;
/** Class capturing a tsconfig parse error. */
class TsconfigParseError extends Error {
}
exports.TsconfigParseError = TsconfigParseError;
/**
* Attempts to parse the specified tsconfig file.
*
* @throws {TsconfigParseError} If the tsconfig could not be read or parsed.
*/
function parseTsconfigFile(tsconfigPath, fileSystem) {
if (!fileSystem.fileExists(tsconfigPath)) {
throw new TsconfigParseError(`Tsconfig cannot not be read: ${tsconfigPath}`);
}
const { config, error } = ts.readConfigFile(tsconfigPath, p => fileSystem.read(fileSystem.resolve(p)));
// If there is a config reading error, we never attempt to parse the config.
if (error) {
throw new TsconfigParseError((0, diagnostics_1.formatDiagnostics)([error], fileSystem));
}
const parsed = ts.parseJsonConfigFileContent(config, new virtual_host_1.FileSystemHost(fileSystem), (0, path_1.dirname)(tsconfigPath), {});
// Skip the "No inputs found..." error since we don't want to interrupt the migration if a
// tsconfig doesn't match a file. This will result in an empty `Program` which is still valid.
const errors = parsed.errors.filter(diag => diag.code !== NO_INPUTS_ERROR_CODE);
if (errors.length) {
throw new TsconfigParseError((0, diagnostics_1.formatDiagnostics)(errors, fileSystem));
}
return parsed;
}
//# sourceMappingURL=parse-tsconfig.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parse-tsconfig.js","sourceRoot":"","sources":["parse-tsconfig.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAmBH,8CAkCC;AAnDD,iCAAiC;AAEjC,iDAA8C;AAC9C,+BAA6B;AAC7B,+CAAgD;AAEhD,sFAAsF;AACtF,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAEnC,8CAA8C;AAC9C,MAAa,kBAAmB,SAAQ,KAAK;CAAG;AAAhD,gDAAgD;AAEhD;;;;GAIG;AACH,SAAgB,iBAAiB,CAC/B,YAA2B,EAC3B,UAAsB;IAEtB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,kBAAkB,CAAC,gCAAgC,YAAY,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,EAAC,MAAM,EAAE,KAAK,EAAC,GAAG,EAAE,CAAC,cAAc,CACvC,YAAY,EACZ,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,CAC7C,CAAC;IAEF,4EAA4E;IAC5E,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,kBAAkB,CAAC,IAAA,+BAAiB,EAAC,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,CAAC,0BAA0B,CAC1C,MAAM,EACN,IAAI,6BAAc,CAAC,UAAU,CAAC,EAC9B,IAAA,cAAO,EAAC,YAAY,CAAC,EACrB,EAAE,CACH,CAAC;IAEF,0FAA0F;IAC1F,8FAA8F;IAC9F,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,oBAAoB,CAAC,CAAC;IAEhF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,IAAI,kBAAkB,CAAC,IAAA,+BAAiB,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}

View File

@@ -0,0 +1,18 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
/** Type that describes a property name with an obtainable text. */
type PropertyNameWithText = Exclude<ts.PropertyName, ts.ComputedPropertyName>;
/**
* Gets the text of the given property name. Returns null if the property
* name couldn't be determined statically.
*/
export declare function getPropertyNameText(node: ts.PropertyName): string | null;
/** Checks whether the given property name has a text. */
export declare function hasPropertyNameText(node: ts.PropertyName): node is PropertyNameWithText;
export {};

View File

@@ -0,0 +1,27 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPropertyNameText = getPropertyNameText;
exports.hasPropertyNameText = hasPropertyNameText;
const ts = require("typescript");
/**
* Gets the text of the given property name. Returns null if the property
* name couldn't be determined statically.
*/
function getPropertyNameText(node) {
if (ts.isIdentifier(node) || ts.isStringLiteralLike(node)) {
return node.text;
}
return null;
}
/** Checks whether the given property name has a text. */
function hasPropertyNameText(node) {
return ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isIdentifier(node);
}
//# sourceMappingURL=property-name.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"property-name.js","sourceRoot":"","sources":["property-name.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAWH,kDAKC;AAGD,kDAEC;AAnBD,iCAAiC;AAKjC;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,IAAqB;IACvD,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1D,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yDAAyD;AACzD,SAAgB,mBAAmB,CAAC,IAAqB;IACvD,OAAO,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AACxF,CAAC"}

View File

@@ -0,0 +1,36 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as ts from 'typescript';
import { FileSystem } from '../file-system';
declare module 'typescript' {
interface FileSystemEntries {
readonly files: readonly string[];
readonly directories: readonly string[];
}
const matchFiles: undefined | ((path: string, extensions: readonly string[] | undefined, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries, realpath: (path: string) => string, directoryExists: (path: string) => boolean) => string[]);
}
/**
* Implementation of a TypeScript parse config host that relies fully on
* a given virtual file system.
*/
export declare class FileSystemHost implements ts.ParseConfigHost {
private _fileSystem;
useCaseSensitiveFileNames: boolean;
constructor(_fileSystem: FileSystem);
fileExists(path: string): boolean;
readFile(path: string): string | undefined;
readDirectory(rootDir: string, extensions: string[], excludes: string[] | undefined, includes: string[], depth?: number): string[];
private _getFileSystemEntries;
}
/**
* Creates a TypeScript compiler host that fully relies fully on the given
* virtual file system. i.e. no interactions with the working directory.
*/
export declare function createFileSystemCompilerHost(options: ts.CompilerOptions, fileSystem: FileSystem): ts.CompilerHost;
/** Creates a format diagnostic host that works with the given file system. */
export declare function createFormatDiagnosticHost(fileSystem: FileSystem): ts.FormatDiagnosticsHost;

View File

@@ -0,0 +1,71 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileSystemHost = void 0;
exports.createFileSystemCompilerHost = createFileSystemCompilerHost;
exports.createFormatDiagnosticHost = createFormatDiagnosticHost;
const ts = require("typescript");
/**
* Implementation of a TypeScript parse config host that relies fully on
* a given virtual file system.
*/
class FileSystemHost {
constructor(_fileSystem) {
this._fileSystem = _fileSystem;
this.useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames;
}
fileExists(path) {
return this._fileSystem.fileExists(this._fileSystem.resolve(path));
}
readFile(path) {
const content = this._fileSystem.read(this._fileSystem.resolve(path));
if (content === null) {
return undefined;
}
// Strip BOM as otherwise TSC methods (e.g. "getWidth") will return an offset which
// which breaks the CLI UpdateRecorder. https://github.com/angular/angular/pull/30719
return content.replace(/^\uFEFF/, '');
}
readDirectory(rootDir, extensions, excludes, includes, depth) {
if (ts.matchFiles === undefined) {
throw Error('Unable to read directory in virtual file system host. This means that ' +
'TypeScript changed its file matching internals.\n\nPlease consider downgrading your ' +
'TypeScript version, and report an issue in the Angular Components repository.');
}
return ts.matchFiles(rootDir, extensions, extensions, includes, this.useCaseSensitiveFileNames, '/', depth, p => this._getFileSystemEntries(p), p => this._fileSystem.resolve(p), p => this._fileSystem.directoryExists(this._fileSystem.resolve(p)));
}
_getFileSystemEntries(path) {
return this._fileSystem.readDirectory(this._fileSystem.resolve(path));
}
}
exports.FileSystemHost = FileSystemHost;
/**
* Creates a TypeScript compiler host that fully relies fully on the given
* virtual file system. i.e. no interactions with the working directory.
*/
function createFileSystemCompilerHost(options, fileSystem) {
const host = ts.createCompilerHost(options, true);
const virtualHost = new FileSystemHost(fileSystem);
host.readFile = virtualHost.readFile.bind(virtualHost);
host.readDirectory = virtualHost.readDirectory.bind(virtualHost);
host.fileExists = virtualHost.fileExists.bind(virtualHost);
host.directoryExists = dirPath => fileSystem.directoryExists(fileSystem.resolve(dirPath));
host.getCurrentDirectory = () => '/';
host.getCanonicalFileName = p => fileSystem.resolve(p);
return host;
}
/** Creates a format diagnostic host that works with the given file system. */
function createFormatDiagnosticHost(fileSystem) {
return {
getCanonicalFileName: p => fileSystem.resolve(p),
getCurrentDirectory: () => '/',
getNewLine: () => '\n',
};
}
//# sourceMappingURL=virtual-host.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"virtual-host.js","sourceRoot":"","sources":["virtual-host.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,32 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { TargetVersion } from './target-version';
export type VersionChanges<T> = {
[target in TargetVersion]?: ReadableChange<T>[];
};
export type ReadableChange<T> = {
pr: string;
changes: T[];
};
/** Conditional type that unwraps the value of a version changes type. */
export type ValueOfChanges<T> = T extends VersionChanges<infer X> ? X : null;
/**
* Gets the changes for a given target version from the specified version changes object.
*
* For readability and a good overview of breaking changes, the version change data always
* includes the related Pull Request link. Since this data is not needed when performing the
* upgrade, this unused data can be removed and the changes data can be flattened into an
* easy iterable array.
*/
export declare function getChangesForTarget<T>(target: TargetVersion, data: VersionChanges<T>): T[];
/**
* Gets all changes from the specified version changes object. This is helpful in case a migration
* rule does not distinguish data based on the target version, but for readability the
* upgrade data is separated for each target version.
*/
export declare function getAllChanges<T>(data: VersionChanges<T>): T[];

View File

@@ -0,0 +1,38 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getChangesForTarget = getChangesForTarget;
exports.getAllChanges = getAllChanges;
const target_version_1 = require("./target-version");
/**
* Gets the changes for a given target version from the specified version changes object.
*
* For readability and a good overview of breaking changes, the version change data always
* includes the related Pull Request link. Since this data is not needed when performing the
* upgrade, this unused data can be removed and the changes data can be flattened into an
* easy iterable array.
*/
function getChangesForTarget(target, data) {
if (!data) {
const version = target_version_1.TargetVersion[target];
throw new Error(`No data could be found for target version: ${version}`);
}
return (data[target] || []).reduce((result, prData) => result.concat(prData.changes), []);
}
/**
* Gets all changes from the specified version changes object. This is helpful in case a migration
* rule does not distinguish data based on the target version, but for readability the
* upgrade data is separated for each target version.
*/
function getAllChanges(data) {
return Object.keys(data)
.map(targetVersion => getChangesForTarget(targetVersion, data))
.reduce((result, versionData) => result.concat(versionData), []);
}
//# sourceMappingURL=version-changes.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"version-changes.js","sourceRoot":"","sources":["version-changes.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAwBH,kDAOC;AAOD,sCAIC;AAxCD,qDAA+C;AAc/C;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CAAI,MAAqB,EAAE,IAAuB;IACnF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,OAAO,GAAI,8BAAwC,CAAC,MAAM,CAAC,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,8CAA8C,OAAO,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAS,CAAC,CAAC;AACnG,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAI,IAAuB;IACtD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;SACrB,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,mBAAmB,CAAC,aAA8B,EAAE,IAAI,CAAC,CAAC;SAC/E,MAAM,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC"}