增加了dependencyBuilder

This commit is contained in:
Xu Chang 2024-04-09 20:51:21 +08:00
parent fc7b54feaf
commit d43f3f4c9f
12 changed files with 1269 additions and 104 deletions

View File

@ -1,5 +0,0 @@
import { CascadeRelationItem, RelationHierarchy, EntityDict } from "../types/Entity";
export type GenericRelation = 'owner';
export declare function convertHierarchyToAuth<ED extends EntityDict, T extends keyof ED>(entity: T, hierarchy: RelationHierarchy<NonNullable<ED[T]['Relation']>>): {
[K in NonNullable<ED[T]['Relation']>]?: CascadeRelationItem;
};

View File

@ -1,25 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertHierarchyToAuth = void 0;
function convertHierarchyToAuth(entity, hierarchy) {
const reverseHierarchy = {};
for (const r in hierarchy) {
for (const r2 of hierarchy[r]) {
if (reverseHierarchy[r2]) {
reverseHierarchy[r2]?.push(r);
}
else {
reverseHierarchy[r2] = [r];
}
}
}
const result = {};
for (const r in reverseHierarchy) {
result[r] = {
cascadePath: '',
relations: reverseHierarchy[r],
};
}
return result;
}
exports.convertHierarchyToAuth = convertHierarchyToAuth;

View File

@ -1,5 +0,0 @@
import { GenericAction } from "../../actions/action";
export type ParticularAction = 'confirm';
export declare const actions: string[];
export type Action = GenericAction | ParticularAction | string;
export declare const ActionDefDict: {};

View File

@ -1,5 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ActionDefDict = exports.actions = void 0;
exports.actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "confirm"];
exports.ActionDefDict = {};

5
lib/compiler/dependencyBuilder.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
/**
* src/initialize.dev, src/initialize.prod, src/initializeFeatures, src/context/FrontendContext, src/contextBackendContext
* dependency相关的项目文件
*/
export default function buildDependency(rebuild?: boolean): void;

View File

