budibase/packages/string-templates/src/helpers/index.ts

104 lines
2.8 KiB
TypeScript
Raw Normal View History

2024-02-21 19:40:50 +01:00
import Helper from "./Helper"
2024-03-19 18:47:39 +01:00
import Handlebars from "handlebars"
2024-02-21 19:40:50 +01:00
import * as externalHandlebars from "./external"
import { processJS } from "./javascript"
import {
2021-01-26 13:43:26 +01:00
HelperFunctionNames,
HelperFunctionBuiltin,
LITERAL_MARKER,
2024-02-21 19:40:50 +01:00
} from "./constants"
2024-02-22 00:39:27 +01:00
2024-02-21 19:40:50 +01:00
export { getJsHelperList } from "./list"
const HTML_SWAPS = {
"<": "&lt;",
">": "&gt;",
}
2024-02-22 11:52:50 +01:00
function isObject(value: string | any[]) {
2022-05-04 18:36:30 +02:00
if (value == null || typeof value !== "object") {
return false
}
return (
value.toString() === "[object Object]" ||
(value.length > 0 && typeof value[0] === "object")
)
}
const HELPERS = [
// external helpers
2024-02-22 11:52:50 +01:00
new Helper(HelperFunctionNames.OBJECT, (value: any) => {
2024-03-19 18:47:39 +01:00
return new Handlebars.SafeString(JSON.stringify(value))
}),
2021-10-11 15:53:55 +02:00
// javascript helper
new Helper(HelperFunctionNames.JS, processJS, false),
// this help is applied to all statements
2024-02-22 11:52:50 +01:00
new Helper(
HelperFunctionNames.ALL,
(value: string, inputs: { __opts: any }) => {
const { __opts } = inputs
if (isObject(value)) {
2024-03-19 18:47:39 +01:00
return new Handlebars.SafeString(JSON.stringify(value))
2024-02-22 11:52:50 +01:00
}
// null/undefined values produce bad results
if (__opts && __opts.onlyFound && value == null) {
return __opts.input
}
if (value == null || typeof value !== "string") {
return value == null ? "" : value
}
// TODO: check, this should always be false
if (value && (value as any).string) {
value = (value as any).string
}
2024-03-14 23:51:24 +01:00
let text: any = value
2024-02-22 11:52:50 +01:00
if (__opts && __opts.escapeNewlines) {
text = value.replace(/\n/g, "\\n")
}
2024-03-19 18:47:39 +01:00
text = new Handlebars.SafeString(text.replace(/&amp;/g, "&"))
2024-02-22 11:52:50 +01:00
if (text == null || typeof text !== "string") {
return text
}
return text.replace(/[<>]/g, (tag: string) => {
return HTML_SWAPS[tag as keyof typeof HTML_SWAPS] || tag
})
}
2024-02-22 11:52:50 +01:00
),
// adds a note for post-processor
2024-02-22 11:52:50 +01:00
new Helper(HelperFunctionNames.LITERAL, (value: any) => {
if (value === undefined) {
return ""
}
2021-01-26 13:43:26 +01:00
const type = typeof value
const outputVal = type === "object" ? JSON.stringify(value) : value
return `{{${LITERAL_MARKER} ${type}-${outputVal}}}`
2021-01-26 13:43:26 +01:00
}),
]
2024-02-21 19:40:50 +01:00
export function HelperNames() {
return Object.values(HelperFunctionNames).concat(
HelperFunctionBuiltin,
2021-01-21 18:30:51 +01:00
externalHandlebars.externalHelperNames
)
}
2024-02-22 11:52:50 +01:00
export function registerMinimum(handlebars: typeof Handlebars) {
for (let helper of HELPERS) {
helper.register(handlebars)
}
}
2024-02-22 11:52:50 +01:00
export function registerAll(handlebars: typeof Handlebars) {
2024-02-21 19:40:50 +01:00
registerMinimum(handlebars)
// register imported helpers
externalHandlebars.registerAll(handlebars)
}
2024-02-22 11:52:50 +01:00
export function unregisterAll(handlebars: any) {
for (let helper of HELPERS) {
helper.unregister(handlebars)
}
// unregister all imported helpers
externalHandlebars.unregisterAll(handlebars)
}