oak-general-business/lib/utils/selectionRewriter.js

190 lines
6.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rewriteSelection = rewriteSelection;
exports.rewriteOperation = rewriteOperation;
const relation_1 = require("oak-domain/lib/store/relation");
const types_1 = require("oak-domain/lib/types");
const assert_1 = require("oak-domain/lib/utils/assert");
/**
* 这个修改是不可反复做的,会产生无穷递归
* 因此只能产生新的filter结构
* @param schema
* @param entity
* @param filter2
*/
function rewriteFilter(schema, entity, filter) {
const filter2 = {};
const addOrLogic = (orLogic) => {
if (!filter2.$or) {
Object.assign(filter2, {
$or: orLogic,
});
}
else if (filter2.$and) {
filter2.$and.push({
$or: orLogic,
});
}
else {
Object.assign({
$and: [
{
$or: orLogic,
}
]
});
}
};
for (const attr in filter) {
if (attr.startsWith('#') || attr === '$text' || attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
filter2[attr] = filter[attr];
}
else if (['$and', '$or'].includes(attr)) {
filter2[attr] = filter[attr].map((ele) => rewriteFilter(schema, entity, ele));
}
else if (attr === '$not') {
Object.assign(filter2, {
$not: rewriteFilter(schema, entity, filter[attr]),
});
}
else {
/**
* 这里要处理的就是把userId受到的约束扩展到存在merge的case
* 大部分这类约束都来自relation类型的checkerauth。来自auth的由系统创建的checker一定是{ userId: xxx }的形式,但用户手写的有可能是{ user: { id: xxxx }}的形式
*/
if (attr.endsWith('Id') && attr !== 'entityId' && schema[entity].attributes[attr]?.type === 'ref') {
// 只要是指向user的ref都要处理
const rel = (0, relation_1.judgeRelation)(schema, entity, attr.slice(0, attr.length - 2));
if (rel === 'user') {
addOrLogic([
{
[attr]: filter[attr],
}, {
[attr.slice(0, attr.length - 2)]: {
userState: 'merged',
refId: filter[attr],
}
}
]);
}
else {
filter2[attr] = filter[attr];
}
}
else if (attr === 'entity' && filter[attr] === 'user') {
(0, assert_1.assert)(filter.entityId);
addOrLogic([
{
entityId: filter.entityId,
},
{
user: {
userState: 'merged',
refId: filter.entityId,
}
}
]);
}
else {
const rel = (0, relation_1.judgeRelation)(schema, entity, attr);
if (rel === 2) {
const filter3 = rewriteFilter(schema, attr, filter[attr]);
if (attr === 'user') {
Object.assign(filter2, {
[attr]: {
$or: [
filter3,
{
userState: 'merged',
ref: filter3
}
]
}
});
}
else {
Object.assign(filter2, {
[attr]: filter3,
});
}
}
else if (typeof rel === 'string') {
const filter3 = rewriteFilter(schema, rel, filter[attr]);
if (rel === 'user') {
Object.assign(filter2, {
[attr]: {
$or: [
filter3,
{
userState: 'merged',
ref: filter3
}
]
}
});
}
else {
Object.assign(filter2, {
[attr]: filter3,
});
}
}
else if (rel instanceof Array) {
const [e] = rel;
(0, assert_1.assert)(e !== 'user', '会出现一对多user的情况么');
Object.assign(filter2, {
[attr]: rewriteFilter(schema, e, filter[attr]),
});
}
else {
(0, assert_1.assert)(rel === 1);
filter2[attr] = filter[attr];
}
}
}
}
return filter2;
}
function rewriteSelection(schema, entity, selection, context, option, isAggr) {
const { filter, data } = selection;
if (filter && !filter['#oak-general-business--rewrited']) {
const filter2 = rewriteFilter(schema, entity, filter);
// 避免被重写多次
Object.assign(filter2, {
['#oak-general-business--rewrited']: true,
});
selection.filter = filter2;
}
// RewriteSelection只在入口处调用一次因此需要在这里处理一对多的projection
const rewriteProjection = (e, d) => {
for (const attr in d) {
const rel = (0, relation_1.judgeRelation)(schema, e, attr);
if (rel === 2) {
rewriteProjection(attr, d[attr]);
}
else if (typeof rel === 'string') {
rewriteProjection(rel, d[attr]);
}
else if (typeof rel === 'object' && rel instanceof Array) {
rewriteSelection(schema, rel[0], d[attr], context, option, isAggr);
}
}
};
if (!isAggr) {
rewriteProjection(entity, data);
}
return;
}
function rewriteOperation(schema, entity, operation) {
const { filter } = operation;
if (filter && !filter['#oak-general-business--rewrited']) {
const filter2 = rewriteFilter(schema, entity, filter);
// 避免被重写多次
Object.assign(filter2, {
['#oak-general-business--rewrited']: true,
});
operation.filter = filter2;
}
return;
}