fix(evaluators): fix date result in variable (#1781)

This commit is contained in:
Junyi 2023-04-28 13:50:35 +07:00 committed by GitHub
parent 23ad507261
commit 4db3b283b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 9 deletions

View File

@ -36,7 +36,7 @@ const ConstantTypes = {
string: {
label: `{{t("String")}}`,
value: 'string',
component({ onChange, value }) {
component: function StringComponent({ onChange, value }) {
return <AntInput value={value} onChange={(ev) => onChange(ev.target.value)} />;
},
default: '',
@ -44,7 +44,7 @@ const ConstantTypes = {
number: {
label: '{{t("Number")}}',
value: 'number',
component({ onChange, value }) {
component: function NumberComponent({ onChange, value }) {
return <InputNumber value={value} onChange={onChange} />;
},
default: 0,
@ -52,7 +52,7 @@ const ConstantTypes = {
boolean: {
label: `{{t("Boolean")}}`,
value: 'boolean',
component: function Com({ onChange, value }) {
component: function BooleanComponent({ onChange, value }) {
const { t } = useTranslation();
return (
<Select
@ -71,7 +71,7 @@ const ConstantTypes = {
date: {
label: '{{t("Date")}}',
value: 'date',
component({ onChange, value }) {
component: function DateComponent({ onChange, value }) {
return (
<DatePicker
value={moment(value)}
@ -89,7 +89,7 @@ const ConstantTypes = {
null: {
label: `{{t("Null")}}`,
value: 'null',
component: function Com() {
component: function NullComponent() {
const { t } = useTranslation();
return <AntInput readOnly placeholder={t('Null')} className="null-value" />;
},

View File

@ -27,6 +27,15 @@ describe('evaluate', () => {
expect(result).toBe(1);
});
it('function result Date', () => {
const result = formulaEval('{{a}}', {
a() {
return new Date();
},
});
expect(result).toMatch(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?Z/);
});
it('number path to array item 0 (math.js)', () => {
expect(() => mathEval('{{a.0}}', { a: [1, 2, 3] })).toThrow();
});

View File

@ -55,6 +55,10 @@ export function evaluate(this: Evaluator, expression: string, scope: Scope = {})
result = replaceNumberIndex(v, context);
}
if (result instanceof Date) {
result = `'${result.toISOString()}'`;
}
return ` ${result} `;
});
return this(exp, context);

View File

@ -16,7 +16,7 @@ import JobModel from './models/Job';
import WorkflowModel from './models/Workflow';
import Processor from './Processor';
import initTriggers, { Trigger } from './triggers';
import initFunctions from './functions';
import initFunctions, { CustomFunction } from './functions';
import { createLogger, Logger, LoggerOptions, getLoggerLevel, getLoggerFilePath } from '@nocobase/logger';
type Pending = [ExecutionModel, JobModel?];
@ -25,7 +25,7 @@ type ID = number | string;
export default class WorkflowPlugin extends Plugin {
instructions: Registry<Instruction> = new Registry();
triggers: Registry<Trigger> = new Registry();
functions: Registry<Function> = new Registry();
functions: Registry<CustomFunction> = new Registry();
private executing: ExecutionModel | null = null;
private pending: Pending[] = [];
private events: [WorkflowModel, any, { context?: any }][] = [];
@ -193,7 +193,7 @@ export default class WorkflowPlugin extends Plugin {
}
}
public trigger(workflow: WorkflowModel, context: Object, options: { context?: any } = {}): void {
public trigger(workflow: WorkflowModel, context: { [key: string]: any }, options: { context?: any } = {}): void {
// `null` means not to trigger
if (context == null) {
return;

View File

@ -130,6 +130,24 @@ describe('workflow > instructions > calculation', () => {
const [job] = await execution.getJobs();
expect(job.result).toBe(2);
});
it('$system.now()', async () => {
const n1 = await workflow.createNode({
type: 'calculation',
config: {
engine: 'math.js',
expression: '{{$system.now}}',
},
});
const post = await PostRepo.create({ values: { title: 't1' } });
await sleep(500);
const [execution] = await workflow.getExecutions();
const [job] = await execution.getJobs();
expect(job.result).toMatch(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?Z/);
});
});
describe('formula.js', () => {

View File

@ -1,10 +1,14 @@
import Plugin from '..';
import ExecutionModel from '../models/Execution';
import FlowNodeModel from '../models/FlowNode';
export type CustomFunction = (this: { execution: ExecutionModel; node?: FlowNodeModel }) => any;
function now() {
return new Date();
}
export default function ({ functions }: Plugin, more: { [key: string]: Function } = {}) {
export default function ({ functions }: Plugin, more: { [key: string]: CustomFunction } = {}) {
functions.register('now', now);
for (const [name, fn] of Object.entries(more)) {