@netgrif/components
Version:
Netgrif Application Engine frontend Angular components
247 lines • 11.2 kB
JavaScript
;
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