UNPKG

@o3r/schematics

Version:

Schematics module of the Otter framework

107 lines 6.13 kB
"use strict"; 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