diff --git a/packages/core/utils/package.json b/packages/core/utils/package.json index c47e648845..22811259e7 100644 --- a/packages/core/utils/package.json +++ b/packages/core/utils/package.json @@ -14,7 +14,8 @@ "graphlib": "^2.1.8", "handlebars": "^4.7.8", "multer": "^1.4.5-lts.1", - "object-path": "^0.11.8" + "object-path": "^0.11.8", + "liquidjs": "^10.20.3" }, "gitHead": "d0b4efe4be55f8c79a98a331d99d9f8cf99021a1" } diff --git a/packages/core/utils/src/__tests__/json-templates.test.ts b/packages/core/utils/src/__tests__/json-templates.test.ts index 064f71bc1f..712cb58486 100644 --- a/packages/core/utils/src/__tests__/json-templates.test.ts +++ b/packages/core/utils/src/__tests__/json-templates.test.ts @@ -25,3 +25,17 @@ describe('json-templates', () => { }); }); }); + +describe('json-templates filters', () => { + it('format filters', async () => { + const template = { + today: '{{now | date_format: "YYYY-MM-DD"}}', + }; + const result = parse(template)({ + now: new Date('2025-01-01: 12:00:00'), + }); + expect(result).toEqual({ + today: '2025-01-01', + }); + }); +}); diff --git a/packages/core/utils/src/json-templates.ts b/packages/core/utils/src/json-templates.ts index 8e65ca6f0c..cf3a14f152 100644 --- a/packages/core/utils/src/json-templates.ts +++ b/packages/core/utils/src/json-templates.ts @@ -13,6 +13,8 @@ // Created by Curran Kelleher and Chrostophe Serafin. // Contributions from Paul Brewer and Javier Blanco Martinez. import { get } from 'lodash'; +import liquidjsEngine from './liquidjs'; +import engine from './liquidjs'; // An enhanced version of `typeof` that handles arrays and dates as well. function type(value) { @@ -39,7 +41,6 @@ function Parameter(match) { if (i !== -1) { param = { key: matchValue.substr(0, i), - defaultValue: matchValue.substr(i + 1), }; } else { param = { key: matchValue }; @@ -82,43 +83,14 @@ export function parse(value) { const parseString = (() => { // This regular expression detects instances of the // template parameter syntax such as {{foo}} or {{foo:someDefault}}. - const regex = /{{(\w|:|[\s-+.,@/()?=*_$])+}}/g; + const regex = /{{(\w|:|[\s-+.,@/()?=*_$|])+}}/g; return (str) => { - let parameters = []; - let templateFn = (context) => str; - + const templateFn = (context) => { + return engine.parseAndRenderSync(str, context); + }; + const parameters = liquidjsEngine.fullVariablesSync(str).map((variable) => ({ key: variable })); const matches = str.match(regex); - if (matches) { - parameters = matches.map(Parameter); - templateFn = (context) => { - context = context || {}; - return matches.reduce((result, match, i) => { - const parameter = parameters[i]; - let value = get(context, parameter.key); - - if (typeof value === 'undefined') { - value = parameter.defaultValue; - } - - if (typeof value === 'function') { - value = value(); - } - - // Accommodate non-string as original values. - if (matches.length === 1 && str.startsWith('{{') && str.endsWith('}}')) { - return value; - } - - // Treat Date value inside string to ISO string. - if (value instanceof Date) { - value = value.toISOString(); - } - - return result.replace(match, value == null ? '' : value); - }, str); - }; - } return Template(templateFn, parameters); }; diff --git a/packages/core/utils/src/liquidjs/filters/date.ts b/packages/core/utils/src/liquidjs/filters/date.ts new file mode 100644 index 0000000000..74d24ece10 --- /dev/null +++ b/packages/core/utils/src/liquidjs/filters/date.ts @@ -0,0 +1,25 @@ +/** + * 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 { QUnitType } from 'dayjs'; + +export function dateFormat(initialValue: any, format: string) { + return dayjs.isDayjs(initialValue) ? initialValue.format(format) : dayjs(initialValue).format(format); +} + +export function dateAdd(initialValue: any, number: number, unit: any) { + const value = dayjs.isDayjs(initialValue) ? initialValue : dayjs(initialValue); + return value.add(number, unit); +} + +export function dateSubtract(initialValue: any, number: number, unit: any) { + const value = dayjs.isDayjs(initialValue) ? initialValue : dayjs(initialValue); + return value.subtract(number, unit); +} diff --git a/packages/core/utils/src/liquidjs/filters/index.ts b/packages/core/utils/src/liquidjs/filters/index.ts new file mode 100644 index 0000000000..9dae7c1033 --- /dev/null +++ b/packages/core/utils/src/liquidjs/filters/index.ts @@ -0,0 +1,16 @@ +/** + * 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 { Liquid } from 'liquidjs'; +import { dateFormat, dateAdd, dateSubtract } from './date'; +export function registerFilters(liquid: Liquid) { + liquid.registerFilter('date_format', dateFormat); + liquid.registerFilter('date_add', dateFormat); + liquid.registerFilter('date_subtract', dateFormat); +} diff --git a/packages/core/utils/src/liquidjs/index.ts b/packages/core/utils/src/liquidjs/index.ts new file mode 100644 index 0000000000..fae57a2efb --- /dev/null +++ b/packages/core/utils/src/liquidjs/index.ts @@ -0,0 +1,16 @@ +/** + * 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 { Liquid } from 'liquidjs'; +import { registerFilters } from './filters'; +const engine = new Liquid(); + +registerFilters(engine); + +export default engine;