UNPKG

@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
"use strict"; 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