module的相关代码
This commit is contained in:
parent
4c78de2233
commit
fd540fe96f
|
|
@ -5,7 +5,6 @@ import { SyncConfig } from "./Sync";
|
|||
import { AttrUpdateMatrix } from './EntityDesc';
|
||||
import { ActionDefDict } from './Action';
|
||||
import { StyleDict } from './Style';
|
||||
import { Exportation, Importation } from './Port';
|
||||
/**
|
||||
* 后台配置
|
||||
*/
|
||||
|
|
@ -14,7 +13,7 @@ export type ServerConfiguration<ED extends BaseEntityDict & EntityDict, Cxt exte
|
|||
type: 'mysql';
|
||||
host: string;
|
||||
database: string;
|
||||
port: number;
|
||||
port?: number;
|
||||
user: string;
|
||||
password?: string;
|
||||
connectionLimit: number;
|
||||
|
|
@ -37,7 +36,8 @@ export type AccessConfiguration = {
|
|||
bridge?: string;
|
||||
};
|
||||
http: {
|
||||
port: number;
|
||||
hostname: string;
|
||||
port?: number;
|
||||
ssl?: boolean;
|
||||
path?: string;
|
||||
};
|
||||
|
|
@ -45,12 +45,10 @@ export type AccessConfiguration = {
|
|||
/**
|
||||
* 业务逻辑的通用配置
|
||||
*/
|
||||
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt extends AsyncContext<ED>> = {
|
||||
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict> = {
|
||||
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[];
|
||||
|
|
@ -58,6 +56,7 @@ export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt exte
|
|||
cacheSavedEntities?: (keyof ED)[];
|
||||
cacheKeepFreshPeriod?: number;
|
||||
};
|
||||
export type DependencyConfiguration = string[];
|
||||
/**
|
||||
* 渲染相关定义
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -36,4 +36,7 @@ export interface Connector<ED extends EntityDict, FrontCxt extends SyncContext<E
|
|||
url: string;
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
getFullData: (keys?: (keyof ED)[]) => Promise<{
|
||||
[T in keyof ED]?: ED[T]['OpSchema'][];
|
||||
}>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,5 +77,6 @@ export declare class SimpleConnector<ED extends EntityDict, FrontCxt extends Syn
|
|||
url: string;
|
||||
headers?: Record<string, string> | undefined;
|
||||
};
|
||||
getFullData(): Promise<{}>;
|
||||
}
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -213,5 +213,9 @@ class SimpleConnector {
|
|||
headers: headers && JSON.parse(headers),
|
||||
};
|
||||
}
|
||||
async getFullData() {
|
||||
console.error('前后台模式下暂时不支持此操作,请到数据库查看数据');
|
||||
return {};
|
||||
}
|
||||
}
|
||||
exports.SimpleConnector = SimpleConnector;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import intersection from 'lodash/intersection';
|
|||
import intersectionBy from 'lodash/intersectionBy';
|
||||
import omit from 'lodash/omit';
|
||||
import merge from 'lodash/merge';
|
||||
import mergeWith from 'lodash/mergeWith';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import pick from 'lodash/pick';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
|
@ -21,4 +22,11 @@ import differenceBy from 'lodash/differenceBy';
|
|||
import groupBy from 'lodash/groupBy';
|
||||
import unionBy from 'lodash/unionBy';
|
||||
import pullAll from 'lodash/pullAll';
|
||||
export { unset, pull, uniq, uniqBy, get, set, intersection, intersectionBy, omit, merge, cloneDeep, pick, isEqual, union, difference, differenceBy, groupBy, unionBy, pullAll, };
|
||||
/**
|
||||
* merge两个对象,遇到array时使用连接合并
|
||||
* @param object
|
||||
* @param source
|
||||
* @returns
|
||||
*/
|
||||
declare function mergeRecursively<TObject, TSource>(object: TObject, source: TSource): TObject & TSource;
|
||||
export { unset, pull, uniq, uniqBy, get, set, intersection, intersectionBy, omit, merge, mergeWith, mergeRecursively, cloneDeep, pick, isEqual, union, difference, differenceBy, groupBy, unionBy, pullAll, };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.pullAll = exports.unionBy = exports.groupBy = exports.differenceBy = exports.difference = exports.union = exports.isEqual = exports.pick = exports.cloneDeep = exports.merge = exports.omit = exports.intersectionBy = exports.intersection = exports.set = exports.get = exports.uniqBy = exports.uniq = exports.pull = exports.unset = void 0;
|
||||
exports.pullAll = exports.unionBy = exports.groupBy = exports.differenceBy = exports.difference = exports.union = exports.isEqual = exports.pick = exports.cloneDeep = exports.mergeRecursively = exports.mergeWith = exports.merge = exports.omit = exports.intersectionBy = exports.intersection = exports.set = exports.get = exports.uniqBy = exports.uniq = exports.pull = exports.unset = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
/**
|
||||
* 避免lodash打包体积过大
|
||||
|
|
@ -26,6 +26,8 @@ const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|||
exports.omit = omit_1.default;
|
||||
const merge_1 = tslib_1.__importDefault(require("lodash/merge"));
|
||||
exports.merge = merge_1.default;
|
||||
const mergeWith_1 = tslib_1.__importDefault(require("lodash/mergeWith"));
|
||||
exports.mergeWith = mergeWith_1.default;
|
||||
const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
|
||||
exports.cloneDeep = cloneDeep_1.default;
|
||||
const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
|
||||
|
|
@ -44,3 +46,19 @@ const unionBy_1 = tslib_1.__importDefault(require("lodash/unionBy"));
|
|||
exports.unionBy = unionBy_1.default;
|
||||
const pullAll_1 = tslib_1.__importDefault(require("lodash/pullAll"));
|
||||
exports.pullAll = pullAll_1.default;
|
||||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
/**
|
||||
* merge两个对象,遇到array时使用连接合并
|
||||
* @param object
|
||||
* @param source
|
||||
* @returns
|
||||
*/
|
||||
function mergeRecursively(object, source) {
|
||||
return (0, mergeWith_1.default)(object, source, (objValue, srcValue) => {
|
||||
if (objValue instanceof Array) {
|
||||
(0, assert_1.default)(srcValue instanceof Array, '合并的对象必须结构一致');
|
||||
return objValue.concat(srcValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.mergeRecursively = mergeRecursively;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import { AsyncContext } from "../../store/AsyncRowStore";
|
||||
import { SyncContext } from "../../store/SyncRowStore";
|
||||
import { EntityDict } from "../../types/Entity";
|
||||
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
|
||||
import { Checker } from '../../types/Auth';
|
||||
import { CommonConfiguration } from '../../types/Configuration';
|
||||
/**
|
||||
* 合并引入模块中的checker和common
|
||||
* @param modules
|
||||
* @returns
|
||||
*/
|
||||
export default function combineBaseModules<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED> | SyncContext<ED>>(...modules: string[]): {
|
||||
checkers: Array<Checker<ED, keyof ED, Cxt>>;
|
||||
common: CommonConfiguration<ED>;
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
const lodash_1 = require("../../utils/lodash");
|
||||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
/**
|
||||
* 合并引入模块中的checker和common
|
||||
* @param modules
|
||||
* @returns
|
||||
*/
|
||||
function combineBaseModules(...modules) {
|
||||
// 合并模块中的checker/common
|
||||
return modules.map((module) => {
|
||||
const checkers = require(`${module}/lib/checkers`).default;
|
||||
const common = require(`${module}/lib/configuration`).default;
|
||||
(0, assert_1.default)(checkers instanceof Array, `${module}模块中的checkers不是数组`);
|
||||
(0, assert_1.default)(typeof common === 'object', `${module}模块中的common配置不是对象`);
|
||||
return {
|
||||
checkers,
|
||||
common,
|
||||
};
|
||||
}).reduce((prev, current) => ({
|
||||
checkers: (0, lodash_1.mergeRecursively)(prev.checkers, current.checkers),
|
||||
common: (0, lodash_1.mergeRecursively)(prev.common, current.common),
|
||||
}));
|
||||
}
|
||||
exports.default = combineBaseModules;
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './combine.dev';
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import { AsyncContext } from "../../store/AsyncRowStore";
|
||||
import { SyncContext } from "../../store/SyncRowStore";
|
||||
import { EntityDict } from "../../types/Entity";
|
||||
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
|
||||
import { Aspect, Exportation, Importation, Routine, Timer, Trigger, Watcher } from '../../types';
|
||||
export default function combineModuleDev<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]): {
|
||||
aspectDict: Record<string, Aspect<ED, Cxt>>;
|
||||
data: { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; };
|
||||
importations: Importation<ED, keyof ED, string, Cxt>;
|
||||
exportations: Exportation<ED, keyof ED, string, Cxt>;
|
||||
watchers: Watcher<ED, keyof ED, Cxt>[];
|
||||
timers: Timer<ED, keyof ED, Cxt>[];
|
||||
startRoutines: Routine<ED, keyof ED, Cxt>[];
|
||||
triggers: Trigger<ED, keyof ED, Cxt>[];
|
||||
checkers: import("../../types").Checker<ED, keyof ED, never>[];
|
||||
common: import("../../types/Configuration").CommonConfiguration<ED>;
|
||||
};
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
const combine_common_1 = tslib_1.__importDefault(require("./combine.common"));
|
||||
const lodash_1 = require("../../utils/lodash");
|
||||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
function combineModuleDev(...modules) {
|
||||
const { checkers, common } = (0, combine_common_1.default)(...modules);
|
||||
const others = modules.map((module) => ({
|
||||
triggers: require(`${module}/lib/triggers`).default,
|
||||
aspectDict: require(`${module}/lib/aspects`).default,
|
||||
watchers: require(`${module}/lib/watchers`).default,
|
||||
timers: require(`${module}/lib/timers`).default,
|
||||
startRoutines: require(`${module}/lib/routines/start`).default,
|
||||
importations: require(`${module}/lib/ports`).importations,
|
||||
exportations: require(`${module}/lib/ports`).exportations,
|
||||
data: require(`${module}/lib/data`).default,
|
||||
})).reduce((prev, current, index) => {
|
||||
const check = (module, name) => {
|
||||
(0, assert_1.default)(typeof module.aspectDict === 'object', `${name}模块中的aspectDict不是对象`);
|
||||
(0, assert_1.default)(typeof module.data === 'object', `${name}模块中的data不是对象`);
|
||||
(0, assert_1.default)(module.exportations instanceof Array, `${name}模块中的exportations不是数组`);
|
||||
(0, assert_1.default)(module.importations instanceof Array, `${name}模块中的importations不是数组`);
|
||||
(0, assert_1.default)(module.watchers instanceof Array, `${name}模块中的watchers不是数组`);
|
||||
(0, assert_1.default)(module.timers instanceof Array, `${name}模块中的timers不是数组`);
|
||||
(0, assert_1.default)(module.triggers instanceof Array, `${name}模块中的triggers不是数组`);
|
||||
(0, assert_1.default)(module.startRoutines instanceof Array, `${name}模块中的startRoutines不是数组`);
|
||||
};
|
||||
if (index === 1) {
|
||||
check(prev, modules[0]);
|
||||
}
|
||||
check(current, modules[index]);
|
||||
// aspectDict中不应当有同名对象
|
||||
const its = (0, lodash_1.intersection)(Object.keys(prev.aspectDict), Object.keys(current.aspectDict));
|
||||
if (its.length > 0) {
|
||||
throw new Error(`模块${modules[index]}的aspectDict中,存在和其它模块同步的aspect【${its.join(',')}】,请正确处理`);
|
||||
}
|
||||
return {
|
||||
aspectDict: (0, lodash_1.mergeRecursively)(prev.aspectDict, current.aspectDict),
|
||||
data: (0, lodash_1.mergeRecursively)(prev.data, current.data),
|
||||
importations: (0, lodash_1.mergeRecursively)(prev.importations, current.importations),
|
||||
exportations: (0, lodash_1.mergeRecursively)(prev.exportations, current.exportations),
|
||||
watchers: (0, lodash_1.mergeRecursively)(prev.watchers, current.watchers),
|
||||
timers: (0, lodash_1.merge)(prev.timers, current.timers),
|
||||
startRoutines: (0, lodash_1.merge)(prev.startRoutines, current.startRoutines),
|
||||
triggers: (0, lodash_1.merge)(prev.triggers, current.triggers),
|
||||
};
|
||||
});
|
||||
return {
|
||||
checkers,
|
||||
common,
|
||||
...others,
|
||||
};
|
||||
}
|
||||
exports.default = combineModuleDev;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
tslib_1.__exportStar(require("./combine.dev"), exports);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { AsyncContext } from "../../store/AsyncRowStore";
|
||||
import { SyncContext } from "../../store/SyncRowStore";
|
||||
import { EntityDict } from "../../types/Entity";
|
||||
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
|
||||
export default function combineModuleDev<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]): {
|
||||
checkers: import("../../types").Checker<ED, keyof ED, never>[];
|
||||
common: import("../../types/Configuration").CommonConfiguration<ED>;
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
const combine_common_1 = tslib_1.__importDefault(require("./combine.common"));
|
||||
function combineModuleDev(...modules) {
|
||||
return (0, combine_common_1.default)(...modules);
|
||||
}
|
||||
exports.default = combineModuleDev;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import { AsyncContext } from "../../store/AsyncRowStore";
|
||||
import { SyncContext } from "../../store/SyncRowStore";
|
||||
import { EntityDict } from "../../types/Entity";
|
||||
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
|
||||
import { Aspect, Exportation, Importation, Routine, Timer, Trigger, Watcher } from '../../types';
|
||||
export default function combineModuleServer<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]): {
|
||||
aspectDict: Record<string, Aspect<ED, Cxt>>;
|
||||
data: { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; };
|
||||
importations: Importation<ED, keyof ED, string, Cxt>;
|
||||
exportations: Exportation<ED, keyof ED, string, Cxt>;
|
||||
watchers: Watcher<ED, keyof ED, Cxt>[];
|
||||
timers: Timer<ED, keyof ED, Cxt>[];
|
||||
startRoutines: Routine<ED, keyof ED, Cxt>[];
|
||||
triggers: Trigger<ED, keyof ED, Cxt>[];
|
||||
checkers: import("../../types").Checker<ED, keyof ED, never>[];
|
||||
common: import("../../types/Configuration").CommonConfiguration<ED>;
|
||||
};
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
const combine_common_1 = tslib_1.__importDefault(require("./combine.common"));
|
||||
const lodash_1 = require("../../utils/lodash");
|
||||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
function combineModuleServer(...modules) {
|
||||
const { checkers, common } = (0, combine_common_1.default)(...modules);
|
||||
const others = modules.map((module) => ({
|
||||
triggers: require(`${module}/lib/triggers`).default,
|
||||
aspectDict: require(`${module}/lib/aspects`).default,
|
||||
watchers: require(`${module}/lib/watchers`).default,
|
||||
timers: require(`${module}/lib/timers`).default,
|
||||
startRoutines: require(`${module}/lib/routines/start`).default,
|
||||
importations: require(`${module}/lib/ports`).importations,
|
||||
exportations: require(`${module}/lib/ports`).exportations,
|
||||
data: require(`${module}/lib/data`).default,
|
||||
})).reduce((prev, current, index) => {
|
||||
const check = (module, name) => {
|
||||
(0, assert_1.default)(typeof module.aspectDict === 'object', `${name}模块中的aspectDict不是对象`);
|
||||
(0, assert_1.default)(typeof module.data === 'object', `${name}模块中的data不是对象`);
|
||||
(0, assert_1.default)(module.exportations instanceof Array, `${name}模块中的exportations不是数组`);
|
||||
(0, assert_1.default)(module.importations instanceof Array, `${name}模块中的importations不是数组`);
|
||||
(0, assert_1.default)(module.watchers instanceof Array, `${name}模块中的watchers不是数组`);
|
||||
(0, assert_1.default)(module.timers instanceof Array, `${name}模块中的timers不是数组`);
|
||||
(0, assert_1.default)(module.triggers instanceof Array, `${name}模块中的triggers不是数组`);
|
||||
(0, assert_1.default)(module.startRoutines instanceof Array, `${name}模块中的startRoutines不是数组`);
|
||||
};
|
||||
if (index === 1) {
|
||||
check(prev, modules[0]);
|
||||
}
|
||||
check(current, modules[index]);
|
||||
// aspectDict中不应当有同名对象
|
||||
const its = (0, lodash_1.intersection)(Object.keys(prev.aspectDict), Object.keys(current.aspectDict));
|
||||
if (its.length > 0) {
|
||||
throw new Error(`模块${modules[index]}的aspectDict中,存在和其它模块同步的aspect【${its.join(',')}】,请正确处理`);
|
||||
}
|
||||
return {
|
||||
aspectDict: (0, lodash_1.mergeRecursively)(prev.aspectDict, current.aspectDict),
|
||||
data: (0, lodash_1.mergeRecursively)(prev.data, current.data),
|
||||
importations: (0, lodash_1.mergeRecursively)(prev.importations, current.importations),
|
||||
exportations: (0, lodash_1.mergeRecursively)(prev.exportations, current.exportations),
|
||||
watchers: (0, lodash_1.mergeRecursively)(prev.watchers, current.watchers),
|
||||
timers: (0, lodash_1.merge)(prev.timers, current.timers),
|
||||
startRoutines: (0, lodash_1.merge)(prev.startRoutines, current.startRoutines),
|
||||
triggers: (0, lodash_1.merge)(prev.triggers, current.triggers),
|
||||
};
|
||||
});
|
||||
return {
|
||||
checkers,
|
||||
common,
|
||||
...others,
|
||||
};
|
||||
}
|
||||
exports.default = combineModuleServer;
|
||||
|
|
@ -38,7 +38,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
|
|||
private volatileEntities: Array<keyof ED>;
|
||||
|
||||
private logger: Logger;
|
||||
private contextBuilder: (cxtString?: string) => Promise<Cxt>;
|
||||
private contextBuilder: () => Cxt;
|
||||
private onVolatileTrigger: <T extends keyof ED>(
|
||||
entity: T,
|
||||
trigger: VolatileTrigger<ED, T, Cxt>,
|
||||
|
|
@ -48,7 +48,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
|
|||
) => Promise<void>;
|
||||
|
||||
constructor(
|
||||
contextBuilder: (cxtString?: string) => Promise<Cxt>,
|
||||
contextBuilder: () => Cxt,
|
||||
logger: Logger = console,
|
||||
onVolatileTrigger?: <T extends keyof ED>(
|
||||
entity: T,
|
||||
|
|
@ -64,7 +64,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
|
|||
this.volatileEntities = [];
|
||||
this.counter = 0;
|
||||
this.onVolatileTrigger = onVolatileTrigger || (async (entity, trigger, ids, cxtStr, option) => {
|
||||
const context = await this.contextBuilder(cxtStr);
|
||||
const context = this.contextBuilder();
|
||||
await context.begin();
|
||||
try {
|
||||
await this.execVolatileTrigger(entity, trigger.name, ids, context, option);
|
||||
|
|
@ -551,7 +551,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
|
|||
$lt: timestamp,
|
||||
}
|
||||
};
|
||||
const context = await this.contextBuilder();
|
||||
const context = this.contextBuilder();
|
||||
if (context.clusterInfo?.usingCluster) {
|
||||
const { instanceCount, instanceId } = context.clusterInfo!;
|
||||
filter.$$seq$$ = {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export type ServerConfiguration<ED extends BaseEntityDict & EntityDict, Cxt exte
|
|||
type: 'mysql',
|
||||
host: string;
|
||||
database: string;
|
||||
port: number;
|
||||
port?: number;
|
||||
user: string;
|
||||
password?: string;
|
||||
connectionLimit: number;
|
||||
|
|
@ -50,8 +50,11 @@ export type AccessConfiguration = {
|
|||
bridge?: string;
|
||||
},
|
||||
http: {
|
||||
// 后台所在域名
|
||||
hostname: string;
|
||||
|
||||
// 监听端口号
|
||||
port: number;
|
||||
port?: number;
|
||||
|
||||
// 是否配用https(nginx)
|
||||
ssl?: boolean;
|
||||
|
|
@ -64,12 +67,10 @@ export type AccessConfiguration = {
|
|||
/**
|
||||
* 业务逻辑的通用配置
|
||||
*/
|
||||
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt extends AsyncContext<ED>> = {
|
||||
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict> = {
|
||||
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[];
|
||||
|
|
@ -78,6 +79,8 @@ export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt exte
|
|||
cacheKeepFreshPeriod?: number;
|
||||
};
|
||||
|
||||
export type DependencyConfiguration = string[];
|
||||
|
||||
/**
|
||||
* 渲染相关定义
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -61,4 +61,9 @@ export interface Connector<ED extends EntityDict, FrontCxt extends SyncContext<E
|
|||
url: string;
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
|
||||
// 获得所有数据(测试环境用)
|
||||
getFullData: (keys?: (keyof ED)[]) => Promise<{
|
||||
[T in keyof ED]?: ED[T]['OpSchema'][];
|
||||
}>
|
||||
}
|
||||
|
|
@ -266,4 +266,9 @@ export class SimpleConnector<ED extends EntityDict, FrontCxt extends SyncContext
|
|||
headers: headers && JSON.parse(headers),
|
||||
};
|
||||
}
|
||||
|
||||
async getFullData() {
|
||||
console.error('前后台模式下暂时不支持此操作,请到数据库查看数据');
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import intersection from 'lodash/intersection';
|
|||
import intersectionBy from 'lodash/intersectionBy';
|
||||
import omit from 'lodash/omit';
|
||||
import merge from 'lodash/merge';
|
||||
import mergeWith from 'lodash/mergeWith';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import pick from 'lodash/pick';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
|
@ -21,6 +22,22 @@ import differenceBy from 'lodash/differenceBy';
|
|||
import groupBy from 'lodash/groupBy';
|
||||
import unionBy from 'lodash/unionBy';
|
||||
import pullAll from 'lodash/pullAll';
|
||||
import assert from 'assert';
|
||||
|
||||
/**
|
||||
* merge两个对象,遇到array时使用连接合并
|
||||
* @param object
|
||||
* @param source
|
||||
* @returns
|
||||
*/
|
||||
function mergeRecursively<TObject, TSource>(object: TObject, source: TSource) {
|
||||
return mergeWith(object, source, (objValue, srcValue) => {
|
||||
if (objValue instanceof Array) {
|
||||
assert(srcValue instanceof Array, '合并的对象必须结构一致');
|
||||
return objValue.concat(srcValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
unset,
|
||||
|
|
@ -33,6 +50,8 @@ export {
|
|||
intersectionBy,
|
||||
omit,
|
||||
merge,
|
||||
mergeWith,
|
||||
mergeRecursively,
|
||||
cloneDeep,
|
||||
pick,
|
||||
isEqual,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
import { mergeRecursively } from '../../utils/lodash';
|
||||
import { AsyncContext } from "../../store/AsyncRowStore";
|
||||
import { SyncContext } from "../../store/SyncRowStore";
|
||||
import { EntityDict } from "../../types/Entity";
|
||||
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
|
||||
import { Checker } from '../../types/Auth';
|
||||
import { CommonConfiguration } from '../../types/Configuration';
|
||||
import assert from 'assert';
|
||||
|
||||
/**
|
||||
* 合并引入模块中的checker和common
|
||||
* @param modules
|
||||
* @returns
|
||||
*/
|
||||
export default function combineBaseModules<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED> | SyncContext<ED>>(...modules: string[]) {
|
||||
// 合并模块中的checker/common
|
||||
return modules.map(
|
||||
(module) => {
|
||||
const checkers = require(`${module}/lib/checkers`).default;
|
||||
const common = require(`${module}/lib/configuration`).default;
|
||||
assert(checkers instanceof Array, `${module}模块中的checkers不是数组`);
|
||||
assert(typeof common === 'object', `${module}模块中的common配置不是对象`);
|
||||
|
||||
return {
|
||||
checkers,
|
||||
common,
|
||||
};
|
||||
}
|
||||
).reduce((prev, current) => ({
|
||||
checkers: mergeRecursively(prev.checkers, current.checkers),
|
||||
common: mergeRecursively(prev.common, current.common),
|
||||
})) as {
|
||||
checkers: Array<Checker<ED, keyof ED, Cxt>>;
|
||||
common: CommonConfiguration<ED>;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
import combineBaseModules from './combine.common';
|
||||
import { intersection, merge, mergeRecursively } from '../../utils/lodash';
|
||||
import { AsyncContext } from "../../store/AsyncRowStore";
|
||||
import { SyncContext } from "../../store/SyncRowStore";
|
||||
import { EntityDict } from "../../types/Entity";
|
||||
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
|
||||
import assert from 'assert';
|
||||
import { Aspect, Exportation, Importation, Routine, Timer, Trigger, Watcher } from '../../types';
|
||||
import { RenderConfiguration } from '../../types/Configuration';
|
||||
|
||||
|
||||
export default function combineModuleDev<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]) {
|
||||
const { checkers, common } = combineBaseModules<ED, Cxt & FrontCxt>(...modules);
|
||||
|
||||
const others = modules.map(
|
||||
(module) => ({
|
||||
triggers: require(`${module}/lib/triggers`).default,
|
||||
aspectDict: require(`${module}/lib/aspects`).default,
|
||||
watchers: require(`${module}/lib/watchers`).default,
|
||||
timers: require(`${module}/lib/timers`).default,
|
||||
startRoutines: require(`${module}/lib/routines/start`).default,
|
||||
importations: require(`${module}/lib/ports`).importations,
|
||||
exportations: require(`${module}/lib/ports`).exportations,
|
||||
data: require(`${module}/lib/data`).default,
|
||||
})
|
||||
).reduce(
|
||||
(prev, current, index) => {
|
||||
const check = (module: typeof prev, name: string) => {
|
||||
assert(typeof module.aspectDict === 'object', `${name}模块中的aspectDict不是对象`);
|
||||
assert(typeof module.data === 'object', `${name}模块中的data不是对象`);
|
||||
assert(module.exportations instanceof Array, `${name}模块中的exportations不是数组`);
|
||||
assert(module.importations instanceof Array, `${name}模块中的importations不是数组`);
|
||||
assert(module.watchers instanceof Array, `${name}模块中的watchers不是数组`);
|
||||
assert(module.timers instanceof Array, `${name}模块中的timers不是数组`);
|
||||
assert(module.triggers instanceof Array, `${name}模块中的triggers不是数组`);
|
||||
assert(module.startRoutines instanceof Array, `${name}模块中的startRoutines不是数组`);
|
||||
};
|
||||
|
||||
if (index === 1) {
|
||||
check(prev, modules[0]);
|
||||
}
|
||||
check(current, modules[index]);
|
||||
// aspectDict中不应当有同名对象
|
||||
const its = intersection(Object.keys(prev.aspectDict), Object.keys(current.aspectDict));
|
||||
if (its.length > 0) {
|
||||
throw new Error(`模块${modules[index]}的aspectDict中,存在和其它模块同步的aspect【${its.join(',')}】,请正确处理`);
|
||||
}
|
||||
return {
|
||||
aspectDict: mergeRecursively(prev.aspectDict, current.aspectDict) ,
|
||||
data: mergeRecursively(prev.data, current.data),
|
||||
importations: mergeRecursively(prev.importations, current.importations),
|
||||
exportations: mergeRecursively(prev.exportations, current.exportations),
|
||||
watchers: mergeRecursively(prev.watchers, current.watchers),
|
||||
timers: merge(prev.timers, current.timers),
|
||||
startRoutines: merge(prev.startRoutines, current.startRoutines),
|
||||
triggers: merge(prev.triggers, current.triggers),
|
||||
};
|
||||
}
|
||||
) as {
|
||||
aspectDict: Record<string, Aspect<ED, Cxt>>;
|
||||
data: {
|
||||
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
|
||||
};
|
||||
importations: Importation<ED, keyof ED, string, Cxt>;
|
||||
exportations: Exportation<ED, keyof ED, string, Cxt>;
|
||||
watchers: Watcher<ED, keyof ED, Cxt>[];
|
||||
timers: Timer<ED, keyof ED, Cxt>[];
|
||||
startRoutines: Routine<ED, keyof ED, Cxt>[];
|
||||
triggers: Trigger<ED, keyof ED, Cxt>[];
|
||||
};
|
||||
|
||||
return {
|
||||
checkers,
|
||||
common,
|
||||
...others,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import combineBaseModules from './combine.common';
|
||||
import { mergeRecursively } from '../../utils/lodash';
|
||||
import { AsyncContext } from "../../store/AsyncRowStore";
|
||||
import { SyncContext } from "../../store/SyncRowStore";
|
||||
import { EntityDict } from "../../types/Entity";
|
||||
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
|
||||
import assert from 'assert';
|
||||
import { RenderConfiguration } from '../../types/Configuration';
|
||||
|
||||
|
||||
export default function combineModuleDev<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]) {
|
||||
return combineBaseModules<ED, Cxt & FrontCxt>(...modules);
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import combineBaseModules from './combine.common';
|
||||
import { intersection, merge, mergeRecursively } from '../../utils/lodash';
|
||||
import { AsyncContext } from "../../store/AsyncRowStore";
|
||||
import { SyncContext } from "../../store/SyncRowStore";
|
||||
import { EntityDict } from "../../types/Entity";
|
||||
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
|
||||
import assert from 'assert';
|
||||
import { Aspect, Exportation, Importation, Routine, Timer, Trigger, Watcher } from '../../types';
|
||||
|
||||
|
||||
export default function combineModuleServer<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]) {
|
||||
const { checkers, common } = combineBaseModules<ED, Cxt & FrontCxt>(...modules);
|
||||
|
||||
const others = modules.map(
|
||||
(module) => ({
|
||||
triggers: require(`${module}/lib/triggers`).default,
|
||||
aspectDict: require(`${module}/lib/aspects`).default,
|
||||
watchers: require(`${module}/lib/watchers`).default,
|
||||
timers: require(`${module}/lib/timers`).default,
|
||||
startRoutines: require(`${module}/lib/routines/start`).default,
|
||||
importations: require(`${module}/lib/ports`).importations,
|
||||
exportations: require(`${module}/lib/ports`).exportations,
|
||||
data: require(`${module}/lib/data`).default,
|
||||
})
|
||||
).reduce(
|
||||
(prev, current, index) => {
|
||||
const check = (module: typeof prev, name: string) => {
|
||||
assert(typeof module.aspectDict === 'object', `${name}模块中的aspectDict不是对象`);
|
||||
assert(typeof module.data === 'object', `${name}模块中的data不是对象`);
|
||||
assert(module.exportations instanceof Array, `${name}模块中的exportations不是数组`);
|
||||
assert(module.importations instanceof Array, `${name}模块中的importations不是数组`);
|
||||
assert(module.watchers instanceof Array, `${name}模块中的watchers不是数组`);
|
||||
assert(module.timers instanceof Array, `${name}模块中的timers不是数组`);
|
||||
assert(module.triggers instanceof Array, `${name}模块中的triggers不是数组`);
|
||||
assert(module.startRoutines instanceof Array, `${name}模块中的startRoutines不是数组`);
|
||||
};
|
||||
|
||||
if (index === 1) {
|
||||
check(prev, modules[0]);
|
||||
}
|
||||
check(current, modules[index]);
|
||||
// aspectDict中不应当有同名对象
|
||||
const its = intersection(Object.keys(prev.aspectDict), Object.keys(current.aspectDict));
|
||||
if (its.length > 0) {
|
||||
throw new Error(`模块${modules[index]}的aspectDict中,存在和其它模块同步的aspect【${its.join(',')}】,请正确处理`);
|
||||
}
|
||||
return {
|
||||
aspectDict: mergeRecursively(prev.aspectDict, current.aspectDict) ,
|
||||
data: mergeRecursively(prev.data, current.data),
|
||||
importations: mergeRecursively(prev.importations, current.importations),
|
||||
exportations: mergeRecursively(prev.exportations, current.exportations),
|
||||
watchers: mergeRecursively(prev.watchers, current.watchers),
|
||||
timers: merge(prev.timers, current.timers),
|
||||
startRoutines: merge(prev.startRoutines, current.startRoutines),
|
||||
triggers: merge(prev.triggers, current.triggers),
|
||||
};
|
||||
}
|
||||
) as {
|
||||
aspectDict: Record<string, Aspect<ED, Cxt>>;
|
||||
data: {
|
||||
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
|
||||
};
|
||||
importations: Importation<ED, keyof ED, string, Cxt>;
|
||||
exportations: Exportation<ED, keyof ED, string, Cxt>;
|
||||
watchers: Watcher<ED, keyof ED, Cxt>[];
|
||||
timers: Timer<ED, keyof ED, Cxt>[];
|
||||
startRoutines: Routine<ED, keyof ED, Cxt>[];
|
||||
triggers: Trigger<ED, keyof ED, Cxt>[];
|
||||
};
|
||||
|
||||
return {
|
||||
checkers,
|
||||
common,
|
||||
...others,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './combine.dev';
|
||||
Loading…
Reference in New Issue