@budibase/string-templates 2.22.1 → 2.22.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/bundle.cjs +1 -0
  2. package/dist/bundle.mjs +1 -1
  3. package/dist/conversion/index.d.ts +2 -2
  4. package/dist/errors.d.ts +1 -2
  5. package/dist/helpers/Helper.d.ts +9 -8
  6. package/dist/helpers/constants.d.ts +8 -8
  7. package/dist/helpers/date.d.ts +2 -2
  8. package/dist/helpers/external.d.ts +8 -15
  9. package/dist/helpers/index.d.ts +5 -6
  10. package/dist/helpers/javascript.d.ts +7 -4
  11. package/dist/helpers/list.d.ts +2 -2
  12. package/dist/iife.d.ts +1 -1
  13. package/dist/index.d.ts +1078 -20
  14. package/dist/processors/index.d.ts +3 -2
  15. package/dist/processors/postprocessor.d.ts +7 -7
  16. package/dist/processors/preprocessor.d.ts +10 -10
  17. package/dist/tsconfig.tsbuildinfo +1 -0
  18. package/dist/types.d.ts +8 -0
  19. package/dist/utilities.d.ts +11 -11
  20. package/package.json +13 -13
  21. package/src/conversion/{index.js → index.ts} +13 -11
  22. package/src/errors.ts +3 -0
  23. package/src/helpers/Helper.ts +34 -0
  24. package/src/helpers/{constants.js → constants.ts} +3 -3
  25. package/src/helpers/{date.js → date.ts} +26 -16
  26. package/src/helpers/{external.js → external.ts} +13 -11
  27. package/src/helpers/index.ts +103 -0
  28. package/src/helpers/{javascript.js → javascript.ts} +20 -18
  29. package/src/helpers/{list.js → list.ts} +11 -11
  30. package/src/iife.ts +3 -0
  31. package/src/{index.js → index.ts} +100 -85
  32. package/src/processors/{index.js → index.ts} +7 -6
  33. package/src/processors/postprocessor.ts +56 -0
  34. package/src/processors/preprocessor.ts +82 -0
  35. package/src/types.ts +8 -0
  36. package/src/{utilities.js → utilities.ts} +22 -17
  37. package/dist/index.d.mts +0 -23
  38. package/src/errors.js +0 -11
  39. package/src/helpers/Helper.js +0 -29
  40. package/src/helpers/index.js +0 -100
  41. package/src/iife.js +0 -3
  42. package/src/index.mjs +0 -26
  43. package/src/processors/postprocessor.js +0 -49
  44. package/src/processors/preprocessor.js +0 -78
  45. /package/{manifest.json → src/manifest.json} +0 -0
