diff --git a/lib/compiler/dependencyBuilder.js b/lib/compiler/dependencyBuilder.js index 8637b03..3a48dc6 100644 --- a/lib/compiler/dependencyBuilder.js +++ b/lib/compiler/dependencyBuilder.js @@ -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)) { diff --git a/lib/store/IntrinsicCheckers.js b/lib/store/IntrinsicCheckers.js index 58b3286..b2b5cf6 100644 --- a/lib/store/IntrinsicCheckers.js +++ b/lib/store/IntrinsicCheckers.js @@ -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) { diff --git a/lib/store/RelationAuth.js b/lib/store/RelationAuth.js index 7f725a4..1bdce47 100644 --- a/lib/store/RelationAuth.js +++ b/lib/store/RelationAuth.js @@ -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)); diff --git a/lib/types/Sync.d.ts b/lib/types/Sync.d.ts index ac0718c..3459fbc 100644 --- a/lib/types/Sync.d.ts +++ b/lib/types/Sync.d.ts @@ -38,6 +38,8 @@ export interface PushEntityDef[] = []; 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 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 { - 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) { diff --git a/src/store/RelationAuth.ts b/src/store/RelationAuth.ts index acb4c79..7fe8101 100644 --- a/src/store/RelationAuth.ts +++ b/src/store/RelationAuth.ts @@ -217,7 +217,7 @@ export class RelationAuth { 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 { 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 { } ); } + + 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)); diff --git a/src/types/Sync.ts b/src/types/Sync.ts index 067347d..1ee3ed6 100644 --- a/src/types/Sync.ts +++ b/src/types/Sync.ts @@ -47,6 +47,8 @@ export interface PushEntityDef> { 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>; // 在这个entity上需要同步的entities - pullEntities?: Array>; // 从这个entity上可能会接收到的同步entites + pullEntities?: Array>; // 从这个entity上可能会接收到的同步entities }; export interface SyncRemoteConfig> extends SyncRemoteConfigBase {