@ -0,0 +1,422 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const assert_1 = tslib_1.__importDefault(require("assert"));
const path_1 = require("path");
const fs_1 = require("fs");
const ts = tslib_1.__importStar(require("typescript"));
const string_1 = require("../utils/string");
const env_1 = require("./env");
const { factory } = ts;
function join(...paths) {
const path = (0, path_1.join)(...paths);
return path.replaceAll('\\', '/');
}
function destructVariableDeclaration(vd) {
(0, assert_1.default)(ts.isIdentifier(vd.name));
(0, assert_1.default)(vd.name.text.startsWith('total'));
const on = (0, string_1.firstLetterLowerCase)(vd.name.text.slice(5));
const { initializer } = vd;
(0, assert_1.default)(ts.isCallExpression(initializer));
(0, assert_1.default)(ts.isIdentifier(initializer.expression) && initializer.expression.text === 'mergeConcatMany');
(0, assert_1.default)(initializer.arguments.length === 1);
const [arg] = initializer.arguments;
(0, assert_1.default)(ts.isAsExpression(arg));
const { expression } = arg;
(0, assert_1.default)(ts.isArrayLiteralExpression(expression));
return {
on,
expression,
};
}
/**
* 生成initialize.prod.ts
* @param cwd
* @param dependencies
* @param briefNames
* @param sourceFile
* @param printer
*/
function outputIntializeProd(cwd, dependencies, briefNames, sourceFile, printer) {
const { statements } = sourceFile;
const objectDict = {};
// 所有的import
const importStatements = [];
dependencies.forEach((dep, idx) => {
const depDir = join(cwd, 'node_modules', dep);
if (!(0, fs_1.existsSync)(depDir)) {
throw new Error(`依赖模块${dep}未能找到相应的安装目录【${depDir}`);
}
const esDir = join(depDir, 'es');
const libDir = join(depDir, 'lib');
const esDirExisted = (0, fs_1.existsSync)(esDir);
const libDirExisted = (0, fs_1.existsSync)(libDir);
if (!esDirExisted && !libDirExisted) {
throw new Error(`依赖模块${dep}中没有es或者lib目录`);
}
const destDir = esDirExisted ? esDir : libDir;
const destDirName = esDirExisted ? 'es' : 'lib';
const objectDirs = ['checkers'];
objectDirs.forEach((o) => {
if ((0, fs_1.existsSync)(join(destDir, o))) {
const variableName = `${briefNames[idx]}${(0, string_1.firstLetterUpperCase)(o)}`;
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(variableName), undefined), factory.createStringLiteral(join(dep, destDirName, o)), undefined));
if (objectDict[o]) {
objectDict[o].push(variableName);
}
else {
objectDict[o] = [variableName];
}
}
});
// common
if ((0, fs_1.existsSync)(join(destDir, 'configuration'))) {
const variableName = `${briefNames[idx]}Common`;
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(variableName), undefined), factory.createStringLiteral(join(dep, destDirName, 'configuration')), undefined));
if (objectDict.common) {
objectDict.common.push(variableName);
}
else {
objectDict.common = [variableName];
}
}
// render
if ((0, fs_1.existsSync)(join(destDir, 'configuration', 'render.js'))) {
const variableName = `${briefNames[idx]}Render`;
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(variableName), undefined), factory.createStringLiteral(join(dep, destDirName, 'configuration', 'render')), undefined));
if (objectDict.render) {
objectDict.render.push(variableName);
}
else {
objectDict.render = [variableName];
}
}
// features
if ((0, fs_1.existsSync)(join(destDir, 'features'))) {
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, factory.createIdentifier("create"), factory.createIdentifier(`create${(0, string_1.firstLetterUpperCase)(briefNames[idx])}Features`)),
factory.createImportSpecifier(false, factory.createIdentifier("FeatureDict"), factory.createIdentifier(`${(0, string_1.firstLetterUpperCase)(briefNames[idx])}FeatureDict`))
])), factory.createStringLiteral(join(dep, destDirName, 'features')), undefined));
if (objectDict.features) {
objectDict.features.push(briefNames[idx]);
}
else {
objectDict.features = [briefNames[idx]];
}
}
});
const funcStmt = statements.find((stmt) => ts.isFunctionDeclaration(stmt) && stmt.modifiers?.find(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword) && stmt.modifiers.find(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword));
(0, assert_1.default)(funcStmt);
const idx = statements.indexOf(funcStmt);
const statements2 = [
...statements.slice(0, idx),
...importStatements,
...statements.slice(idx)
];
const stmt0 = funcStmt.body?.statements[0];
(0, assert_1.default)(ts.isVariableStatement(stmt0));
let vdl = stmt0.declarationList;
vdl.declarations.forEach((declaration) => {
const { on, expression } = destructVariableDeclaration(declaration);
if (objectDict[on]) {
const { elements } = expression;
Object.assign(expression, {
elements: elements.concat(...objectDict[on].map(ele => factory.createIdentifier(ele)))
});
}
});
if (objectDict.features) {
const stmt1 = funcStmt.body?.statements[1];
(0, assert_1.default)(ts.isVariableStatement(stmt1));
const tfDec = stmt1.declarationList.declarations[0];
const { name, initializer } = tfDec;
(0, assert_1.default)(ts.isIdentifier(name) && name.text === 'totalFeatures');
(0, assert_1.default)(ts.isAsExpression(initializer));
const { type } = initializer;
(0, assert_1.default)(ts.isIntersectionTypeNode(type));
Object.assign(type, {
types: type.types.concat(objectDict.features.map(ele => factory.createTypeReferenceNode(`${(0, string_1.firstLetterUpperCase)(ele)}FeatureDict`, [
factory.createTypeReferenceNode('EntityDict')
])))
});
Object.assign(funcStmt.body, {
statements: [
...funcStmt.body.statements.slice(0, 4),
...objectDict.features.map((ele) => [
factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier(`${ele}Features`), undefined, undefined, factory.createCallExpression(factory.createIdentifier(`create${(0, string_1.firstLetterUpperCase)(ele)}Features`), undefined, [factory.createIdentifier("totalFeatures")]))], ts.NodeFlags.Const)),
factory.createExpressionStatement(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Object"), factory.createIdentifier("assign")), undefined, [
factory.createIdentifier("totalFeatures"),
factory.createIdentifier(`${ele}Features`)
]))
]).flat(),
...funcStmt.body.statements.slice(4),
]
});
}
const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray(statements2), sourceFile);
const filename = join(cwd, 'src', 'initialize.prod.ts');
(0, fs_1.writeFileSync)(filename, result, { flag: 'w' });
console.log('构建initialize.prod.ts文件成功');
}
/**
* 生成initialize.dev.ts
* @param cwd
* @param dependencies
* @param briefNames
* @param sourceFile
* @param printer
*/
function outputIntializeDev(cwd, dependencies, briefNames, sourceFile, printer) {
const { statements } = sourceFile;
const objectDict = {};
// 所有的import
const importStatements = [];
dependencies.forEach((dep, idx) => {
const depDir = join(cwd, 'node_modules', dep);
if (!(0, fs_1.existsSync)(depDir)) {
throw new Error(`依赖模块${dep}未能找到相应的安装目录【${depDir}`);
}
const esDir = join(depDir, 'es');
const libDir = join(depDir, 'lib');
const esDirExisted = (0, fs_1.existsSync)(esDir);
const libDirExisted = (0, fs_1.existsSync)(libDir);
if (!esDirExisted && !libDirExisted) {
throw new Error(`依赖模块${dep}中没有es或者lib目录`);
}
const destDir = esDirExisted ? esDir : libDir;
const destDirName = esDirExisted ? 'es' : 'lib';
const objectDirs = ['triggers', 'checkers', 'watchers', 'timers', 'data', 'aspects'];
objectDirs.forEach((o) => {
if ((0, fs_1.existsSync)(join(destDir, o))) {
const variableName = `${briefNames[idx]}${(0, string_1.firstLetterUpperCase)(o)}`;
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(variableName), undefined), factory.createStringLiteral(join(dep, destDirName, o)), undefined));
if (objectDict[o]) {
objectDict[o].push(variableName);
}
else {
objectDict[o] = [variableName];
}
}
});
// startRoutine
if ((0, fs_1.existsSync)(join(destDir, 'routines', 'start'))) {
const variableName = `${briefNames[idx]}StartRoutines`;
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(variableName), undefined), factory.createStringLiteral(join(dep, destDirName, 'routines/start')), undefined));
if (objectDict.startRoutines) {
objectDict.startRoutines.push(variableName);
}
else {
objectDict.startRoutines = [variableName];
}
}
// common
if ((0, fs_1.existsSync)(join(destDir, 'configuration'))) {
const variableName = `${briefNames[idx]}Common`;
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(variableName), undefined), factory.createStringLiteral(join(dep, destDirName, 'configuration')), undefined));
if (objectDict.common) {
objectDict.common.push(variableName);
}
else {
objectDict.common = [variableName];
}
}
// render
if ((0, fs_1.existsSync)(join(destDir, 'configuration', 'render.js'))) {
const variableName = `${briefNames[idx]}Render`;
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(variableName), undefined), factory.createStringLiteral(join(dep, destDirName, 'configuration', 'render')), undefined));
if (objectDict.render) {
objectDict.render.push(variableName);
}
else {
objectDict.render = [variableName];
}
}
// features
if ((0, fs_1.existsSync)(join(destDir, 'features'))) {
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, factory.createIdentifier("create"), factory.createIdentifier(`create${(0, string_1.firstLetterUpperCase)(briefNames[idx])}Features`)),
factory.createImportSpecifier(false, factory.createIdentifier("FeatureDict"), factory.createIdentifier(`${(0, string_1.firstLetterUpperCase)(briefNames[idx])}FeatureDict`))
])), factory.createStringLiteral(join(dep, destDirName, 'features')), undefined));
if (objectDict.features) {
objectDict.features.push(briefNames[idx]);
}
else {
objectDict.features = [briefNames[idx]];
}
}
// ports
if ((0, fs_1.existsSync)(join(destDir, 'ports'))) {
const importVariableName = `${briefNames[idx]}Importations`;
const exportVariableName = `${briefNames[idx]}Exportations`;
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, factory.createIdentifier("importations"), factory.createIdentifier(importVariableName)),
factory.createImportSpecifier(false, factory.createIdentifier("exportations"), factory.createIdentifier(exportVariableName))
])), factory.createStringLiteral(join(dep, destDirName, 'ports')), undefined));
if (objectDict.importations) {
objectDict.importations.push(importVariableName);
}
else {
objectDict.importations = [importVariableName];
}
if (objectDict.exportations) {
objectDict.exportations.push(exportVariableName);
}
else {
objectDict.exportations = [exportVariableName];
}
}
});
const funcStmt = statements.find((stmt) => ts.isFunctionDeclaration(stmt) && stmt.modifiers?.find(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword) && stmt.modifiers.find(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword));
(0, assert_1.default)(funcStmt);
const idx = statements.indexOf(funcStmt);
const statements2 = [
...statements.slice(0, idx),
...importStatements,
...statements.slice(idx)
];
const stmt0 = funcStmt.body?.statements[0];
(0, assert_1.default)(ts.isVariableStatement(stmt0));
let vdl = stmt0.declarationList;
vdl.declarations.forEach((declaration) => {
const { on, expression } = destructVariableDeclaration(declaration);
if (objectDict[on]) {
const { elements } = expression;
Object.assign(expression, {
elements: elements.concat(...objectDict[on].map(ele => factory.createIdentifier(ele)))
});
}
});
if (objectDict.features) {
const stmt2 = funcStmt.body?.statements[2];
(0, assert_1.default)(ts.isVariableStatement(stmt2));
const tfDec = stmt2.declarationList.declarations[0];
const { name, initializer } = tfDec;
(0, assert_1.default)(ts.isIdentifier(name) && name.text === 'totalFeatures');
(0, assert_1.default)(ts.isAsExpression(initializer));
const { type } = initializer;
(0, assert_1.default)(ts.isIntersectionTypeNode(type));
Object.assign(type, {
types: type.types.concat(objectDict.features.map(ele => factory.createTypeReferenceNode(`${(0, string_1.firstLetterUpperCase)(ele)}FeatureDict`, [
factory.createTypeReferenceNode('EntityDict')
])))
});
Object.assign(funcStmt.body, {
statements: [
...funcStmt.body.statements.slice(0, 5),
...objectDict.features.map((ele) => [
factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier(`${ele}Features`), undefined, undefined, factory.createCallExpression(factory.createIdentifier(`create${(0, string_1.firstLetterUpperCase)(ele)}Features`), undefined, [factory.createIdentifier("totalFeatures")]))], ts.NodeFlags.Const)),
factory.createExpressionStatement(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Object"), factory.createIdentifier("assign")), undefined, [
factory.createIdentifier("totalFeatures"),
factory.createIdentifier(`${ele}Features`)
]))
]).flat(),
...funcStmt.body.statements.slice(5),
]
});
}
const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray(statements2), sourceFile);
const filename = join(cwd, 'src', 'initialize.dev.ts');
(0, fs_1.writeFileSync)(filename, result, { flag: 'w' });
console.log('构建initialize.dev.ts文件成功');
}
function outputIntializeFeatures(cwd, dependencies, briefNames, sourceFile, printer) {
const { statements } = sourceFile;
const features = [];
// 所有的import
const importStatements = [];
// 如果有oak-general-business需要AccessConfiguration自动注入
if (dependencies.includes('oak-general-business')) {
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier("accessConfiguration"), undefined), factory.createStringLiteral("@project/configuration/access"), undefined));
}
dependencies.forEach((dep, idx) => {
const depDir = join(cwd, 'node_modules', dep);
if (!(0, fs_1.existsSync)(depDir)) {
throw new Error(`依赖模块${dep}未能找到相应的安装目录【${depDir}`);
}
const esDir = join(depDir, 'es');
const libDir = join(depDir, 'lib');
const esDirExisted = (0, fs_1.existsSync)(esDir);
const libDirExisted = (0, fs_1.existsSync)(libDir);
if (!esDirExisted && !libDirExisted) {
throw new Error(`依赖模块${dep}中没有es或者lib目录`);
}
const destDir = esDirExisted ? esDir : libDir;
const destDirName = esDirExisted ? 'es' : 'lib';
// features
if ((0, fs_1.existsSync)(join(destDir, 'features'))) {
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, factory.createIdentifier("initialize"), factory.createIdentifier(`initialize${(0, string_1.firstLetterUpperCase)(briefNames[idx])}Features`)),
factory.createImportSpecifier(false, factory.createIdentifier("FeatureDict"), factory.createIdentifier(`${(0, string_1.firstLetterUpperCase)(briefNames[idx])}FeatureDict`))
])), factory.createStringLiteral(join(dep, destDirName, 'features')), undefined));
features.push(briefNames[idx]);
}
});
const funcStmt = statements.find((stmt) => ts.isFunctionDeclaration(stmt) && stmt.modifiers?.find(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword) && stmt.modifiers.find(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword));
(0, assert_1.default)(funcStmt);
const idx = statements.indexOf(funcStmt);
const statements2 = [
...statements.slice(0, idx),
...importStatements,
...statements.slice(idx)
];
if (features.length > 0) {
(0, assert_1.default)(funcStmt.parameters.length === 1);
const [param] = funcStmt.parameters;
const { type } = param;
(0, assert_1.default)(ts.isIntersectionTypeNode(type));
Object.assign(type, {
types: type.types.concat(features.map(ele => factory.createTypeReferenceNode(`${(0, string_1.firstLetterUpperCase)(ele)}FeatureDict`, [
factory.createTypeReferenceNode('EntityDict')
])))
});
Object.assign(funcStmt.body, {
statements: [
...features.map((ele, idx) => {
const args = [
factory.createIdentifier("features"),
];
if (dependencies[idx] === 'oak-general-business') {
args.push(factory.createIdentifier("accessConfiguration"));
}
return factory.createExpressionStatement(factory.createAwaitExpression(factory.createCallExpression(factory.createIdentifier(`initialize${(0, string_1.firstLetterUpperCase)(ele)}Features`), undefined, args)));
}).flat(),
...funcStmt.body.statements,
]
});
}
const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray(statements2), sourceFile);
const filename = join(cwd, 'src', 'initializeFeatures.ts');
(0, fs_1.writeFileSync)(filename, result, { flag: 'w' });
console.log('构建initializeFeatures.ts文件成功');
}
/**
* 本函数用于构建src/initialize.dev, src/initialize.prod, src/initializeFeatures, src/context/FrontendContext, src/contextBackendContext
* 这些和dependency相关的项目文件
*/
function buildDependency(rebuild) {
const cwd = process.cwd();
const initDevFile = join(cwd, 'src', 'initialize.dev.ts');
if ((0, fs_1.existsSync)(initDevFile) && !rebuild) {
console.log('src/initialize.dev.ts文件已经存在无需构建启动文件');
return;
}
const depConfigFile = join(cwd, 'src', 'configuration', 'dependency.ts');
if (!(0, fs_1.existsSync)(depConfigFile)) {
console.error(`${depConfigFile}不存在,无法构建启动文件`);
}
// 这里依赖配置是ts文件得翻译成js再读取
const result = ts.transpileModule((0, fs_1.readFileSync)(depConfigFile, 'utf-8'), { compilerOptions: { module: ts.ModuleKind.CommonJS } });
const dependencies = eval(result.outputText);
const briefNames = dependencies.map((dep, idx) => `${dep.split('-').map(ele => ele[0]).join('')}${idx}`);
const templateFileList = [
join(cwd, 'node_modules', env_1.OAK_CLI_MODULE_NAME, 'templateFiles', 'initialize.dev.ts'),
join(cwd, 'node_modules', env_1.OAK_CLI_MODULE_NAME, 'templateFiles', 'initialize.prod.ts'),
join(cwd, 'node_modules', env_1.OAK_CLI_MODULE_NAME, 'templateFiles', 'initializeFeatures.ts'),
];
const program = ts.createProgram(templateFileList, {});
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
outputIntializeDev(cwd, dependencies, briefNames, program.getSourceFile(templateFileList[0]), printer);
outputIntializeProd(cwd, dependencies, briefNames, program.getSourceFile(templateFileList[1]), printer);
outputIntializeFeatures(cwd, dependencies, briefNames, program.getSourceFile(templateFileList[2]), printer);
}
exports.default = buildDependency;

