mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-01 18:52:20 +08:00
feat(plugin-workflow): add date range options to system variables (#4728)
* feat(plugin-workflow): add date range options to system variable in workflow plugin * feat(plugin-workflow): fix according to code review * feat(plugin-workflow): add more functions * feat(plugin-workflow): fix according to code review * feat(plugin-workflow): add test * feat(plugin-workflow): support india timezone * feat(plugin-workflow): fix test * feat(plugin-workflow): add ts type * feat(plugin-workflow): fix * feat(plugin-workflow): fix
This commit is contained in:
parent
86a56ef7cc
commit
512557f80a
@ -260,9 +260,15 @@ export function utc2unit(options: Utc2unitOptions) {
|
|||||||
const r = fn[unit]?.();
|
const r = fn[unit]?.();
|
||||||
return timezone ? r + timezone : r;
|
return timezone ? r + timezone : r;
|
||||||
}
|
}
|
||||||
|
type ToUnitParams = {
|
||||||
|
now?: any;
|
||||||
|
timezone?: string | number;
|
||||||
|
field?: {
|
||||||
|
timezone?: string | number;
|
||||||
|
};
|
||||||
|
};
|
||||||
export const toUnit = (unit, offset?: number) => {
|
export const toUnit = (unit, offset?: number) => {
|
||||||
return ({ now, timezone, field }) => {
|
return ({ now, timezone, field }: ToUnitParams) => {
|
||||||
if (field?.timezone) {
|
if (field?.timezone) {
|
||||||
timezone = field?.timezone;
|
timezone = field?.timezone;
|
||||||
}
|
}
|
||||||
@ -271,7 +277,7 @@ export const toUnit = (unit, offset?: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const toDays = (offset: number) => {
|
const toDays = (offset: number) => {
|
||||||
return ({ now, timezone, field }) => {
|
return ({ now, timezone, field }: ToUnitParams) => {
|
||||||
if (field?.timezone) {
|
if (field?.timezone) {
|
||||||
timezone = field?.timezone;
|
timezone = field?.timezone;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { uniqBy } from 'lodash';
|
import { uniqBy } from 'lodash';
|
||||||
|
|
||||||
import { Variable, parseCollectionName, useApp, useCompile, usePlugin } from '@nocobase/client';
|
import { Variable, parseCollectionName, useApp, useCompile, usePlugin } from '@nocobase/client';
|
||||||
@ -53,6 +54,114 @@ export type UseVariableOptions = {
|
|||||||
|
|
||||||
export const defaultFieldNames = { label: 'label', value: 'value', children: 'children' } as const;
|
export const defaultFieldNames = { label: 'label', value: 'value', children: 'children' } as const;
|
||||||
|
|
||||||
|
const getDateOptions = (t) => [
|
||||||
|
{
|
||||||
|
key: 'yesterday',
|
||||||
|
value: 'yesterday',
|
||||||
|
label: t('Yesterday'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'today',
|
||||||
|
value: 'today',
|
||||||
|
label: t('Today'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'tomorrow',
|
||||||
|
value: 'tomorrow',
|
||||||
|
label: t('Tomorrow'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'lastWeek',
|
||||||
|
value: 'lastWeek',
|
||||||
|
label: t('Last week'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'thisWeek',
|
||||||
|
value: 'thisWeek',
|
||||||
|
label: t('This week'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'nextWeek',
|
||||||
|
value: 'nextWeek',
|
||||||
|
label: t('Next week'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'lastMonth',
|
||||||
|
value: 'lastMonth',
|
||||||
|
label: t('Last month'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'thisMonth',
|
||||||
|
value: 'thisMonth',
|
||||||
|
label: t('This month'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'nextMonth',
|
||||||
|
value: 'nextMonth',
|
||||||
|
label: t('Next month'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'lastQuarter',
|
||||||
|
value: 'lastQuarter',
|
||||||
|
label: t('Last quarter'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'thisQuarter',
|
||||||
|
value: 'thisQuarter',
|
||||||
|
label: t('This quarter'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'nextQuarter',
|
||||||
|
value: 'nextQuarter',
|
||||||
|
label: t('Next quarter'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'lastYear',
|
||||||
|
value: 'lastYear',
|
||||||
|
label: t('Last year'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'thisYear',
|
||||||
|
value: 'thisYear',
|
||||||
|
label: t('This year'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'nextYear',
|
||||||
|
value: 'nextYear',
|
||||||
|
label: t('Next year'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'last7Days',
|
||||||
|
value: 'last7Days',
|
||||||
|
label: t('Last 7 days'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'next7Days',
|
||||||
|
value: 'next7Days',
|
||||||
|
label: t('Next 7 days'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'last30Days',
|
||||||
|
value: 'last30Days',
|
||||||
|
label: t('Last 30 days'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'next30Days',
|
||||||
|
value: 'next30Days',
|
||||||
|
label: t('Next 30 days'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'last90Days',
|
||||||
|
value: 'last90Days',
|
||||||
|
label: t('Last 90 days'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'next90Days',
|
||||||
|
value: 'next90Days',
|
||||||
|
label: t('Next 90 days'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export const nodesOptions = {
|
export const nodesOptions = {
|
||||||
label: `{{t("Node result", { ns: "${NAMESPACE}" })}}`,
|
label: `{{t("Node result", { ns: "${NAMESPACE}" })}}`,
|
||||||
value: '$jobsMapByNodeKey',
|
value: '$jobsMapByNodeKey',
|
||||||
@ -113,6 +222,7 @@ export const systemOptions = {
|
|||||||
label: `{{t("System variables", { ns: "${NAMESPACE}" })}}`,
|
label: `{{t("System variables", { ns: "${NAMESPACE}" })}}`,
|
||||||
value: '$system',
|
value: '$system',
|
||||||
useOptions({ types, fieldNames = defaultFieldNames }: UseVariableOptions) {
|
useOptions({ types, fieldNames = defaultFieldNames }: UseVariableOptions) {
|
||||||
|
const { t } = useTranslation();
|
||||||
return [
|
return [
|
||||||
...(!types || types.includes('date')
|
...(!types || types.includes('date')
|
||||||
? [
|
? [
|
||||||
@ -121,6 +231,12 @@ export const systemOptions = {
|
|||||||
[fieldNames.label]: lang('System time'),
|
[fieldNames.label]: lang('System time'),
|
||||||
[fieldNames.value]: 'now',
|
[fieldNames.value]: 'now',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'dateRange',
|
||||||
|
[fieldNames.label]: lang('Date range'),
|
||||||
|
[fieldNames.value]: 'dateRange',
|
||||||
|
children: getDateOptions(t),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
];
|
];
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
"System variables": "시스템 변수",
|
"System variables": "시스템 변수",
|
||||||
"System time": "시스템 시간",
|
"System time": "시스템 시간",
|
||||||
"Date variables": "날짜 변수",
|
"Date variables": "날짜 변수",
|
||||||
|
"Date range": "날짜 범위",
|
||||||
"Executed at": "실행된 시각",
|
"Executed at": "실행된 시각",
|
||||||
"Queueing": "대기 중",
|
"Queueing": "대기 중",
|
||||||
"On going": "진행 중",
|
"On going": "진행 중",
|
||||||
|
@ -104,6 +104,7 @@
|
|||||||
"System variables": "系统变量",
|
"System variables": "系统变量",
|
||||||
"System time": "系统时间",
|
"System time": "系统时间",
|
||||||
"Date variables": "日期变量",
|
"Date variables": "日期变量",
|
||||||
|
"Date range": "日期范围",
|
||||||
|
|
||||||
"Executed at": "执行于",
|
"Executed at": "执行于",
|
||||||
"Queueing": "队列中",
|
"Queueing": "队列中",
|
||||||
|
@ -11,6 +11,7 @@ import { Model, Transaction, Transactionable } from '@nocobase/database';
|
|||||||
import { appendArrayColumn } from '@nocobase/evaluators';
|
import { appendArrayColumn } from '@nocobase/evaluators';
|
||||||
import { Logger } from '@nocobase/logger';
|
import { Logger } from '@nocobase/logger';
|
||||||
import { parse } from '@nocobase/utils';
|
import { parse } from '@nocobase/utils';
|
||||||
|
import set from 'lodash/set';
|
||||||
import type Plugin from './Plugin';
|
import type Plugin from './Plugin';
|
||||||
import { EXECUTION_STATUS, JOB_STATUS } from './constants';
|
import { EXECUTION_STATUS, JOB_STATUS } from './constants';
|
||||||
import { Runner } from './instructions';
|
import { Runner } from './instructions';
|
||||||
@ -381,7 +382,7 @@ export default class Processor {
|
|||||||
node,
|
node,
|
||||||
};
|
};
|
||||||
for (const [name, fn] of this.options.plugin.functions.getEntities()) {
|
for (const [name, fn] of this.options.plugin.functions.getEntities()) {
|
||||||
systemFns[name] = fn.bind(scope);
|
set(systemFns, name, fn.bind(scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
const $scopes = {};
|
const $scopes = {};
|
||||||
|
@ -0,0 +1,628 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { Application } from '@nocobase/server';
|
||||||
|
import Database from '@nocobase/database';
|
||||||
|
import { parse } from '@nocobase/utils';
|
||||||
|
import { dateRangeFns } from '@nocobase/plugin-workflow';
|
||||||
|
import { getApp, sleep } from '@nocobase/plugin-workflow-test';
|
||||||
|
|
||||||
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
let last2days;
|
||||||
|
let yesterday;
|
||||||
|
let startOfYesterday;
|
||||||
|
let endOfYesterday;
|
||||||
|
|
||||||
|
let today;
|
||||||
|
let startOfToday;
|
||||||
|
let endOfToday;
|
||||||
|
|
||||||
|
let tomorrow;
|
||||||
|
let startOfTomorrow;
|
||||||
|
let endOfTomorrow;
|
||||||
|
|
||||||
|
let theDayAfterTomorrow;
|
||||||
|
|
||||||
|
let lastWeek;
|
||||||
|
let lastWeekFirstDay;
|
||||||
|
let lastWeekLastDay;
|
||||||
|
let thisWeekFirstDay;
|
||||||
|
let thisWeekLastDay;
|
||||||
|
let nextWeek;
|
||||||
|
let nextWeekFirstDay;
|
||||||
|
let nextWeekLastDay;
|
||||||
|
|
||||||
|
let lastMonth;
|
||||||
|
let lastMonthFirstDay;
|
||||||
|
let lastMonthLastDay;
|
||||||
|
let thisMonthFirstDay;
|
||||||
|
let thisMonthLastDay;
|
||||||
|
let nextMonth;
|
||||||
|
let nextMonthFirstDay;
|
||||||
|
let nextMonthLastDay;
|
||||||
|
|
||||||
|
let lastQuarter;
|
||||||
|
let lastQuarterFirstDay;
|
||||||
|
let lastQuarterLastDay;
|
||||||
|
let thisQuarterFirstDay;
|
||||||
|
let thisQuarterLastDay;
|
||||||
|
let nextQuarter;
|
||||||
|
let nextQuarterFirstDay;
|
||||||
|
let nextQuarterLastDay;
|
||||||
|
|
||||||
|
let lastYear;
|
||||||
|
let lastYearFirstDay;
|
||||||
|
let lastYearLastDay;
|
||||||
|
let thisYearFirstDay;
|
||||||
|
let thisYearLastDay;
|
||||||
|
let nextYear;
|
||||||
|
let nextYearFirstDay;
|
||||||
|
let nextYearLastDay;
|
||||||
|
|
||||||
|
describe('workflow > functions > system variable', () => {
|
||||||
|
let app: Application;
|
||||||
|
let db: Database;
|
||||||
|
let PostCollection;
|
||||||
|
let PostRepo;
|
||||||
|
let TagModel;
|
||||||
|
let CommentRepo;
|
||||||
|
let WorkflowModel;
|
||||||
|
let workflow;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
app = await getApp();
|
||||||
|
|
||||||
|
db = app.db;
|
||||||
|
PostCollection = db.getCollection('posts');
|
||||||
|
PostRepo = PostCollection.repository;
|
||||||
|
|
||||||
|
last2days = dayjs().tz(timezone).subtract(2, 'day');
|
||||||
|
|
||||||
|
yesterday = dayjs().tz(timezone).subtract(1, 'day');
|
||||||
|
startOfYesterday = yesterday.clone().startOf('day');
|
||||||
|
endOfYesterday = yesterday.clone().endOf('day');
|
||||||
|
|
||||||
|
today = dayjs().tz(timezone);
|
||||||
|
startOfToday = today.clone().startOf('day');
|
||||||
|
endOfToday = today.clone().endOf('day');
|
||||||
|
|
||||||
|
tomorrow = dayjs().tz(timezone).add(1, 'day');
|
||||||
|
startOfTomorrow = tomorrow.clone().startOf('day');
|
||||||
|
endOfTomorrow = tomorrow.clone().endOf('day');
|
||||||
|
|
||||||
|
theDayAfterTomorrow = dayjs().tz(timezone).add(2, 'day');
|
||||||
|
|
||||||
|
lastWeek = dayjs().tz(timezone).subtract(1, 'week');
|
||||||
|
lastWeekFirstDay = lastWeek.clone().startOf('week');
|
||||||
|
lastWeekLastDay = lastWeek.clone().endOf('week');
|
||||||
|
thisWeekFirstDay = today.clone().tz(timezone).startOf('week');
|
||||||
|
thisWeekLastDay = today.clone().endOf('week');
|
||||||
|
nextWeek = dayjs().tz(timezone).add(1, 'week');
|
||||||
|
nextWeekFirstDay = nextWeek.clone().startOf('week');
|
||||||
|
nextWeekLastDay = nextWeek.clone().endOf('week');
|
||||||
|
|
||||||
|
lastMonth = dayjs().tz(timezone).subtract(1, 'month');
|
||||||
|
lastMonthFirstDay = lastMonth.clone().startOf('month');
|
||||||
|
lastMonthLastDay = lastMonth.clone().endOf('month');
|
||||||
|
thisMonthFirstDay = today.clone().startOf('month');
|
||||||
|
thisMonthLastDay = today.clone().endOf('month');
|
||||||
|
nextMonth = dayjs().tz(timezone).add(1, 'month');
|
||||||
|
nextMonthFirstDay = nextMonth.clone().startOf('month');
|
||||||
|
nextMonthLastDay = nextMonth.clone().endOf('month');
|
||||||
|
|
||||||
|
lastQuarter = dayjs().tz(timezone).subtract(1, 'quarter');
|
||||||
|
lastQuarterFirstDay = lastQuarter.clone().startOf('quarter');
|
||||||
|
lastQuarterLastDay = lastQuarter.clone().endOf('quarter');
|
||||||
|
thisQuarterFirstDay = today.clone().startOf('quarter');
|
||||||
|
thisQuarterLastDay = today.clone().endOf('quarter');
|
||||||
|
nextQuarter = dayjs().tz(timezone).add(1, 'quarter');
|
||||||
|
nextQuarterFirstDay = nextQuarter.clone().startOf('quarter');
|
||||||
|
nextQuarterLastDay = nextQuarter.clone().endOf('quarter');
|
||||||
|
|
||||||
|
lastYear = dayjs().tz(timezone).subtract(1, 'year');
|
||||||
|
lastYearFirstDay = lastYear.clone().startOf('year');
|
||||||
|
lastYearLastDay = lastYear.clone().endOf('year');
|
||||||
|
thisYearFirstDay = today.clone().startOf('year');
|
||||||
|
thisYearLastDay = today.clone().endOf('year');
|
||||||
|
nextYear = dayjs().tz(timezone).add(1, 'year');
|
||||||
|
nextYearFirstDay = nextYear.clone().startOf('year');
|
||||||
|
nextYearLastDay = nextYear.clone().endOf('year');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => app.destroy());
|
||||||
|
|
||||||
|
describe('system variable should', () => {
|
||||||
|
it('filter yesterday record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.yesterday}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'yesterday', updatedAt: yesterday.toDate() },
|
||||||
|
{ title: 'start of yesterday', updatedAt: startOfYesterday.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of yesterday 1s',
|
||||||
|
updatedAt: startOfYesterday.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of yesterday', updatedAt: endOfYesterday.toDate() },
|
||||||
|
{ title: 'the time after end of yesterday 1s', updatedAt: endOfYesterday.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter today record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.today}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'today', updatedAt: today.toDate() },
|
||||||
|
{ title: 'start of today', updatedAt: startOfToday.toDate() },
|
||||||
|
{ title: 'the time before start of today 1s', updatedAt: startOfToday.clone().subtract(1, 's').toDate() },
|
||||||
|
{ title: 'end of today', updatedAt: endOfToday.toDate() },
|
||||||
|
{ title: 'the time after end of today 1s', updatedAt: endOfToday.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter tomorrow record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.tomorrow}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'tomorrow', updatedAt: tomorrow.toDate() },
|
||||||
|
{ title: 'start of tomorrow', updatedAt: startOfTomorrow.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of tomorrow 1s',
|
||||||
|
updatedAt: startOfTomorrow.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of tomorrow', updatedAt: endOfTomorrow.toDate() },
|
||||||
|
{ title: 'the time after end of tomorrow 1s', updatedAt: endOfTomorrow.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter last week record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.lastWeek}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'last week', updatedAt: lastWeek.toDate() },
|
||||||
|
{ title: 'start of last week', updatedAt: lastWeekFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of last week 1s',
|
||||||
|
updatedAt: lastWeekFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of last week', updatedAt: lastWeekLastDay.toDate() },
|
||||||
|
{ title: 'the time after end of last week 1s', updatedAt: lastWeekLastDay.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter this week record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.thisWeek}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'this week', updatedAt: today.toDate() },
|
||||||
|
{ title: 'start of this week', updatedAt: thisWeekFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of this week 1s',
|
||||||
|
updatedAt: thisWeekFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of this week', updatedAt: thisWeekLastDay.toDate() },
|
||||||
|
{ title: 'the time after end of this week 1s', updatedAt: thisWeekLastDay.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter next week record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.nextWeek}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'next week', updatedAt: nextWeek.toDate() },
|
||||||
|
{ title: 'start of next week', updatedAt: nextWeekFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of next week 1s',
|
||||||
|
updatedAt: nextWeekFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of next week', updatedAt: nextWeekLastDay.toDate() },
|
||||||
|
{ title: 'the time after end of next week 1s', updatedAt: nextWeekLastDay.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter last month record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.lastMonth}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'last month', updatedAt: lastMonth.toDate() },
|
||||||
|
{ title: 'start of last month', updatedAt: lastMonthFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of last month 1s',
|
||||||
|
updatedAt: lastMonthFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of last month', updatedAt: lastMonthLastDay.toDate() },
|
||||||
|
{ title: 'the time after end of last month 1s', updatedAt: lastMonthLastDay.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter this month record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.thisMonth}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'this month', updatedAt: today.toDate() },
|
||||||
|
{ title: 'start of this month', updatedAt: thisMonthFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of this month 1s',
|
||||||
|
updatedAt: thisMonthFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of this month', updatedAt: thisMonthLastDay.toDate() },
|
||||||
|
{ title: 'the time after end of this month 1s', updatedAt: thisMonthLastDay.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter next month record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.nextMonth}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'next month', updatedAt: nextMonth.toDate() },
|
||||||
|
{ title: 'start of next month', updatedAt: nextMonthFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of next month 1s',
|
||||||
|
updatedAt: nextMonthFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of next month', updatedAt: nextMonthLastDay.toDate() },
|
||||||
|
{ title: 'the time after end of next month 1s', updatedAt: nextMonthLastDay.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter last quarter record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.lastQuarter}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'last quarter', updatedAt: lastQuarter.toDate() },
|
||||||
|
{ title: 'start of last quarter', updatedAt: lastQuarterFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of last quarter 1s',
|
||||||
|
updatedAt: lastQuarterFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of last quarter', updatedAt: lastQuarterLastDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time after end of last quarter 1s',
|
||||||
|
updatedAt: lastQuarterLastDay.clone().add(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter this quarter record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.thisQuarter}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'this quarter', updatedAt: today.toDate() },
|
||||||
|
{ title: 'start of this quarter', updatedAt: thisQuarterFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of this quarter 1s',
|
||||||
|
updatedAt: thisQuarterFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of this quarter', updatedAt: thisQuarterLastDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time after end of this quarter 1s',
|
||||||
|
updatedAt: thisQuarterLastDay.clone().add(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter next quarter record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.nextQuarter}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'next quarter', updatedAt: nextQuarter.toDate() },
|
||||||
|
{ title: 'start of next quarter', updatedAt: nextQuarterFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of next quarter 1s',
|
||||||
|
updatedAt: nextQuarterFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of next quarter', updatedAt: nextQuarterLastDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time after end of next quarter 1s',
|
||||||
|
updatedAt: nextQuarterLastDay.clone().add(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter last year record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.lastYear}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'last year', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'start of last year', updatedAt: lastYearFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of last year 1s',
|
||||||
|
updatedAt: lastYearFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of last year', updatedAt: lastYearLastDay.toDate() },
|
||||||
|
{ title: 'the time after end of last year 1s', updatedAt: lastYearLastDay.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[0].title);
|
||||||
|
expect(result[1].title).toBe(posts[1].title);
|
||||||
|
expect(result[2].title).toBe(posts[3].title);
|
||||||
|
});
|
||||||
|
it('filter this year record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.thisYear}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'this year', updatedAt: today.toDate() },
|
||||||
|
{ title: 'start of this year', updatedAt: thisYearFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of this year 1s',
|
||||||
|
updatedAt: thisYearFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of this year', updatedAt: thisYearLastDay.toDate() },
|
||||||
|
{ title: 'the time after end of this year 1s', updatedAt: thisYearLastDay.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
it('filter next year record', async () => {
|
||||||
|
const filter = parse({
|
||||||
|
updatedAt: {
|
||||||
|
$dateOn: '{{$system.dateRange.nextYear}}',
|
||||||
|
},
|
||||||
|
})({
|
||||||
|
$system: { dateRange: dateRangeFns },
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await PostRepo.createMany({
|
||||||
|
records: [
|
||||||
|
{ title: 'a year ago', updatedAt: lastYear.toDate() },
|
||||||
|
{ title: 'next year', updatedAt: nextYear.toDate() },
|
||||||
|
{ title: 'start of next year', updatedAt: nextYearFirstDay.toDate() },
|
||||||
|
{
|
||||||
|
title: 'the time before start of next year 1s',
|
||||||
|
updatedAt: nextYearFirstDay.clone().subtract(1, 's').toDate(),
|
||||||
|
},
|
||||||
|
{ title: 'end of next year', updatedAt: nextYearLastDay.toDate() },
|
||||||
|
{ title: 'the time after end of next year 1s', updatedAt: nextYearLastDay.clone().add(1, 's').toDate() },
|
||||||
|
],
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const result = await PostRepo.find({ filter });
|
||||||
|
expect(result.length).toBe(3);
|
||||||
|
expect(result[0].title).toBe(posts[1].title);
|
||||||
|
expect(result[1].title).toBe(posts[2].title);
|
||||||
|
expect(result[2].title).toBe(posts[4].title);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -7,18 +7,102 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { utc2unit, getDateVars } from '@nocobase/utils';
|
||||||
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
import Plugin from '..';
|
import Plugin from '..';
|
||||||
import type { ExecutionModel, FlowNodeModel } from '../types';
|
import type { ExecutionModel, FlowNodeModel } from '../types';
|
||||||
|
|
||||||
export type CustomFunction = (this: { execution: ExecutionModel; node?: FlowNodeModel }) => any;
|
export type CustomFunction = (this: { execution: ExecutionModel; node?: FlowNodeModel }) => any;
|
||||||
|
|
||||||
|
function getTimezone() {
|
||||||
|
const offset = new Date().getTimezoneOffset();
|
||||||
|
const hours = String(Math.floor(Math.abs(offset) / 60)).padStart(2, '0');
|
||||||
|
const minutes = String(Math.abs(offset) % 60).padStart(2, '0');
|
||||||
|
const sign = offset <= 0 ? '+' : '-';
|
||||||
|
return `${sign}${hours}:${minutes}`;
|
||||||
|
}
|
||||||
|
const getRangeByDay = (offset: number) =>
|
||||||
|
utc2unit({ now: new Date(), unit: 'day', offset: offset, timezone: getTimezone() });
|
||||||
|
|
||||||
|
const getOffsetFromMS = (start, end) => Math.floor((end - start) / 1000 / 60 / 60 / 24);
|
||||||
|
|
||||||
function now() {
|
function now() {
|
||||||
return new Date();
|
return new Date();
|
||||||
}
|
}
|
||||||
|
const dateVars = getDateVars();
|
||||||
|
export const dateRangeFns = {
|
||||||
|
yesterday() {
|
||||||
|
return dateVars.yesterday({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
today() {
|
||||||
|
return dateVars.today({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
tomorrow() {
|
||||||
|
return dateVars.tomorrow({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
lastWeek() {
|
||||||
|
return dateVars.lastWeek({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
thisWeek() {
|
||||||
|
return dateVars.thisWeek({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
nextWeek() {
|
||||||
|
return dateVars.nextWeek({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
lastMonth() {
|
||||||
|
return dateVars.lastMonth({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
thisMonth() {
|
||||||
|
return dateVars.thisMonth({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
nextMonth() {
|
||||||
|
return dateVars.nextMonth({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
lastQuarter() {
|
||||||
|
return dateVars.lastQuarter({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
thisQuarter() {
|
||||||
|
return dateVars.thisQuarter({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
nextQuarter() {
|
||||||
|
return dateVars.nextQuarter({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
lastYear() {
|
||||||
|
return dateVars.lastYear({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
thisYear() {
|
||||||
|
return dateVars.thisYear({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
nextYear() {
|
||||||
|
return dateVars.nextYear({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
last7Days() {
|
||||||
|
return dateVars.last7Days({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
next7Days() {
|
||||||
|
return dateVars.next7Days({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
last30Days() {
|
||||||
|
return dateVars.last30Days({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
next30Days() {
|
||||||
|
return dateVars.next30Days({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
last90Days() {
|
||||||
|
return dateVars.last90Days({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
next90Days() {
|
||||||
|
return dateVars.next90Days({ now: new Date(), timezone: getTimezone() });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export default function ({ functions }: Plugin, more: { [key: string]: CustomFunction } = {}) {
|
export default function ({ functions }: Plugin, more: { [key: string]: CustomFunction } = {}) {
|
||||||
functions.register('now', now);
|
functions.register('now', now);
|
||||||
|
|
||||||
|
Object.keys(dateRangeFns).forEach((key) => {
|
||||||
|
functions.register(`dateRange.${key}`, dateRangeFns[key]);
|
||||||
|
});
|
||||||
|
|
||||||
for (const [name, fn] of Object.entries(more)) {
|
for (const [name, fn] of Object.entries(more)) {
|
||||||
functions.register(name, fn);
|
functions.register(name, fn);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
export * from './utils';
|
export * from './utils';
|
||||||
export * from './constants';
|
export * from './constants';
|
||||||
export * from './instructions';
|
export * from './instructions';
|
||||||
|
export * from './functions';
|
||||||
export { Trigger } from './triggers';
|
export { Trigger } from './triggers';
|
||||||
export { default as Processor } from './Processor';
|
export { default as Processor } from './Processor';
|
||||||
export { default } from './Plugin';
|
export { default } from './Plugin';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user