UNPKG

ng-alain

Version:

Schematics specific to NG-ALAIN

160 lines 6.45 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ROUTINS_FILENAME = void 0; exports.getSourceFile = getSourceFile; exports.applyChanges = applyChanges; exports.findRoutesPath = findRoutesPath; exports.importInStandalone = importInStandalone; exports.addServiceToModuleOrStandalone = addServiceToModuleOrStandalone; exports.consoleTree = consoleTree; const core_1 = require("@angular-devkit/core"); const schematics_1 = require("@angular-devkit/schematics"); const ast_utils_1 = require("@schematics/angular/utility/ast-utils"); const change_1 = require("@schematics/angular/utility/change"); const ts = require("typescript"); const alain_1 = require("./alain"); exports.ROUTINS_FILENAME = 'routes.ts'; /** Reads file given path and returns TypeScript source file. */ function getSourceFile(tree, path) { const buffer = tree.read(path); if (!buffer) { throw new schematics_1.SchematicsException(`Could not find file for path: ${path}`); } const content = buffer.toString(); return ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true); } function applyChanges(tree, path, changes) { const exportRecorder = tree.beginUpdate(path); for (const change of changes) { if (change instanceof change_1.InsertChange) { exportRecorder.insertLeft(change.pos, change.toAdd); } } tree.commitUpdate(exportRecorder); } function getComponentMetadata(source) { const allNodes = (0, ast_utils_1.getSourceNodes)(source); const identifier = 'Component'; return allNodes .filter(node => { return (node.kind == ts.SyntaxKind.Decorator && node.expression.kind == ts.SyntaxKind.CallExpression); }) .map(node => node.expression) .filter(expr => { if (expr.expression.kind == ts.SyntaxKind.Identifier) { const id = expr.expression; return id.text == identifier; } return false; }) .filter(expr => expr.arguments[0] && expr.arguments[0].kind == ts.SyntaxKind.ObjectLiteralExpression) .map(expr => expr.arguments[0]); } function addSymbolToComponentMetadata(source, filePath, symbolName, metadataField = 'imports') { const nodes = getComponentMetadata(source); if (nodes.length <= 0) return []; const node = nodes[0]; if (!node || !ts.isObjectLiteralExpression(node)) { return []; } // Get all the children property assignment of object literals. const matchingProperties = (0, ast_utils_1.getMetadataField)(node, metadataField); if (matchingProperties.length == 0) { // We haven't found the field in the metadata declaration. Insert a new field. let position; let toInsert; if (node.properties.length == 0) { position = node.getEnd() - 1; toInsert = `\n ${metadataField}: [\n${core_1.tags.indentBy(4) `${symbolName}`}\n ]\n`; } else { const childNode = node.properties[node.properties.length - 1]; position = childNode.getEnd(); // Get the indentation of the last element, if any. const text = childNode.getFullText(source); const matches = text.match(/^(\r?\n)(\s*)/); if (matches) { toInsert = `,${matches[0]}${metadataField}: [${matches[1]}` + `${core_1.tags.indentBy(matches[2].length + 2) `${symbolName}`}${matches[0]}]`; } else { toInsert = `, ${metadataField}: [${symbolName}]`; } } return [new change_1.InsertChange(filePath, position, toInsert)]; } const assignment = matchingProperties[0]; // If it's not an array, nothing we can do really. if (!ts.isPropertyAssignment(assignment) || !ts.isArrayLiteralExpression(assignment.initializer)) { return []; } let expresssion; const assignmentInit = assignment.initializer; const elements = assignmentInit.elements; if (elements.length) { const symbolsArray = elements.map(node => core_1.tags.oneLine `${node.getText()}`); if (symbolsArray.includes(core_1.tags.oneLine `${symbolName}`)) { return []; } expresssion = elements[elements.length - 1]; } else { expresssion = assignmentInit; } let toInsert; let position = expresssion.getEnd(); if (ts.isArrayLiteralExpression(expresssion)) { // We found the field but it's empty. Insert it just before the `]`. position--; toInsert = `\n${core_1.tags.indentBy(4) `${symbolName}`}\n `; } else { // Get the indentation of the last element, if any. const text = expresssion.getFullText(source); const matches = text.match(/^(\r?\n)(\s*)/); if (matches) { toInsert = `,${matches[1]}${core_1.tags.indentBy(matches[2].length) `${symbolName}`}`; } else { toInsert = `, ${symbolName}`; } } return [new change_1.InsertChange(filePath, position, toInsert)]; } function findRoutesPath(tree, path) { let dir = tree.getDir(path); while (dir) { const found = dir.subfiles.filter(p => p.endsWith(exports.ROUTINS_FILENAME)); if (found.length > 0) { return (0, core_1.normalize)(`${dir.path}/${exports.ROUTINS_FILENAME}`); } dir = dir.parent; } return ''; } function importInStandalone(tree, filePath, componentName, componentPath, metadataField = 'imports') { // imports (0, alain_1.addImportToModule)(tree, filePath, componentName, componentPath); // import in component const source = getSourceFile(tree, filePath); const changes = addSymbolToComponentMetadata(source, filePath, componentName, metadataField); applyChanges(tree, filePath, changes); } function addServiceToModuleOrStandalone(tree, standalone, filePath, serviceName, importPath) { const source = getSourceFile(tree, filePath); if (standalone) { importInStandalone(tree, filePath, serviceName, importPath, 'providers'); } else { const changes = (0, ast_utils_1.addProviderToModule)(source, filePath, serviceName, importPath); applyChanges(tree, filePath, changes); } } function consoleTree(tree) { tree.visit(filePath => { console.log(filePath); }); } //# sourceMappingURL=ast.js.map