View File

@ -11,3 +11,4 @@ export declare const NUMERICAL_LITERL_DEFAULT_SCALE = 2;
export declare const INT_LITERL_DEFAULT_WIDTH = 4; export declare const INT_LITERL_DEFAULT_WIDTH = 4;
export declare const OAK_EXTERNAL_LIBS_FILEPATH: (path: string) => string; export declare const OAK_EXTERNAL_LIBS_FILEPATH: (path: string) => string;
export * from './entities'; export * from './entities';
export declare const OAK_CLI_MODULE_NAME = "@xuchangzju/oak-cli";

View File

@ -1,6 +1,6 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.OAK_EXTERNAL_LIBS_FILEPATH = exports.INT_LITERL_DEFAULT_WIDTH = exports.NUMERICAL_LITERL_DEFAULT_SCALE = exports.NUMERICAL_LITERL_DEFAULT_PRECISION = exports.STRING_LITERAL_MAX_LENGTH = exports.ENTITY_NAME_MAX_LENGTH = exports.ACTION_CONSTANT_IN_OAK_DOMAIN = exports.TYPE_PATH_IN_OAK_DOMAIN = exports.ENTITY_PATH_IN_OAK_DOMAIN = exports.ENTITY_PATH_IN_OAK_GENERAL_BUSINESS = exports.LIB_PATH = exports.LIB_OAK_DOMAIN = void 0; exports.OAK_CLI_MODULE_NAME = exports.OAK_EXTERNAL_LIBS_FILEPATH = exports.INT_LITERL_DEFAULT_WIDTH = exports.NUMERICAL_LITERL_DEFAULT_SCALE = exports.NUMERICAL_LITERL_DEFAULT_PRECISION = exports.STRING_LITERAL_MAX_LENGTH = exports.ENTITY_NAME_MAX_LENGTH = exports.ACTION_CONSTANT_IN_OAK_DOMAIN = exports.TYPE_PATH_IN_OAK_DOMAIN = exports.ENTITY_PATH_IN_OAK_DOMAIN = exports.ENTITY_PATH_IN_OAK_GENERAL_BUSINESS = exports.LIB_PATH = exports.LIB_OAK_DOMAIN = void 0;
const tslib_1 = require("tslib"); const tslib_1 = require("tslib");
const path_1 = tslib_1.__importDefault(require("path")); const path_1 = tslib_1.__importDefault(require("path"));
exports.LIB_OAK_DOMAIN = 'oak-domain'; exports.LIB_OAK_DOMAIN = 'oak-domain';
@ -43,3 +43,4 @@ const OAK_EXTERNAL_LIBS_FILEPATH = (path) => {
}; };
exports.OAK_EXTERNAL_LIBS_FILEPATH = OAK_EXTERNAL_LIBS_FILEPATH; exports.OAK_EXTERNAL_LIBS_FILEPATH = OAK_EXTERNAL_LIBS_FILEPATH;
tslib_1.__exportStar(require("./entities"), exports); tslib_1.__exportStar(require("./entities"), exports);
exports.OAK_CLI_MODULE_NAME = '@xuchangzju/oak-cli';

