mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
feat(json-templates): enhance date filter handling and support non-string types
This commit is contained in:
parent
144534f170
commit
8503080803
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { parse } from '../json-templates';
|
import { parse } from '../json-templates';
|
||||||
|
import { TokenKind } from 'liquidjs';
|
||||||
describe('json-templates', () => {
|
describe('json-templates', () => {
|
||||||
it('parse json with string template', async () => {
|
it('parse json with string template', async () => {
|
||||||
const template = {
|
const template = {
|
||||||
@ -29,16 +29,18 @@ describe('json-templates', () => {
|
|||||||
describe('json-templates filters', () => {
|
describe('json-templates filters', () => {
|
||||||
it('date filters', async () => {
|
it('date filters', async () => {
|
||||||
const template = {
|
const template = {
|
||||||
|
now: '{{now}}',
|
||||||
today: '{{now | date_format: "YYYY-MM-DD"}}',
|
today: '{{now | date_format: "YYYY-MM-DD"}}',
|
||||||
yesterday: '{{now | date_subtract: 1, "day" | date_format: "YYYY-MM-DD"}}',
|
yesterday: '{{now | date_subtract: 1, "day" | date_format: "YYYY-MM-DD"}}',
|
||||||
};
|
};
|
||||||
|
|
||||||
const compiledFn = parse(template);
|
const parsed = parse(template);
|
||||||
compiledFn.parameters.some((parameter) => parameter.key === 'now');
|
const now = new Date('2025-01-01: 12:00:00');
|
||||||
const result = compiledFn({
|
const result = parsed({
|
||||||
now: new Date('2025-01-01: 12:00:00'),
|
now,
|
||||||
});
|
});
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
now,
|
||||||
today: '2025-01-01',
|
today: '2025-01-01',
|
||||||
yesterday: '2024-12-31',
|
yesterday: '2024-12-31',
|
||||||
});
|
});
|
||||||
@ -61,17 +63,31 @@ describe('json-templates filters', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('when non-string type', async () => {
|
||||||
|
class Form {}
|
||||||
|
const form = new Form();
|
||||||
|
const template = {
|
||||||
|
form: '{{form}}',
|
||||||
|
};
|
||||||
|
const result = parse(template)({
|
||||||
|
form,
|
||||||
|
});
|
||||||
|
expect(result).toEqual({
|
||||||
|
form,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('when key is undefined, ignore it', async () => {
|
it('when key is undefined, ignore it', async () => {
|
||||||
const template = {
|
const template = {
|
||||||
key1: '{{current.key1}}',
|
key1: '{{current.key1}}',
|
||||||
key2: '{{current.key2}}',
|
key2: '{{current.key2}}',
|
||||||
};
|
};
|
||||||
const result = parse(template)({
|
const result = parse(template)({
|
||||||
current: { key1: 'value1', key2: undefined },
|
current: { key1: 'value1' },
|
||||||
});
|
});
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
key1: 'value1',
|
key1: 'value1',
|
||||||
key2: '',
|
key2: undefined,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -12,9 +12,12 @@
|
|||||||
//
|
//
|
||||||
// Created by Curran Kelleher and Chrostophe Serafin.
|
// Created by Curran Kelleher and Chrostophe Serafin.
|
||||||
// Contributions from Paul Brewer and Javier Blanco Martinez.
|
// Contributions from Paul Brewer and Javier Blanco Martinez.
|
||||||
import { get } from 'lodash';
|
import { get, template } from 'lodash';
|
||||||
import liquidjsEngine from './liquidjs';
|
import liquidjsEngine from './liquidjs';
|
||||||
|
import { TokenKind } from 'liquidjs';
|
||||||
import engine from './liquidjs';
|
import engine from './liquidjs';
|
||||||
|
import raw from 'liquidjs/dist/tags/raw';
|
||||||
|
import b from 'packages/core/database/src/__tests__/fixtures/c1/b';
|
||||||
|
|
||||||
// An enhanced version of `typeof` that handles arrays and dates as well.
|
// An enhanced version of `typeof` that handles arrays and dates as well.
|
||||||
function type(value) {
|
function type(value) {
|
||||||
@ -30,25 +33,6 @@ function type(value) {
|
|||||||
return valueType;
|
return valueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a parameter object from a match result.
|
|
||||||
// e.g. "['{{foo}}']" --> { key: "foo" }
|
|
||||||
// e.g. "['{{foo:bar}}']" --> { key: "foo", defaultValue: "bar" }
|
|
||||||
function Parameter(match) {
|
|
||||||
let param;
|
|
||||||
const matchValue = match.substr(2, match.length - 4).trim();
|
|
||||||
const i = matchValue.indexOf(':');
|
|
||||||
|
|
||||||
if (i !== -1) {
|
|
||||||
param = {
|
|
||||||
key: matchValue.substr(0, i),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
param = { key: matchValue };
|
|
||||||
}
|
|
||||||
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs a template function with deduped `parameters` property.
|
// Constructs a template function with deduped `parameters` property.
|
||||||
function Template(fn, parameters) {
|
function Template(fn, parameters) {
|
||||||
fn.parameters = Array.from(new Map(parameters.map((parameter) => [parameter.key, parameter])).values());
|
fn.parameters = Array.from(new Map(parameters.map((parameter) => [parameter.key, parameter])).values());
|
||||||
@ -85,10 +69,56 @@ const parseString = (() => {
|
|||||||
// template parameter syntax such as {{foo}} or {{foo:someDefault}}.
|
// template parameter syntax such as {{foo}} or {{foo:someDefault}}.
|
||||||
|
|
||||||
return (str) => {
|
return (str) => {
|
||||||
|
const rawTemplates = liquidjsEngine.parse(str);
|
||||||
|
// const ref = {};
|
||||||
|
// rawTemplates.forEach((template) => {
|
||||||
|
// if (template.token.kind === TokenKind.Output) {
|
||||||
|
// // @ts-ignore
|
||||||
|
// const variable = template.value?.initial?.postfix;
|
||||||
|
// // @ts-ignore
|
||||||
|
// ref.variableName = variable[0].props[0].content;
|
||||||
|
// // @ts-ignore
|
||||||
|
// ref.filters = template.value?.filters.map(({ name, handler, args }) => ({
|
||||||
|
// name,
|
||||||
|
// handler,
|
||||||
|
// args: args.map((arg) => arg.content),
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
const templates = rawTemplates
|
||||||
|
.filter((rawTemplate) => rawTemplate.token.kind === TokenKind.Output)
|
||||||
|
.map((rawTemplate) => {
|
||||||
|
const fullVariables = liquidjsEngine.fullVariablesSync(rawTemplate.token.input);
|
||||||
|
return {
|
||||||
|
// @ts-ignore
|
||||||
|
variableName: fullVariables[0],
|
||||||
|
tokenBegin: rawTemplate.token.begin,
|
||||||
|
tokenEnd: rawTemplate.token.end,
|
||||||
|
// @ts-ignore
|
||||||
|
filters: rawTemplate.value?.filters.map(({ name, handler, args }) => ({
|
||||||
|
name,
|
||||||
|
handler,
|
||||||
|
args: args.map((arg) => arg.content),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
});
|
||||||
const templateFn = (context) => {
|
const templateFn = (context) => {
|
||||||
return engine.parseAndRenderSync(str, context);
|
if (templates.length === 1 && templates[0].tokenBegin === 0 && templates[0].tokenEnd === str.length) {
|
||||||
|
let value = get(context, templates[0].variableName);
|
||||||
|
if (typeof value === 'function') {
|
||||||
|
value = value();
|
||||||
|
}
|
||||||
|
if (Array.isArray(templates[0].filters)) {
|
||||||
|
return templates[0].filters.reduce((acc, filter) => filter.handler(...[acc, ...filter.args]), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return engine.renderSync(rawTemplates, context);
|
||||||
};
|
};
|
||||||
const parameters = liquidjsEngine.fullVariablesSync(str).map((variable) => ({ key: variable }));
|
|
||||||
|
// Accommodate non-string as original values.
|
||||||
|
|
||||||
|
const parameters = templates.map((template) => ({ key: template.variableName }));
|
||||||
|
|
||||||
return Template(templateFn, parameters);
|
return Template(templateFn, parameters);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user