123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- 'use strict';
- /**
- * @license Angular v19.2.13
- * (c) 2010-2025 Google LLC. https://angular.io/
- * License: MIT
- */
- 'use strict';
- var schematics = require('@angular-devkit/schematics');
- var p = require('path');
- var project_tsconfig_paths = require('./project_tsconfig_paths-CDVxT6Ov.cjs');
- var compiler_host = require('./compiler_host-B1Gyeytz.cjs');
- var ts = require('typescript');
- var imports = require('./imports-CIX-JgAN.cjs');
- require('@angular-devkit/core');
- require('./checker-5pyJrZ9G.cjs');
- require('os');
- require('fs');
- require('module');
- require('url');
- function migrateFile(sourceFile, rewriteFn) {
- const changeTracker = new compiler_host.ChangeTracker(ts.createPrinter());
- const visitNode = (node) => {
- const provider = tryParseProviderExpression(node);
- if (provider) {
- replaceProviderWithNewApi({
- sourceFile,
- node,
- provider,
- changeTracker,
- });
- return;
- }
- ts.forEachChild(node, visitNode);
- };
- ts.forEachChild(sourceFile, visitNode);
- for (const change of changeTracker.recordChanges().get(sourceFile)?.values() ?? []) {
- rewriteFn(change.start, change.removeLength ?? 0, change.text);
- }
- }
- function replaceProviderWithNewApi({ sourceFile, node, provider, changeTracker, }) {
- const { initializerCode, importInject, provideInitializerFunctionName, initializerToken } = provider;
- const initializerTokenSpecifier = imports.getImportSpecifier(sourceFile, angularCoreModule, initializerToken);
- // The token doesn't come from `@angular/core`.
- if (!initializerTokenSpecifier) {
- return;
- }
- // Replace the provider with the new provide function.
- changeTracker.replaceText(sourceFile, node.getStart(), node.getWidth(), `${provideInitializerFunctionName}(${initializerCode})`);
- // Remove the `*_INITIALIZER` token from imports.
- changeTracker.removeImport(sourceFile, initializerToken, angularCoreModule);
- // Add the `inject` function to imports if needed.
- if (importInject) {
- changeTracker.addImport(sourceFile, 'inject', angularCoreModule);
- }
- // Add the `provide*Initializer` function to imports.
- changeTracker.addImport(sourceFile, provideInitializerFunctionName, angularCoreModule);
- }
- function tryParseProviderExpression(node) {
- if (!ts.isObjectLiteralExpression(node)) {
- return;
- }
- let deps = [];
- let initializerToken;
- let useExisting;
- let useFactoryCode;
- let useValue;
- let multi = false;
- for (const property of node.properties) {
- if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name)) {
- switch (property.name.text) {
- case 'deps':
- if (ts.isArrayLiteralExpression(property.initializer)) {
- deps = property.initializer.elements.map((el) => el.getText());
- }
- break;
- case 'provide':
- initializerToken = property.initializer.getText();
- break;
- case 'useExisting':
- useExisting = property.initializer;
- break;
- case 'useFactory':
- useFactoryCode = property.initializer.getText();
- break;
- case 'useValue':
- useValue = property.initializer;
- break;
- case 'multi':
- multi = property.initializer.kind === ts.SyntaxKind.TrueKeyword;
- break;
- }
- }
- // Handle the `useFactory() {}` shorthand case.
- if (ts.isMethodDeclaration(property) && property.name.getText() === 'useFactory') {
- const params = property.parameters.map((param) => param.getText()).join(', ');
- useFactoryCode = `(${params}) => ${property.body?.getText()}`;
- }
- }
- if (!initializerToken || !multi) {
- return;
- }
- const provideInitializerFunctionName = initializerTokenToFunctionMap.get(initializerToken);
- if (!provideInitializerFunctionName) {
- return;
- }
- const info = {
- initializerToken,
- provideInitializerFunctionName,
- importInject: false,
- };
- if (useExisting) {
- return {
- ...info,
- importInject: true,
- initializerCode: `() => inject(${useExisting.getText()})()`,
- };
- }
- if (useFactoryCode) {
- const args = deps.map((dep) => `inject(${dep})`);
- return {
- ...info,
- importInject: deps.length > 0,
- initializerCode: `() => {
- const initializerFn = (${useFactoryCode})(${args.join(', ')});
- return initializerFn();
- }`,
- };
- }
- if (useValue) {
- return { ...info, initializerCode: useValue.getText() };
- }
- return;
- }
- const angularCoreModule = '@angular/core';
- const initializerTokenToFunctionMap = new Map([
- ['APP_INITIALIZER', 'provideAppInitializer'],
- ['ENVIRONMENT_INITIALIZER', 'provideEnvironmentInitializer'],
- ['PLATFORM_INITIALIZER', 'providePlatformInitializer'],
- ]);
- function migrate() {
- return async (tree) => {
- const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
- const basePath = process.cwd();
- const allPaths = [...buildPaths, ...testPaths];
- if (!allPaths.length) {
- throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the provide initializer migration.');
- }
- for (const tsconfigPath of allPaths) {
- runMigration(tree, tsconfigPath, basePath);
- }
- };
- }
- function runMigration(tree, tsconfigPath, basePath) {
- const program = compiler_host.createMigrationProgram(tree, tsconfigPath, basePath);
- const sourceFiles = program
- .getSourceFiles()
- .filter((sourceFile) => compiler_host.canMigrateFile(basePath, sourceFile, program));
- for (const sourceFile of sourceFiles) {
- let update = null;
- const rewriter = (startPos, width, text) => {
- if (update === null) {
- // Lazily initialize update, because most files will not require migration.
- update = tree.beginUpdate(p.relative(basePath, sourceFile.fileName));
- }
- update.remove(startPos, width);
- if (text !== null) {
- update.insertLeft(startPos, text);
- }
- };
- migrateFile(sourceFile, rewriter);
- if (update !== null) {
- tree.commitUpdate(update);
- }
- }
- }
- exports.migrate = migrate;
|