View File

@ -7,6 +7,7 @@ const fs_extra_1 = require("fs-extra");
const assert_1 = tslib_1.__importDefault(require("assert")); const assert_1 = tslib_1.__importDefault(require("assert"));
const ts = tslib_1.__importStar(require("typescript")); const ts = tslib_1.__importStar(require("typescript"));
const node_watch_1 = tslib_1.__importDefault(require("node-watch")); const node_watch_1 = tslib_1.__importDefault(require("node-watch"));
const env_1 = require("./env");
const { factory } = ts; const { factory } = ts;
const NameSpaceDescDict = {}; const NameSpaceDescDict = {};
function checkPageDir(dir, relativePath, ns, type) { function checkPageDir(dir, relativePath, ns, type) {
@ -161,33 +162,28 @@ function judgeUseOakRouterBuilder(statements) {
} }
function outputInWebAppDir(appDir) { function outputInWebAppDir(appDir) {
const routerFileName = (0, path_1.join)(appDir, 'router', 'allRouters.ts'); const routerFileName = (0, path_1.join)(appDir, 'router', 'allRouters.ts');
const templateFileName = (0, path_1.join)(appDir, 'router', 'allRoutersTemplate.ts'); const templateFileName = (0, path_1.join)(appDir, '../../../..', 'node_modules', env_1.OAK_CLI_MODULE_NAME, 'templateFiles', 'allRouters.ts');
if ((0, fs_extra_1.existsSync)(templateFileName)) { const program = ts.createProgram([templateFileName], {
const program = ts.createProgram([templateFileName], { removeComments: false,
removeComments: false, });
}); const routerFile = program.getSourceFile(templateFileName);
const routerFile = program.getSourceFile(templateFileName); (0, assert_1.default)(routerFile);
(0, assert_1.default)(routerFile); const namespaceDir = (0, path_1.join)(appDir, 'namespaces');
const namespaceDir = (0, path_1.join)(appDir, 'namespaces'); const { statements } = routerFile;
const { statements } = routerFile; if (judgeUseOakRouterBuilder(statements)) {
if (judgeUseOakRouterBuilder(statements)) { statements.forEach((statement) => {
statements.forEach((statement) => { if (ts.isVariableStatement(statement)) {
if (ts.isVariableStatement(statement)) { const declaration = statement.declarationList.declarations.find(declaration => ts.isIdentifier(declaration.name) && declaration.name.text === 'allRouters');
const declaration = statement.declarationList.declarations.find(declaration => ts.isIdentifier(declaration.name) && declaration.name.text === 'allRouters'); if (declaration) {
if (declaration) { Object.assign(declaration, {
Object.assign(declaration, { initializer: makeWebAllRouters(namespaceDir, (0, path_1.join)(appDir, '../../../..'), (0, path_1.dirname)(routerFileName))
initializer: makeWebAllRouters(namespaceDir, (0, path_1.join)(appDir, '../../../..'), (0, path_1.dirname)(templateFileName)) });
});
}
} }
}); }
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed, removeComments: false }); });
const result = printer.printNode(ts.EmitHint.Unspecified, routerFile, routerFile); const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed, removeComments: false });
(0, fs_extra_1.writeFileSync)(routerFileName, result); const result = printer.printNode(ts.EmitHint.Unspecified, routerFile, routerFile);
} (0, fs_extra_1.writeFileSync)(routerFileName, result);
}
else {
console.warn(`${appDir}的目录结构未按照标准建立,缺少了${templateFileName},请从模板中补充`);
} }
} }
function outputInWebDir(dir) { function outputInWebDir(dir) {

View File

@ -0,0 +1,782 @@
import assert from 'assert';
import { join as pathJoin } from 'path';
import { existsSync, readFileSync, writeFileSync } from 'fs';
import * as ts from 'typescript';
import { firstLetterLowerCase, firstLetterUpperCase } from '../utils/string';
import { OAK_CLI_MODULE_NAME } from './env';
const { factory } = ts;
function join(...paths: string[]) {
const path = pathJoin(...paths);
return path.replaceAll('\\', '/');
}
function destructVariableDeclaration(vd: ts.VariableDeclaration) {
assert(ts.isIdentifier(vd.name))
assert(vd.name.text.startsWith('total'));
const on = firstLetterLowerCase(vd.name.text.slice(5));
const { initializer } = vd;
assert(ts.isCallExpression(initializer!));
assert(ts.isIdentifier(initializer.expression) && initializer.expression.text === 'mergeConcatMany');
assert(initializer.arguments.length === 1);
const [arg] = initializer.arguments;
assert(ts.isAsExpression(arg));
const { expression } = arg;
assert(ts.isArrayLiteralExpression(expression));
return {
on,
expression,
};
}
/**
* initialize.prod.ts
* @param cwd
* @param dependencies
* @param briefNames
* @param sourceFile
* @param printer
*/
function outputIntializeProd(
cwd: string,
dependencies: string[],
briefNames: string[],
sourceFile: ts.SourceFile,
printer: ts.Printer
) {
const { statements } = sourceFile;
const objectDict: Record<string, string[]> = {};
// 所有的import
const importStatements: ts.Statement[] = [];
dependencies.forEach(
(dep, idx) => {
const depDir = join(cwd, 'node_modules', dep);
if (!existsSync(depDir)) {
throw new Error(`依赖模块${dep}未能找到相应的安装目录【${depDir}`);
}
const esDir = join(depDir, 'es');
const libDir = join(depDir, 'lib');
const esDirExisted = existsSync(esDir);
const libDirExisted = existsSync(libDir);
if (!esDirExisted && !libDirExisted) {
throw new Error(`依赖模块${dep}中没有es或者lib目录`);
}
const destDir = esDirExisted ? esDir : libDir;
const destDirName = esDirExisted ? 'es' : 'lib';
const objectDirs = ['checkers'];
objectDirs.forEach(
(o) => {
if (existsSync(join(destDir, o))) {
const variableName = `${briefNames[idx]}${firstLetterUpperCase(o)}`;
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
factory.createIdentifier(variableName),
undefined
),
factory.createStringLiteral(join(dep, destDirName, o)),
undefined
)
);
if (objectDict[o]) {
objectDict[o].push(variableName);
}
else {
objectDict[o] = [variableName];
}
}
}
);
// common
if (existsSync(join(destDir, 'configuration'))) {
const variableName = `${briefNames[idx]}Common`;
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
factory.createIdentifier(variableName),
undefined
),
factory.createStringLiteral(join(dep, destDirName, 'configuration')),
undefined
)
);
if (objectDict.common) {
objectDict.common.push(variableName);
}
else {
objectDict.common = [variableName];
}
}
// render
if (existsSync(join(destDir, 'configuration', 'render.js'))) {
const variableName = `${briefNames[idx]}Render`;
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
factory.createIdentifier(variableName),
undefined
),
factory.createStringLiteral(join(dep, destDirName, 'configuration', 'render')),
undefined
)
);
if (objectDict.render) {
objectDict.render.push(variableName);
}
else {
objectDict.render = [variableName];
}
}
// features
if (existsSync(join(destDir, 'features'))) {
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
undefined,
factory.createNamedImports([
factory.createImportSpecifier(
false,
factory.createIdentifier("create"),
factory.createIdentifier(`create${firstLetterUpperCase(briefNames[idx])}Features`)
),
factory.createImportSpecifier(
false,
factory.createIdentifier("FeatureDict"),
factory.createIdentifier(`${firstLetterUpperCase(briefNames[idx])}FeatureDict`)
)
])
),
factory.createStringLiteral(join(dep, destDirName, 'features')),
undefined
)
);
if (objectDict.features) {
objectDict.features.push(briefNames[idx]);
}
else {
objectDict.features = [briefNames[idx]];
}
}
}
);
const funcStmt = statements.find(
(stmt) => ts.isFunctionDeclaration(stmt) && stmt.modifiers?.find(
modifier => modifier.kind === ts.SyntaxKind.ExportKeyword
) && stmt.modifiers.find(
modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword
)
) as ts.FunctionDeclaration;
assert(funcStmt);
const idx = statements.indexOf(funcStmt);
const statements2 = [
...statements.slice(0, idx),
...importStatements,
...statements.slice(idx)
];
const stmt0 = funcStmt.body?.statements[0];
assert(ts.isVariableStatement(stmt0!));
let vdl = stmt0.declarationList;
vdl.declarations.forEach(
(declaration) => {
const { on, expression } = destructVariableDeclaration(declaration);
if (objectDict[on]) {
const { elements } = expression;
Object.assign(expression, {
elements: elements.concat(...objectDict[on].map(
ele => factory.createIdentifier(ele)
))
});
}
}
);
if (objectDict.features) {
const stmt1 = funcStmt.body?.statements[1];
assert(ts.isVariableStatement(stmt1!));
const tfDec = stmt1.declarationList.declarations[0];
const { name, initializer } = tfDec;
assert(ts.isIdentifier(name) && name.text === 'totalFeatures');
assert(ts.isAsExpression(initializer!));
const { type } = initializer;
assert(ts.isIntersectionTypeNode(type));
Object.assign(type, {
types: type.types.concat(
objectDict.features.map(
ele => factory.createTypeReferenceNode(
`${firstLetterUpperCase(ele)}FeatureDict`,
[
factory.createTypeReferenceNode('EntityDict')
]
)
)
)
});
Object.assign(funcStmt.body!, {
statements: [
...funcStmt.body!.statements.slice(0, 4),
...objectDict.features.map(
(ele) => [
factory.createVariableStatement(
undefined,
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(
factory.createIdentifier(`${ele}Features`),
undefined,
undefined,
factory.createCallExpression(
factory.createIdentifier(`create${firstLetterUpperCase(ele)}Features`),
undefined,
[factory.createIdentifier("totalFeatures")]
)
)],
ts.NodeFlags.Const
)
),
factory.createExpressionStatement(factory.createCallExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier("Object"),
factory.createIdentifier("assign")
),
undefined,
[
factory.createIdentifier("totalFeatures"),
factory.createIdentifier(`${ele}Features`)
]
))
]
).flat(),
...funcStmt.body!.statements.slice(4),
]
})
}
const result = printer.printList(
ts.ListFormat.SourceFileStatements,
factory.createNodeArray(statements2),
sourceFile);
const filename = join(cwd, 'src', 'initialize.prod.ts');
writeFileSync(filename, result, { flag: 'w' });
console.log('构建initialize.prod.ts文件成功');
}
/**
* initialize.dev.ts
* @param cwd
* @param dependencies
* @param briefNames
* @param sourceFile
* @param printer
*/
function outputIntializeDev(
cwd: string,
dependencies: string[],
briefNames: string[],
sourceFile: ts.SourceFile,
printer: ts.Printer
) {
const { statements } = sourceFile;
const objectDict: Record<string, string[]> = {};
// 所有的import
const importStatements: ts.Statement[] = [];
dependencies.forEach(
(dep, idx) => {
const depDir = join(cwd, 'node_modules', dep);
if (!existsSync(depDir)) {
throw new Error(`依赖模块${dep}未能找到相应的安装目录【${depDir}`);
}
const esDir = join(depDir, 'es');
const libDir = join(depDir, 'lib');
const esDirExisted = existsSync(esDir);
const libDirExisted = existsSync(libDir);
if (!esDirExisted && !libDirExisted) {
throw new Error(`依赖模块${dep}中没有es或者lib目录`);
}
const destDir = esDirExisted ? esDir : libDir;
const destDirName = esDirExisted ? 'es' : 'lib';
const objectDirs = ['triggers', 'checkers', 'watchers', 'timers', 'data', 'aspects'];
objectDirs.forEach(
(o) => {
if (existsSync(join(destDir, o))) {
const variableName = `${briefNames[idx]}${firstLetterUpperCase(o)}`;
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
factory.createIdentifier(variableName),
undefined
),
factory.createStringLiteral(join(dep, destDirName, o)),
undefined
)
);
if (objectDict[o]) {
objectDict[o].push(variableName);
}
else {
objectDict[o] = [variableName];
}
}
}
);
// startRoutine
if (existsSync(join(destDir, 'routines', 'start'))) {
const variableName = `${briefNames[idx]}StartRoutines`;
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
factory.createIdentifier(variableName),
undefined
),
factory.createStringLiteral(join(dep, destDirName, 'routines/start')),
undefined
)
);
if (objectDict.startRoutines) {
objectDict.startRoutines.push(variableName);
}
else {
objectDict.startRoutines = [variableName];
}
}
// common
if (existsSync(join(destDir, 'configuration'))) {
const variableName = `${briefNames[idx]}Common`;
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
factory.createIdentifier(variableName),
undefined
),
factory.createStringLiteral(join(dep, destDirName, 'configuration')),
undefined
)
);
if (objectDict.common) {
objectDict.common.push(variableName);
}
else {
objectDict.common = [variableName];
}
}
// render
if (existsSync(join(destDir, 'configuration', 'render.js'))) {
const variableName = `${briefNames[idx]}Render`;
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
factory.createIdentifier(variableName),
undefined
),
factory.createStringLiteral(join(dep, destDirName, 'configuration', 'render')),
undefined
)
);
if (objectDict.render) {
objectDict.render.push(variableName);
}
else {
objectDict.render = [variableName];
}
}
// features
if (existsSync(join(destDir, 'features'))) {
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
undefined,
factory.createNamedImports([
factory.createImportSpecifier(
false,
factory.createIdentifier("create"),
factory.createIdentifier(`create${firstLetterUpperCase(briefNames[idx])}Features`)
),
factory.createImportSpecifier(
false,
factory.createIdentifier("FeatureDict"),
factory.createIdentifier(`${firstLetterUpperCase(briefNames[idx])}FeatureDict`)
)
])
),
factory.createStringLiteral(join(dep, destDirName, 'features')),
undefined
)
);
if (objectDict.features) {
objectDict.features.push(briefNames[idx]);
}
else {
objectDict.features = [briefNames[idx]];
}
}
// ports
if (existsSync(join(destDir, 'ports'))) {
const importVariableName = `${briefNames[idx]}Importations`;
const exportVariableName = `${briefNames[idx]}Exportations`;
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
undefined,
factory.createNamedImports([
factory.createImportSpecifier(
false,
factory.createIdentifier("importations"),
factory.createIdentifier(importVariableName)
),
factory.createImportSpecifier(
false,
factory.createIdentifier("exportations"),
factory.createIdentifier(exportVariableName)
)
])
),
factory.createStringLiteral(join(dep, destDirName, 'ports')),
undefined
)
);
if (objectDict.importations) {
objectDict.importations.push(importVariableName);
}
else {
objectDict.importations = [importVariableName];
}
if (objectDict.exportations) {
objectDict.exportations.push(exportVariableName);
}
else {
objectDict.exportations = [exportVariableName];
}
}
}
);
const funcStmt = statements.find(
(stmt) => ts.isFunctionDeclaration(stmt) && stmt.modifiers?.find(
modifier => modifier.kind === ts.SyntaxKind.ExportKeyword
) && stmt.modifiers.find(
modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword
)
) as ts.FunctionDeclaration;
assert(funcStmt);
const idx = statements.indexOf(funcStmt);
const statements2 = [
...statements.slice(0, idx),
...importStatements,
...statements.slice(idx)
];
const stmt0 = funcStmt.body?.statements[0];
assert(ts.isVariableStatement(stmt0!));
let vdl = stmt0.declarationList;
vdl.declarations.forEach(
(declaration) => {
const { on, expression } = destructVariableDeclaration(declaration);
if (objectDict[on]) {
const { elements } = expression;
Object.assign(expression, {
elements: elements.concat(...objectDict[on].map(
ele => factory.createIdentifier(ele)
))
});
}
}
);
if (objectDict.features) {
const stmt2 = funcStmt.body?.statements[2];
assert(ts.isVariableStatement(stmt2!));
const tfDec = stmt2.declarationList.declarations[0];
const { name, initializer } = tfDec;
assert(ts.isIdentifier(name) && name.text === 'totalFeatures');
assert(ts.isAsExpression(initializer!));
const { type } = initializer;
assert(ts.isIntersectionTypeNode(type));
Object.assign(type, {
types: type.types.concat(
objectDict.features.map(
ele => factory.createTypeReferenceNode(
`${firstLetterUpperCase(ele)}FeatureDict`,
[
factory.createTypeReferenceNode('EntityDict')
]
)
)
)
});
Object.assign(funcStmt.body!, {
statements: [
...funcStmt.body!.statements.slice(0, 5),
...objectDict.features.map(
(ele) => [
factory.createVariableStatement(
undefined,
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(
factory.createIdentifier(`${ele}Features`),
undefined,
undefined,
factory.createCallExpression(
factory.createIdentifier(`create${firstLetterUpperCase(ele)}Features`),
undefined,
[factory.createIdentifier("totalFeatures")]
)
)],
ts.NodeFlags.Const
)
),
factory.createExpressionStatement(factory.createCallExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier("Object"),
factory.createIdentifier("assign")
),
undefined,
[
factory.createIdentifier("totalFeatures"),
factory.createIdentifier(`${ele}Features`)
]
))
]
).flat(),
...funcStmt.body!.statements.slice(5),
]
})
}
const result = printer.printList(
ts.ListFormat.SourceFileStatements,
factory.createNodeArray(statements2),
sourceFile);
const filename = join(cwd, 'src', 'initialize.dev.ts');
writeFileSync(filename, result, { flag: 'w' });
console.log('构建initialize.dev.ts文件成功');
}
function outputIntializeFeatures(
cwd: string,
dependencies: string[],
briefNames: string[],
sourceFile: ts.SourceFile,
printer: ts.Printer
) {
const { statements } = sourceFile;
const features: string[] = [];
// 所有的import
const importStatements: ts.Statement[] = [];
// 如果有oak-general-business需要AccessConfiguration自动注入
if (dependencies.includes('oak-general-business')) {
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
factory.createIdentifier("accessConfiguration"),
undefined
),
factory.createStringLiteral("@project/configuration/access"),
undefined
)
);
}
dependencies.forEach(
(dep, idx) => {
const depDir = join(cwd, 'node_modules', dep);
if (!existsSync(depDir)) {
throw new Error(`依赖模块${dep}未能找到相应的安装目录【${depDir}`);
}
const esDir = join(depDir, 'es');
const libDir = join(depDir, 'lib');
const esDirExisted = existsSync(esDir);
const libDirExisted = existsSync(libDir);
if (!esDirExisted && !libDirExisted) {
throw new Error(`依赖模块${dep}中没有es或者lib目录`);
}
const destDir = esDirExisted ? esDir : libDir;
const destDirName = esDirExisted ? 'es' : 'lib';
// features
if (existsSync(join(destDir, 'features'))) {
importStatements.push(
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
undefined,
factory.createNamedImports([
factory.createImportSpecifier(
false,
factory.createIdentifier("initialize"),
factory.createIdentifier(`initialize${firstLetterUpperCase(briefNames[idx])}Features`)
),
factory.createImportSpecifier(
false,
factory.createIdentifier("FeatureDict"),
factory.createIdentifier(`${firstLetterUpperCase(briefNames[idx])}FeatureDict`)
)
])
),
factory.createStringLiteral(join(dep, destDirName, 'features')),
undefined
)
);
features.push(briefNames[idx]);
}
}
);
const funcStmt = statements.find(
(stmt) => ts.isFunctionDeclaration(stmt) && stmt.modifiers?.find(
modifier => modifier.kind === ts.SyntaxKind.ExportKeyword
) && stmt.modifiers.find(
modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword
)
) as ts.FunctionDeclaration;
assert(funcStmt);
const idx = statements.indexOf(funcStmt);
const statements2 = [
...statements.slice(0, idx),
...importStatements,
...statements.slice(idx)
];
if (features.length > 0) {
assert(funcStmt.parameters.length === 1);
const [param] = funcStmt.parameters;
const { type } = param!;
assert(ts.isIntersectionTypeNode(type!));
Object.assign(type, {
types: type.types.concat(
features.map(
ele => factory.createTypeReferenceNode(
`${firstLetterUpperCase(ele)}FeatureDict`,
[
factory.createTypeReferenceNode('EntityDict')
]
)
)
)
});
Object.assign(funcStmt.body!, {
statements: [
...features.map(
(ele, idx) => {
const args = [
factory.createIdentifier("features"),
];
if (dependencies[idx] === 'oak-general-business') {
args.push(
factory.createIdentifier("accessConfiguration")
);
}
return factory.createExpressionStatement(
factory.createAwaitExpression(
factory.createCallExpression(
factory.createIdentifier(`initialize${firstLetterUpperCase(ele)}Features`),
undefined,
args
)
)
)
}
).flat(),
...funcStmt.body!.statements,
]
})
}
const result = printer.printList(
ts.ListFormat.SourceFileStatements,
factory.createNodeArray(statements2),
sourceFile);
const filename = join(cwd, 'src', 'initializeFeatures.ts');
writeFileSync(filename, result, { flag: 'w' });
console.log('构建initializeFeatures.ts文件成功');
}
/**
* src/initialize.dev, src/initialize.prod, src/initializeFeatures, src/context/FrontendContext, src/contextBackendContext
* dependency相关的项目文件
*/
export default function buildDependency(rebuild?: boolean) {
const cwd = process.cwd();
const initDevFile = join(cwd, 'src', 'initialize.dev.ts');
if (existsSync(initDevFile) && !rebuild) {
console.log('src/initialize.dev.ts文件已经存在无需构建启动文件');
return;
}
const depConfigFile = join(cwd, 'src', 'configuration', 'dependency.ts');
if (!existsSync(depConfigFile)) {
console.error(`${depConfigFile}不存在,无法构建启动文件`);
}
// 这里依赖配置是ts文件得翻译成js再读取
const result = ts.transpileModule(readFileSync(depConfigFile, 'utf-8'), { compilerOptions: { module: ts.ModuleKind.CommonJS } });
const dependencies = eval(result.outputText) as string[];
const briefNames = dependencies.map(
(dep, idx) => `${dep.split('-').map(ele => ele[0]).join('')}${idx}`
);
const templateFileList = [
join(cwd, 'node_modules', OAK_CLI_MODULE_NAME, 'templateFiles', 'initialize.dev.ts'),
join(cwd, 'node_modules', OAK_CLI_MODULE_NAME, 'templateFiles', 'initialize.prod.ts'),
join(cwd, 'node_modules', OAK_CLI_MODULE_NAME, 'templateFiles', 'initializeFeatures.ts'),
];
const program = ts.createProgram(templateFileList, {});
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
outputIntializeDev(cwd, dependencies, briefNames, program.getSourceFile(templateFileList[0])!, printer);
outputIntializeProd(cwd, dependencies, briefNames, program.getSourceFile(templateFileList[1])!, printer);
outputIntializeFeatures(cwd, dependencies, briefNames, program.getSourceFile(templateFileList[2])!, printer);
}

