feat: jsonify, inspect, to_integer, normalize_whitespace filters

This commit is contained in:
Yang Jun
2024-05-06 21:10:27 +08:00
committed by Jun Yang
parent ea0eab93d1
commit 842b45c96a
19 changed files with 258 additions and 17 deletions
+2 -4
View File
@@ -4,7 +4,7 @@ import * as urlFilters from './url'
import * as arrayFilters from './array'
import * as dateFilters from './date'
import * as stringFilters from './string'
import { Default, json, raw } from './misc'
import misc from './misc'
import { FilterImplOptions } from '../template'
export const filters: Record<string, FilterImplOptions> = {
@@ -14,7 +14,5 @@ export const filters: Record<string, FilterImplOptions> = {
...arrayFilters,
...dateFilters,
...stringFilters,
json,
raw,
default: Default
...misc
}
+28 -3
View File
@@ -2,18 +2,43 @@ import { isFalsy } from '../render/boolean'
import { identify, isArray, isString, toValue } from '../util/underscore'
import { FilterImpl } from '../template'
export function Default<T1 extends boolean, T2> (this: FilterImpl, value: T1, defaultValue: T2, ...args: Array<[string, any]>): T1 | T2 {
function defaultFilter<T1 extends boolean, T2> (this: FilterImpl, value: T1, defaultValue: T2, ...args: Array<[string, any]>): T1 | T2 {
value = toValue(value)
if (isArray(value) || isString(value)) return value.length ? value : defaultValue
if (value === false && (new Map(args)).get('allow_false')) return false as T1
return isFalsy(value, this.context) ? defaultValue : value
}
export function json (value: any, space = 0) {
function json (value: any, space = 0) {
return JSON.stringify(value, null, space)
}
export const raw = {
function inspect (value: any, space = 0) {
const ancestors: object[] = []
return JSON.stringify(value, function (this: unknown, _key: unknown, value: any) {
if (typeof value !== 'object' || value === null) return value
// `this` is the object that value is contained in, i.e., its direct parent.
while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this) ancestors.pop()
if (ancestors.includes(value)) return '[Circular]'
ancestors.push(value)
return value
}, space)
}
function to_integer (value: any) {
return Number(value)
}
const raw = {
raw: true,
handler: identify
}
export default {
default: defaultFilter,
raw,
jsonify: json,
to_integer,
json,
inspect
}
+5
View File
@@ -112,3 +112,8 @@ export function truncatewords (v: string, words = 15, o = '...') {
if (arr.length >= words) ret += o
return ret
}
export function normalize_whitespace (v: string) {
v = stringify(v)
return v.replace(/\s+/g, ' ')
}
+2 -2
View File
@@ -3,7 +3,7 @@ import { LRU, LiquidCache } from './cache'
import { FS, LookupType } from './fs'
import * as fs from './fs/fs-impl'
import { defaultOperators, Operators } from './render'
import { json } from './filters/misc'
import misc from './filters/misc'
import { escape } from './filters/html'
type OutputEscape = (value: any) => string
@@ -193,7 +193,7 @@ export function normalize (options: LiquidOptions): NormalizedFullOptions {
function getOutputEscapeFunction (nameOrFunction: OutputEscapeOption): OutputEscape {
if (nameOrFunction === 'escape') return escape
if (nameOrFunction === 'json') return json
if (nameOrFunction === 'json') return misc.json
assert(isFunction(nameOrFunction), '`outputEscape` need to be of type string or function')
return nameOrFunction
}