Skip to content

Commit

Permalink
feat(angular): add ast util to add a provider to bootstrapApplication (
Browse files Browse the repository at this point in the history
  • Loading branch information
Coly010 committed Jan 4, 2023
1 parent 8c014f0 commit d9efb98
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
42 changes: 42 additions & 0 deletions packages/angular/src/utils/nx-devkit/ast-utils.spec.ts
Expand Up @@ -3,6 +3,7 @@ import {
addImportToDirective,
addImportToModule,
addImportToPipe,
addProviderToBootstrapApplication,
isStandalone,
} from './ast-utils';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
Expand Down Expand Up @@ -260,4 +261,45 @@ describe('Angular AST Utils', () => {
// ASSERT
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));"
`);
});
});
33 changes: 33 additions & 0 deletions packages/angular/src/utils/nx-devkit/ast-utils.ts
Expand Up @@ -9,6 +9,7 @@ import {
removeChange,
replaceChange,
} from '@nrwl/workspace/src/utilities/ast-utils';
import { tsquery } from '@phenomnomnominal/tsquery';

type DecoratorName = 'Component' | 'Directive' | 'NgModule' | 'Pipe';

Expand Down Expand Up @@ -605,6 +606,38 @@ function getListOfRoutes(
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(
host: Tree,
source: ts.SourceFile,
Expand Down
10 changes: 8 additions & 2 deletions packages/angular/src/utils/nx-devkit/route-utils.ts
Expand Up @@ -131,12 +131,18 @@ export function addProviderToRoute(
}
);

const routeText = selectedRouteNode.getText();
if (routeProivdersNodes.length === 0) {
const newFileContents = `${routesFileContents.slice(
0,
selectedRouteNode.getEnd() - 1
)}, providers: [${providerToAdd}]${routesFileContents.slice(
)}${
routesFileContents
.slice(0, selectedRouteNode.getEnd() - 1)
.trim()
.endsWith(',')
? ''
: ', '
}providers: [${providerToAdd}]${routesFileContents.slice(
selectedRouteNode.getEnd() - 1,
routesFileContents.length
)}`;
Expand Down

0 comments on commit d9efb98

Please sign in to comment.