devui-admin-test
Version:
Schematics for ng-devui-admin
172 lines (156 loc) • 5.59 kB
text/typescript
import { strings } from '@angular-devkit/core';
import { chain, Rule, schematic, SchematicsException, Tree } from '@angular-devkit/schematics';
import { buildRelativePath, findModule } from '@schematics/angular/utility/find-module';
import {
addModule,
getPageNameFromFilePath,
getSourceNodes,
insertHTMLFile,
insertStyleFile,
insertTSFile,
readIntoSourceFile,
} from '../utils';
import { Schema as BlockOptions } from './schema';
import * as fs from 'fs';
import * as path from 'path';
import ts = require('typescript');
function readFileIntoString(tree: Tree, filePath: string): string {
const buffer = tree.read(filePath);
let strContent = '';
if (buffer) strContent = buffer.toString('utf-8');
return strContent;
}
function readTsFileContent(tree: Tree, filePath: string): { methods: string; properties: string } {
const methods: string[] = [];
const properties: string[] = [];
const sourceFile = readIntoSourceFile(tree, filePath);
const nodes: ts.Node[] = getSourceNodes(sourceFile);
nodes.forEach((n) => {
if (n.kind === ts.SyntaxKind.MethodDeclaration) {
methods.push('\n\t' + n.getText());
}
if (n.kind === ts.SyntaxKind.PropertyDeclaration) {
properties.push('\n\t' + n.getText());
}
});
return {
methods: methods.join(''),
properties: properties.join('') + '\n',
};
}
function genAddModulesRules(modules: string[], modulePath: string): Rule {
let rules: Rule[] = [];
modules.forEach((m) => {
rules.push(
schematic('plugin', {
modulePath: modulePath,
insertModuleName: m,
})
);
});
return chain(rules);
}
function getBlockInfo(tree: Tree, blockPath: string): { componentModules: string[]; selector: string } {
let blockPackage = null;
const blockPackageBuffer = tree.read(blockPath);
if (blockPackageBuffer) {
blockPackage = JSON.parse(blockPackageBuffer.toString());
} else {
throw new SchematicsException(`Cannot find block ${blockPath}, please download first.`);
}
return {
componentModules: blockPackage['blockConfig']['componentModules'],
selector: blockPackage['blockConfig']['selector'],
};
}
function writeBlock(tree: Tree, srcPath: string, desPath: string): void {
let buffer = tree.read(srcPath);
if (buffer) {
tree.create(desPath, buffer);
}
}
function insertOptions(
tree: Tree,
options: BlockOptions,
blockInfo: { componentModules: string[]; selector: string },
modulePath: string
): Rule {
const blockContent = readTsFileContent(
tree,
`node_modules/ng-devui-materials/${strings.dasherize(options.blockName)}/src/${strings.dasherize(options.blockName)}.component.ts`
);
if (options.importWay === 'by-code') {
return chain([
insertTSFile(
`${options.dirPath}/${getPageNameFromFilePath(options.dirPath)}.component.ts`,
'property',
blockContent.properties,
`${strings.classify(getPageNameFromFilePath(options.dirPath))}Component`
),
insertTSFile(`${options.dirPath}/${getPageNameFromFilePath(options.dirPath)}.component.ts`, 'method', blockContent.methods),
insertHTMLFile(
`${options.dirPath}/${getPageNameFromFilePath(options.dirPath)}.component.html`,
readFileIntoString(
tree,
`node_modules/ng-devui-materials/${strings.dasherize(options.blockName)}/src/${strings.dasherize(
options.blockName
)}.component.html`
)
),
insertStyleFile(
`${options.dirPath}/${getPageNameFromFilePath(options.dirPath)}.component.scss`,
readFileIntoString(
tree,
`node_modules/ng-devui-materials/${strings.dasherize(options.blockName)}/src/${strings.dasherize(
options.blockName
)}.component.scss`
)
),
genAddModulesRules(blockInfo.componentModules, modulePath),
]);
} else {
const srcPath = path.join(
__dirname,
'..',
'..',
'..',
'node_modules',
`ng-devui-materials/${strings.dasherize(options.blockName)}/src`
);
fs.readdirSync(srcPath).forEach((p) => {
if (fs.statSync(`${srcPath}/${p}`).isDirectory()) {
fs.readdirSync(`${srcPath}/${p}`).forEach((d) => {
writeBlock(
tree,
`node_modules/ng-devui-materials/${strings.dasherize(options.blockName)}/src/${p}/${d}`,
`${options.dirPath}/${strings.dasherize(options.blockName)}/${p}/${d}`
);
});
} else {
writeBlock(
tree,
`node_modules/ng-devui-materials/${strings.dasherize(options.blockName)}/src/${p}`,
`${options.dirPath}/${strings.dasherize(options.blockName)}/${p}`
);
}
});
const relativeModulePath = buildRelativePath(
modulePath,
`/${options.dirPath}/${strings.dasherize(options.blockName)}/${strings.dasherize(options.blockName)}.module`
);
return chain([
addModule(modulePath, `${strings.classify(options.blockName)}Module`, relativeModulePath!),
insertHTMLFile(
`${options.dirPath}/${getPageNameFromFilePath(options.dirPath)}.component.html`,
`<${blockInfo.selector}></${blockInfo.selector}>`
),
]);
}
}
export default function (options: BlockOptions): Rule {
return (tree: Tree) => {
const modulePath = findModule(tree, options.dirPath);
const blockInfo = getBlockInfo(tree, `node_modules/ng-devui-materials/${strings.dasherize(options.blockName)}/package.json`);
return chain([insertOptions(tree, options, blockInfo, modulePath)]);
};
}