@@ -0,0 +1,82 @@
1
+ import { HelperNames } from "../helpers"
2
+ import { swapStrings, isAlphaNumeric } from "../utilities"
3
+
4
+ const FUNCTION_CASES = ["#", "else", "/"]
5
+
6
+ export const PreprocessorNames = {
7
+ SWAP_TO_DOT: "swap-to-dot-notation",
8
+ FIX_FUNCTIONS: "fix-functions",
9
+ FINALISE: "finalise",
10
+ }
11
+
12
+ /* eslint-disable no-unused-vars */
13
+ class Preprocessor {
14
+ name: string
15
+ private fn: any
16
+
17
+ constructor(name: string, fn: any) {
18
+ this.name = name
19
+ this.fn = fn
20
+ }
21
+
22
+ process(fullString: string, statement: string, opts: Object) {
23
+ const output = this.fn(statement, opts)
24
+ const idx = fullString.indexOf(statement)
25
+ return swapStrings(fullString, idx, statement.length, output)
26
+ }
27
+ }
28
+
29
+ export const processors = [
30
+ new Preprocessor(PreprocessorNames.SWAP_TO_DOT, (statement: string) => {
31
+ let startBraceIdx = statement.indexOf("[")
32
+ let lastIdx = 0
33
+ while (startBraceIdx !== -1) {
34
+ // if the character previous to the literal specifier is alphanumeric this should happen
35
+ if (isAlphaNumeric(statement.charAt(startBraceIdx - 1))) {
36
+ statement = swapStrings(statement, startBraceIdx + lastIdx, 1, ".[")
37
+ }
38
+ lastIdx = startBraceIdx + 1
39
+ const nextBraceIdx = statement.substring(lastIdx + 1).indexOf("[")
40
+ startBraceIdx = nextBraceIdx > 0 ? lastIdx + 1 + nextBraceIdx : -1
41
+ }
42
+ return statement
43
+ }),
44
+
45
+ new Preprocessor(PreprocessorNames.FIX_FUNCTIONS, (statement: string) => {
46
+ for (let specialCase of FUNCTION_CASES) {
47
+ const toFind = `{ ${specialCase}`,
48
+ replacement = `{${specialCase}`
49
+ statement = statement.replace(new RegExp(toFind, "g"), replacement)
50
+ }
51
+ return statement
52
+ }),
53
+
54
+ new Preprocessor(
55
+ PreprocessorNames.FINALISE,
56
+ (statement: string, opts: { noHelpers: any }) => {
57
+ const noHelpers = opts && opts.noHelpers
58
+ let insideStatement = statement.slice(2, statement.length - 2)
59
+ if (insideStatement.charAt(0) === " ") {
60
+ insideStatement = insideStatement.slice(1)
61
+ }
62
+ if (insideStatement.charAt(insideStatement.length - 1) === " ") {
63
+ insideStatement = insideStatement.slice(0, insideStatement.length - 1)
64
+ }
65
+ const possibleHelper = insideStatement.split(" ")[0]
66
+ // function helpers can't be wrapped
67
+ for (let specialCase of FUNCTION_CASES) {
68
+ if (possibleHelper.includes(specialCase)) {
69
+ return statement
70
+ }
71
+ }
72
+ const testHelper = possibleHelper.trim().toLowerCase()
73
+ if (
74
+ !noHelpers &&
75
+ HelperNames().some(option => testHelper === option.toLowerCase())
76
+ ) {
77
+ insideStatement = `(${insideStatement})`
78
+ }
79
+ return `{{ all ${insideStatement} }}`
80
+ }
81
+ ),
82
+ ]
package/src/types.ts ADDED
@@ -0,0 +1,8 @@
1
+ export interface ProcessOptions {
2
+ cacheTemplates?: boolean
3
+ noEscaping?: boolean
4
+ noHelpers?: boolean
5
+ noFinalise?: boolean
6
+ escapeNewlines?: boolean
7
+ onlyFound?: boolean
8
+ }
@@ -1,28 +1,28 @@
1
1
  const ALPHA_NUMERIC_REGEX = /^[A-Za-z0-9]+$/g
2
2
 
