对新的auth设计的大量适配
This commit is contained in:
parent
fc0a391638
commit
6f41bc2b30
|
|
@ -52,9 +52,10 @@ class AppLoader extends types_1.AppLoader {
|
|||
constructor(path, contextBuilder, dbConfig) {
|
||||
super(path);
|
||||
const { storageSchema } = require(`${path}/lib/oak-app-domain/Storage`);
|
||||
const { ActionCascadePathGraph, RelationCascadePathGraph } = require(`${path}/lib/oak-app-domain/Relation`);
|
||||
this.externalDependencies = require(`${path}/lib/config/externalDependencies`).default;
|
||||
this.aspectDict = Object.assign({}, index_1.default, this.requireSth('lib/aspects/index'));
|
||||
this.dbStore = new DbStore_1.DbStore(storageSchema, contextBuilder, dbConfig);
|
||||
this.dbStore = new DbStore_1.DbStore(storageSchema, contextBuilder, dbConfig, ActionCascadePathGraph, RelationCascadePathGraph);
|
||||
this.contextBuilder = contextBuilder;
|
||||
}
|
||||
initTriggers() {
|
||||
|
|
@ -67,7 +68,8 @@ class AppLoader extends types_1.AppLoader {
|
|||
adTriggers.forEach((trigger) => this.dbStore.registerTrigger(trigger));
|
||||
checkers.forEach((checker) => this.dbStore.registerChecker(checker));
|
||||
adCheckers.forEach((checker) => this.dbStore.registerChecker(checker));
|
||||
const dynamicCheckers = (0, checkers_1.createDynamicCheckers)(this.dbStore.getSchema(), authDict);
|
||||
// todo cascadeRemoveTrigger要挪到Schema定义里
|
||||
const dynamicCheckers = (0, checkers_1.createDynamicCheckers)(this.dbStore.getSchema(), {});
|
||||
dynamicCheckers.forEach((checker) => this.dbStore.registerChecker(checker));
|
||||
const dynamicTriggers = (0, triggers_1.createDynamicTriggers)(this.dbStore.getSchema());
|
||||
dynamicTriggers.forEach((trigger) => this.dbStore.registerTrigger(trigger));
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
import { MysqlStore, MySqlSelectOption, MysqlOperateOption } from 'oak-db';
|
||||
import { EntityDict, StorageSchema, Trigger, Checker, SelectOption } from 'oak-domain/lib/types';
|
||||
import { EntityDict, StorageSchema, Trigger, Checker, SelectOption, AuthCascadePath } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { MySQLConfiguration } from 'oak-db/lib/MySQL/types/Configuration';
|
||||
import { AsyncContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
export declare class DbStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends MysqlStore<ED, Cxt> implements AsyncRowStore<ED, Cxt> {
|
||||
private executor;
|
||||
constructor(storageSchema: StorageSchema<ED>, contextBuilder: (scene?: string) => (store: DbStore<ED, Cxt>) => Promise<AsyncContext<ED>>, mysqlConfiguration: MySQLConfiguration);
|
||||
private relationAuth;
|
||||
constructor(storageSchema: StorageSchema<ED>, contextBuilder: (scene?: string) => (store: DbStore<ED, Cxt>) => Promise<Cxt>, mysqlConfiguration: MySQLConfiguration, actionCascadeGraph: AuthCascadePath<ED>[], relationCascadeGraph: AuthCascadePath<ED>[]);
|
||||
/**
|
||||
* relationAuth中需要缓存一些维表的数据
|
||||
*/
|
||||
private initRelationAuthTriggers;
|
||||
protected cascadeUpdateAsync<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: AsyncContext<ED>, option: MysqlOperateOption): Promise<import("oak-domain/lib/types").OperationResult<ED>>;
|
||||
operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: MysqlOperateOption): Promise<import("oak-domain/lib/types").OperationResult<ED>>;
|
||||
select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: MySqlSelectOption): Promise<Partial<ED[T]["Schema"]>[]>;
|
||||
|
|
|
|||
|
|
@ -3,16 +3,52 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
exports.DbStore = void 0;
|
||||
const oak_db_1 = require("oak-db");
|
||||
const TriggerExecutor_1 = require("oak-domain/lib/store/TriggerExecutor");
|
||||
const RelationAuth_1 = require("oak-domain/lib/store/RelationAuth");
|
||||
class DbStore extends oak_db_1.MysqlStore {
|
||||
executor;
|
||||
constructor(storageSchema, contextBuilder, mysqlConfiguration) {
|
||||
relationAuth;
|
||||
constructor(storageSchema, contextBuilder, mysqlConfiguration, actionCascadeGraph, relationCascadeGraph) {
|
||||
super(storageSchema, mysqlConfiguration);
|
||||
this.executor = new TriggerExecutor_1.TriggerExecutor((scene) => contextBuilder(scene)(this));
|
||||
this.relationAuth = new RelationAuth_1.RelationAuth(actionCascadeGraph, relationCascadeGraph, storageSchema);
|
||||
this.initRelationAuthTriggers(contextBuilder);
|
||||
}
|
||||
/**
|
||||
* relationAuth中需要缓存一些维表的数据
|
||||
*/
|
||||
async initRelationAuthTriggers(contextBuilder) {
|
||||
const context = await contextBuilder()(this);
|
||||
const freeActionAuths = await this.select('freeActionAuth', {
|
||||
data: {
|
||||
id: 1,
|
||||
deActions: 1,
|
||||
destEntity: 1,
|
||||
},
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
});
|
||||
this.relationAuth.setFreeActionAuths(freeActionAuths);
|
||||
const directActionAuths = await this.select('directActionAuth', {
|
||||
data: {
|
||||
id: 1,
|
||||
rootEntity: 1,
|
||||
path: 1,
|
||||
deActions: 1,
|
||||
destEntity: 1,
|
||||
},
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
});
|
||||
this.relationAuth.setDirectionActionAuths(directActionAuths);
|
||||
await context.commit();
|
||||
const triggers = this.relationAuth.getAuthDataTriggers();
|
||||
triggers.forEach((trigger) => this.registerTrigger(trigger));
|
||||
}
|
||||
async cascadeUpdateAsync(entity, operation, context, option) {
|
||||
if (!option.blockTrigger) {
|
||||
await this.executor.preOperation(entity, operation, context, option);
|
||||
}
|
||||
await this.relationAuth.checkRelationAsync(entity, operation, context);
|
||||
const result = await super.cascadeUpdateAsync(entity, operation, context, option);
|
||||
if (!option.blockTrigger) {
|
||||
await this.executor.postOperation(entity, operation, context, option);
|
||||
|
|
@ -47,6 +83,7 @@ class DbStore extends oak_db_1.MysqlStore {
|
|||
Object.assign(selection, {
|
||||
action: 'select',
|
||||
});
|
||||
await this.relationAuth.checkRelationAsync(entity, selection, context);
|
||||
if (!option.blockTrigger) {
|
||||
await this.executor.preOperation(entity, selection, context, option);
|
||||
}
|
||||
|
|
@ -75,6 +112,7 @@ class DbStore extends oak_db_1.MysqlStore {
|
|||
const selection2 = Object.assign({
|
||||
action: 'select',
|
||||
}, selection);
|
||||
await this.relationAuth.checkRelationAsync(entity, selection2, context);
|
||||
if (!option.blockTrigger) {
|
||||
await this.executor.preOperation(entity, selection2, context, option);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,6 @@
|
|||
"copyfiles": "^2.4.1",
|
||||
"ts-node": "~10.9.1",
|
||||
"tslib": "^2.4.0",
|
||||
"typescript": "~4.7.4"
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,19 +45,47 @@ export class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt extends Async
|
|||
}
|
||||
|
||||
assert(typeof sth === 'object');
|
||||
const sthOut = {};
|
||||
const sthOut: Record<string, any> = {};
|
||||
sthExternal.forEach(
|
||||
(sth2, idx) => {
|
||||
assert(typeof sth2 === 'object' && !(sth2 instanceof Array), `${join(this.path, 'node_modules', this.externalDependencies[idx], filePath)}中的default输出对象不是非数组对象,与项目对应路径的输出不一致`);
|
||||
const inter = intersection(Object.keys(sthOut), Object.keys(sth2));
|
||||
if (inter.length > 0) {
|
||||
console.warn(`${join(this.path, 'node_modules', this.externalDependencies[idx], filePath)}中的default输出对象中的key值【${inter.join(',')}】与其它对应路径输出的key值有冲突,请仔细检查避免错误`);
|
||||
inter.forEach(
|
||||
(ele) => {
|
||||
if (sth2[ele] instanceof Array && sthOut[ele]) {
|
||||
assert(sthOut[ele] instanceof Array, `${join(this.path, 'node_modules', this.externalDependencies[idx], filePath)}中的default输出对象的${ele}键值是数组,但之前的相应对象的${ele}却不是,请仔细检查以避免错误`);
|
||||
console.warn(`${join(this.path, 'node_modules', this.externalDependencies[idx], filePath)}中的default输出对象中的key值【${ele}】与其它对应路径输出的key值【${ele}】将以数组格式进行合并,请仔细检查避免错误`);
|
||||
sth2[ele].push(...sthOut[ele]);
|
||||
}
|
||||
else if (!(sth2[ele] instanceof Array) && sthOut[ele]) {
|
||||
assert(!(sthOut[ele] instanceof Array), `${join(this.path, 'node_modules', this.externalDependencies[idx], filePath)}中的default输出对象的${ele}键值不是数组,但之前的相应对象的${ele}却是,请仔细检查以避免错误`);
|
||||
console.warn(`${join(this.path, 'node_modules', this.externalDependencies[idx], filePath)}中的default输出对象中的key值【${ele}】将对与其它对应路径输出的key值【${ele}】进行覆盖,请仔细检查避免错误`);
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
Object.assign(sthOut, sth2);
|
||||
}
|
||||
);
|
||||
|
||||
const inter = intersection(Object.keys(sthOut), Object.keys(sth));
|
||||
assert(inter.length === 0, `项目${filePath}中的default输出与第三方库中的输出在键值${inter.join(',')}上冲突,请处理`);
|
||||
if (inter.length > 0) {
|
||||
inter.forEach(
|
||||
(ele) => {
|
||||
if (sth[ele] instanceof Array && sthOut[ele]) {
|
||||
assert(sthOut[ele] instanceof Array, `项目${filePath}中的default输出对象的${ele}键值是数组,但之前的相应对象的${ele}却不是,请仔细检查以避免错误`);
|
||||
console.warn(`项目${filePath}中的default输出对象中的key值【${ele}】与其它引用包该路径输出的key值【${ele}】将以数组格式进行合并,请仔细检查避免错误`);
|
||||
sth[ele].push(...sthOut[ele]);
|
||||
}
|
||||
else if (!(sth[ele] instanceof Array) && sthOut[ele]) {
|
||||
assert(!(sthOut[ele] instanceof Array), `项目${filePath}中的default输出对象的${ele}键值不是数组,但之前的相应对象的${ele}却是,请仔细检查以避免错误`);
|
||||
console.warn(`项目${filePath}中的default输出对象中的key值【${ele}】将对其它引用包该路径输出的key值【${ele}】进行覆盖,请仔细检查避免错误`);
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
Object.assign(sthOut, sth);
|
||||
return sthOut;
|
||||
}
|
||||
|
|
@ -65,9 +93,10 @@ export class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt extends Async
|
|||
constructor(path: string, contextBuilder: (scene?: string) => (store: DbStore<ED, Cxt>) => Promise<Cxt>, dbConfig: MySQLConfiguration) {
|
||||
super(path);
|
||||
const { storageSchema } = require(`${path}/lib/oak-app-domain/Storage`);
|
||||
const { ActionCascadePathGraph, RelationCascadePathGraph } = require(`${path}/lib/oak-app-domain/Relation`);
|
||||
this.externalDependencies = require(`${path}/lib/config/externalDependencies`).default;
|
||||
this.aspectDict = Object.assign({}, generalAspectDict, this.requireSth('lib/aspects/index'));
|
||||
this.dbStore = new DbStore<ED, Cxt>(storageSchema, contextBuilder, dbConfig);
|
||||
this.dbStore = new DbStore<ED, Cxt>(storageSchema, contextBuilder, dbConfig, ActionCascadePathGraph, RelationCascadePathGraph);
|
||||
this.contextBuilder = contextBuilder;
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +120,8 @@ export class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt extends Async
|
|||
(checker) => this.dbStore.registerChecker(checker)
|
||||
);
|
||||
|
||||
const dynamicCheckers = createDynamicCheckers(this.dbStore.getSchema(), authDict);
|
||||
// todo cascadeRemoveTrigger要挪到Schema定义里
|
||||
const dynamicCheckers = createDynamicCheckers(this.dbStore.getSchema(), {});
|
||||
dynamicCheckers.forEach(
|
||||
(checker) => this.dbStore.registerChecker(checker)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,24 +1,72 @@
|
|||
import { MysqlStore, MySqlSelectOption, MysqlOperateOption } from 'oak-db';
|
||||
import { EntityDict, Context, StorageSchema, Trigger, Checker, RowStore, SelectOption } from 'oak-domain/lib/types';
|
||||
import { EntityDict, Context, StorageSchema, Trigger, Checker, RowStore, SelectOption, AuthCascadePath } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { TriggerExecutor } from 'oak-domain/lib/store/TriggerExecutor';
|
||||
import { MySQLConfiguration, } from 'oak-db/lib/MySQL/types/Configuration';
|
||||
import { AsyncContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
import { RelationAuth } from 'oak-domain/lib/store/RelationAuth';
|
||||
|
||||
|
||||
export class DbStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends MysqlStore<ED, Cxt> implements AsyncRowStore<ED, Cxt> {
|
||||
private executor: TriggerExecutor<ED>;
|
||||
private relationAuth: RelationAuth<ED>;
|
||||
|
||||
constructor(storageSchema: StorageSchema<ED>, contextBuilder: (scene?: string) => (store: DbStore<ED, Cxt>) => Promise<AsyncContext<ED>>, mysqlConfiguration: MySQLConfiguration) {
|
||||
constructor(
|
||||
storageSchema: StorageSchema<ED>,
|
||||
contextBuilder: (scene?: string) => (store: DbStore<ED, Cxt>) => Promise<Cxt>,
|
||||
mysqlConfiguration: MySQLConfiguration,
|
||||
actionCascadeGraph: AuthCascadePath<ED>[],
|
||||
relationCascadeGraph: AuthCascadePath<ED>[]) {
|
||||
super(storageSchema, mysqlConfiguration);
|
||||
this.executor = new TriggerExecutor((scene) => contextBuilder(scene)(this));
|
||||
this.relationAuth = new RelationAuth(actionCascadeGraph, relationCascadeGraph, storageSchema);
|
||||
this.initRelationAuthTriggers(contextBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* relationAuth中需要缓存一些维表的数据
|
||||
*/
|
||||
private async initRelationAuthTriggers(contextBuilder: (scene?: string) => (store: DbStore<ED, Cxt>) => Promise<Cxt>) {
|
||||
const context = await contextBuilder()(this);
|
||||
await context.begin();
|
||||
|
||||
// 先direct后free,因为RelationAuth中会根据free判断是否完成
|
||||
const directActionAuths = await this.select('directActionAuth', {
|
||||
data: {
|
||||
id: 1,
|
||||
rootEntity: 1,
|
||||
path: 1,
|
||||
deActions: 1,
|
||||
destEntity: 1,
|
||||
},
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
});
|
||||
this.relationAuth.setDirectionActionAuths(directActionAuths as ED['directActionAuth']['OpSchema'][]);
|
||||
const freeActionAuths = await this.select('freeActionAuth', {
|
||||
data: {
|
||||
id: 1,
|
||||
deActions: 1,
|
||||
destEntity: 1,
|
||||
},
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
});
|
||||
this.relationAuth.setFreeActionAuths(freeActionAuths as ED['freeActionAuth']['OpSchema'][]);
|
||||
|
||||
await context.commit();
|
||||
|
||||
const triggers = this.relationAuth.getAuthDataTriggers<Cxt>();
|
||||
triggers.forEach(
|
||||
(trigger) => this.registerTrigger(trigger)
|
||||
);
|
||||
}
|
||||
|
||||
protected async cascadeUpdateAsync<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: AsyncContext<ED>, option: MysqlOperateOption) {
|
||||
if (!option.blockTrigger) {
|
||||
await this.executor.preOperation(entity, operation, context, option);
|
||||
}
|
||||
await this.relationAuth.checkRelationAsync(entity, operation, context);
|
||||
const result = await super.cascadeUpdateAsync(entity, operation, context, option);
|
||||
if (!option.blockTrigger) {
|
||||
await this.executor.postOperation(entity, operation, context, option);
|
||||
|
|
@ -66,7 +114,7 @@ export class DbStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncCo
|
|||
Object.assign(selection, {
|
||||
action: 'select',
|
||||
});
|
||||
|
||||
await this.relationAuth.checkRelationAsync(entity, selection, context);
|
||||
if (!option.blockTrigger) {
|
||||
await this.executor.preOperation(entity, selection as ED[T]['Operation'], context, option);
|
||||
}
|
||||
|
|
@ -99,6 +147,7 @@ export class DbStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncCo
|
|||
action: 'select',
|
||||
}, selection) as ED[T]['Operation'];
|
||||
|
||||
await this.relationAuth.checkRelationAsync(entity, selection2, context);
|
||||
if (!option.blockTrigger) {
|
||||
await this.executor.preOperation(entity, selection2, context, option);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue