Merge branch 'dev' of https://gitea.51mars.com/Oak-Team/oak-domain into dev
This commit is contained in:
commit
12aeea8db6
|
|
@ -588,9 +588,17 @@ function outputFeatureIndex(dependencies, briefNames, sourceFile, printer, filen
|
|||
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([factory.createImportSpecifier(false, factory.createIdentifier("FeatureDict"), factory.createIdentifier(fdName))])), factory.createStringLiteral(dep), undefined));
|
||||
fdNames.push(fdName);
|
||||
});
|
||||
const stmt4 = statements[4], stmt5 = statements[5];
|
||||
(0, assert_1.default)(ts.isImportDeclaration(stmt4) && ts.isFunctionDeclaration(stmt5));
|
||||
const { name, parameters } = stmt5;
|
||||
let i = 0;
|
||||
while (true) {
|
||||
const stmt = statements[i];
|
||||
if (ts.isFunctionDeclaration(stmt)) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
const stmt3 = statements[i - 1], stmt4 = statements[i];
|
||||
(0, assert_1.default)(ts.isImportDeclaration(stmt3) && ts.isFunctionDeclaration(stmt4));
|
||||
const { name, parameters } = stmt4;
|
||||
(0, assert_1.default)(ts.isIdentifier(name) && name.text === 'create' && parameters.length === 1);
|
||||
const [param] = parameters;
|
||||
const { name: paramName, type } = param;
|
||||
|
|
@ -604,9 +612,9 @@ function outputFeatureIndex(dependencies, briefNames, sourceFile, printer, filen
|
|||
])
|
||||
});
|
||||
statements2 = [
|
||||
...statements.slice(0, 5),
|
||||
...statements.slice(0, i),
|
||||
...importStatements,
|
||||
...statements.slice(5)
|
||||
...statements.slice(i)
|
||||
];
|
||||
if (isModule) {
|
||||
statements2.push(factory.createFunctionDeclaration([
|
||||
|
|
@ -756,7 +764,7 @@ function tryCopyModuleTemplateFiles(cwd, dependencies, briefNames, printer) {
|
|||
const moduleTemplateDir = join(moduleDir, 'template');
|
||||
if ((0, fs_1.existsSync)(moduleTemplateDir)) {
|
||||
// data.ts中规定的初始化数据,拷贝到data目录下,并注入到data/index.ts
|
||||
const dataFile = join(moduleTemplateDir, 'data', 'data.ts');
|
||||
const dataFile = join(moduleTemplateDir, 'data.ts');
|
||||
if ((0, fs_1.existsSync)(dataFile)) {
|
||||
const prjDataFile = join(cwd, 'src', 'data', `${briefNames[idx]}Data.ts`);
|
||||
if (!(0, fs_1.existsSync)(prjDataFile)) {
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ function createAttrUpdateCheckers(schema, attrUpdateMatrix) {
|
|||
const checkers = [];
|
||||
for (const entity in attrUpdateMatrix) {
|
||||
const matrix = attrUpdateMatrix[entity];
|
||||
const updateAttrs = Object.keys(matrix);
|
||||
const updateAttrs = [types_1.UpdateAtAttribute, types_1.TriggerDataAttribute, types_1.TriggerUuidAttribute].concat(Object.keys(matrix));
|
||||
const { actions } = schema[entity];
|
||||
const updateActions = actions.filter((a) => !action_1.readOnlyActions.concat(['create', 'remove']).includes(a));
|
||||
/**
|
||||
|
|
@ -328,7 +328,7 @@ function createAttrUpdateCheckers(schema, attrUpdateMatrix) {
|
|||
throw new types_1.OakAttrCantUpdateException(entity, extras, '更新了不允许的属性');
|
||||
}
|
||||
const condition = attrs.map(ele => matrix[ele]);
|
||||
const actions = condition.map(ele => ele.actions).filter(ele => !!ele);
|
||||
const actions = condition.map(ele => ele?.actions).filter(ele => !!ele);
|
||||
const a = actions.length > 0 && (0, lodash_1.intersection)(actions.flat());
|
||||
if (a) {
|
||||
if (!a.includes(action)) {
|
||||
|
|
@ -338,10 +338,10 @@ function createAttrUpdateCheckers(schema, attrUpdateMatrix) {
|
|||
}
|
||||
}
|
||||
const filters = condition.map(ele => {
|
||||
if (typeof ele.filter === 'function') {
|
||||
if (typeof ele?.filter === 'function') {
|
||||
return ele.filter(action || 'select');
|
||||
}
|
||||
return ele.filter;
|
||||
return ele?.filter;
|
||||
}).filter(ele => !!ele);
|
||||
const f = filters.length > 0 && (0, filter_1.combineFilters)(entity, schema, filters);
|
||||
if (f) {
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ class RelationAuth {
|
|||
if (!entity2) {
|
||||
entity2 = relations[0]?.entity;
|
||||
}
|
||||
else {
|
||||
else if (relations.length) {
|
||||
(0, assert_1.default)(entity2 === relations[0]?.entity);
|
||||
}
|
||||
return relations.map(ele => ele.id);
|
||||
|
|
@ -156,6 +156,7 @@ class RelationAuth {
|
|||
const relationIds = getRelationIds();
|
||||
if (relationIds instanceof Promise) {
|
||||
return relationIds.then((ids) => {
|
||||
(0, assert_1.default)(ids.length > 0);
|
||||
return Promise.all(ids.map(ele => checkOnRelationId(entity2, ele, entityFilter))).then((value) => {
|
||||
if (intersection) {
|
||||
return !(value.includes(false));
|
||||
|
|
@ -164,6 +165,10 @@ class RelationAuth {
|
|||
});
|
||||
});
|
||||
}
|
||||
if (relationIds.length === 0) {
|
||||
// 如果没有relationId(前端cache中),直接返回false
|
||||
return false;
|
||||
}
|
||||
const value = relationIds.map(ele => checkOnRelationId(entity2, ele, entityFilter));
|
||||
if (intersection) {
|
||||
return !(value.includes(false));
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ export interface PushEntityDef<ED extends EntityDict & BaseEntityDict, T extends
|
|||
* 同步结果回调,根据接口的幂等原理,同步一定要完全成功再回调
|
||||
*/
|
||||
onSynchronized?: (result: {
|
||||
remoteEntity: keyof ED;
|
||||
remoteEntityId: string;
|
||||
action: ED[T]['Action'];
|
||||
data: ED[T]['Operation']['data'];
|
||||
rowIds: string[];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "oak-domain",
|
||||
"version": "5.1.2",
|
||||
"version": "5.1.5",
|
||||
"author": {
|
||||
"name": "XuChang"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1108,9 +1108,17 @@ function outputFeatureIndex(
|
|||
}
|
||||
);
|
||||
|
||||
const stmt4 = statements[4], stmt5 = statements[5];
|
||||
assert(ts.isImportDeclaration(stmt4) && ts.isFunctionDeclaration(stmt5));
|
||||
const { name, parameters } = stmt5;
|
||||
let i = 0;
|
||||
while (true) {
|
||||
const stmt = statements[i];
|
||||
if (ts.isFunctionDeclaration(stmt)) {
|
||||
break;
|
||||
}
|
||||
i ++;
|
||||
}
|
||||
const stmt3 = statements[i-1], stmt4 = statements[i];
|
||||
assert(ts.isImportDeclaration(stmt3) && ts.isFunctionDeclaration(stmt4));
|
||||
const { name, parameters } = stmt4;
|
||||
assert(ts.isIdentifier(name!) && name.text === 'create' && parameters.length === 1);
|
||||
const [param] = parameters;
|
||||
const { name: paramName, type } = param;
|
||||
|
|
@ -1127,9 +1135,9 @@ function outputFeatureIndex(
|
|||
});
|
||||
|
||||
statements2 = [
|
||||
...statements.slice(0, 5),
|
||||
...statements.slice(0, i),
|
||||
...importStatements,
|
||||
...statements.slice(5)
|
||||
...statements.slice(i)
|
||||
];
|
||||
if (isModule) {
|
||||
statements2.push(
|
||||
|
|
@ -1442,7 +1450,7 @@ function tryCopyModuleTemplateFiles(
|
|||
const moduleTemplateDir = join(moduleDir, 'template');
|
||||
if (existsSync(moduleTemplateDir)) {
|
||||
// data.ts中规定的初始化数据,拷贝到data目录下,并注入到data/index.ts
|
||||
const dataFile = join(moduleTemplateDir, 'data', 'data.ts');
|
||||
const dataFile = join(moduleTemplateDir, 'data.ts');
|
||||
if (existsSync(dataFile)) {
|
||||
const prjDataFile = join(cwd, 'src', 'data', `${briefNames[idx]}Data.ts`);
|
||||
if (!existsSync(prjDataFile)) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ActionDefDict, 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, UpdateAtAttribute, TriggerDataAttribute, TriggerUuidAttribute } from "../types";
|
||||
import { SyncContext } from "./SyncRowStore";
|
||||
import { AsyncContext } from "./AsyncRowStore";
|
||||
import { pick, intersection, difference, omit } from '../utils/lodash';
|
||||
|
|
@ -326,7 +326,7 @@ function cascadelyCheckUpdateFilters<ED extends EntityDict & BaseEntityDict, T e
|
|||
if (!f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 此时看应用了success的attributes更新后,能否消除掉f中的部分条件
|
||||
const result = analyzeFilterRelation(entity, schema, successAttrFilter, f, true);
|
||||
if (typeof result === 'boolean') {
|
||||
|
|
@ -380,7 +380,7 @@ function createAttrUpdateCheckers<ED extends EntityDict & BaseEntityDict, Cxt ex
|
|||
const checkers: Checker<ED, keyof ED, Cxt | FrontCxt>[] = [];
|
||||
for (const entity in attrUpdateMatrix) {
|
||||
const matrix = attrUpdateMatrix[entity]!;
|
||||
const updateAttrs = Object.keys(matrix) as string[];
|
||||
const updateAttrs = [UpdateAtAttribute, TriggerDataAttribute, TriggerUuidAttribute].concat(Object.keys(matrix));
|
||||
const { actions } = schema[entity];
|
||||
const updateActions = actions.filter(
|
||||
(a) => !readOnlyActions.concat(['create', 'remove']).includes(a)
|
||||
|
|
@ -400,7 +400,7 @@ function createAttrUpdateCheckers<ED extends EntityDict & BaseEntityDict, Cxt ex
|
|||
throw new OakAttrCantUpdateException(entity, extras, '更新了不允许的属性');
|
||||
}
|
||||
const condition = attrs.map(ele => matrix[ele]!);
|
||||
const actions = condition.map(ele => ele.actions).filter(ele => !!ele);
|
||||
const actions = condition.map(ele => ele?.actions).filter(ele => !!ele);
|
||||
const a = actions.length > 0 && intersection(actions.flat());
|
||||
if (a) {
|
||||
if (!a.includes(action)) {
|
||||
|
|
@ -412,10 +412,10 @@ function createAttrUpdateCheckers<ED extends EntityDict & BaseEntityDict, Cxt ex
|
|||
}
|
||||
}
|
||||
const filters = condition.map(ele => {
|
||||
if (typeof ele.filter === 'function') {
|
||||
if (typeof ele?.filter === 'function') {
|
||||
return ele.filter(action || 'select');
|
||||
}
|
||||
return ele.filter;
|
||||
return ele?.filter;
|
||||
}).filter(ele => !!ele);
|
||||
const f = filters.length > 0 && combineFilters(entity, schema, filters);
|
||||
if (f) {
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict> {
|
|||
if (!entity2) {
|
||||
entity2 = relations[0]?.entity;
|
||||
}
|
||||
else {
|
||||
else if (relations.length) {
|
||||
assert(entity2 === relations[0]?.entity);
|
||||
}
|
||||
return relations.map(ele => ele.id!);
|
||||
|
|
@ -227,6 +227,7 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict> {
|
|||
if (relationIds instanceof Promise) {
|
||||
return relationIds.then(
|
||||
(ids) => {
|
||||
assert(ids.length > 0);
|
||||
return Promise.all(
|
||||
ids.map(
|
||||
ele => checkOnRelationId(entity2!, ele, entityFilter)
|
||||
|
|
@ -242,6 +243,11 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict> {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (relationIds.length === 0) {
|
||||
// 如果没有relationId(前端cache中),直接返回false
|
||||
return false;
|
||||
}
|
||||
const value = relationIds.map(ele => checkOnRelationId(entity2!, ele, entityFilter)) as boolean[];
|
||||
if (intersection) {
|
||||
return !(value.includes(false));
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ export interface PushEntityDef<ED extends EntityDict & BaseEntityDict, T extends
|
|||
* 同步结果回调,根据接口的幂等原理,同步一定要完全成功再回调
|
||||
*/
|
||||
onSynchronized?: (result: {
|
||||
remoteEntity: keyof ED;
|
||||
remoteEntityId: string;
|
||||
action: ED[T]['Action'],
|
||||
data: ED[T]['Operation']['data'];
|
||||
rowIds: string[];
|
||||
|
|
@ -57,10 +59,10 @@ export interface PushEntityDef<ED extends EntityDict & BaseEntityDict, T extends
|
|||
export interface SyncRemoteConfigBase<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> {
|
||||
entity: keyof ED; // 对方结点所关联的entity名称(两边一致)
|
||||
endpoint?: string; // 对方结点同步数据的endpoint,默认为/sync/:entity
|
||||
pathToUser?: string; // entity到对应remote user的路径(如果remote user和enitity之间是relation关系则为空)
|
||||
pathToUser?: string; // entity到对应remote user的路径(如果remote user和entity之间是relation关系则为空)
|
||||
relationName?: string; // 如果remote user和entity之间是relation关系,此处表达的是relation名称)
|
||||
pushEntities?: Array<PushEntityDef<ED, keyof ED, Cxt>>; // 在这个entity上需要同步的entities
|
||||
pullEntities?: Array<PullEntityDef<ED, keyof ED, Cxt>>; // 从这个entity上可能会接收到的同步entites
|
||||
pullEntities?: Array<PullEntityDef<ED, keyof ED, Cxt>>; // 从这个entity上可能会接收到的同步entities
|
||||
};
|
||||
|
||||
export interface SyncRemoteConfig<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends SyncRemoteConfigBase<ED, Cxt> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue