@o3r/schematics
Version:
Schematics module of the Otter framework
107 lines • 6.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.addImportsIntoComponentDecoratorTransformerFactory = exports.getO3rComponentInfoOrThrowIfNotFound = exports.NoOtterComponent = exports.askConfirmationToConvertComponent = exports.isO3rClassComponent = exports.isNgClassComponent = exports.isO3rClassDecorator = exports.isNgClassDecorator = void 0;
const ts = require("typescript");
const ast_1 = require("./ast");
const error_1 = require("./error");
/**
* Returns true if `node` is the decorator of an Angular component
* @param node
*/
const isNgClassDecorator = (node) => (0, ast_1.isDecoratorWithArg)(node)
&& node.expression.expression.escapedText.toString() === 'Component';
exports.isNgClassDecorator = isNgClassDecorator;
/**
* Returns true if `node` is the decorator of an Otter component
* @param node
*/
const isO3rClassDecorator = (node) => (0, ast_1.isDecoratorWithArg)(node)
&& node.expression.expression.escapedText.toString() === 'O3rComponent';
exports.isO3rClassDecorator = isO3rClassDecorator;
/**
* Returns true if `classDeclaration` is an Otter component
* @param classDeclaration
*/
const isNgClassComponent = (classDeclaration) => (ts.getDecorators(classDeclaration) || []).some((decorator) => (0, exports.isNgClassDecorator)(decorator));
exports.isNgClassComponent = isNgClassComponent;
/**
* Returns true if `classDeclaration` is an Otter component
* @param classDeclaration
*/
const isO3rClassComponent = (classDeclaration) => (0, exports.isNgClassComponent)(classDeclaration)
&& (ts.getDecorators(classDeclaration) || []).some((decorator) => (0, exports.isO3rClassDecorator)(decorator));
exports.isO3rClassComponent = isO3rClassComponent;
const askConfirmationToConvertComponent = async () => (await Promise.resolve().then(() => require('@angular/cli/src/utilities/prompt'))).askConfirmation('Component found is not an Otter component. Would you like to convert it?', true);
exports.askConfirmationToConvertComponent = askConfirmationToConvertComponent;
class NoOtterComponent extends Error {
constructor(componentPath) {
super(`
No Otter component found in ${componentPath}.
You can convert your Angular component into an Otter component by running the following command:
ng g @o3r/core:convert-component --path="${componentPath}".
`);
}
}
exports.NoOtterComponent = NoOtterComponent;
/**
* Returns Otter component information
* @param tree
* @param componentPath
*/
const getO3rComponentInfoOrThrowIfNotFound = (tree, componentPath) => {
const sourceFile = ts.createSourceFile(componentPath, tree.readText(componentPath), ts.ScriptTarget.ES2020, true);
const ngComponentDeclaration = sourceFile.statements.find((s) => ts.isClassDeclaration(s) && (0, exports.isNgClassComponent)(s));
if (!ngComponentDeclaration) {
throw new error_1.O3rCliError(`No Angular component found in ${componentPath}.`);
}
if (!(0, exports.isO3rClassComponent)(ngComponentDeclaration)) {
throw new NoOtterComponent(componentPath);
}
const name = ngComponentDeclaration.name?.escapedText.toString().replace(/Component$/, '');
if (!name) {
throw new error_1.O3rCliError(`The class' name is not specified. Please provide one for the Otter component defined in ${componentPath}.`);
}
const selectorExpression = (0, ast_1.getPropertyFromDecoratorFirstArgument)(ts.getDecorators(ngComponentDeclaration)?.find((decorator) => (0, exports.isNgClassDecorator)(decorator)), 'selector');
const selector = selectorExpression && ts.isStringLiteral(selectorExpression)
? selectorExpression.text
: selectorExpression?.getText();
if (!selector) {
throw new error_1.O3rCliError(`The component's selector is not specified. Please provide one for the Otter component defined in ${componentPath}.`);
}
const standaloneExpression = (0, ast_1.getPropertyFromDecoratorFirstArgument)(ts.getDecorators(ngComponentDeclaration)?.find((decorator) => (0, exports.isNgClassDecorator)(decorator)), 'standalone');
const standalone = standaloneExpression?.kind !== ts.SyntaxKind.FalseKeyword;
const templateUrlExpression = (0, ast_1.getPropertyFromDecoratorFirstArgument)(ts.getDecorators(ngComponentDeclaration)?.find((decorator) => (0, exports.isNgClassDecorator)(decorator)), 'templateUrl');
const templateRelativePath = templateUrlExpression && ts.isStringLiteral(templateUrlExpression)
? templateUrlExpression.text
: templateUrlExpression?.getText();
return {
name,
selector,
standalone,
templateRelativePath
};
};
exports.getO3rComponentInfoOrThrowIfNotFound = getO3rComponentInfoOrThrowIfNotFound;
/**
* Transformer factory to add imports into the angular component decorator
* @param imports
*/
const addImportsIntoComponentDecoratorTransformerFactory = (imports) => (ctx) => (rootNode) => {
const { factory } = ctx;
const visit = (node) => {
if ((0, exports.isNgClassDecorator)(node)) {
const importInitializer = (0, ast_1.getPropertyFromDecoratorFirstArgument)(node, 'imports');
const importsList = importInitializer && ts.isArrayLiteralExpression(importInitializer) ? [...importInitializer.elements] : [];
return factory.updateDecorator(node, factory.updateCallExpression(node.expression, node.expression.expression, node.expression.typeArguments, [
factory.createObjectLiteralExpression([
...node.expression.arguments[0].properties.filter((prop) => prop.name?.getText() !== 'imports'),
factory.createPropertyAssignment('imports', factory.createArrayLiteralExpression(importsList.concat(imports.map((importName) => factory.createIdentifier(importName))), true))
], true)
]));
}
return ts.visitEachChild(node, visit, ctx);
};
return ts.visitNode(rootNode, visit);
};
exports.addImportsIntoComponentDecoratorTransformerFactory = addImportsIntoComponentDecoratorTransformerFactory;
//# sourceMappingURL=component.js.map