View File

@ -41,4 +41,6 @@ export const OAK_EXTERNAL_LIBS_FILEPATH = (path: string) => {
return Path.join(path, 'config/oakExternalLib.json'); return Path.join(path, 'config/oakExternalLib.json');
} }
export * from './entities'; export * from './entities';
export const OAK_CLI_MODULE_NAME = '@xuchangzju/oak-cli';

View File

@ -3,6 +3,7 @@ import { readdirSync, statSync, existsSync, writeFileSync } from 'fs-extra';
import assert from 'assert'; import assert from 'assert';
import * as ts from 'typescript'; import * as ts from 'typescript';
import NodeWatch from 'node-watch'; import NodeWatch from 'node-watch';
import { OAK_CLI_MODULE_NAME } from './env';
const { factory } = ts; const { factory } = ts;
/** /**
@ -37,7 +38,7 @@ const { factory } = ts;
* -------index.json namespace下的配置 * -------index.json namespace下的配置
* -------pageMap.json pageMap注入到这里 * -------pageMap.json pageMap注入到这里
* --router * --router
* ----index.ts router.ts注入到这里 * ----index.ts allRouters.ts注入到这里
* *
*/ */
@ -352,44 +353,39 @@ function judgeUseOakRouterBuilder(statements: ts.NodeArray<ts.Statement>) {
function outputInWebAppDir(appDir: string) { function outputInWebAppDir(appDir: string) {
const routerFileName = join(appDir, 'router', 'allRouters.ts'); const routerFileName = join(appDir, 'router', 'allRouters.ts');
const templateFileName = join(appDir, 'router', 'allRoutersTemplate.ts'); const templateFileName = join(appDir, '../../../..', 'node_modules', OAK_CLI_MODULE_NAME, 'templateFiles', 'allRouters.ts');
if (existsSync(templateFileName)) { const program = ts.createProgram([templateFileName], {
const program = ts.createProgram([templateFileName], { removeComments: false,
removeComments: false, });
}); const routerFile = program.getSourceFile(templateFileName);
const routerFile = program.getSourceFile(templateFileName); assert(routerFile);
assert(routerFile); const namespaceDir = join(appDir, 'namespaces');
const namespaceDir = join(appDir, 'namespaces'); const { statements } = routerFile;
const { statements } = routerFile; if (judgeUseOakRouterBuilder(statements)) {
if (judgeUseOakRouterBuilder(statements)) { statements.forEach(
statements.forEach( (statement) => {
(statement) => { if (ts.isVariableStatement(statement)) {
if (ts.isVariableStatement(statement)) { const declaration = statement.declarationList.declarations.find(
const declaration = statement.declarationList.declarations.find( declaration => ts.isIdentifier(declaration.name) && declaration.name.text === 'allRouters'
declaration => ts.isIdentifier(declaration.name) && declaration.name.text === 'allRouters' );
); if (declaration) {
if (declaration) { Object.assign(declaration, {
Object.assign(declaration, { initializer: makeWebAllRouters(namespaceDir, join(appDir, '../../../..'), dirname(routerFileName))
initializer: makeWebAllRouters(namespaceDir, join(appDir, '../../../..'), dirname(templateFileName)) });
});
}
} }
} }
); }
);
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed, removeComments: false }); const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed, removeComments: false });
const result = printer.printNode( const result = printer.printNode(
ts.EmitHint.Unspecified, ts.EmitHint.Unspecified,
routerFile, routerFile,
routerFile, routerFile,
); );
writeFileSync(routerFileName, result); writeFileSync(routerFileName, result);
}
}
else {
console.warn(`${appDir}的目录结构未按照标准建立,缺少了${templateFileName},请从模板中补充`);
} }
} }
@ -415,7 +411,7 @@ function watchDir(projectDir: string, startupDir: string, type: 'native' | 'web'
if (startupDir.startsWith('web')) { if (startupDir.startsWith('web')) {
const srcAppDir = join(projectDir, startupDir, 'src', 'app'); const srcAppDir = join(projectDir, startupDir, 'src', 'app');
const apps = readdirSync(srcAppDir); const apps = readdirSync(srcAppDir);
const tryOutputAppDir = (ns: string) => { const tryOutputAppDir = (ns: string) => {
apps.forEach( apps.forEach(
(app) => { (app) => {
const appDir = join(srcAppDir, app); const appDir = join(srcAppDir, app);
@ -427,7 +423,7 @@ function watchDir(projectDir: string, startupDir: string, type: 'native' | 'web'
} }
); );
} }
NodeWatch(srcPageDir, { NodeWatch(srcPageDir, {
recursive: true, recursive: true,
filter: new RegExp('web\.tsx|web\.pc\.tsx|index\.xml|render\.(native|ios|android)\.tsx'), filter: new RegExp('web\.tsx|web\.pc\.tsx|index\.xml|render\.(native|ios|android)\.tsx'),