UNPKG

@netgrif/components

Version:

Netgrif Application Engine frontend Angular components

247 lines 11.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addImport = exports.addProviderToComponent = exports.findNodesInChildren = exports.forEachSubDirFile = exports.forEachProjectFile = exports.forEachSourceTsFile = exports.createRelativePath = exports.createFilesFromTemplates = exports.getTsSource = exports.fileEntryToTsSource = exports.getFileData = exports.getAppModule = exports.createChangesRecorder = exports.commitChangesToFile = exports.getNaeConfiguration = exports.getNaeConfigurationString = exports.getProjectInfo = void 0; const ts = require("@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript"); const schematics_1 = require("@angular-devkit/schematics"); const core_1 = require("@angular-devkit/core"); const change_1 = require("@schematics/angular/utility/change"); const file_system_node_1 = require("./models/file-system-node"); const project_info_1 = require("./models/project-info"); const modified_library_functions_1 = require("./modified-library-functions"); const ast_utils_1 = require("@schematics/angular/utility/ast-utils"); function getProjectInfo(tree) { const workspaceConfig = tree.read('/angular.json'); if (!workspaceConfig) { throw new schematics_1.SchematicsException('Could not find Angular workspace configuration. Missing \'angular.json\'.'); } const workspaceContent = workspaceConfig.toString(); const workspace = JSON.parse(workspaceContent); const result = new project_info_1.ProjectInfo(); result.projectName = workspace.defaultProject; result.projectNameClassified = core_1.strings.classify(result.projectName); result.projectNameDasherized = core_1.strings.dasherize(result.projectName); const project = workspace.projects[result.projectName]; const projectType = project.projectType === 'application' ? 'app' : 'lib'; result.path = `${project.sourceRoot}/${projectType}`; result.projectPrefix = project.prefix; result.projectPrefixDasherized = core_1.strings.dasherize(result.projectPrefix); return result; } exports.getProjectInfo = getProjectInfo; function getNaeConfigurationString(tree) { const naeConfig = tree.read('/nae.json'); if (!naeConfig) { throw new schematics_1.SchematicsException('Could not find Netgrif Application Engine workspace configuration. Missing \'nae.json\'.'); } return naeConfig.toString(); } exports.getNaeConfigurationString = getNaeConfigurationString; function getNaeConfiguration(tree) { return JSON.parse(getNaeConfigurationString(tree)); } exports.getNaeConfiguration = getNaeConfiguration; function commitChangesToFile(tree, file, changes) { const changesRecorder = createChangesRecorder(tree, file, changes); tree.commitUpdate(changesRecorder); } exports.commitChangesToFile = commitChangesToFile; function createChangesRecorder(tree, file, changes) { const exportRecorder = tree.beginUpdate(file.path); for (const change of changes) { if (change instanceof change_1.InsertChange) { exportRecorder.insertLeft(change.pos, change.toAdd); } else if (change instanceof change_1.RemoveChange) { exportRecorder.remove(change.order, change.toRemove.length); } else if (change instanceof change_1.NoopChange) { continue; } else { throw new schematics_1.SchematicsException('Other change types are currently not supported by Netgrif utility implementation'); } } return exportRecorder; } exports.createChangesRecorder = createChangesRecorder; function getAppModule(tree, projectPath) { return getFileData(tree, projectPath, 'app.module.ts'); } exports.getAppModule = getAppModule; function getFileData(tree, projectRootPath, relativeFilePath) { const file = tree.get(`${projectRootPath}/${relativeFilePath}`); if (!file) { throw new schematics_1.SchematicsException(`Could not find requested file. Missing '${relativeFilePath}'.`); } return { fileEntry: file, sourceFile: fileEntryToTsSource(file) }; } exports.getFileData = getFileData; function fileEntryToTsSource(file, encoding = 'utf8') { const source = getTsSource(file.path, file.content.toString(encoding)); if (source === null) { throw new schematics_1.SchematicsException(`'${file.path}' could not be read. Make sure it has UTF-8 encoding.`); } return source; } exports.fileEntryToTsSource = fileEntryToTsSource; function getTsSource(path, content) { return ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true); } exports.getTsSource = getTsSource; /** * A convenience method that creates source files from template files and places them at the specified location in the file system. * @param pathToTemplates path relative to the location of the schematic entry-point file * (might not necessarily be the same as the file that contains the call!) * @param pathToMoveGeneratedFiles path relative to the workspace root where the generated files should be placed * @param options the object that supplies parameters to the template files */ function createFilesFromTemplates(pathToTemplates, pathToMoveGeneratedFiles, options = {}) { const templateSource = (0, schematics_1.apply)((0, schematics_1.url)(pathToTemplates), [ (0, schematics_1.applyTemplates)(options), (0, schematics_1.move)((0, core_1.normalize)(pathToMoveGeneratedFiles)), ]); return (0, schematics_1.mergeWith)(templateSource); } exports.createFilesFromTemplates = createFilesFromTemplates; /** * computes the relative path from one file to another * @param sourcePath - path relative to project root of the source file * @param destinationPath - path relative to project root of the destination file * @return path that leads from source file to destination file */ function createRelativePath(sourcePath, destinationPath) { const root = new file_system_node_1.FileSystemNode('', null); let lastNode = root; sourcePath.split('/').forEach(pathPart => { if (pathPart === '.') { return; // continue } const newNode = new file_system_node_1.FileSystemNode(pathPart, lastNode); lastNode.children.push(newNode); lastNode = newNode; }); const sourceNode = lastNode; lastNode = root; destinationPath.split('/').forEach(pathPart => { if (pathPart === '.') { return; } if (lastNode.children.length === 1 && lastNode.children[0].path === pathPart) { lastNode = lastNode.children[0]; } else { const newNode = new file_system_node_1.FileSystemNode(pathPart, lastNode); lastNode.children.push(newNode); lastNode = newNode; } }); let currentNode = sourceNode.parent; const pathFragments = []; let traversalDirectionUp = true; if (currentNode.children.length === 2) { pathFragments.push('.'); traversalDirectionUp = false; currentNode = currentNode.children[1]; } while (traversalDirectionUp) { if (currentNode.children.length === 2) { traversalDirectionUp = false; currentNode = currentNode.children[1]; // destination path is always added second } else { currentNode = currentNode.parent; pathFragments.push('..'); } } while (true) { pathFragments.push(currentNode.path); if (currentNode.children.length > 0) { currentNode = currentNode.children[0]; } else { break; } } return pathFragments.join('/'); } exports.createRelativePath = createRelativePath; /** * Recursively iterates over every non-test, typescript source file in the project * and executes the given lambda with it as the input parameter. */ function forEachSourceTsFile(tree, lambda) { forEachProjectFile(tree, (fe => { if (fe.path.endsWith('.ts') && !fe.path.endsWith('.spec.ts')) { lambda(fe); } })); } exports.forEachSourceTsFile = forEachSourceTsFile; /** * Recursively iterates over every file in the project and executes the given lambda with it as the input parameter. * @param tree tree to get access to the file system * @param lambda the function that is called with each of the project files as it's argument */ function forEachProjectFile(tree, lambda) { const projectInfo = getProjectInfo(tree); const rootDir = tree.getDir(projectInfo.path); forEachSubDirFile(rootDir, lambda); } exports.forEachProjectFile = forEachProjectFile; /** * Recursively iterates over every file in the given directory and executes the given lambda with it as the input parameter. * @param subRoot the directory which should be recursively explored. * The files in the given directory and all it's subdirectories are processed by this function * @param lambda the function that is called with each of the files as it's argument */ function forEachSubDirFile(subRoot, lambda) { subRoot.subfiles.forEach(pathFragment => { const file = subRoot.file(pathFragment); if (file !== null) { lambda(file); } }); subRoot.subdirs.forEach(pathFragment => { forEachSubDirFile(subRoot.dir(pathFragment), lambda); }); } exports.forEachSubDirFile = forEachSubDirFile; /** * Finds all nodes of the given type among the child nodes of the given node. * @param start the node who's children should be searched * @param target the type of node that should be found * @param recursive whether children of children should be examined recursively or not * @returns an array of the children that are of the given type. Order of the children is not guaranteed. */ function findNodesInChildren(start, target, recursive = false) { const result = []; start.getChildren().forEach(child => { if (child.kind === target) { result.push(child); } if (recursive && child.getChildren().length !== 0) { result.push(...findNodesInChildren(child, target, recursive)); } }); return result; } exports.findNodesInChildren = findNodesInChildren; /** * Adds another provider to the providers of a specified component * @param componentFile the file with the component * @param symbolName the class name of the added provider * @param importPath the path from which to import the symbol * @param insertedText? the text that should be inserted into the providers array */ function addProviderToComponent(componentFile, symbolName, importPath = null, insertedText) { return (0, modified_library_functions_1.addSymbolToDecoratorMetadata)(fileEntryToTsSource(componentFile), componentFile.path, 'Component', 'providers', symbolName, insertedText, importPath); } exports.addProviderToComponent = addProviderToComponent; function addImport(file, newImport) { return (0, ast_utils_1.insertImport)(fileEntryToTsSource(file), file.path, newImport.className, newImport.fileImportPath); } exports.addImport = addImport; //# sourceMappingURL=utility-functions.js.map