@nx/angular
Version:
93 lines (92 loc) • 5.97 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.setRouterInitialNavigation = setRouterInitialNavigation;
const devkit_1 = require("@nx/devkit");
const js_1 = require("@nx/js");
const tsquery_1 = require("@phenomnomnominal/tsquery");
const typescript_1 = require("typescript");
function setRouterInitialNavigation(tree, options) {
const printer = (0, typescript_1.createPrinter)();
const project = (0, devkit_1.readProjectConfiguration)(tree, options.project);
(0, devkit_1.visitNotIgnoredFiles)(tree, project.root, (filePath) => {
// we are only interested in .ts files
if (!filePath.endsWith('.ts')) {
return;
}
if (options.standalone) {
processFileWithStandaloneSetup(tree, filePath, printer);
}
else {
processFileWithNgModuleSetup(tree, filePath, printer);
}
});
}
function processFileWithStandaloneSetup(tree, filePath, printer) {
let content = tree.read(filePath, 'utf-8');
let sourceFile = tsquery_1.tsquery.ast(content);
const provideRouterCallExpression = getProvideRouterCallExpression(sourceFile);
if (!provideRouterCallExpression) {
return;
}
if (provideRouterCallExpression.arguments.some((arg) => (0, typescript_1.isCallExpression)(arg) &&
(0, typescript_1.isIdentifier)(arg.expression) &&
arg.expression.text === 'withEnabledBlockingInitialNavigation')) {
return;
}
const updatedProvideRouterCallExpression = printer.printNode(typescript_1.EmitHint.Unspecified, updateProvideRouterCallExpression(provideRouterCallExpression), sourceFile);
content = `${content.slice(0, provideRouterCallExpression.getStart())}${updatedProvideRouterCallExpression}${content.slice(provideRouterCallExpression.getEnd())}`;
tree.write(filePath, content);
sourceFile = tsquery_1.tsquery.ast(content);
sourceFile = (0, js_1.insertImport)(tree, sourceFile, filePath, 'withEnabledBlockingInitialNavigation', '@angular/router');
const withDisabledInitialNavigationImportNode = (0, tsquery_1.tsquery)(sourceFile, 'ImportDeclaration ImportSpecifier:has(Identifier[name=withDisabledInitialNavigation])')[0];
if (!withDisabledInitialNavigationImportNode) {
return;
}
const hasTrailingComma = withDisabledInitialNavigationImportNode.parent.elements.hasTrailingComma;
content = tree.read(filePath, 'utf-8');
tree.write(filePath, `${content.slice(0, withDisabledInitialNavigationImportNode.getStart())}${content.slice(withDisabledInitialNavigationImportNode.getEnd() +
(hasTrailingComma ? 1 : 0))}`);
}
function updateProvideRouterCallExpression(node) {
const filteredArgs = node.arguments.filter((arg) => !((0, typescript_1.isCallExpression)(arg) &&
(0, typescript_1.isIdentifier)(arg.expression) &&
arg.expression.text === 'withDisabledInitialNavigation'));
const initialNavigationFeatureArg = typescript_1.factory.createCallExpression(typescript_1.factory.createIdentifier('withEnabledBlockingInitialNavigation'), [], []);
return typescript_1.factory.updateCallExpression(node, node.expression, node.typeArguments, [...filteredArgs, initialNavigationFeatureArg]);
}
function processFileWithNgModuleSetup(tree, filePath, printer) {
const content = tree.read(filePath, 'utf-8');
const sourceFile = tsquery_1.tsquery.ast(content);
const routerModuleForRootCallExpression = getRouterModuleForRootCallExpression(sourceFile);
if (!routerModuleForRootCallExpression) {
return;
}
const updatedRouterModuleForRootCallExpression = printer.printNode(typescript_1.EmitHint.Unspecified, updateRouterModuleForRootCallExpression(routerModuleForRootCallExpression), sourceFile);
tree.write(filePath, `${content.slice(0, routerModuleForRootCallExpression.getStart())}${updatedRouterModuleForRootCallExpression}${content.slice(routerModuleForRootCallExpression.getEnd())}`);
}
function updateRouterModuleForRootCallExpression(node) {
const existingOptions = node.arguments[1];
const existingProperties = existingOptions?.properties
? typescript_1.factory.createNodeArray(existingOptions.properties.filter((exp) => !((0, typescript_1.isPropertyAssignment)(exp) &&
(0, typescript_1.isIdentifier)(exp.name) &&
exp.name.text === 'initialNavigation')))
: typescript_1.factory.createNodeArray();
const enabledLiteral = typescript_1.factory.createStringLiteral('enabledBlocking', true);
const initialNavigationProperty = typescript_1.factory.createPropertyAssignment('initialNavigation', enabledLiteral);
const routerOptions = existingOptions
? typescript_1.factory.updateObjectLiteralExpression(existingOptions, typescript_1.factory.createNodeArray([
...existingProperties,
initialNavigationProperty,
]))
: typescript_1.factory.createObjectLiteralExpression(typescript_1.factory.createNodeArray([initialNavigationProperty]));
const args = [node.arguments[0], routerOptions];
return typescript_1.factory.createCallExpression(node.expression, node.typeArguments, args);
}
function getProvideRouterCallExpression(sourceFile) {
const routerModuleForRootCalls = (0, tsquery_1.tsquery)(sourceFile, 'PropertyAssignment:has(Identifier[name=providers]) > ArrayLiteralExpression CallExpression:has(Identifier[name=provideRouter])', { visitAllChildren: true });
return routerModuleForRootCalls.length ? routerModuleForRootCalls[0] : null;
}
function getRouterModuleForRootCallExpression(sourceFile) {
const routerModuleForRootCalls = (0, tsquery_1.tsquery)(sourceFile, 'Decorator > CallExpression:has(Identifier[name=NgModule]) PropertyAssignment:has(Identifier[name=imports]) > ArrayLiteralExpression CallExpression:has(Identifier[name=forRoot])', { visitAllChildren: true });
return routerModuleForRootCalls.length ? routerModuleForRootCalls[0] : null;
}