3
- module.exports.FIND_HBS_REGEX = /{{([^{].*?)}}/g
4
- module.exports.FIND_ANY_HBS_REGEX = /{?{{([^{].*?)}}}?/g
5
- module.exports.FIND_TRIPLE_HBS_REGEX = /{{{([^{].*?)}}}/g
3
+ export const FIND_HBS_REGEX = /{{([^{].*?)}}/g
4
+ export const FIND_ANY_HBS_REGEX = /{?{{([^{].*?)}}}?/g
5
+ export const FIND_TRIPLE_HBS_REGEX = /{{{([^{].*?)}}}/g
6
6
 
7
- module.exports.isBackendService = () => {
7
+ export const isBackendService = () => {
8
8
  return typeof window === "undefined"
9
9
  }
10
10
 
11
- module.exports.isJSAllowed = () => {
11
+ export const isJSAllowed = () => {
12
12
  return process && !process.env.NO_JS
13
13
  }
14
14
 
15
15
  // originally this could be done with a single regex using look behinds
16
16
  // but safari does not support this feature
17
17
  // original regex: /(?<!{){{[^{}]+}}(?!})/g
18
- module.exports.findDoubleHbsInstances = string => {
18
+ export const findDoubleHbsInstances = (string: string): string[] => {
19
19
  let copied = string
20
- const doubleRegex = new RegExp(exports.FIND_HBS_REGEX)
21
- const regex = new RegExp(exports.FIND_TRIPLE_HBS_REGEX)
20
+ const doubleRegex = new RegExp(FIND_HBS_REGEX)
21
+ const regex = new RegExp(FIND_TRIPLE_HBS_REGEX)
22
22
  const tripleMatches = copied.match(regex)
23
23
  // remove triple braces
24
24
  if (tripleMatches) {
25
- tripleMatches.forEach(match => {
25
+ tripleMatches.forEach((match: string) => {
26
26
  copied = copied.replace(match, "")
27
27
  })
28
28
  }
@@ -30,34 +30,39 @@ module.exports.findDoubleHbsInstances = string => {
30
30
  return doubleMatches ? doubleMatches : []
31
31
  }
32
32
 
33
- module.exports.isAlphaNumeric = char => {
33
+ export const isAlphaNumeric = (char: string) => {
34
34
  return char.match(ALPHA_NUMERIC_REGEX)
35
35
  }
36
36
 
37
- module.exports.swapStrings = (string, start, length, swap) => {
37
+ export const swapStrings = (
38
+ string: string,
39
+ start: number,
40
+ length: number,
41
+ swap: string
42
+ ) => {
38
43
  return string.slice(0, start) + swap + string.slice(start + length)
39
44
  }
40
45
 
41
- module.exports.removeHandlebarsStatements = (
42
- string,
46
+ export const removeHandlebarsStatements = (
47
+ string: string,
43
48
  replacement = "Invalid binding"
44
49
  ) => {
45
- let regexp = new RegExp(exports.FIND_HBS_REGEX)
50
+ let regexp = new RegExp(FIND_HBS_REGEX)
46
51
  let matches = string.match(regexp)
47
52
  if (matches == null) {
48
53
  return string
49
54
  }
50
55
  for (let match of matches) {
51
56
  const idx = string.indexOf(match)
52
- string = exports.swapStrings(string, idx, match.length, replacement)
57
+ string = swapStrings(string, idx, match.length, replacement)
53
58
  }
54
59
  return string
55
60
  }
56
61
 
57
- module.exports.btoa = plainText => {
62
+ export const btoa = (plainText: string) => {
58
63
  return Buffer.from(plainText, "utf-8").toString("base64")
59
64
  }
60
65
 
61
- module.exports.atob = base64 => {
66
+ export const atob = (base64: string) => {
62
67
  return Buffer.from(base64, "base64").toString("utf-8")
63
68
  }
package/dist/index.d.mts DELETED
@@ -1,23 +0,0 @@
1
- /**
2
- * ES6 entrypoint for rollup
3
- */
4
- export const isValid: (string: any, opts?: any) => boolean;
5
- export const makePropSafe: (property: string) => string;
6
- export const getManifest: () => any;
7
- export const isJSBinding: (handlebars: any) => boolean;
8
- export const encodeJSBinding: (javascript: any) => string;
9
- export const decodeJSBinding: (handlebars: any) => string;
10
- export const processStringSync: (string: string, context: any, opts?: any) => string;
11
- export const processObjectSync: (object: any, context: any, opts?: any) => any;
12
- export const processString: (string: string, context: any, opts?: any) => Promise<string>;
13
- export const processObject: (object: any, context: any, opts?: any) => Promise<any>;
14
- export const doesContainStrings: (template: string, strings: string[]) => boolean;
15
- export const doesContainString: (template: string, string: string) => boolean;
16
- export const disableEscaping: (string: any) => any;
17
- export const findHBSBlocks: (string: string) => string[];
18
- export const convertToJS: (hbs: any) => string;
19
- export const setJSRunner: (runner: any) => any;
20
- export const setOnErrorLog: (delegate: any) => any;
21
- export const FIND_ANY_HBS_REGEX: RegExp;
22
- export const helpersToRemoveForJs: string[];
23
- export * from "./errors.js";
package/src/errors.js DELETED
@@ -1,11 +0,0 @@
1
- class JsErrorTimeout extends Error {
2
- code = "ERR_SCRIPT_EXECUTION_TIMEOUT"
3
-
4
- constructor() {
5
- super()
6
- }
7
- }
8
-
9
- module.exports = {
10
- JsErrorTimeout,
11
- }
@@ -1,29 +0,0 @@
1
- class Helper {
2
- constructor(name, fn, useValueFallback = true) {
3
- this.name = name
4
- this.fn = fn
5
- this.useValueFallback = useValueFallback
6
- }
7
-
8
- register(handlebars) {
9
- // wrap the function so that no helper can cause handlebars to break
10
- handlebars.registerHelper(this.name, (value, info) => {
11
- let context = {}
12
- if (info && info.data && info.data.root) {
13
- context = info.data.root
14
- }
15
- const result = this.fn(value, context)
16
- if (result == null) {
17
- return this.useValueFallback ? value : null
18
- } else {
19
- return result
20
- }
21
- })
22
- }
23
-
24
- unregister(handlebars) {
25
- handlebars.unregisterHelper(this.name)
26
- }
27
- }
28
-
29
- module.exports = Helper
@@ -1,100 +0,0 @@
1
- const Helper = require("./Helper")
2
- const { SafeString } = require("handlebars")
3
- const externalHandlebars = require("./external")
4
- const { processJS } = require("./javascript")
5
- const {
6
- HelperFunctionNames,
7
- HelperFunctionBuiltin,
8
- LITERAL_MARKER,
9
- } = require("./constants")
10
- const { getJsHelperList } = require("./list")
11
-
12
- const HTML_SWAPS = {
13
- "<": "&lt;",
14
- ">": "&gt;",
15
- }
16
-
17
- function isObject(value) {
18
- if (value == null || typeof value !== "object") {
19
- return false
20
- }
21
- return (
22
- value.toString() === "[object Object]" ||
23
- (value.length > 0 && typeof value[0] === "object")
24
- )
25
- }
26
-
27
- const HELPERS = [
28
- // external helpers
29
- new Helper(HelperFunctionNames.OBJECT, value => {
30
- return new SafeString(JSON.stringify(value))
31
- }),
32
- // javascript helper
33
- new Helper(HelperFunctionNames.JS, processJS, false),
34
- // this help is applied to all statements
35
- new Helper(HelperFunctionNames.ALL, (value, inputs) => {
36
- const { __opts } = inputs
37
- if (isObject(value)) {
38
- return new SafeString(JSON.stringify(value))
39
- }
40
- // null/undefined values produce bad results
41
- if (__opts && __opts.onlyFound && value == null) {
42
- return __opts.input
43
- }
44
- if (value == null || typeof value !== "string") {
45
- return value == null ? "" : value
46
- }
47
- if (value && value.string) {
48
- value = value.string
49
- }
50
- let text = value
51
- if (__opts && __opts.escapeNewlines) {
52
- text = value.replace(/\n/g, "\\n")
53
- }
54
- text = new SafeString(text.replace(/&amp;/g, "&"))
55
- if (text == null || typeof text !== "string") {
56
- return text
57
- }
58
- return text.replace(/[<>]/g, tag => {
59
- return HTML_SWAPS[tag] || tag
60
- })
61
- }),
62
- // adds a note for post-processor
63
- new Helper(HelperFunctionNames.LITERAL, value => {
64
- if (value === undefined) {
65
- return ""
66
- }
67
- const type = typeof value
68
- const outputVal = type === "object" ? JSON.stringify(value) : value
69
- return `{{${LITERAL_MARKER} ${type}-${outputVal}}}`
70
- }),
71
- ]
72
-
73
- module.exports.HelperNames = () => {
74
- return Object.values(HelperFunctionNames).concat(
75
- HelperFunctionBuiltin,
76
- externalHandlebars.externalHelperNames
77
- )
78
- }
79
-
80
- module.exports.registerMinimum = handlebars => {
81
- for (let helper of HELPERS) {
82
- helper.register(handlebars)
83
- }
84
- }
85
-
86
- module.exports.registerAll = handlebars => {
87
- module.exports.registerMinimum(handlebars)
88
- // register imported helpers
89
- externalHandlebars.registerAll(handlebars)
90
- }
91
-
92
- module.exports.unregisterAll = handlebars => {
93
- for (let helper of HELPERS) {
94
- helper.unregister(handlebars)
95
- }
96
- // unregister all imported helpers
97
- externalHandlebars.unregisterAll(handlebars)
98
- }
99
-
100
- module.exports.getJsHelperList = getJsHelperList
package/src/iife.js DELETED
@@ -1,3 +0,0 @@
1
- module.exports.iifeWrapper = script => {
2
- return `(function(){\n${script}\n})();`
3
- }
package/src/index.mjs DELETED
@@ -1,26 +0,0 @@
1
- import templates from "./index.js"
2
-
3
- /**
4
- * ES6 entrypoint for rollup
5
- */
6
- export const isValid = templates.isValid
7
- export const makePropSafe = templates.makePropSafe
8
- export const getManifest = templates.getManifest
9
- export const isJSBinding = templates.isJSBinding
10
- export const encodeJSBinding = templates.encodeJSBinding
11
- export const decodeJSBinding = templates.decodeJSBinding
12
- export const processStringSync = templates.processStringSync
13
- export const processObjectSync = templates.processObjectSync
14
- export const processString = templates.processString
15
- export const processObject = templates.processObject
16
- export const doesContainStrings = templates.doesContainStrings
17
- export const doesContainString = templates.doesContainString
18
- export const disableEscaping = templates.disableEscaping
19
- export const findHBSBlocks = templates.findHBSBlocks
20
- export const convertToJS = templates.convertToJS
21
- export const setJSRunner = templates.setJSRunner
22
- export const setOnErrorLog = templates.setOnErrorLog
23
- export const FIND_ANY_HBS_REGEX = templates.FIND_ANY_HBS_REGEX
24
- export const helpersToRemoveForJs = templates.helpersToRemoveForJs
25
-
26
- export * from "./errors.js"
@@ -1,49 +0,0 @@
1
- const { LITERAL_MARKER } = require("../helpers/constants")
2
-
3
- const PostProcessorNames = {
4
- CONVERT_LITERALS: "convert-literals",
5
- }
6
-
7
- /* eslint-disable no-unused-vars */
8
- class Postprocessor {
9
- constructor(name, fn) {
10
- this.name = name
11
- this.fn = fn
12
- }
13
-
14
- process(statement) {
15
- return this.fn(statement)
16
- }
17
- }
18
-
19
- module.exports.PostProcessorNames = PostProcessorNames
20
-
21
- module.exports.processors = [
22
- new Postprocessor(PostProcessorNames.CONVERT_LITERALS, statement => {
23
- if (typeof statement !== "string" || !statement.includes(LITERAL_MARKER)) {
24
- return statement
25
- }
26
- const splitMarkerIndex = statement.indexOf("-")
27
- const type = statement.substring(12, splitMarkerIndex)
28
- const value = statement.substring(
29
- splitMarkerIndex + 1,
30
- statement.length - 2
31
- )
32
- switch (type) {
33
- case "string":
34
- return value
35
- case "number":
36
- return parseFloat(value)
37
- case "boolean":
38
- return value === "true"
39
- case "object":
40
- return JSON.parse(value)
41
- case "js_result":
42
- // We use the literal helper to process the result of JS expressions
43
- // as we want to be able to return any types.
44
- // We wrap the value in an abject to be able to use undefined properly.
45
- return JSON.parse(value).data
46
- }
47
- return value
48
- }),
49
- ]
@@ -1,78 +0,0 @@
1
- const { HelperNames } = require("../helpers")
2
- const { swapStrings, isAlphaNumeric } = require("../utilities")
3
-
4
- const FUNCTION_CASES = ["#", "else", "/"]
5
-
6
- const PreprocessorNames = {
7
- SWAP_TO_DOT: "swap-to-dot-notation",
8
- FIX_FUNCTIONS: "fix-functions",
9
- FINALISE: "finalise",
10
- }
11
-
12
- /* eslint-disable no-unused-vars */
13
- class Preprocessor {
14
- constructor(name, fn) {
15
- this.name = name
16
- this.fn = fn
17
- }
18
-
19
- process(fullString, statement, opts) {
20
- const output = this.fn(statement, opts)
21
- const idx = fullString.indexOf(statement)
22
- return swapStrings(fullString, idx, statement.length, output)
23
- }
24
- }
25
-
26
- module.exports.processors = [
27
- new Preprocessor(PreprocessorNames.SWAP_TO_DOT, statement => {
28
- let startBraceIdx = statement.indexOf("[")
29
- let lastIdx = 0
30
- while (startBraceIdx !== -1) {
31
- // if the character previous to the literal specifier is alphanumeric this should happen
32
- if (isAlphaNumeric(statement.charAt(startBraceIdx - 1))) {
33
- statement = swapStrings(statement, startBraceIdx + lastIdx, 1, ".[")
34
- }
35
- lastIdx = startBraceIdx + 1
36
- const nextBraceIdx = statement.substring(lastIdx + 1).indexOf("[")
37
- startBraceIdx = nextBraceIdx > 0 ? lastIdx + 1 + nextBraceIdx : -1
38
- }
39
- return statement
40
- }),
41
-
42
- new Preprocessor(PreprocessorNames.FIX_FUNCTIONS, statement => {
43
- for (let specialCase of FUNCTION_CASES) {
44
- const toFind = `{ ${specialCase}`,
45
- replacement = `{${specialCase}`
46
- statement = statement.replace(new RegExp(toFind, "g"), replacement)
47
- }
48
- return statement
49
- }),
50
-
51
- new Preprocessor(PreprocessorNames.FINALISE, (statement, opts) => {
52
- const noHelpers = opts && opts.noHelpers
53
- let insideStatement = statement.slice(2, statement.length - 2)
54
- if (insideStatement.charAt(0) === " ") {
55
- insideStatement = insideStatement.slice(1)
56
- }
57
- if (insideStatement.charAt(insideStatement.length - 1) === " ") {
58
- insideStatement = insideStatement.slice(0, insideStatement.length - 1)
59
- }
60
- const possibleHelper = insideStatement.split(" ")[0]
61
- // function helpers can't be wrapped
62
- for (let specialCase of FUNCTION_CASES) {
63
- if (possibleHelper.includes(specialCase)) {
64
- return statement
65
- }
66
- }
67
- const testHelper = possibleHelper.trim().toLowerCase()
68
- if (
69
- !noHelpers &&
70
- HelperNames().some(option => testHelper === option.toLowerCase())
71
- ) {
72
- insideStatement = `(${insideStatement})`
73
- }
74
- return `{{ all ${insideStatement} }}`
75
- }),
76
- ]
77
-
78
- module.exports.PreprocessorNames = PreprocessorNames
File without changes