@dlr-eoc/core-ui
Version:
This project includes schematics to add the base UKIS-Layout to an angular application. The Layout is based on Clarity so [add this first](https://clarity.design/get-started/developing/angular)!
307 lines • 15.2 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getMainPath = getMainPath;
exports.addServiceComponentModule = addServiceComponentModule;
exports.removeServiceComponentModule = removeServiceComponentModule;
const schematics_1 = require("@angular-devkit/schematics");
const workspace_1 = require("@schematics/angular/utility/workspace");
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
const change_1 = require("@schematics/angular/utility/change");
const core_1 = require("@angular-devkit/core");
const ng_ast_utils_1 = require("@schematics/angular/utility/ng-ast-utils");
const utility_1 = require("@schematics/angular/utility");
/**
* https://github.com/angular/angular-cli/blob/fb14945c02a3f150d6965e77324416b1ec7cc575/packages/schematics/angular/utility/ast-utils.ts#L9
* angular schematics is using it's own typescript so we have to import the same and not -> import * as ts from 'typescript';
*/
const ts = require("@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript");
const core_2 = require("@angular-devkit/core");
const workspace_utils_1 = require("./workspace-utils");
function applyToUpdateRecorder(recorder, changes) {
for (const change of changes) {
if (change instanceof change_1.InsertChange) {
recorder.insertLeft(change.pos, change.toAdd);
}
else if (change instanceof change_1.RemoveChange) {
recorder.remove(change.order, change.toRemove.length);
}
else if (change instanceof change_1.ReplaceChange) {
recorder.remove(change.order, change.oldText.length);
recorder.insertLeft(change.order, change.newText);
}
else if (!(change instanceof change_1.NoopChange)) {
throw new Error('Unknown Change type encountered when updating a recorder.');
}
}
}
function applyChanges(changes, tree, modulePath) {
const recorder = tree.beginUpdate(modulePath);
applyToUpdateRecorder(recorder, changes);
tree.commitUpdate(recorder);
}
function getMainPath(project) {
let mainPath = (0, core_1.join)((0, core_1.normalize)(project.root), project.sourceRoot || (0, core_1.join)((0, core_1.normalize)(project.root), 'src'), 'main.ts');
// https://github.com/angular/angular-cli/blob/HEAD/packages/angular/pwa/pwa/index.ts#L100
if ((0, workspace_utils_1.hasArchitectBuildOptionsMain)(project.extensions)) {
mainPath = (0, core_1.join)((0, core_1.normalize)(project.root), project.extensions.architect.build.options.main);
}
return mainPath;
}
function addServiceComponentModule(optionsProject, item, modulePathStr) {
return (tree, context) => __awaiter(this, void 0, void 0, function* () {
const workspace = yield (0, workspace_1.getWorkspace)(tree);
const projectName = (0, workspace_utils_1.getProjectName)(workspace, optionsProject);
if (projectName) {
const project = workspace.projects.get(projectName);
if (project && (0, workspace_utils_1.checkProjectSourceRoot)(project, context)) {
let mainPath = getMainPath(project);
const isStandalone = (0, ng_ast_utils_1.isStandaloneApp)(tree, mainPath);
if (isStandalone) {
if (item.provide) {
return (0, utility_1.addRootProvider)(projectName, ({ code, external }) => code `${external(item.classifiedName, item.path)}`);
}
else {
return (0, schematics_1.noop)();
}
}
else {
let modulePath = (0, ng_ast_utils_1.getAppModulePath)(tree, mainPath);
if (modulePathStr && tree.exists(modulePathStr)) {
modulePath = modulePathStr;
}
context.logger.debug(`module path: ${modulePath}`);
const moduleSource = getTsSourceFile(tree, modulePath);
if (!item.standalone) {
if (item.provide) {
const changes = (0, ast_utils_1.addProviderToModule)(moduleSource, modulePath, item.classifiedName, item.path);
applyChanges(changes, tree, modulePath);
}
else if (item.module) {
const change = (0, ast_utils_1.addImportToModule)(moduleSource, modulePath, item.classifiedName, item.path);
applyChanges(change, tree, modulePath);
}
else if (item.declare) {
const changes = (0, ast_utils_1.addDeclarationToModule)(moduleSource, modulePath, item.classifiedName, item.path);
applyChanges(changes, tree, modulePath);
}
else {
const change = [(0, ast_utils_1.insertImport)(moduleSource, modulePath, item.classifiedName, item.path)];
applyChanges(change, tree, modulePath);
}
}
}
}
}
});
}
function removeServiceComponentModule(optionsProject, item, modulePathStr) {
return (tree, context) => __awaiter(this, void 0, void 0, function* () {
const workspace = yield (0, workspace_1.getWorkspace)(tree);
const projectName = (0, workspace_utils_1.getProjectName)(workspace, optionsProject);
if (projectName) {
const project = workspace.projects.get(projectName);
if (project && (0, workspace_utils_1.checkProjectSourceRoot)(project, context)) {
let mainPath = getMainPath(project);
const isStandalone = (0, ng_ast_utils_1.isStandaloneApp)(tree, mainPath);
if (isStandalone) {
// TODO remove things
return (0, schematics_1.noop)();
}
else {
let modulePath = (0, ng_ast_utils_1.getAppModulePath)(tree, mainPath);
if (modulePathStr && tree.exists(modulePathStr)) {
modulePath = modulePathStr;
}
context.logger.debug(`module path: ${modulePath}`);
const moduleSource = getTsSourceFile(tree, modulePath);
if (!item.standalone) {
if (item.provide) {
const changes = removeProviderFromModule(moduleSource, modulePath, item.classifiedName, item.path);
applyChanges(changes, tree, modulePath);
}
else if (item.module) {
const change = removeImportFromModule(moduleSource, modulePath, item.classifiedName, item.path);
applyChanges(change, tree, modulePath);
}
else if (item.declare) {
const changes = removeDeclarationFromModule(moduleSource, modulePath, item.classifiedName, item.path);
applyChanges(changes, tree, modulePath);
}
else {
const symbolName = item.classifiedName.replace(/\..*$/, '');
const change = [...removeImport(moduleSource, modulePath, symbolName, item.path)];
applyChanges(change, tree, modulePath);
}
}
}
}
}
});
}
function removeProviderFromModule(source, modulePath, classifiedName, importPath) {
return removeSymbolFromNgModuleMetadata(source, modulePath, 'providers', classifiedName, importPath);
}
function removeImportFromModule(source, modulePath, classifiedName, importPath) {
return removeSymbolFromNgModuleMetadata(source, modulePath, 'imports', classifiedName, importPath);
}
function removeDeclarationFromModule(source, modulePath, classifiedName, importPath) {
return removeSymbolFromNgModuleMetadata(source, modulePath, 'declarations', classifiedName, importPath);
}
/**
* https://github.com/angular/angular-cli/blob/fb14945c02a3f150d6965e77324416b1ec7cc575/packages/schematics/angular/utility/ast-utils.ts#L22
* RemoveChange: host.read => content.substring // from pos to remove length
*
* If there are multiple same imports all get removed
*/
function removeImport(source, fileToEdit, symbolName, fileName, isDefault = false) {
const rootNode = source;
// SyntaxKind: https://github.com/microsoft/TypeScript/blob/v4.2.3/src/compiler/types.ts#L21
const allImports = (0, ast_utils_1.findNodes)(rootNode, ts.SyntaxKind.ImportDeclaration);
// get nodes that map to import statements from the file fileName
const relevantImports = allImports.filter(node => {
// StringLiteral of the ImportDeclaration is the import file (fileName in this case).
const importFiles = node.getChildren()
.filter(ts.isStringLiteral)
.map(n => n.text);
return importFiles.filter(file => file === fileName).length === 1;
});
if (relevantImports.length > 0) {
let importsAsterisk = false;
// imports from import file
// Node: https://github.com/microsoft/TypeScript/blob/v4.2.3/src/compiler/types.ts#L837
const imports = [];
relevantImports.forEach(node => {
Array.prototype.push.apply(imports, (0, ast_utils_1.findNodes)(node, ts.SyntaxKind.Identifier));
if ((0, ast_utils_1.findNodes)(node, ts.SyntaxKind.AsteriskToken).length > 0) {
importsAsterisk = true;
}
});
// if imports * from fileName, don't add symbolName
if (importsAsterisk) {
return [new change_1.NoopChange()];
}
const importTextNodes = imports.filter(n => n.text === symbolName);
// console.log(importTextNodes);
// remove import if it's there
if (importTextNodes.length) {
const open = isDefault ? '' : '{ ';
const close = isDefault ? '' : ' }';
const changes = importTextNodes.map(node => {
const position = node.getStart();
const toRemove = `import ${open}${symbolName}${close}` +
` from '${fileName}'}`;
return new change_1.RemoveChange(fileToEdit, position, toRemove);
});
return changes;
}
else {
return [new change_1.NoopChange()];
}
}
else {
return [new change_1.NoopChange()];
}
}
/**
* https://github.com/angular/angular-cli/blob/fb14945c02a3f150d6965e77324416b1ec7cc575/packages/schematics/angular/utility/ast-utils.ts#L341
*/
function removeSymbolFromNgModuleMetadata(source, ngModulePath, metadataField, symbolName, importPath = null) {
const nodes = (0, ast_utils_1.getDecoratorMetadata)(source, 'NgModule', '@angular/core');
let nodeArray = null;
let node = nodes[0]; // tslint:disable-line:no-any
/* const printNodes = nodes.map(n => {
const tempnode: any = n;
tempnode.kindText = Object.keys(ts.SyntaxKind).map(k => {
const value = (ts.SyntaxKind as any)[k];
if (value === n.kind) {
return k;
}
}).find(i => i !== undefined);
return tempnode;
});
console.log(printNodes); */
// Find the decorator declaration.
if (!node) {
return [];
}
// Get all the children property assignment of object literals.
const matchingProperties = (0, ast_utils_1.getMetadataField)(node, metadataField);
// We have found the field in the metadata declaration. So we try to remove it.
if (matchingProperties.length) {
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;
if (arrLiteral.elements.length === 0) {
// Forward the property.
node = arrLiteral;
}
else {
nodeArray = arrLiteral.elements;
}
if (Array.isArray(nodeArray) && nodeArray.length) {
// const nodeArray = node;
const symbolsArray = nodeArray.map(n => core_2.tags.oneLine `${n.getText()}`);
const hasIndex = symbolsArray.indexOf(core_2.tags.oneLine `${symbolName}`);
// found symbol in nodes array
if (hasIndex !== -1) {
node = nodeArray[hasIndex];
}
else {
// not found so return;
return [];
}
}
let toRemove;
let position = node.getStart();
if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
// We found the field but it's empty. Insert it just before the `]`.
position--;
toRemove = `\n${core_2.tags.indentBy(4) `${symbolName}`}\n `;
console.log('We found the field but its empty', position, toRemove);
return [];
}
else {
// Get the indentation of the last element, if any.
const text = node.getFullText(source);
const matches = text.match(/^(\r?\n)(\s*)/);
if (matches) {
toRemove = `,${matches[1]}${core_2.tags.indentBy(matches[2].length) `${symbolName}`}`;
}
else {
toRemove = `, ${symbolName}`;
}
}
if (importPath !== null) {
return [
new change_1.RemoveChange(ngModulePath, position, toRemove),
...removeImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath),
];
}
return [new change_1.RemoveChange(ngModulePath, position, toRemove)];
}
else {
return [new change_1.NoopChange()];
}
}
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;
}
//# sourceMappingURL=ast-utils.js.map