feat(angular): add ast util to add a provider to bootstrapApplication (#14136)
This commit is contained in:
parent
8c014f0d48
commit
d9efb98ebb
@ -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));"
|
||||||
|
`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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
|
||||||
)}`;
|
)}`;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user