feat(angular): add ast util to add a provider to bootstrapApplication (#14136)

This commit is contained in:
Colum Ferry 2023-01-04 16:34:18 +00:00 committed by GitHub
parent 8c014f0d48
commit d9efb98ebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 2 deletions

View File

@ -3,6 +3,7 @@ import {
addImportToDirective, addImportToDirective,
addImportToModule, addImportToModule,
addImportToPipe, addImportToPipe,
addProviderToBootstrapApplication,
isStandalone, isStandalone,
} from './ast-utils'; } from './ast-utils';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
@ -260,4 +261,45 @@ describe('Angular AST Utils', () => {
// ASSERT // ASSERT
expect(isStandalone(tsSourceFile, 'Pipe')).toBeTruthy(); expect(isStandalone(tsSourceFile, 'Pipe')).toBeTruthy();
}); });
it('should add a provider to the bootstrapApplication call', () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
tree.write(
'main.ts',
`import { bootstrapApplication } from '@angular/platform-browser';
import {
provideRouter,
withEnabledBlockingInitialNavigation,
} from '@angular/router';
import { AppComponent } from './app/app.component';
import { appRoutes } from './app/app.routes';
bootstrapApplication(AppComponent, {
providers: [
provideRouter(appRoutes, withEnabledBlockingInitialNavigation()),
],
}).catch((err) => console.error(err));`
);
// ACT
addProviderToBootstrapApplication(tree, 'main.ts', 'provideStore()');
// ASSERT
expect(tree.read('main.ts', 'utf-8')).toMatchInlineSnapshot(`
"import { bootstrapApplication } from '@angular/platform-browser';
import {
provideRouter,
withEnabledBlockingInitialNavigation,
} from '@angular/router';
import { AppComponent } from './app/app.component';
import { appRoutes } from './app/app.routes';
bootstrapApplication(AppComponent, {
providers: [provideStore(),
provideRouter(appRoutes, withEnabledBlockingInitialNavigation()),
],
}).catch((err) => console.error(err));"
`);
});
}); });

View File

@ -9,6 +9,7 @@ import {
removeChange, removeChange,
replaceChange, replaceChange,
} from '@nrwl/workspace/src/utilities/ast-utils'; } from '@nrwl/workspace/src/utilities/ast-utils';
import { tsquery } from '@phenomnomnominal/tsquery';
type DecoratorName = 'Component' | 'Directive' | 'NgModule' | 'Pipe'; type DecoratorName = 'Component' | 'Directive' | 'NgModule' | 'Pipe';
@ -605,6 +606,38 @@ function getListOfRoutes(
return null; return null;
} }
export function addProviderToBootstrapApplication(
tree: Tree,
filePath: string,
providerToAdd: string
) {
const PROVIDERS_ARRAY_SELECTOR =
'CallExpression:has(Identifier[name=bootstrapApplication]) ObjectLiteralExpression > PropertyAssignment:has(Identifier[name=providers]) > ArrayLiteralExpression';
const fileContents = tree.read(filePath, 'utf-8');
const ast = tsquery.ast(fileContents);
const providersArrayNodes = tsquery(ast, PROVIDERS_ARRAY_SELECTOR, {
visitAllChildren: true,
});
if (providersArrayNodes.length === 0) {
throw new Error(
`Providers does not exist in the bootstrapApplication call within ${filePath}.`
);
}
const arrayNode = providersArrayNodes[0];
const newFileContents = `${fileContents.slice(
0,
arrayNode.getStart() + 1
)}${providerToAdd},${fileContents.slice(
arrayNode.getStart() + 1,
fileContents.length
)}`;
tree.write(filePath, newFileContents);
}
export function addProviderToModule( export function addProviderToModule(
host: Tree, host: Tree,
source: ts.SourceFile, source: ts.SourceFile,

View File

@ -131,12 +131,18 @@ export function addProviderToRoute(
} }
); );
const routeText = selectedRouteNode.getText();
if (routeProivdersNodes.length === 0) { if (routeProivdersNodes.length === 0) {
const newFileContents = `${routesFileContents.slice( const newFileContents = `${routesFileContents.slice(
0, 0,
selectedRouteNode.getEnd() - 1 selectedRouteNode.getEnd() - 1
)}, providers: [${providerToAdd}]${routesFileContents.slice( )}${
routesFileContents
.slice(0, selectedRouteNode.getEnd() - 1)
.trim()
.endsWith(',')
? ''
: ', '
}providers: [${providerToAdd}]${routesFileContents.slice(
selectedRouteNode.getEnd() - 1, selectedRouteNode.getEnd() - 1,
routesFileContents.length routesFileContents.length
)}`; )}`;