5.0对configuration进行了重新规划

This commit is contained in:
Xu Chang 2024-03-28 21:25:10 +08:00
parent dcaba52594
commit 4c78de2233
33 changed files with 547 additions and 76 deletions

View File

@ -1,4 +1,4 @@
export declare const ActionDefDict: {
export declare const actionDefDict: {
modi: {
iState: import("../types").ActionDef<string, string>;
};

View File

@ -1,9 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ActionDefDict = void 0;
exports.actionDefDict = void 0;
const Action_1 = require("./Modi/Action");
const Action_2 = require("./User/Action");
exports.ActionDefDict = {
modi: Action_1.ActionDefDict,
user: Action_2.ActionDefDict
exports.actionDefDict = {
modi: Action_1.actionDefDict,
user: Action_2.actionDefDict
};

View File

@ -5,6 +5,6 @@ export type IAction = 'apply' | 'abandon' | string;
export type ParticularAction = IAction;
export declare const actions: string[];
export type Action = GenericAction | ParticularAction | string;
export declare const ActionDefDict: {
export declare const actionDefDict: {
iState: ActionDef<string, string>;
};

View File

@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ActionDefDict = exports.actions = void 0;
exports.actionDefDict = exports.actions = void 0;
const IActionDef = {
stm: {
apply: ['active', 'applied'],
@ -9,6 +9,6 @@ const IActionDef = {
is: 'active',
};
exports.actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "apply", "abandon"];
exports.ActionDefDict = {
exports.actionDefDict = {
iState: IActionDef
};

3
lib/base-app-domain/Modi/Style.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
import { EntityDef } from "./Schema";
import { StyleDef } from "../../types/Style";
export declare const style: StyleDef<EntityDef["OpSchema"], EntityDef["Action"]>;

View File

@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.style = void 0;
exports.style = {
icon: {
apply: '',
abandon: '',
},
color: {
iState: {
active: '#0000FF',
applied: '#008000',
abandoned: '#A9A9A9',
}
}
};

3
lib/base-app-domain/StyleDict.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
import { EntityDict } from "./EntityDict";
import { StyleDict } from "../types/Style";
export declare const styleDict: StyleDict<EntityDict>;

View File

@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.styleDict = void 0;
const Style_1 = require("./Modi/Style");
const Style_2 = require("./User/Style");
exports.styleDict = {
modi: Style_1.style,
user: Style_2.style
};

View File

@ -6,6 +6,6 @@ export type ParticularAction = UserAction;
export declare const actions: string[];
export declare const UserActionDef: ActionDef<UserAction, UserState>;
export type Action = GenericAction | ParticularAction | RelationAction | string;
export declare const ActionDefDict: {
export declare const actionDefDict: {
userState: ActionDef<string, string>;
};

View File

@ -1,12 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ActionDefDict = exports.UserActionDef = exports.actions = void 0;
exports.actionDefDict = exports.UserActionDef = exports.actions = void 0;
exports.actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "grant", "revoke", "mergeTo"];
exports.UserActionDef = {
stm: {
mergeTo: ['normal', 'merged'],
},
};
exports.ActionDefDict = {
exports.actionDefDict = {
userState: exports.UserActionDef
};

3
lib/base-app-domain/User/Style.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
import { EntityDef } from "./Schema";
import { StyleDef } from "../../types/Style";
export declare const style: StyleDef<EntityDef["OpSchema"], EntityDef["Action"]>;

View File

@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.style = void 0;
exports.style = {
icon: {
mergeTo: '',
},
color: {
userState: {
normal: '#112233',
merged: '#223344',
}
}
};

View File

@ -2,3 +2,4 @@ export * from './EntityDict';
export * from './Storage';
export * from './ActionDefDict';
export * from './Relation';
export * from './StyleDict';

View File

@ -5,3 +5,4 @@ tslib_1.__exportStar(require("./EntityDict"), exports);
tslib_1.__exportStar(require("./Storage"), exports);
tslib_1.__exportStar(require("./ActionDefDict"), exports);
tslib_1.__exportStar(require("./Relation"), exports);
tslib_1.__exportStar(require("./StyleDict"), exports);

View File

@ -27,6 +27,7 @@ const ActionImportStatements = () => [
factory.createImportSpecifier(false, undefined, factory.createIdentifier("RelationAction")),
])), factory.createStringLiteral((0, env_1.ACTION_CONSTANT_IN_OAK_DOMAIN)()), undefined)
];
const StyleAsts = {};
const ActionAsts = {};
const SchemaAsts = {};
function addRelationship(many, one, key, notNull) {
@ -1120,6 +1121,9 @@ function analyzeEntity(filename, path, program, relativePath) {
_static = true; // static如果有值只能为true
}
};
const dealWithStyleDesc = (declaration) => {
StyleAsts[moduleName] = declaration;
};
const dealWithEntityDesc = (declaration) => {
if (ts.isObjectLiteralExpression(declaration)) {
const { properties } = declaration;
@ -1136,6 +1140,11 @@ function analyzeEntity(filename, path, program, relativePath) {
(0, assert_1.default)(ts.isPropertyAssignment(configurationProperty));
dealWithConfiguration(configurationProperty.initializer);
}
const styleDescProperty = properties.find(ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'style');
if (styleDescProperty) {
(0, assert_1.default)(ts.isPropertyAssignment(styleDescProperty));
dealWithStyleDesc(styleDescProperty.initializer);
}
}
else if (ts.isIdentifier(declaration)) {
const checker = program.getTypeChecker();
@ -1146,7 +1155,6 @@ function analyzeEntity(filename, path, program, relativePath) {
* 拿不到数据定义(在js中)(original.declaration.initializer是undefined)
*/
(0, assert_1.default)(false, '用变量赋值给entityDesc暂时还解析不了');
console.log(original);
}
};
declarations.forEach((declaration) => {
@ -3206,7 +3214,7 @@ function outputAction(outputDir, printer) {
for (const external in fromExternalImports) {
statements.splice(0, 0, factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports(fromExternalImports[external].map(ele => factory.createImportSpecifier(false, ele[1] === undefined ? undefined : factory.createIdentifier(ele[1]), factory.createIdentifier(ele[0]))))), factory.createStringLiteral(external), undefined));
}
statements.push(factory.createVariableStatement([factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier("ActionDefDict"), undefined, undefined, factory.createObjectLiteralExpression(actionDefNames.map(ele => factory.createPropertyAssignment(factory.createIdentifier(`${ele}State`), factory.createIdentifier(`${(0, string_1.firstLetterUpperCase)(ele)}ActionDef`))), true))], ts.NodeFlags.Const)));
statements.push(factory.createVariableStatement([factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier("actionDefDict"), undefined, undefined, factory.createObjectLiteralExpression(actionDefNames.map(ele => factory.createPropertyAssignment(factory.createIdentifier(`${ele}State`), factory.createIdentifier(`${(0, string_1.firstLetterUpperCase)(ele)}ActionDef`))), true))], ts.NodeFlags.Const)));
/* const result = printer.printNode(
ts.EmitHint.Unspecified,
factory.createSourceFile(statements,
@ -3218,10 +3226,10 @@ function outputAction(outputDir, printer) {
const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray(importStatements.concat(statements)), sourceFile);
const filename = path_1.default.join(outputDir, entity, 'Action.ts');
(0, fs_1.writeFileSync)(filename, result, { flag: 'w' });
actionDictStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([factory.createImportSpecifier(false, factory.createIdentifier("ActionDefDict"), factory.createIdentifier(entity))])), factory.createStringLiteral(`./${entity}/Action`)));
propertyAssignments.push(factory.createPropertyAssignment(factory.createIdentifier((0, string_1.firstLetterLowerCase)(entity)), factory.createIdentifier(entity)));
actionDictStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([factory.createImportSpecifier(false, factory.createIdentifier("actionDefDict"), factory.createIdentifier((0, string_1.firstLetterLowerCase)(entity)))])), factory.createStringLiteral(`./${entity}/Action`)));
propertyAssignments.push(factory.createShorthandPropertyAssignment(factory.createIdentifier((0, string_1.firstLetterLowerCase)(entity))));
}
actionDictStatements.push(factory.createVariableStatement([factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier("ActionDefDict"), undefined, undefined, factory.createObjectLiteralExpression(propertyAssignments, true))], ts.NodeFlags.Const)));
actionDictStatements.push(factory.createVariableStatement([factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier("actionDefDict"), undefined, undefined, factory.createObjectLiteralExpression(propertyAssignments, true))], ts.NodeFlags.Const)));
const resultFile = ts.createSourceFile("someFileName.ts", "", ts.ScriptTarget.Latest, /*setParentNodes*/ false, ts.ScriptKind.TS);
const result = printer.printNode(ts.EmitHint.Unspecified, factory.createSourceFile(actionDictStatements, factory.createToken(ts.SyntaxKind.EndOfFileToken), ts.NodeFlags.None), resultFile);
const fileName = path_1.default.join(outputDir, 'ActionDefDict.ts');
@ -3577,6 +3585,7 @@ function outputIndexTs(outputDir) {
export * from './Storage';
export * from './ActionDefDict';
export * from './Relation';
export * from './StyleDict';
`;
const filename = path_1.default.join(outputDir, 'index.ts');
(0, fs_1.writeFileSync)(filename, indexTs, { flag: 'w' });
@ -4132,6 +4141,40 @@ function outputRelation2(outputDir, printer) {
const filename = path_1.default.join(outputDir, 'Relation.ts');
(0, fs_1.writeFileSync)(filename, result, { flag: 'w' });
}
/**
* 输出oak-app-domain中的StyleDict.ts文件
* @param outputDir
* @param printer
*/
function outputStyleDict(outputDir, printer) {
for (const entity in StyleAsts) {
const stmts = [
factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier("EntityDef"))
])), factory.createStringLiteral("./Schema"), undefined),
factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([factory.createImportSpecifier(false, undefined, factory.createIdentifier("StyleDef"))])), factory.createStringLiteral(`${(0, env_1.TYPE_PATH_IN_OAK_DOMAIN)()}Style`), undefined),
factory.createVariableStatement([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier("style"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("StyleDef"), [
factory.createIndexedAccessTypeNode(factory.createTypeReferenceNode(factory.createIdentifier("EntityDef"), undefined), factory.createLiteralTypeNode(factory.createStringLiteral("OpSchema"))),
factory.createIndexedAccessTypeNode(factory.createTypeReferenceNode(factory.createIdentifier("EntityDef"), undefined), factory.createLiteralTypeNode(factory.createStringLiteral("Action")))
]), StyleAsts[entity])], ts.NodeFlags.Const))
];
const { sourceFile } = Schema[entity];
const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray(stmts), sourceFile);
const filename = path_1.default.join(outputDir, entity, 'Style.ts');
(0, fs_1.writeFileSync)(filename, result, { flag: 'w' });
}
const stmts = [
factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier("EntityDict"))
])), factory.createStringLiteral("./EntityDict"), undefined),
factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([factory.createImportSpecifier(false, undefined, factory.createIdentifier("StyleDict"))])), factory.createStringLiteral(`${(0, env_1.TYPE_PATH_IN_OAK_DOMAIN)(1)}Style`), undefined),
...Object.keys(StyleAsts).map((entity) => factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([factory.createImportSpecifier(false, factory.createIdentifier("style"), factory.createIdentifier((0, string_1.firstLetterLowerCase)(entity)))])), factory.createStringLiteral(`./${entity}/Style`), undefined)),
factory.createVariableStatement([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier("styleDict"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("StyleDict"), [factory.createTypeReferenceNode(factory.createIdentifier("EntityDict"), undefined)]), factory.createObjectLiteralExpression(Object.keys(StyleAsts).map((entity) => factory.createShorthandPropertyAssignment(factory.createIdentifier((0, string_1.firstLetterLowerCase)(entity)), undefined)), true))], ts.NodeFlags.Const))
];
const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray(stmts), ts.createSourceFile("someFileName.ts", "", ts.ScriptTarget.Latest, /*setParentNodes*/ false, ts.ScriptKind.TS));
const filename = path_1.default.join(outputDir, 'StyleDict.ts');
(0, fs_1.writeFileSync)(filename, result, { flag: 'w' });
}
function analyzeEntities(inputDir, relativePath) {
const files = (0, fs_1.readdirSync)(inputDir);
const fullFilenames = files.map(ele => {
@ -4161,6 +4204,7 @@ function buildSchema(outputDir) {
outputEntityDict(outputDir, printer);
outputStorage(outputDir, printer);
outputRelation2(outputDir, printer);
outputStyleDict(outputDir, printer);
outputIndexTs(outputDir);
if (!process.env.COMPLING_AS_LIB) {
outputPackageJson(outputDir);

View File

@ -46,4 +46,17 @@ const entityDesc = {
],
},
],
style: {
icon: {
apply: '',
abandon: '',
},
color: {
iState: {
active: '#0000FF',
applied: '#008000',
abandoned: '#A9A9A9',
}
}
}
};

View File

@ -29,4 +29,15 @@ exports.entityDesc = {
}
},
},
style: {
icon: {
mergeTo: '',
},
color: {
userState: {
normal: '#112233',
merged: '#223344',
}
}
}
};

View File

@ -1,5 +1,5 @@
import { ActionDictOfEntityDict, Checker, EntityDict, StorageSchema, AttrUpdateMatrix } from "../types";
import { ActionDefDict, Checker, EntityDict, StorageSchema, AttrUpdateMatrix } from "../types";
import { SyncContext } from "./SyncRowStore";
import { AsyncContext } from "./AsyncRowStore";
import { EntityDict as BaseEntityDict } from '../base-app-domain/EntityDict';
export declare function makeIntrinsicCheckers<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(schema: StorageSchema<ED>, actionDefDict: ActionDictOfEntityDict<ED>, attrUpdateMatrix?: AttrUpdateMatrix<ED>): Checker<ED, keyof ED, Cxt | FrontCxt>[];
export declare function makeIntrinsicCheckers<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(schema: StorageSchema<ED>, actionDefDict: ActionDefDict<ED>, attrUpdateMatrix?: AttrUpdateMatrix<ED>): Checker<ED, keyof ED, Cxt | FrontCxt>[];

View File

@ -1,8 +1,8 @@
import { ActionDictOfEntityDict, Checker, EntityDict, StorageSchema, Trigger, Watcher, AttrUpdateMatrix } from "../types";
import { ActionDefDict, Checker, EntityDict, StorageSchema, Trigger, Watcher, AttrUpdateMatrix } from "../types";
import { SyncContext } from "./SyncRowStore";
import { AsyncContext } from "./AsyncRowStore";
import { EntityDict as BaseEntityDict } from '../base-app-domain/EntityDict';
export declare function makeIntrinsicCTWs<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(schema: StorageSchema<ED>, actionDefDict: ActionDictOfEntityDict<ED>, attrUpdateMatrix?: AttrUpdateMatrix<ED>): {
export declare function makeIntrinsicCTWs<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(schema: StorageSchema<ED>, actionDefDict: ActionDefDict<ED>, attrUpdateMatrix?: AttrUpdateMatrix<ED>): {
triggers: Trigger<ED, keyof ED, Cxt>[];
checkers: Checker<ED, keyof ED, Cxt | FrontCxt>[];
watchers: Watcher<ED, keyof ED, Cxt>[];

View File

@ -8,7 +8,7 @@ export type ActionDef<A extends Action, S extends State> = {
};
is?: S;
};
export type ActionDictOfEntityDict<E extends EntityDict> = {
export type ActionDefDict<E extends EntityDict> = {
[T in keyof E]?: {
[A in keyof E[T]['OpSchema']]?: ActionDef<string, string>;
};

View File

@ -1,7 +1,15 @@
import { AuthDeduceRelationMap, EntityDict } from './Entity';
import { EntityDict as BaseEntityDict } from "../base-app-domain";
import { AsyncContext } from '../store/AsyncRowStore';
import { SyncConfig } from "./Sync";
import { AttrUpdateMatrix } from './EntityDesc';
import { ActionDefDict } from './Action';
import { StyleDict } from './Style';
import { Exportation, Importation } from './Port';
/**
*
*
*/
export type ServerConfiguration = {
export type ServerConfiguration<ED extends BaseEntityDict & EntityDict, Cxt extends AsyncContext<ED>> = {
database: {
type: 'mysql';
host: string;
@ -12,14 +20,15 @@ export type ServerConfiguration = {
connectionLimit: number;
charset: "utf8mb4_general_ci";
};
http: {
port: number;
workDir: {
path: string;
};
sync?: SyncConfig<ED, Cxt>;
};
/**
*
* 访
*/
export type ProjectConfiguration = {
export type AccessConfiguration = {
routerPrefixes?: {
aspect?: string;
endpoint?: string;
@ -27,6 +36,33 @@ export type ProjectConfiguration = {
getSubscribePoint?: string;
bridge?: string;
};
http: {
port: number;
ssl?: boolean;
path?: string;
};
};
/**
*
*/
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt extends AsyncContext<ED>> = {
attrUpdateMatrix: AttrUpdateMatrix<ED>;
actionDefDict: ActionDefDict<ED>;
authDeduceRelationMap: AuthDeduceRelationMap<ED>;
importations?: Importation<ED, keyof ED, any, Cxt>[];
exportations?: Exportation<ED, keyof ED, any, Cxt>[];
selectFreeEntities?: (keyof ED)[];
updateFreeDict?: {
[A in keyof ED]?: string[];
};
cacheSavedEntities?: (keyof ED)[];
cacheKeepFreshPeriod?: number;
};
/**
*
*/
export type RenderConfiguration<ED extends BaseEntityDict & EntityDict> = {
styleDict: StyleDict<ED>;
};
/**
*

View File

@ -1,3 +1,2 @@
"use strict";
// 将项目的所有配置规范化到一起未完成by Xc 20240207
Object.defineProperty(exports, "__esModule", { value: true });

View File

@ -1,12 +1,19 @@
import { LocaleDef } from './Locale';
import { Index } from './Storage';
import { EntityShape, Configuration, EntityDict } from './Entity';
export type EntityDesc<Schema extends EntityShape, Action extends string = '', Relation extends string = '', V extends Record<string, string> = {}> = {
locales: LocaleDef<Schema, Action, Relation, V>;
import { StyleDesc } from './Style';
export type EntityDesc<Schema extends EntityShape, Action extends string = '', Relation extends string = '', V extends Record<string, string> = {
['##oak_illegal##']: '';
}> = {
locales: LocaleDef<Schema, Action, Relation, keyof V extends '##oak_illegal##' ? {} : V>;
indexes?: Index<Schema>[];
configuration?: Configuration;
recursiveDepth?: number;
};
} & (Action extends '' ? (keyof V extends '##oak_illegal##' ? {} : {
style: StyleDesc<Action, V>;
}) : {
style: StyleDesc<Action, V>;
});
export type AttrUpdateMatrix<ED extends EntityDict> = {
[T in keyof ED]?: {
[A in keyof ED[T]['Update']['data']]?: {

41
lib/types/Style.d.ts vendored
View File

@ -1,11 +1,40 @@
import { EntityDict } from './Entity';
import { EntityDict, GeneralEntityShape } from './Entity';
import { EntityDict as BaseEntityDict } from '../base-app-domain';
type ThemeColor = 'default' | 'success' | 'warning' | 'error' | 'primary' | 'danger';
export type ColorDict<ED extends BaseEntityDict & EntityDict> = {
[T in keyof ED]?: {
[A in keyof ED[T]['OpSchema']]?: {
[E in ED[T]['OpSchema'][A]]?: ThemeColor | `#${string}`;
type Color = `#${string}`;
type IconName = string;
export type StyleDesc<Action extends string = '', V extends Record<string, string> = {
['##oak_illegal##']: '';
}> = Action extends '' ? (keyof V extends '##oak_illegal##' ? {} : {
color: {
[A in keyof V]: {
[E in V[A]]: Color;
};
};
}) : (keyof V extends '##oak_illegal##' ? {
icon: {
[A in Action]?: IconName;
};
} : {
icon: {
[A in Action]?: IconName;
};
color: {
[A in keyof V]: {
[E in V[A]]: Color;
};
};
});
export type StyleDef<ED extends GeneralEntityShape, Action extends string> = {
color?: {
[A in keyof ED]?: {
[E in ED[A]]?: Color;
};
};
icon?: {
[A in Action]?: IconName;
};
};
export type StyleDict<ED extends BaseEntityDict & EntityDict> = {
[T in keyof ED]?: StyleDef<ED[T]['OpSchema'], ED[T]['Action']>;
};
export {};

View File

@ -98,6 +98,10 @@ const ActionImportStatements = () => [
)
];
const StyleAsts: {
[module: string]: ts.ObjectLiteralExpression;
} = {};
const ActionAsts: {
[module: string]: {
statements: Array<ts.Statement>;
@ -1203,13 +1207,13 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
assert(node.type.literal.text.length < STRING_LITERAL_MAX_LENGTH, `Relation定义的字符串长度不长于${STRING_LITERAL_MAX_LENGTH}${filename}${node.type.literal.text}`);
relationValues.push(node.type.literal.text);
}
else if (ts.isTypeReferenceNode(node.type)){
else if (ts.isTypeReferenceNode(node.type)) {
const relationStrings = tryGetStringLiteralValues(moduleName, filename, 'relation', node.type, program);
assert(relationStrings.length > 0);
relationValues.push(...relationStrings);
}
else {
assert (ts.isUnionTypeNode(node.type), `Relation的定义只能是string类型或者string union类型或者两者的union${filename}`);
assert(ts.isUnionTypeNode(node.type), `Relation的定义只能是string类型或者string union类型或者两者的union${filename}`);
node.type.types.forEach(
(ele) => {
if (ts.isLiteralTypeNode(ele)) {
@ -1218,7 +1222,7 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
relationValues.push(ele.literal.text);
}
else {
assert (ts.isTypeReferenceNode(ele), `Relation的定义只能是string类型或者string union类型或者两者的union${filename}`);
assert(ts.isTypeReferenceNode(ele), `Relation的定义只能是string类型或者string union类型或者两者的union${filename}`);
const relationStrings = tryGetStringLiteralValues(moduleName, filename, 'relation', ele, program);
assert(relationStrings.length > 0);
relationValues.push(...relationStrings);
@ -1513,6 +1517,9 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
_static = true; // static如果有值只能为true
}
};
const dealWithStyleDesc = (declaration: ts.ObjectLiteralExpression) => {
StyleAsts[moduleName] = declaration;
}
const dealWithEntityDesc = (declaration: ts.Expression) => {
if (ts.isObjectLiteralExpression(declaration)) {
const { properties } = declaration;
@ -1538,6 +1545,14 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
assert(ts.isPropertyAssignment(configurationProperty));
dealWithConfiguration(configurationProperty.initializer as ts.ObjectLiteralExpression);
}
const styleDescProperty = properties.find(
ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'style'
);
if (styleDescProperty) {
assert(ts.isPropertyAssignment(styleDescProperty!));
dealWithStyleDesc(styleDescProperty.initializer as ts.ObjectLiteralExpression);
}
}
else if (ts.isIdentifier(declaration)) {
const checker = program.getTypeChecker();
@ -1549,9 +1564,6 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
*/
assert(false, '用变量赋值给entityDesc暂时还解析不了');
console.log(original);
}
};
declarations.forEach(
@ -5765,7 +5777,7 @@ function outputSchema(outputDir: string, printer: ts.Printer) {
function outputAction(outputDir: string, printer: ts.Printer) {
const actionDictStatements: ts.Statement[] = [];
const propertyAssignments: ts.PropertyAssignment[] = [];
const propertyAssignments: ts.ShorthandPropertyAssignment[] = [];
for (const entity in ActionAsts) {
const { sourceFile, statements, importActionFrom, importStateFrom, importActionDefFrom, actionDefNames } = ActionAsts[entity];
const importStatements: ts.Statement[] = [];
@ -5833,7 +5845,7 @@ function outputAction(outputDir: string, printer: ts.Printer) {
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(
factory.createIdentifier("ActionDefDict"),
factory.createIdentifier("actionDefDict"),
undefined,
undefined,
factory.createObjectLiteralExpression(
@ -5873,17 +5885,16 @@ function outputAction(outputDir: string, printer: ts.Printer) {
undefined,
factory.createNamedImports([factory.createImportSpecifier(
false,
factory.createIdentifier("ActionDefDict"),
factory.createIdentifier(entity)
factory.createIdentifier("actionDefDict"),
factory.createIdentifier(firstLetterLowerCase(entity))
)])
),
factory.createStringLiteral(`./${entity}/Action`)
)
);
propertyAssignments.push(
factory.createPropertyAssignment(
factory.createShorthandPropertyAssignment(
factory.createIdentifier(firstLetterLowerCase(entity)),
factory.createIdentifier(entity)
)
);
}
@ -5893,7 +5904,7 @@ function outputAction(outputDir: string, printer: ts.Printer) {
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(
factory.createIdentifier("ActionDefDict"),
factory.createIdentifier("actionDefDict"),
undefined,
undefined,
factory.createObjectLiteralExpression(
@ -6738,6 +6749,7 @@ function outputIndexTs(outputDir: string) {
export * from './Storage';
export * from './ActionDefDict';
export * from './Relation';
export * from './StyleDict';
`;
const filename = PathLib.join(outputDir, 'index.ts');
writeFileSync(filename, indexTs, { flag: 'w' });
@ -7398,6 +7410,168 @@ function outputRelation2(outputDir: string, printer: ts.Printer) {
writeFileSync(filename, result, { flag: 'w' });
}
/**
* oak-app-domain中的StyleDict.ts文件
* @param outputDir
* @param printer
*/
function outputStyleDict(outputDir: string, printer: ts.Printer) {
for (const entity in StyleAsts) {
const stmts: ts.Statement[] = [
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
undefined,
factory.createNamedImports([
factory.createImportSpecifier(
false,
undefined,
factory.createIdentifier("EntityDef")
)
])
),
factory.createStringLiteral("./Schema"),
undefined
),
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
undefined,
factory.createNamedImports([factory.createImportSpecifier(
false,
undefined,
factory.createIdentifier("StyleDef")
)])
),
factory.createStringLiteral(`${TYPE_PATH_IN_OAK_DOMAIN()}Style`),
undefined
),
factory.createVariableStatement(
[factory.createToken(ts.SyntaxKind.ExportKeyword)],
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(
factory.createIdentifier("style"),
undefined,
factory.createTypeReferenceNode(
factory.createIdentifier("StyleDef"),
[
factory.createIndexedAccessTypeNode(
factory.createTypeReferenceNode(
factory.createIdentifier("EntityDef"),
undefined
),
factory.createLiteralTypeNode(factory.createStringLiteral("OpSchema"))
),
factory.createIndexedAccessTypeNode(
factory.createTypeReferenceNode(
factory.createIdentifier("EntityDef"),
undefined
),
factory.createLiteralTypeNode(factory.createStringLiteral("Action"))
)
]
),
StyleAsts[entity]
)],
ts.NodeFlags.Const
)
)
];
const { sourceFile } = Schema[entity];
const result = printer.printList(
ts.ListFormat.SourceFileStatements,
factory.createNodeArray(stmts),
sourceFile);
const filename = PathLib.join(outputDir, entity, 'Style.ts');
writeFileSync(filename, result, { flag: 'w' });
}
const stmts: ts.Statement[] = [
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
undefined,
factory.createNamedImports([
factory.createImportSpecifier(
false,
undefined,
factory.createIdentifier("EntityDict")
)
])
),
factory.createStringLiteral("./EntityDict"),
undefined
),
factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
undefined,
factory.createNamedImports([factory.createImportSpecifier(
false,
undefined,
factory.createIdentifier("StyleDict")
)])
),
factory.createStringLiteral(`${TYPE_PATH_IN_OAK_DOMAIN(1)}Style`),
undefined
),
...Object.keys(StyleAsts).map(
(entity) => factory.createImportDeclaration(
undefined,
factory.createImportClause(
false,
undefined,
factory.createNamedImports([factory.createImportSpecifier(
false,
factory.createIdentifier("style"),
factory.createIdentifier(firstLetterLowerCase(entity))
)])
),
factory.createStringLiteral(`./${entity}/Style`),
undefined
)
),
factory.createVariableStatement(
[factory.createToken(ts.SyntaxKind.ExportKeyword)],
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(
factory.createIdentifier("styleDict"),
undefined,
factory.createTypeReferenceNode(
factory.createIdentifier("StyleDict"),
[factory.createTypeReferenceNode(
factory.createIdentifier("EntityDict"),
undefined
)]
),
factory.createObjectLiteralExpression(
Object.keys(StyleAsts).map(
(entity) => factory.createShorthandPropertyAssignment(
factory.createIdentifier(firstLetterLowerCase(entity)),
undefined
)
),
true
)
)],
ts.NodeFlags.Const
)
)
];
const result = printer.printList(
ts.ListFormat.SourceFileStatements,
factory.createNodeArray(stmts),
ts.createSourceFile("someFileName.ts", "", ts.ScriptTarget.Latest, /*setParentNodes*/ false, ts.ScriptKind.TS));
const filename = PathLib.join(outputDir, 'StyleDict.ts');
writeFileSync(filename, result, { flag: 'w' });
}
export function analyzeEntities(inputDir: string, relativePath?: string) {
const files = readdirSync(inputDir);
const fullFilenames = files.map(
@ -7435,6 +7609,7 @@ export function buildSchema(outputDir: string): void {
outputEntityDict(outputDir, printer);
outputStorage(outputDir, printer);
outputRelation2(outputDir, printer);
outputStyleDict(outputDir, printer);
outputIndexTs(outputDir);

View File

@ -66,4 +66,17 @@ const entityDesc: EntityDesc<Schema, Action, '', {
],
},
],
style: {
icon: {
apply: '',
abandon: '',
},
color: {
iState: {
active: '#0000FF',
applied: '#008000',
abandoned: '#A9A9A9',
}
}
}
};

View File

@ -45,5 +45,16 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
},
}
},
},
},
style: {
icon: {
mergeTo: '',
},
color: {
userState: {
normal: '#112233',
merged: '#223344',
}
}
}
};

View File

@ -1,4 +1,4 @@
import { ActionDictOfEntityDict, Checker, EntityDict, StorageSchema, RowChecker, OakUniqueViolationException, CHECKER_MAX_PRIORITY, AttrUpdateMatrix, LogicalChecker, OakAttrCantUpdateException } from "../types";
import { ActionDefDict, Checker, EntityDict, StorageSchema, RowChecker, OakUniqueViolationException, CHECKER_MAX_PRIORITY, AttrUpdateMatrix, LogicalChecker, OakAttrCantUpdateException } from "../types";
import { SyncContext } from "./SyncRowStore";
import { AsyncContext } from "./AsyncRowStore";
import { pick, intersection, difference } from '../utils/lodash';
@ -202,7 +202,7 @@ function createUniqueCheckers<ED extends EntityDict & BaseEntityDict, Cxt extend
}
function createActionTransformerCheckers<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(
actionDefDict: ActionDictOfEntityDict<ED>
actionDefDict: ActionDefDict<ED>
) {
const checkers: Array<Checker<ED, keyof ED, Cxt | FrontCxt>> = [];
for (const entity in actionDefDict) {
@ -349,7 +349,7 @@ function createAttrUpdateCheckers<ED extends EntityDict & BaseEntityDict, Cxt ex
export function makeIntrinsicCheckers<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(
schema: StorageSchema<ED>,
actionDefDict: ActionDictOfEntityDict<ED>,
actionDefDict: ActionDefDict<ED>,
attrUpdateMatrix?: AttrUpdateMatrix<ED>,
) {
const checkers: Checker<ED, keyof ED, Cxt | FrontCxt>[] = [];

View File

@ -1,4 +1,4 @@
import { ActionDictOfEntityDict, BBWatcher, Checker, EntityDict, StorageSchema, Trigger, Watcher, AttrUpdateMatrix } from "../types";
import { ActionDefDict, BBWatcher, Checker, EntityDict, StorageSchema, Trigger, Watcher, AttrUpdateMatrix } from "../types";
import { SyncContext } from "./SyncRowStore";
import { AsyncContext } from "./AsyncRowStore";
import { EntityDict as BaseEntityDict } from '../base-app-domain/EntityDict';
@ -38,7 +38,7 @@ function createExpiredWatchers<ED extends EntityDict & BaseEntityDict>(schema: S
export function makeIntrinsicCTWs<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(
schema: StorageSchema<ED>,
actionDefDict: ActionDictOfEntityDict<ED>,
actionDefDict: ActionDefDict<ED>,
attrUpdateMatrix?: AttrUpdateMatrix<ED>,
) {
const checkers: Checker<ED, keyof ED, Cxt | FrontCxt>[] = makeIntrinsicCheckers<ED, Cxt, FrontCxt>(schema, actionDefDict, attrUpdateMatrix);

View File

@ -11,7 +11,7 @@ export type ActionDef<A extends Action, S extends State> = {
is?: S,
};
export type ActionDictOfEntityDict<E extends EntityDict> = {
export type ActionDefDict<E extends EntityDict> = {
[T in keyof E]?: {
[A in keyof E[T]['OpSchema']]?: ActionDef<string, string>;
};

View File

@ -1,9 +1,17 @@
// 将项目的所有配置规范化到一起未完成by Xc 20240207
import { AuthDeduceRelationMap, EntityDict } from './Entity';
import { EntityDict as BaseEntityDict } from "../base-app-domain";
import { AsyncContext } from '../store/AsyncRowStore';
import { SyncConfig } from "./Sync";
import { AttrUpdateMatrix } from './EntityDesc';
import { ActionDefDict } from './Action';
import { StyleDict } from './Style';
import { Exportation, Importation } from './Port';
/**
*
*
*/
export type ServerConfiguration = {
export type ServerConfiguration<ED extends BaseEntityDict & EntityDict, Cxt extends AsyncContext<ED>> = {
database: {
type: 'mysql',
host: string;
@ -14,16 +22,16 @@ export type ServerConfiguration = {
connectionLimit: number;
charset: "utf8mb4_general_ci",
},
http: {
// 监听端口号
port: number;
}
workDir: {
path: string;
},
sync?: SyncConfig<ED, Cxt>;
};
/**
*
* 访
*/
export type ProjectConfiguration = {
export type AccessConfiguration = {
// 各种接口的路由前缀(一般不建议配置)
routerPrefixes?: {
// 默认aspect
@ -40,9 +48,42 @@ export type ProjectConfiguration = {
// 默认bridge
bridge?: string;
}
}
},
http: {
// 监听端口号
port: number;
// 是否配用https(nginx)
ssl?: boolean;
// nginx proxy path
path?: string;
}
};
/**
*
*/
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt extends AsyncContext<ED>> = {
attrUpdateMatrix: AttrUpdateMatrix<ED>;
actionDefDict: ActionDefDict<ED>;
authDeduceRelationMap: AuthDeduceRelationMap<ED>;
importations?: Importation<ED, keyof ED, any, Cxt>[];
exportations?: Exportation<ED, keyof ED, any, Cxt>[];
selectFreeEntities?: (keyof ED)[];
updateFreeDict?: {
[A in keyof ED]?: string[];
};
cacheSavedEntities?: (keyof ED)[];
cacheKeepFreshPeriod?: number;
};
/**
*
*/
export type RenderConfiguration<ED extends BaseEntityDict & EntityDict> = {
styleDict: StyleDict<ED>;
};
/**
*

View File

@ -1,17 +1,26 @@
import { LocaleDef } from './Locale';
import { Index } from './Storage';
import { EntityShape, Configuration, EntityDict } from './Entity';
import { StyleDesc } from './Style';
export type EntityDesc<
Schema extends EntityShape,
Action extends string = '',
Relation extends string = '',
V extends Record<string, string> = {}> = {
locales: LocaleDef<Schema, Action, Relation, V>;
V extends Record<string, string> = { ['##oak_illegal##']: '' }> = {
locales: LocaleDef<Schema, Action, Relation, keyof V extends '##oak_illegal##' ? {} : V>;
indexes?: Index<Schema>[];
configuration?: Configuration;
recursiveDepth?: number;
};
} & (
Action extends '' ? (
keyof V extends '##oak_illegal##' ? {} : {
style: StyleDesc<Action, V>;
}
) : {
style: StyleDesc<Action, V>;
}
);
// 定义对象的更新约束,在什么状态下可以(通过什么动作)更新什么属性

View File

@ -1,12 +1,45 @@
import { EntityDict } from './Entity';
import { EntityDict, GeneralEntityShape } from './Entity';
import { EntityDict as BaseEntityDict } from '../base-app-domain';
type ThemeColor = 'default' | 'success' | 'warning' | 'error' | 'primary' | 'danger';
type Color = `#${string}`;
type IconName = string;
export type ColorDict<ED extends BaseEntityDict & EntityDict> = {
[T in keyof ED]?: {
[A in keyof ED[T]['OpSchema']]?: {
[E in ED[T]['OpSchema'][A]]?: ThemeColor | `#${string}`;
export type StyleDesc<Action extends string = '', V extends Record<string, string> = { ['##oak_illegal##']: '' }> = Action extends '' ? (
keyof V extends '##oak_illegal##' ? {} : {
color: {
[A in keyof V]: {
[E in V[A]]: Color;
};
};
}
) : (
keyof V extends '##oak_illegal##' ? {
icon: {
[A in Action]?: IconName;
};
} : {
icon: {
[A in Action]?: IconName;
};
color: {
[A in keyof V]: {
[E in V[A]]: Color;
};
};
}
);
export type StyleDef<ED extends GeneralEntityShape, Action extends string> = {
color?: {
[A in keyof ED]?: {
[E in ED[A]]?: Color;
};
};
icon?: {
[A in Action]?: IconName;
};
};
export type StyleDict<ED extends BaseEntityDict & EntityDict> = {
[T in keyof ED]?: StyleDef<ED[T]['OpSchema'], ED[T]['Action']>;
};