UNPKG

@alyle/ui

Version:

Minimal Design, a set of components for Angular

217 lines • 8.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTsSourceFile = getTsSourceFile; exports.addImport = addImport; exports.prettierConstructorParameters = prettierConstructorParameters; exports.addSymbolToDecoratorMetadata = addSymbolToDecoratorMetadata; exports.addProviderDecorator = addProviderDecorator; exports.addProvider = addProvider; const schematics_1 = require("@angular-devkit/schematics"); const ts = require("typescript"); const vendored_ast_utils_1 = require("./vendored-ast-utils"); const change_1 = require("@schematics/angular/utility/change"); const schematics_2 = require("@angular/cdk/schematics"); function getTsSourceFile(host, path) { const buffer = host.read(path); if (!buffer) { throw new schematics_1.SchematicsException(`Could not read file (${path}).`); } const content = buffer.toString(); const source = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true); return source; } function addImport(host, filePath, importModule, path) { let importModules; if (typeof importModule === 'string') { importModules = [importModule]; } else { importModules = importModule; } // add import theme importModules.forEach((val) => { const fileSource = getTsSourceFile(host, filePath); const importPath = path; if (!(0, vendored_ast_utils_1.isImported)(fileSource, val, importPath)) { const change = (0, vendored_ast_utils_1.insertImport)(fileSource, filePath, val, importPath); if (change) { const recorder = host.beginUpdate(filePath); recorder.insertLeft(change.pos, change.toAdd); host.commitUpdate(recorder); } } }); } function prettierConstructorParameters(host, filePath, constructor) { const parenToken = constructor.getChildren() .filter(prop => prop.kind === ts.SyntaxKind.OpenParenToken || prop.kind === ts.SyntaxKind.CloseParenToken); // .map(prop => prop.getFullText().trim()); const buffer = host.read(filePath); if (buffer === null) { throw new schematics_1.SchematicsException(`Could not read index file: ${filePath}`); } const syntaxList = constructor.getChildren() .filter(prop => prop.kind === ts.SyntaxKind.SyntaxList)[0]; const contructorBefore = `${parenToken[0].getFullText()}${syntaxList.getFullText()}${parenToken[1].getFullText()}`; const parameters = syntaxList.getChildren() .filter(prop => prop.kind === ts.SyntaxKind.Parameter) .map((parameter, index) => { const param = parameter.getText(); let comment = parameter.getFullText().replace(param, '').trim(); if (comment) { comment += `\n`; if (index === 0) { comment += `\n${comment}`; } } return `${comment}${param}`; }); const parametersStr = parameters.join(`,\n${` `.repeat(14)}`); const result = `${parenToken[0].getFullText().trim()}${parametersStr}${parenToken[1].getFullText().trim()}`; host.overwrite(filePath, buffer.toString().replace(contructorBefore, result)); } function addSymbolToDecoratorMetadata(source, ngModulePath, decorator, metadataField, symbolName, importPath = null) { const nodes = (0, vendored_ast_utils_1.getDecoratorMetadata)(source, decorator, '@angular/core'); let node = nodes[0]; // tslint:disable-line:no-any // Find the decorator declaration. if (!node) { return []; } // Get all the children property assignment of object literals. const matchingProperties = (0, vendored_ast_utils_1.getMetadataField)(node, metadataField); // Get the last node of the array literal. if (!matchingProperties) { return []; } // tslint:disable-next-line: triple-equals if (matchingProperties.length == 0) { // We haven't found the field in the metadata declaration. Insert a new field. const expr = node; // tslint:disable-next-line: no-shadowed-variable let position; // tslint:disable-next-line: no-shadowed-variable let toInsert; // tslint:disable-next-line: triple-equals if (expr.properties.length == 0) { position = expr.getEnd() - 1; toInsert = ` ${metadataField}: [${symbolName}]\n`; } else { node = expr.properties[expr.properties.length - 1]; position = node.getEnd(); // Get the indentation of the last element, if any. const text = node.getFullText(source); const matches = text.match(/^\r?\n\s*/); if (matches && matches.length > 0) { toInsert = `,${matches[0]}${metadataField}: [${symbolName}]`; } else { toInsert = `, ${metadataField}: [${symbolName}]`; } } if (importPath !== null) { return [ new change_1.InsertChange(ngModulePath, position, toInsert), (0, vendored_ast_utils_1.insertImport)(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath), ]; } else { return [new change_1.InsertChange(ngModulePath, position, toInsert)]; } } const assignment = matchingProperties[0]; // If it's not an array, nothing we can do really. if (assignment.initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) { return []; } const arrLiteral = assignment.initializer; // tslint:disable-next-line: triple-equals if (arrLiteral.elements.length == 0) { // Forward the property. node = arrLiteral; } else { node = arrLiteral.elements; } if (!node) { // tslint:disable-next-line: no-console console.error('No app module found. Please add your new class to your component.'); return []; } if (Array.isArray(node)) { const nodeArray = node; // tslint:disable-next-line: no-shadowed-variable const symbolsArray = nodeArray.map(node => node.getText()); if (symbolsArray.includes(symbolName)) { return []; } node = node[node.length - 1]; } let toInsert; let position = node.getEnd(); // tslint:disable-next-line: triple-equals if (node.kind == ts.SyntaxKind.ObjectLiteralExpression) { // We haven't found the field in the metadata declaration. Insert a new // field. const expr = node; // tslint:disable-next-line: triple-equals if (expr.properties.length == 0) { position = expr.getEnd() - 1; toInsert = ` ${symbolName}\n`; } else { // Get the indentation of the last element, if any. const text = node.getFullText(source); if (text.match(/^\r?\r?\n/)) { toInsert = `,${text.match(/^\r?\n\s*/)[0]}${symbolName}`; } else { toInsert = `, ${symbolName}`; } } // tslint:disable-next-line: triple-equals } else if (node.kind == ts.SyntaxKind.ArrayLiteralExpression) { // We found the field but it's empty. Insert it just before the `]`. position--; toInsert = `${symbolName}`; } else { // Get the indentation of the last element, if any. const text = node.getFullText(source); if (text.match(/^\r?\n/)) { toInsert = `,${text.match(/^\r?\n(\r?)\s*/)[0]}${symbolName}`; } else { toInsert = `, ${symbolName}`; } } if (importPath !== null) { return [ new change_1.InsertChange(ngModulePath, position, toInsert), (0, vendored_ast_utils_1.insertImport)(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath), ]; } return [new change_1.InsertChange(ngModulePath, position, toInsert)]; } /** * Custom function to insert a provider into Decorator. It also imports it. */ function addProviderDecorator(source, modulePath, decorator, classifiedName, importPath) { return addSymbolToDecoratorMetadata(source, modulePath, decorator, 'providers', classifiedName, importPath); } function addProvider(host, modulePath, decorator, classifiedName, src) { const moduleSource = (0, schematics_2.parseSourceFile)(host, modulePath); if (!moduleSource) { throw new schematics_1.SchematicsException(`Module not found: ${modulePath}`); } const changes = addProviderDecorator(moduleSource, modulePath, decorator, classifiedName, src); const recorder = host.beginUpdate(modulePath); changes.forEach((change) => { if (change instanceof change_1.InsertChange) { recorder.insertLeft(change.pos, change.toAdd); } }); host.commitUpdate(recorder); } //# sourceMappingURL=ast.js.map