More types
This commit is contained in:
parent
566c4e5c17
commit
c60baaa012
|
@ -1,31 +1,34 @@
|
|||
export default class Helper {
|
||||
private name
|
||||
private fn
|
||||
private useValueFallback
|
||||
private name: any
|
||||
private fn: any
|
||||
private useValueFallback: boolean
|
||||
|
||||
constructor(name, fn, useValueFallback = true) {
|
||||
constructor(name: string, fn: any, useValueFallback = true) {
|
||||
this.name = name
|
||||
this.fn = fn
|
||||
this.useValueFallback = useValueFallback
|
||||
}
|
||||
|
||||
register(handlebars) {
|
||||
register(handlebars: typeof Handlebars) {
|
||||
// wrap the function so that no helper can cause handlebars to break
|
||||
handlebars.registerHelper(this.name, (value, info) => {
|
||||
let context = {}
|
||||
if (info && info.data && info.data.root) {
|
||||
context = info.data.root
|
||||
handlebars.registerHelper(
|
||||
this.name,
|
||||
(value: any, info: { data: { root: {} } }) => {
|
||||
let context = {}
|
||||
if (info && info.data && info.data.root) {
|
||||
context = info.data.root
|
||||
}
|
||||
const result = this.fn(value, context)
|
||||
if (result == null) {
|
||||
return this.useValueFallback ? value : null
|
||||
} else {
|
||||
return result
|
||||
}
|
||||
}
|
||||
const result = this.fn(value, context)
|
||||
if (result == null) {
|
||||
return this.useValueFallback ? value : null
|
||||
} else {
|
||||
return result
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
unregister(handlebars) {
|
||||
unregister(handlebars: { unregisterHelper: any }) {
|
||||
handlebars.unregisterHelper(this.name)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import helpers from "@budibase/handlebars-helpers"
|
||||
const helpers = require("@budibase/handlebars-helpers")
|
||||
import { date, duration } from "./date"
|
||||
import { HelperFunctionBuiltin } from "./constants"
|
||||
|
||||
|
@ -27,7 +27,7 @@ const ADDED_HELPERS = {
|
|||
export const externalCollections = EXTERNAL_FUNCTION_COLLECTIONS
|
||||
export const addedHelpers = ADDED_HELPERS
|
||||
|
||||
export function registerAll(handlebars) {
|
||||
export function registerAll(handlebars: typeof Handlebars) {
|
||||
for (let [name, helper] of Object.entries(ADDED_HELPERS)) {
|
||||
handlebars.registerHelper(name, helper)
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ export function registerAll(handlebars) {
|
|||
externalHelperNames = externalNames.concat(Object.keys(ADDED_HELPERS))
|
||||
}
|
||||
|
||||
export function unregisterAll(handlebars) {
|
||||
export function unregisterAll(handlebars: typeof Handlebars) {
|
||||
for (let name of Object.keys(ADDED_HELPERS)) {
|
||||
handlebars.unregisterHelper(name)
|
||||
}
|
||||
|
@ -65,4 +65,4 @@ export function unregisterAll(handlebars) {
|
|||
externalHelperNames = []
|
||||
}
|
||||
|
||||
export let externalHelperNames = []
|
||||
export let externalHelperNames: any[] = []
|
||||
|
|
|
@ -15,7 +15,7 @@ const HTML_SWAPS = {
|
|||
">": ">",
|
||||
}
|
||||
|
||||
function isObject(value) {
|
||||
function isObject(value: string | any[]) {
|
||||
if (value == null || typeof value !== "object") {
|
||||
return false
|
||||
}
|
||||
|
@ -27,42 +27,45 @@ function isObject(value) {
|
|||
|
||||
const HELPERS = [
|
||||
// external helpers
|
||||
new Helper(HelperFunctionNames.OBJECT, value => {
|
||||
new Helper(HelperFunctionNames.OBJECT, (value: any) => {
|
||||
return new SafeString(JSON.stringify(value))
|
||||
}),
|
||||
// javascript helper
|
||||
new Helper(HelperFunctionNames.JS, processJS, false),
|
||||
// this help is applied to all statements
|
||||
new Helper(HelperFunctionNames.ALL, (value, inputs) => {
|
||||
const { __opts } = inputs
|
||||
if (isObject(value)) {
|
||||
return new SafeString(JSON.stringify(value))
|
||||
new Helper(
|
||||
HelperFunctionNames.ALL,
|
||||
(value: string, inputs: { __opts: any }) => {
|
||||
const { __opts } = inputs
|
||||
if (isObject(value)) {
|
||||
return new SafeString(JSON.stringify(value))
|
||||
}
|
||||
// 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
|
||||
}
|
||||
let text = value
|
||||
if (__opts && __opts.escapeNewlines) {
|
||||
text = value.replace(/\n/g, "\\n")
|
||||
}
|
||||
text = new SafeString(text.replace(/&/g, "&")).toString()
|
||||
if (text == null || typeof text !== "string") {
|
||||
return text
|
||||
}
|
||||
return text.replace(/[<>]/g, (tag: string) => {
|
||||
return HTML_SWAPS[tag as keyof typeof HTML_SWAPS] || tag
|
||||
})
|
||||
}
|
||||
// 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
|
||||
}
|
||||
let text = value
|
||||
if (__opts && __opts.escapeNewlines) {
|
||||
text = value.replace(/\n/g, "\\n")
|
||||
}
|
||||
text = new SafeString(text.replace(/&/g, "&"))
|
||||
if (text == null || typeof text !== "string") {
|
||||
return text
|
||||
}
|
||||
return text.replace(/[<>]/g, tag => {
|
||||
return HTML_SWAPS[tag] || tag
|
||||
})
|
||||
}),
|
||||
),
|
||||
// adds a note for post-processor
|
||||
new Helper(HelperFunctionNames.LITERAL, value => {
|
||||
new Helper(HelperFunctionNames.LITERAL, (value: any) => {
|
||||
if (value === undefined) {
|
||||
return ""
|
||||
}
|
||||
|
@ -79,19 +82,19 @@ export function HelperNames() {
|
|||
)
|
||||
}
|
||||
|
||||
export function registerMinimum(handlebars) {
|
||||
export function registerMinimum(handlebars: typeof Handlebars) {
|
||||
for (let helper of HELPERS) {
|
||||
helper.register(handlebars)
|
||||
}
|
||||
}
|
||||
|
||||
export function registerAll(handlebars) {
|
||||
export function registerAll(handlebars: typeof Handlebars) {
|
||||
registerMinimum(handlebars)
|
||||
// register imported helpers
|
||||
externalHandlebars.registerAll(handlebars)
|
||||
}
|
||||
|
||||
export function unregisterAll(handlebars) {
|
||||
export function unregisterAll(handlebars: any) {
|
||||
for (let helper of HELPERS) {
|
||||
helper.unregister(handlebars)
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ function testObject(object: any) {
|
|||
/**
|
||||
* Creates a HBS template function for a given string, and optionally caches it.
|
||||
*/
|
||||
let templateCache = {}
|
||||
function createTemplate(string: string, opts: ProcessOptions) {
|
||||
const templateCache: Record<string, HandlebarsTemplateDelegate<any>> = {}
|
||||
function createTemplate(string: string, opts?: ProcessOptions) {
|
||||
opts = { ...defaultOpts, ...opts }
|
||||
|
||||
// Finalising adds a helper, can't do this with no helpers
|
||||
|
@ -87,7 +87,7 @@ export async function processObject(
|
|||
object: { [x: string]: any },
|
||||
context: object,
|
||||
opts?: { noHelpers?: boolean; escapeNewlines?: boolean; onlyFound?: boolean }
|
||||
) {
|
||||
): Promise<object | Array<any>> {
|
||||
testObject(object)
|
||||
for (let key of Object.keys(object || {})) {
|
||||
if (object[key] != null) {
|
||||
|
@ -114,7 +114,7 @@ export async function processString(
|
|||
string: string,
|
||||
context: object,
|
||||
opts?: ProcessOptions
|
||||
) {
|
||||
): Promise<string> {
|
||||
// TODO: carry out any async calls before carrying out async call
|
||||
return processStringSync(string, context, opts)
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ export function processObjectSync(
|
|||
object: { [x: string]: any },
|
||||
context: any,
|
||||
opts: any
|
||||
) {
|
||||
): object | Array<any> {
|
||||
testObject(object)
|
||||
for (let key of Object.keys(object || {})) {
|
||||
let val = object[key]
|
||||
|
@ -157,7 +157,7 @@ export function processStringSync(
|
|||
string: string,
|
||||
context: object,
|
||||
opts?: ProcessOptions
|
||||
) {
|
||||
): string {
|
||||
// Take a copy of input in case of error
|
||||
const input = string
|
||||
if (typeof string !== "string") {
|
||||
|
@ -220,7 +220,7 @@ export function disableEscaping(string: string) {
|
|||
* @param {string} property The property which is to be wrapped.
|
||||
* @returns {string} The wrapped property ready to be added to a templating string.
|
||||
*/
|
||||
export function makePropSafe(property: any) {
|
||||
export function makePropSafe(property: any): string {
|
||||
return `[${property}]`.replace("[[", "[").replace("]]", "]")
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ export function makePropSafe(property: any) {
|
|||
* @param [opts] optional - specify some options for processing.
|
||||
* @returns {boolean} Whether or not the input string is valid.
|
||||
*/
|
||||
export function isValid(string: any, opts?: any) {
|
||||
export function isValid(string: any, opts?: any): boolean {
|
||||
const validCases = [
|
||||
"string",
|
||||
"number",
|
||||
|
@ -251,7 +251,7 @@ export function isValid(string: any, opts?: any) {
|
|||
})
|
||||
template(context)
|
||||
return true
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
const msg = err && err.message ? err.message : err
|
||||
if (!msg) {
|
||||
return false
|
||||
|
@ -281,7 +281,7 @@ export function getManifest() {
|
|||
* @param handlebars the HBS expression to check
|
||||
* @returns {boolean} whether the expression is JS or not
|
||||
*/
|
||||
export function isJSBinding(handlebars: any) {
|
||||
export function isJSBinding(handlebars: any): boolean {
|
||||
return decodeJSBinding(handlebars) != null
|
||||
}
|
||||
|
||||
|
@ -290,7 +290,7 @@ export function isJSBinding(handlebars: any) {
|
|||
* @param javascript the JS code to encode
|
||||
* @returns {string} the JS HBS expression
|
||||
*/
|
||||
export function encodeJSBinding(javascript: string) {
|
||||
export function encodeJSBinding(javascript: string): string {
|
||||
return `{{ js "${btoa(javascript)}" }}`
|
||||
}
|
||||
|
||||
|
@ -299,7 +299,7 @@ export function encodeJSBinding(javascript: string) {
|
|||
* @param handlebars the JS HBS expression
|
||||
* @returns {string|null} the raw JS code
|
||||
*/
|
||||
export function decodeJSBinding(handlebars: string) {
|
||||
export function decodeJSBinding(handlebars: string): string | null {
|
||||
if (!handlebars || typeof handlebars !== "string") {
|
||||
return null
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ export function decodeJSBinding(handlebars: string) {
|
|||
* @param {string[]} strings The strings to look for.
|
||||
* @returns {boolean} Will return true if all strings found in HBS statement.
|
||||
*/
|
||||
export function doesContainStrings(template: string, strings: any[]) {
|
||||
export function doesContainStrings(template: string, strings: any[]): boolean {
|
||||
let regexp = new RegExp(FIND_HBS_REGEX)
|
||||
let matches = template.match(regexp)
|
||||
if (matches == null) {
|
||||
|
@ -333,7 +333,7 @@ export function doesContainStrings(template: string, strings: any[]) {
|
|||
for (let match of matches) {
|
||||
let hbs = match
|
||||
if (isJSBinding(match)) {
|
||||
hbs = decodeJSBinding(match)
|
||||
hbs = decodeJSBinding(match)!
|
||||
}
|
||||
let allFound = true
|
||||
for (let string of strings) {
|
||||
|
@ -354,7 +354,7 @@ export function doesContainStrings(template: string, strings: any[]) {
|
|||
* @param {string} string The string to search within.
|
||||
* @return {string[]} The found HBS blocks.
|
||||
*/
|
||||
export function findHBSBlocks(string: string) {
|
||||
export function findHBSBlocks(string: string): string[] {
|
||||
if (!string || typeof string !== "string") {
|
||||
return []
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ export function findHBSBlocks(string: string) {
|
|||
* @param {string} string The word or sentence to search for.
|
||||
* @returns {boolean} The this return true if the string is found, false if not.
|
||||
*/
|
||||
export function doesContainString(template: any, string: any) {
|
||||
export function doesContainString(template: any, string: any): boolean {
|
||||
return doesContainStrings(template, [string])
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ export function convertToJS(hbs: string) {
|
|||
const blocks = findHBSBlocks(hbs)
|
||||
let js = "return `",
|
||||
prevBlock: string | null = null
|
||||
const variables = {}
|
||||
const variables: Record<string, any> = {}
|
||||
if (blocks.length === 0) {
|
||||
js += hbs
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue