tachybase_todo/packages/plugins/workflow/src/server/migrations/20230221071831-calculation-expression.ts
chenos 883f1e6fd1
fix: eslint (#1759)
* fix: eslint

* fix: eslint --fix

* fix: changelog
2023-04-25 13:12:14 +08:00

103 lines
2.2 KiB
TypeScript

import { Migration } from '@nocobase/server';
function addQuote(v) {
if (typeof v !== 'string') {
return v;
}
if (v.match(/^{{\s*([^{}]+)\s*}}$/)) {
return v;
}
return `'${v}'`;
}
const calculatorsMap = {
equal: '==',
'===': '==',
notEqual: '!=',
'!==': '!=',
gt: '>',
gte: '>=',
lt: '<',
lte: '<=',
add: '+',
minus: '-',
multiple: '*',
divide: '/',
mod: '%',
includes(a, b) {
return `SEARCH(${b}, ${a}) >= 0`;
},
notIncludes(a, b) {
return `SEARCH(${b}, ${a}) < 0`;
},
startsWith(a, b) {
return `SEARCH(${b}, ${a}) == 0`;
},
endsWith(a, b) {
return `RIGHT(${a}, LEN(${b})) == ${b}`;
},
notStartsWith(a, b) {
return `SEARCH(${b}, ${a}) != 0`;
},
notEndsWith(a, b) {
return `RIGHT(${a}, LEN(${b})) != ${b}`;
},
concat(a, b) {
return `CONCATENATE(${a}, ${b})`;
},
};
function migrateConfig({ calculation, ...config }: any = {}) {
if (!calculation?.calculator || !calculation?.operands?.length) {
return config;
}
const calculator = calculatorsMap[calculation.calculator];
const operands = (calculator.operands ?? []).map((operand) => addQuote(operand));
return {
engine: 'formula.js',
expression:
typeof calculator === 'function'
? calculator(...operands)
: operands.join(` ${calculator ?? calculation.calculator} `),
};
}
export default class extends Migration {
async up() {
const match = await this.app.version.satisfies('<0.9.0-alpha.3');
if (!match) {
return;
}
const NodeRepo = this.context.db.getRepository('flow_nodes');
await this.context.db.sequelize.transaction(async (transaction) => {
const nodes = await NodeRepo.find({
filter: {
type: 'calculation',
},
transaction,
});
console.log('%d nodes need to be migrated.', nodes.length);
await nodes.reduce(
(promise, node) =>
promise.then(() => {
return node.update(
{
config: migrateConfig(node.config),
},
{
transaction,
},
);
}),
Promise.resolve(),
);
});
}
}