From efef47b77e1023d710b8b620147e2089ce593593 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 17:54:20 +0100
Subject: [PATCH 01/75] Indexjs to esm

---
 packages/string-templates/src/index.js  | 118 +++++++++++-------------
 packages/string-templates/src/index.mjs |   2 +-
 2 files changed, 56 insertions(+), 64 deletions(-)

diff --git a/packages/string-templates/src/index.js b/packages/string-templates/src/index.js
index 0125b9e0ab..4299e9d5b2 100644
--- a/packages/string-templates/src/index.js
+++ b/packages/string-templates/src/index.js
@@ -1,21 +1,23 @@
-const vm = require("vm")
-const handlebars = require("handlebars")
-const { registerAll, registerMinimum } = require("./helpers/index")
-const processors = require("./processors")
-const { atob, btoa, isBackendService } = require("./utilities")
-const manifest = require("../manifest.json")
-const {
+import { createContext, runInNewContext } from "vm"
+import { create } from "handlebars"
+import { registerAll, registerMinimum } from "./helpers/index"
+import { preprocess, postprocess } from "./processors"
+import { atob, btoa, isBackendService } from "./utilities"
+import manifest from "../manifest.json"
+import {
   FIND_HBS_REGEX,
   FIND_ANY_HBS_REGEX,
   findDoubleHbsInstances,
-} = require("./utilities")
-const { convertHBSBlock } = require("./conversion")
-const javascript = require("./helpers/javascript")
-const { helpersToRemoveForJs } = require("./helpers/list")
+} from "./utilities"
+import { convertHBSBlock } from "./conversion"
+import { setJSRunner, removeJSRunner } from "./helpers/javascript"
+import { helpersToRemoveForJs } from "./helpers/list"
 
-const hbsInstance = handlebars.create()
+export { setJSRunner, setOnErrorLog } from "./helpers/javascript"
+
+const hbsInstance = create()
 registerAll(hbsInstance)
-const hbsInstanceNoHelpers = handlebars.create()
+const hbsInstanceNoHelpers = create()
 registerMinimum(hbsInstanceNoHelpers)
 const defaultOpts = {
   noHelpers: false,
@@ -52,11 +54,11 @@ function createTemplate(string, opts) {
     return templateCache[key]
   }
 
-  string = processors.preprocess(string, opts)
+  string = preprocess(string, opts)
 
   // Optionally disable built in HBS escaping
   if (opts.noEscaping) {
-    string = exports.disableEscaping(string)
+    string = disableEscaping(string)
   }
 
   // This does not throw an error when template can't be fulfilled,
@@ -77,23 +79,15 @@ function createTemplate(string, opts) {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {Promise<object|array>} The structure input, as fully updated as possible.
  */
-module.exports.processObject = async (object, context, opts) => {
+export async function processObject(object, context, opts) {
   testObject(object)
   for (let key of Object.keys(object || {})) {
     if (object[key] != null) {
       let val = object[key]
       if (typeof val === "string") {
-        object[key] = await module.exports.processString(
-          object[key],
-          context,
-          opts
-        )
+        object[key] = await processString(object[key], context, opts)
       } else if (typeof val === "object") {
-        object[key] = await module.exports.processObject(
-          object[key],
-          context,
-          opts
-        )
+        object[key] = await processObject(object[key], context, opts)
       }
     }
   }
@@ -108,9 +102,9 @@ module.exports.processObject = async (object, context, opts) => {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {Promise<string>} The enriched string, all templates should have been replaced if they can be.
  */
-module.exports.processString = async (string, context, opts) => {
+export async function processString(string, context, opts) {
   // TODO: carry out any async calls before carrying out async call
-  return module.exports.processStringSync(string, context, opts)
+  return processStringSync(string, context, opts)
 }
 
 /**
@@ -122,14 +116,14 @@ module.exports.processString = async (string, context, opts) => {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {object|array} The structure input, as fully updated as possible.
  */
-module.exports.processObjectSync = (object, context, opts) => {
+export function processObjectSync(object, context, opts) {
   testObject(object)
   for (let key of Object.keys(object || {})) {
     let val = object[key]
     if (typeof val === "string") {
-      object[key] = module.exports.processStringSync(object[key], context, opts)
+      object[key] = processStringSync(object[key], context, opts)
     } else if (typeof val === "object") {
-      object[key] = module.exports.processObjectSync(object[key], context, opts)
+      object[key] = processObjectSync(object[key], context, opts)
     }
   }
   return object
@@ -143,7 +137,7 @@ module.exports.processObjectSync = (object, context, opts) => {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {string} The enriched string, all templates should have been replaced if they can be.
  */
-module.exports.processStringSync = (string, context, opts) => {
+export function processStringSync(string, context, opts) {
   // Take a copy of input in case of error
   const input = string
   if (typeof string !== "string") {
@@ -152,7 +146,7 @@ module.exports.processStringSync = (string, context, opts) => {
   function process(stringPart) {
     const template = createTemplate(stringPart, opts)
     const now = Math.floor(Date.now() / 1000) * 1000
-    return processors.postprocess(
+    return postprocess(
       template({
         now: new Date(now).toISOString(),
         __opts: {
@@ -165,7 +159,7 @@ module.exports.processStringSync = (string, context, opts) => {
   }
   try {
     if (opts && opts.onlyFound) {
-      const blocks = exports.findHBSBlocks(string)
+      const blocks = findHBSBlocks(string)
       for (let block of blocks) {
         const outcome = process(block)
         string = string.replace(block, outcome)
@@ -185,7 +179,7 @@ module.exports.processStringSync = (string, context, opts) => {
  * this function will find any double braces and switch to triple.
  * @param string the string to have double HBS statements converted to triple.
  */
-module.exports.disableEscaping = string => {
+export function disableEscaping(string) {
   const matches = findDoubleHbsInstances(string)
   if (matches == null) {
     return string
@@ -206,7 +200,7 @@ module.exports.disableEscaping = string => {
  * @param {string} property The property which is to be wrapped.
  * @returns {string} The wrapped property ready to be added to a templating string.
  */
-module.exports.makePropSafe = property => {
+export function makePropSafe(property) {
   return `[${property}]`.replace("[[", "[").replace("]]", "]")
 }
 
@@ -216,7 +210,7 @@ module.exports.makePropSafe = property => {
  * @param [opts] optional - specify some options for processing.
  * @returns {boolean} Whether or not the input string is valid.
  */
-module.exports.isValid = (string, opts) => {
+export function isValid(string, opts) {
   const validCases = [
     "string",
     "number",
@@ -258,7 +252,7 @@ module.exports.isValid = (string, opts) => {
  * This manifest provides information about each of the helpers and how it can be used.
  * @returns The manifest JSON which has been generated from the helpers.
  */
-module.exports.getManifest = () => {
+export function getManifest() {
   return manifest
 }
 
@@ -267,8 +261,8 @@ module.exports.getManifest = () => {
  * @param handlebars the HBS expression to check
  * @returns {boolean} whether the expression is JS or not
  */
-module.exports.isJSBinding = handlebars => {
-  return module.exports.decodeJSBinding(handlebars) != null
+export function isJSBinding(handlebars) {
+  return decodeJSBinding(handlebars) != null
 }
 
 /**
@@ -276,7 +270,7 @@ module.exports.isJSBinding = handlebars => {
  * @param javascript the JS code to encode
  * @returns {string} the JS HBS expression
  */
-module.exports.encodeJSBinding = javascript => {
+export function encodeJSBinding(javascript) {
   return `{{ js "${btoa(javascript)}" }}`
 }
 
@@ -285,7 +279,7 @@ module.exports.encodeJSBinding = javascript => {
  * @param handlebars the JS HBS expression
  * @returns {string|null} the raw JS code
  */
-module.exports.decodeJSBinding = handlebars => {
+export function decodeJSBinding(handlebars) {
   if (!handlebars || typeof handlebars !== "string") {
     return null
   }
@@ -310,7 +304,7 @@ module.exports.decodeJSBinding = handlebars => {
  * @param {string[]} strings The strings to look for.
  * @returns {boolean} Will return true if all strings found in HBS statement.
  */
-module.exports.doesContainStrings = (template, strings) => {
+export function doesContainStrings(template, strings) {
   let regexp = new RegExp(FIND_HBS_REGEX)
   let matches = template.match(regexp)
   if (matches == null) {
@@ -318,8 +312,8 @@ module.exports.doesContainStrings = (template, strings) => {
   }
   for (let match of matches) {
     let hbs = match
-    if (exports.isJSBinding(match)) {
-      hbs = exports.decodeJSBinding(match)
+    if (isJSBinding(match)) {
+      hbs = decodeJSBinding(match)
     }
     let allFound = true
     for (let string of strings) {
@@ -340,7 +334,7 @@ module.exports.doesContainStrings = (template, strings) => {
  * @param {string} string The string to search within.
  * @return {string[]} The found HBS blocks.
  */
-module.exports.findHBSBlocks = string => {
+export function findHBSBlocks(string) {
   if (!string || typeof string !== "string") {
     return []
   }
@@ -361,15 +355,12 @@ module.exports.findHBSBlocks = 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.
  */
-module.exports.doesContainString = (template, string) => {
-  return exports.doesContainStrings(template, [string])
+export function doesContainString(template, string) {
+  return doesContainStrings(template, [string])
 }
 
-module.exports.setJSRunner = javascript.setJSRunner
-module.exports.setOnErrorLog = javascript.setOnErrorLog
-
-module.exports.convertToJS = hbs => {
-  const blocks = exports.findHBSBlocks(hbs)
+export function convertToJS(hbs) {
+  const blocks = findHBSBlocks(hbs)
   let js = "return `",
     prevBlock = null
   const variables = {}
@@ -396,33 +387,34 @@ module.exports.convertToJS = hbs => {
   return `${varBlock}${js}`
 }
 
-module.exports.FIND_ANY_HBS_REGEX = FIND_ANY_HBS_REGEX
+const _FIND_ANY_HBS_REGEX = FIND_ANY_HBS_REGEX
+export { _FIND_ANY_HBS_REGEX as FIND_ANY_HBS_REGEX }
 
-const errors = require("./errors")
-// We cannot use dynamic exports, otherwise the typescript file will not be generating it
-module.exports.JsErrorTimeout = errors.JsErrorTimeout
+export { JsErrorTimeout } from "./errors"
 
-module.exports.helpersToRemoveForJs = helpersToRemoveForJs
+const _helpersToRemoveForJs = helpersToRemoveForJs
+export { _helpersToRemoveForJs as helpersToRemoveForJs }
 
 function defaultJSSetup() {
   if (!isBackendService()) {
     /**
      * Use polyfilled vm to run JS scripts in a browser Env
      */
-    javascript.setJSRunner((js, context) => {
+    setJSRunner((js, context) => {
       context = {
         ...context,
         alert: undefined,
         setInterval: undefined,
         setTimeout: undefined,
       }
-      vm.createContext(context)
-      return vm.runInNewContext(js, context, { timeout: 1000 })
+      createContext(context)
+      return runInNewContext(js, context, { timeout: 1000 })
     })
   } else {
-    javascript.removeJSRunner()
+    removeJSRunner()
   }
 }
 defaultJSSetup()
 
-module.exports.defaultJSSetup = defaultJSSetup
+const _defaultJSSetup = defaultJSSetup
+export { _defaultJSSetup as defaultJSSetup }
diff --git a/packages/string-templates/src/index.mjs b/packages/string-templates/src/index.mjs
index f54ca7e23e..c8327aa288 100644
--- a/packages/string-templates/src/index.mjs
+++ b/packages/string-templates/src/index.mjs
@@ -1,4 +1,4 @@
-import templates from "./index.js"
+import * as templates from "./index.js"
 
 /**
  * ES6 entrypoint for rollup

From e0873b359c51855795c6b4ce6702e920fa54cae3 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 17:57:58 +0100
Subject: [PATCH 02/75] Mark as module

---
 packages/string-templates/package.json  |  1 +
 packages/string-templates/src/index.mjs | 42 ++++++++++++-------------
 2 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index ceafd5364f..42be7e2299 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -1,5 +1,6 @@
 {
   "name": "@budibase/string-templates",
+  "type": "module",
   "version": "0.0.0",
   "description": "Handlebars wrapper for Budibase templating.",
   "main": "src/index.js",
diff --git a/packages/string-templates/src/index.mjs b/packages/string-templates/src/index.mjs
index c8327aa288..39ab10f75d 100644
--- a/packages/string-templates/src/index.mjs
+++ b/packages/string-templates/src/index.mjs
@@ -1,26 +1,26 @@
-import * as templates from "./index.js"
-
 /**
  * ES6 entrypoint for rollup
  */
-export const isValid = templates.isValid
-export const makePropSafe = templates.makePropSafe
-export const getManifest = templates.getManifest
-export const isJSBinding = templates.isJSBinding
-export const encodeJSBinding = templates.encodeJSBinding
-export const decodeJSBinding = templates.decodeJSBinding
-export const processStringSync = templates.processStringSync
-export const processObjectSync = templates.processObjectSync
-export const processString = templates.processString
-export const processObject = templates.processObject
-export const doesContainStrings = templates.doesContainStrings
-export const doesContainString = templates.doesContainString
-export const disableEscaping = templates.disableEscaping
-export const findHBSBlocks = templates.findHBSBlocks
-export const convertToJS = templates.convertToJS
-export const setJSRunner = templates.setJSRunner
-export const setOnErrorLog = templates.setOnErrorLog
-export const FIND_ANY_HBS_REGEX = templates.FIND_ANY_HBS_REGEX
-export const helpersToRemoveForJs = templates.helpersToRemoveForJs
+export {
+  isValid,
+  makePropSafe,
+  getManifest,
+  isJSBinding,
+  encodeJSBinding,
+  decodeJSBinding,
+  processStringSync,
+  processObjectSync,
+  processString,
+  processObject,
+  doesContainStrings,
+  doesContainString,
+  disableEscaping,
+  findHBSBlocks,
+  convertToJS,
+  setJSRunner,
+  setOnErrorLog,
+  FIND_ANY_HBS_REGEX,
+  helpersToRemoveForJs,
+} from "./index.js"
 
 export * from "./errors.js"

From cdf251f9ccf84608860434c6332626f30b389230 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 19:29:03 +0100
Subject: [PATCH 03/75] Processors to esm

---
 packages/string-templates/src/processors/index.js      | 10 +++++-----
 .../string-templates/src/processors/postprocessor.js   |  8 +++-----
 .../string-templates/src/processors/preprocessor.js    | 10 ++++------
 3 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/packages/string-templates/src/processors/index.js b/packages/string-templates/src/processors/index.js
index aae18aed8b..a5bcf84eaf 100644
--- a/packages/string-templates/src/processors/index.js
+++ b/packages/string-templates/src/processors/index.js
@@ -1,6 +1,6 @@
-const { FIND_HBS_REGEX } = require("../utilities")
-const preprocessor = require("./preprocessor")
-const postprocessor = require("./postprocessor")
+import { FIND_HBS_REGEX } from "../utilities"
+import * as preprocessor from "./preprocessor"
+import * as postprocessor from "./postprocessor"
 
 function process(output, processors, opts) {
   for (let processor of processors) {
@@ -21,7 +21,7 @@ function process(output, processors, opts) {
   return output
 }
 
-module.exports.preprocess = (string, opts) => {
+export function preprocess(string, opts) {
   let processors = preprocessor.processors
   if (opts.noFinalise) {
     processors = processors.filter(
@@ -30,7 +30,7 @@ module.exports.preprocess = (string, opts) => {
   }
   return process(string, processors, opts)
 }
-module.exports.postprocess = string => {
+export function postprocess(string) {
   let processors = postprocessor.processors
   return process(string, processors)
 }
diff --git a/packages/string-templates/src/processors/postprocessor.js b/packages/string-templates/src/processors/postprocessor.js
index f78a572d07..3122d43e53 100644
--- a/packages/string-templates/src/processors/postprocessor.js
+++ b/packages/string-templates/src/processors/postprocessor.js
@@ -1,6 +1,6 @@
-const { LITERAL_MARKER } = require("../helpers/constants")
+import { LITERAL_MARKER } from "../helpers/constants"
 
-const PostProcessorNames = {
+export const PostProcessorNames = {
   CONVERT_LITERALS: "convert-literals",
 }
 
@@ -16,9 +16,7 @@ class Postprocessor {
   }
 }
 
-module.exports.PostProcessorNames = PostProcessorNames
-
-module.exports.processors = [
+export const processors = [
   new Postprocessor(PostProcessorNames.CONVERT_LITERALS, statement => {
     if (typeof statement !== "string" || !statement.includes(LITERAL_MARKER)) {
       return statement
diff --git a/packages/string-templates/src/processors/preprocessor.js b/packages/string-templates/src/processors/preprocessor.js
index 185a3ab38a..a7210fe520 100644
--- a/packages/string-templates/src/processors/preprocessor.js
+++ b/packages/string-templates/src/processors/preprocessor.js
@@ -1,9 +1,9 @@
-const { HelperNames } = require("../helpers")
-const { swapStrings, isAlphaNumeric } = require("../utilities")
+import { HelperNames } from "../helpers"
+import { swapStrings, isAlphaNumeric } from "../utilities"
 
 const FUNCTION_CASES = ["#", "else", "/"]
 
-const PreprocessorNames = {
+export const PreprocessorNames = {
   SWAP_TO_DOT: "swap-to-dot-notation",
   FIX_FUNCTIONS: "fix-functions",
   FINALISE: "finalise",
@@ -23,7 +23,7 @@ class Preprocessor {
   }
 }
 
-module.exports.processors = [
+export const processors = [
   new Preprocessor(PreprocessorNames.SWAP_TO_DOT, statement => {
     let startBraceIdx = statement.indexOf("[")
     let lastIdx = 0
@@ -74,5 +74,3 @@ module.exports.processors = [
     return `{{ all ${insideStatement} }}`
   }),
 ]
-
-module.exports.PreprocessorNames = PreprocessorNames

From b457b0e023f692e6d7b569082869ce587fbbddc4 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 19:40:50 +0100
Subject: [PATCH 04/75] Convert helpers

---
 packages/string-templates/src/errors.js       |  6 +----
 .../string-templates/src/helpers/Helper.js    |  4 +--
 .../string-templates/src/helpers/constants.js |  6 ++---
 packages/string-templates/src/helpers/date.js |  6 ++---
 .../string-templates/src/helpers/external.js  | 22 ++++++++--------
 .../string-templates/src/helpers/index.js     | 26 +++++++++----------
 .../src/helpers/javascript.js                 | 19 +++++++-------
 packages/string-templates/src/helpers/list.js |  7 +++--
 8 files changed, 43 insertions(+), 53 deletions(-)

diff --git a/packages/string-templates/src/errors.js b/packages/string-templates/src/errors.js
index e0dcc3de1c..a0108d5018 100644
--- a/packages/string-templates/src/errors.js
+++ b/packages/string-templates/src/errors.js
@@ -1,11 +1,7 @@
-class JsErrorTimeout extends Error {
+export class JsErrorTimeout extends Error {
   code = "ERR_SCRIPT_EXECUTION_TIMEOUT"
 
   constructor() {
     super()
   }
 }
-
-module.exports = {
-  JsErrorTimeout,
-}
diff --git a/packages/string-templates/src/helpers/Helper.js b/packages/string-templates/src/helpers/Helper.js
index d963c87158..e7e7488c0f 100644
--- a/packages/string-templates/src/helpers/Helper.js
+++ b/packages/string-templates/src/helpers/Helper.js
@@ -1,4 +1,4 @@
-class Helper {
+export default class Helper {
   constructor(name, fn, useValueFallback = true) {
     this.name = name
     this.fn = fn
@@ -25,5 +25,3 @@ class Helper {
     handlebars.unregisterHelper(this.name)
   }
 }
-
-module.exports = Helper
diff --git a/packages/string-templates/src/helpers/constants.js b/packages/string-templates/src/helpers/constants.js
index 1f8cf7a59d..ffccd36ab0 100644
--- a/packages/string-templates/src/helpers/constants.js
+++ b/packages/string-templates/src/helpers/constants.js
@@ -1,4 +1,4 @@
-module.exports.HelperFunctionBuiltin = [
+export const HelperFunctionBuiltin = [
   "#if",
   "#unless",
   "#each",
@@ -15,11 +15,11 @@ module.exports.HelperFunctionBuiltin = [
   "with",
 ]
 
-module.exports.HelperFunctionNames = {
+export const HelperFunctionNames = {
   OBJECT: "object",
   ALL: "all",
   LITERAL: "literal",
   JS: "js",
 }
 
-module.exports.LITERAL_MARKER = "%LITERAL%"
+export const LITERAL_MARKER = "%LITERAL%"
diff --git a/packages/string-templates/src/helpers/date.js b/packages/string-templates/src/helpers/date.js
index 6fe8b288d6..9d663573bd 100644
--- a/packages/string-templates/src/helpers/date.js
+++ b/packages/string-templates/src/helpers/date.js
@@ -1,4 +1,4 @@
-const dayjs = require("dayjs")
+import dayjs from "dayjs"
 dayjs.extend(require("dayjs/plugin/duration"))
 dayjs.extend(require("dayjs/plugin/advancedFormat"))
 dayjs.extend(require("dayjs/plugin/isoWeek"))
@@ -83,7 +83,7 @@ function setLocale(str, pattern, options) {
   dayjs.locale(opts.lang || opts.language)
 }
 
-module.exports.date = (str, pattern, options) => {
+export const date = (str, pattern, options) => {
   const config = initialConfig(str, pattern, options)
 
   // if no args are passed, return a formatted date
@@ -109,7 +109,7 @@ module.exports.date = (str, pattern, options) => {
   return date.format(config.pattern)
 }
 
-module.exports.duration = (str, pattern, format) => {
+export const duration = (str, pattern, format) => {
   const config = initialConfig(str, pattern)
 
   setLocale(config.str, config.pattern)
diff --git a/packages/string-templates/src/helpers/external.js b/packages/string-templates/src/helpers/external.js
index 2487fd91df..7451384293 100644
--- a/packages/string-templates/src/helpers/external.js
+++ b/packages/string-templates/src/helpers/external.js
@@ -1,6 +1,6 @@
-const helpers = require("@budibase/handlebars-helpers")
-const { date, duration } = require("./date")
-const { HelperFunctionBuiltin } = require("./constants")
+import helpers from "@budibase/handlebars-helpers"
+import { date, duration } from "./date"
+import { HelperFunctionBuiltin } from "./constants"
 
 /**
  * full list of supported helpers can be found here:
@@ -24,10 +24,10 @@ const ADDED_HELPERS = {
   duration: duration,
 }
 
-exports.externalCollections = EXTERNAL_FUNCTION_COLLECTIONS
-exports.addedHelpers = ADDED_HELPERS
+export const externalCollections = EXTERNAL_FUNCTION_COLLECTIONS
+export const addedHelpers = ADDED_HELPERS
 
-exports.registerAll = handlebars => {
+export function registerAll(handlebars) {
   for (let [name, helper] of Object.entries(ADDED_HELPERS)) {
     handlebars.registerHelper(name, helper)
   }
@@ -52,17 +52,17 @@ exports.registerAll = handlebars => {
     })
   }
   // add date external functionality
-  exports.externalHelperNames = externalNames.concat(Object.keys(ADDED_HELPERS))
+  externalHelperNames = externalNames.concat(Object.keys(ADDED_HELPERS))
 }
 
-exports.unregisterAll = handlebars => {
+export function unregisterAll(handlebars) {
   for (let name of Object.keys(ADDED_HELPERS)) {
     handlebars.unregisterHelper(name)
   }
-  for (let name of module.exports.externalHelperNames) {
+  for (let name of externalHelperNames) {
     handlebars.unregisterHelper(name)
   }
-  exports.externalHelperNames = []
+  externalHelperNames = []
 }
 
-exports.externalHelperNames = []
+export const externalHelperNames = []
diff --git a/packages/string-templates/src/helpers/index.js b/packages/string-templates/src/helpers/index.js
index 5e6dcbd2b9..bad861567d 100644
--- a/packages/string-templates/src/helpers/index.js
+++ b/packages/string-templates/src/helpers/index.js
@@ -1,13 +1,13 @@
-const Helper = require("./Helper")
-const { SafeString } = require("handlebars")
-const externalHandlebars = require("./external")
-const { processJS } = require("./javascript")
-const {
+import Helper from "./Helper"
+import { SafeString } from "handlebars"
+import * as externalHandlebars from "./external"
+import { processJS } from "./javascript"
+import {
   HelperFunctionNames,
   HelperFunctionBuiltin,
   LITERAL_MARKER,
-} = require("./constants")
-const { getJsHelperList } = require("./list")
+} from "./constants"
+export { getJsHelperList } from "./list"
 
 const HTML_SWAPS = {
   "<": "&lt;",
@@ -70,31 +70,29 @@ const HELPERS = [
   }),
 ]
 
-module.exports.HelperNames = () => {
+export function HelperNames() {
   return Object.values(HelperFunctionNames).concat(
     HelperFunctionBuiltin,
     externalHandlebars.externalHelperNames
   )
 }
 
-module.exports.registerMinimum = handlebars => {
+export function registerMinimum(handlebars) {
   for (let helper of HELPERS) {
     helper.register(handlebars)
   }
 }
 
-module.exports.registerAll = handlebars => {
-  module.exports.registerMinimum(handlebars)
+export function registerAll(handlebars) {
+  registerMinimum(handlebars)
   // register imported helpers
   externalHandlebars.registerAll(handlebars)
 }
 
-module.exports.unregisterAll = handlebars => {
+export function unregisterAll(handlebars) {
   for (let helper of HELPERS) {
     helper.unregister(handlebars)
   }
   // unregister all imported helpers
   externalHandlebars.unregisterAll(handlebars)
 }
-
-module.exports.getJsHelperList = getJsHelperList
diff --git a/packages/string-templates/src/helpers/javascript.js b/packages/string-templates/src/helpers/javascript.js
index 7827736812..b75c9f5ac1 100644
--- a/packages/string-templates/src/helpers/javascript.js
+++ b/packages/string-templates/src/helpers/javascript.js
@@ -1,18 +1,17 @@
-const { atob, isBackendService, isJSAllowed } = require("../utilities")
-const cloneDeep = require("lodash.clonedeep")
-const { LITERAL_MARKER } = require("../helpers/constants")
-const { getJsHelperList } = require("./list")
+import { atob, isBackendService, isJSAllowed } from "../utilities"
+import cloneDeep from "lodash.clonedeep"
+import { LITERAL_MARKER } from "../helpers/constants"
+import { getJsHelperList } from "./list"
 
 // The method of executing JS scripts depends on the bundle being built.
 // This setter is used in the entrypoint (either index.js or index.mjs).
 let runJS
-module.exports.setJSRunner = runner => (runJS = runner)
-module.exports.removeJSRunner = () => {
-  runJS = undefined
-}
+export const setJSRunner = runner => (runJS = runner)
+
+export const removeJSRunner = () => (runJS = undefined)
 
 let onErrorLog
-module.exports.setOnErrorLog = delegate => (onErrorLog = delegate)
+export const setOnErrorLog = delegate => (onErrorLog = delegate)
 
 // Helper utility to strip square brackets from a value
 const removeSquareBrackets = value => {
@@ -41,7 +40,7 @@ const getContextValue = (path, context) => {
 }
 
 // Evaluates JS code against a certain context
-module.exports.processJS = (handlebars, context) => {
+export function processJS(handlebars, context) {
   if (!isJSAllowed() || (isBackendService() && !runJS)) {
     throw new Error("JS disabled in environment.")
   }
diff --git a/packages/string-templates/src/helpers/list.js b/packages/string-templates/src/helpers/list.js
index 883ab5678e..8f08bc6f12 100644
--- a/packages/string-templates/src/helpers/list.js
+++ b/packages/string-templates/src/helpers/list.js
@@ -1,4 +1,4 @@
-const { date, duration } = require("./date")
+import { date, duration } from "./date"
 
 // https://github.com/evanw/esbuild/issues/56
 const externalCollections = {
@@ -13,8 +13,7 @@ const externalCollections = {
   uuid: require("@budibase/handlebars-helpers/lib/uuid"),
 }
 
-const helpersToRemoveForJs = ["sortBy"]
-module.exports.helpersToRemoveForJs = helpersToRemoveForJs
+export const helpersToRemoveForJs = ["sortBy"]
 
 const addedHelpers = {
   date: date,
@@ -23,7 +22,7 @@ const addedHelpers = {
 
 let helpers = undefined
 
-module.exports.getJsHelperList = () => {
+export function getJsHelperList() {
   if (helpers) {
     return helpers
   }

From 92f08d84d708f87715a1ddc35a41ff5cb6c04e1a Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 19:41:14 +0100
Subject: [PATCH 05/75] More convertions

---
 packages/string-templates/src/conversion/index.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/string-templates/src/conversion/index.js b/packages/string-templates/src/conversion/index.js
index 10aaef0d2f..c6ec012ad9 100644
--- a/packages/string-templates/src/conversion/index.js
+++ b/packages/string-templates/src/conversion/index.js
@@ -1,4 +1,4 @@
-const { getJsHelperList } = require("../helpers")
+import { getJsHelperList } from "../helpers"
 
 function getLayers(fullBlock) {
   let layers = []
@@ -103,7 +103,7 @@ function splitBySpace(layer) {
   return parts
 }
 
-module.exports.convertHBSBlock = (block, blockNumber) => {
+export function convertHBSBlock(block, blockNumber) {
   const braceLength = block[2] === "{" ? 3 : 2
   block = block.substring(braceLength, block.length - braceLength).trim()
   const layers = getLayers(block)

From 4aa8456d216844b3f0502faee27a9521c6ceec11 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 19:42:15 +0100
Subject: [PATCH 06/75] More convertions

---
 packages/string-templates/src/utilities.js | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/packages/string-templates/src/utilities.js b/packages/string-templates/src/utilities.js
index 00b2d7d855..9393defc00 100644
--- a/packages/string-templates/src/utilities.js
+++ b/packages/string-templates/src/utilities.js
@@ -1,21 +1,21 @@
 const ALPHA_NUMERIC_REGEX = /^[A-Za-z0-9]+$/g
 
-module.exports.FIND_HBS_REGEX = /{{([^{].*?)}}/g
-module.exports.FIND_ANY_HBS_REGEX = /{?{{([^{].*?)}}}?/g
-module.exports.FIND_TRIPLE_HBS_REGEX = /{{{([^{].*?)}}}/g
+export const FIND_HBS_REGEX = /{{([^{].*?)}}/g
+export const FIND_ANY_HBS_REGEX = /{?{{([^{].*?)}}}?/g
+export const FIND_TRIPLE_HBS_REGEX = /{{{([^{].*?)}}}/g
 
-module.exports.isBackendService = () => {
+export const isBackendService = () => {
   return typeof window === "undefined"
 }
 
-module.exports.isJSAllowed = () => {
+export const isJSAllowed = () => {
   return process && !process.env.NO_JS
 }
 
 // originally this could be done with a single regex using look behinds
 // but safari does not support this feature
 // original regex: /(?<!{){{[^{}]+}}(?!})/g
-module.exports.findDoubleHbsInstances = string => {
+export const findDoubleHbsInstances = string => {
   let copied = string
   const doubleRegex = new RegExp(exports.FIND_HBS_REGEX)
   const regex = new RegExp(exports.FIND_TRIPLE_HBS_REGEX)
@@ -30,15 +30,15 @@ module.exports.findDoubleHbsInstances = string => {
   return doubleMatches ? doubleMatches : []
 }
 
-module.exports.isAlphaNumeric = char => {
+export const isAlphaNumeric = char => {
   return char.match(ALPHA_NUMERIC_REGEX)
 }
 
-module.exports.swapStrings = (string, start, length, swap) => {
+export const swapStrings = (string, start, length, swap) => {
   return string.slice(0, start) + swap + string.slice(start + length)
 }
 
-module.exports.removeHandlebarsStatements = (
+export const removeHandlebarsStatements = (
   string,
   replacement = "Invalid binding"
 ) => {
@@ -54,10 +54,10 @@ module.exports.removeHandlebarsStatements = (
   return string
 }
 
-module.exports.btoa = plainText => {
+export const btoa = plainText => {
   return Buffer.from(plainText, "utf-8").toString("base64")
 }
 
-module.exports.atob = base64 => {
+export const atob = base64 => {
   return Buffer.from(base64, "base64").toString("utf-8")
 }

From 813b96354b62b8e056d9c45f305ece65e5a3fa00 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 19:57:05 +0100
Subject: [PATCH 07/75] Final convertions

---
 packages/string-templates/src/helpers/external.js | 2 +-
 packages/string-templates/src/utilities.js        | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/packages/string-templates/src/helpers/external.js b/packages/string-templates/src/helpers/external.js
index 7451384293..7e849c8fc3 100644
--- a/packages/string-templates/src/helpers/external.js
+++ b/packages/string-templates/src/helpers/external.js
@@ -65,4 +65,4 @@ export function unregisterAll(handlebars) {
   externalHelperNames = []
 }
 
-export const externalHelperNames = []
+export let externalHelperNames = []
diff --git a/packages/string-templates/src/utilities.js b/packages/string-templates/src/utilities.js
index 9393defc00..017f38db47 100644
--- a/packages/string-templates/src/utilities.js
+++ b/packages/string-templates/src/utilities.js
@@ -17,8 +17,8 @@ export const isJSAllowed = () => {
 // original regex: /(?<!{){{[^{}]+}}(?!})/g
 export const findDoubleHbsInstances = string => {
   let copied = string
-  const doubleRegex = new RegExp(exports.FIND_HBS_REGEX)
-  const regex = new RegExp(exports.FIND_TRIPLE_HBS_REGEX)
+  const doubleRegex = new RegExp(FIND_HBS_REGEX)
+  const regex = new RegExp(FIND_TRIPLE_HBS_REGEX)
   const tripleMatches = copied.match(regex)
   // remove triple braces
   if (tripleMatches) {
@@ -42,14 +42,14 @@ export const removeHandlebarsStatements = (
   string,
   replacement = "Invalid binding"
 ) => {
-  let regexp = new RegExp(exports.FIND_HBS_REGEX)
+  let regexp = new RegExp(FIND_HBS_REGEX)
   let matches = string.match(regexp)
   if (matches == null) {
     return string
   }
   for (let match of matches) {
     const idx = string.indexOf(match)
-    string = exports.swapStrings(string, idx, match.length, replacement)
+    string = swapStrings(string, idx, match.length, replacement)
   }
   return string
 }

From 82c610efefd9f8ef9ddeee52dfaad5bf24a1af3c Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 19:57:31 +0100
Subject: [PATCH 08/75] Set string-templates path

---
 packages/worker/tsconfig.build.json | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/worker/tsconfig.build.json b/packages/worker/tsconfig.build.json
index bc477abe4d..f38f31fe67 100644
--- a/packages/worker/tsconfig.build.json
+++ b/packages/worker/tsconfig.build.json
@@ -16,7 +16,8 @@
       "@budibase/backend-core": ["../backend-core/src"],
       "@budibase/backend-core/*": ["../backend-core/*"],
       "@budibase/shared-core": ["../shared-core/src"],
-      "@budibase/pro": ["../pro/src"]
+      "@budibase/pro": ["../pro/src"],
+      "@budibase/string-templates": ["../string-templates/src"]
     }
   },
   "include": ["src/**/*"],

From 8503af6729bfae5f9f6c950ce9863841f4faedbc Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 20:33:53 +0100
Subject: [PATCH 09/75] Point to src

---
 packages/string-templates/package.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 42be7e2299..1e01a18a03 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -4,13 +4,13 @@
   "version": "0.0.0",
   "description": "Handlebars wrapper for Budibase templating.",
   "main": "src/index.js",
-  "module": "dist/bundle.mjs",
+  "module": "src/index.mjs",
   "license": "MPL-2.0",
   "types": "dist/index.d.ts",
   "exports": {
     ".": {
       "require": "./src/index.js",
-      "import": "./dist/bundle.mjs"
+      "import": "./src/index.mjs"
     },
     "./package.json": "./package.json",
     "./test/utils": "./test/utils.js"

From 6b3c4ec651eb73964dcb3aeba45ded7adbb5a36b Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 20:44:15 +0100
Subject: [PATCH 10/75] Update entrypoints

---
 packages/string-templates/package.json     |  7 ++----
 packages/string-templates/rollup.config.js |  6 ++---
 packages/string-templates/src/index.mjs    | 26 ----------------------
 3 files changed, 5 insertions(+), 34 deletions(-)
 delete mode 100644 packages/string-templates/src/index.mjs

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 1e01a18a03..754e058bda 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -3,15 +3,12 @@
   "type": "module",
   "version": "0.0.0",
   "description": "Handlebars wrapper for Budibase templating.",
-  "main": "src/index.js",
+  "main": "dist/index.cjs",
   "module": "src/index.mjs",
   "license": "MPL-2.0",
   "types": "dist/index.d.ts",
   "exports": {
-    ".": {
-      "require": "./src/index.js",
-      "import": "./src/index.mjs"
-    },
+    ".": "./src/index.mjs",
     "./package.json": "./package.json",
     "./test/utils": "./test/utils.js"
   },
diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index d7f45489c9..199a328022 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -10,11 +10,11 @@ const production = !process.env.ROLLUP_WATCH
 
 export default [
   {
-    input: "src/index.mjs",
+    input: "src/index.js",
     output: {
       sourcemap: !production,
-      format: "esm",
-      file: "./dist/bundle.mjs",
+      format: "cjs",
+      file: "./dist/bundle.cjs",
     },
     plugins: [
       resolve({
diff --git a/packages/string-templates/src/index.mjs b/packages/string-templates/src/index.mjs
deleted file mode 100644
index 39ab10f75d..0000000000
--- a/packages/string-templates/src/index.mjs
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * ES6 entrypoint for rollup
- */
-export {
-  isValid,
-  makePropSafe,
-  getManifest,
-  isJSBinding,
-  encodeJSBinding,
-  decodeJSBinding,
-  processStringSync,
-  processObjectSync,
-  processString,
-  processObject,
-  doesContainStrings,
-  doesContainString,
-  disableEscaping,
-  findHBSBlocks,
-  convertToJS,
-  setJSRunner,
-  setOnErrorLog,
-  FIND_ANY_HBS_REGEX,
-  helpersToRemoveForJs,
-} from "./index.js"
-
-export * from "./errors.js"

From 3b757476e0c7d1987287a12bc549971333c9c5fe Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 20:45:35 +0100
Subject: [PATCH 11/75] Setup typescript rollup

---
 packages/string-templates/package.json     | 1 +
 packages/string-templates/rollup.config.js | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 754e058bda..5517457d9a 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -32,6 +32,7 @@
   "devDependencies": {
     "@rollup/plugin-commonjs": "^17.1.0",
     "@rollup/plugin-json": "^4.1.0",
+    "@rollup/plugin-typescript": "8.3.0",
     "concurrently": "^8.2.2",
     "doctrine": "^3.0.0",
     "jest": "29.7.0",
diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index 199a328022..01b1931220 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -4,6 +4,7 @@ import json from "@rollup/plugin-json"
 import { terser } from "rollup-plugin-terser"
 import builtins from "rollup-plugin-node-builtins"
 import globals from "rollup-plugin-node-globals"
+import typescript from "@rollup/plugin-typescript"
 import injectProcessEnv from "rollup-plugin-inject-process-env"
 
 const production = !process.env.ROLLUP_WATCH
@@ -17,6 +18,7 @@ export default [
       file: "./dist/bundle.cjs",
     },
     plugins: [
+      typescript({ tsconfig: "tsconfig.build.json" }),
       resolve({
         preferBuiltins: true,
         browser: true,

From 046e27c7372e871fd6a9c4cb8e76980c94fae05c Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 20:50:57 +0100
Subject: [PATCH 12/75] Change from js to ts

---
 packages/string-templates/rollup.config.js                   | 2 +-
 .../string-templates/src/conversion/{index.js => index.ts}   | 0
 packages/string-templates/src/{errors.js => errors.ts}       | 0
 .../string-templates/src/helpers/{Helper.js => Helper.ts}    | 0
 .../src/helpers/{constants.js => constants.ts}               | 0
 packages/string-templates/src/helpers/{date.js => date.ts}   | 0
 .../src/helpers/{external.js => external.ts}                 | 0
 packages/string-templates/src/helpers/{index.js => index.ts} | 0
 .../src/helpers/{javascript.js => javascript.ts}             | 0
 packages/string-templates/src/helpers/{list.js => list.ts}   | 0
 packages/string-templates/src/{index.js => index.ts}         | 2 +-
 .../string-templates/src/processors/{index.js => index.ts}   | 0
 .../src/processors/{postprocessor.js => postprocessor.ts}    | 0
 .../src/processors/{preprocessor.js => preprocessor.ts}      | 5 ++++-
 packages/string-templates/src/{utilities.js => utilities.ts} | 0
 15 files changed, 6 insertions(+), 3 deletions(-)
 rename packages/string-templates/src/conversion/{index.js => index.ts} (100%)
 rename packages/string-templates/src/{errors.js => errors.ts} (100%)
 rename packages/string-templates/src/helpers/{Helper.js => Helper.ts} (100%)
 rename packages/string-templates/src/helpers/{constants.js => constants.ts} (100%)
 rename packages/string-templates/src/helpers/{date.js => date.ts} (100%)
 rename packages/string-templates/src/helpers/{external.js => external.ts} (100%)
 rename packages/string-templates/src/helpers/{index.js => index.ts} (100%)
 rename packages/string-templates/src/helpers/{javascript.js => javascript.ts} (100%)
 rename packages/string-templates/src/helpers/{list.js => list.ts} (100%)
 rename packages/string-templates/src/{index.js => index.ts} (99%)
 rename packages/string-templates/src/processors/{index.js => index.ts} (100%)
 rename packages/string-templates/src/processors/{postprocessor.js => postprocessor.ts} (100%)
 rename packages/string-templates/src/processors/{preprocessor.js => preprocessor.ts} (95%)
 rename packages/string-templates/src/{utilities.js => utilities.ts} (100%)

diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index 01b1931220..cb17fd893f 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -11,7 +11,7 @@ const production = !process.env.ROLLUP_WATCH
 
 export default [
   {
-    input: "src/index.js",
+    input: "src/index.ts",
     output: {
       sourcemap: !production,
       format: "cjs",
diff --git a/packages/string-templates/src/conversion/index.js b/packages/string-templates/src/conversion/index.ts
similarity index 100%
rename from packages/string-templates/src/conversion/index.js
rename to packages/string-templates/src/conversion/index.ts
diff --git a/packages/string-templates/src/errors.js b/packages/string-templates/src/errors.ts
similarity index 100%
rename from packages/string-templates/src/errors.js
rename to packages/string-templates/src/errors.ts
diff --git a/packages/string-templates/src/helpers/Helper.js b/packages/string-templates/src/helpers/Helper.ts
similarity index 100%
rename from packages/string-templates/src/helpers/Helper.js
rename to packages/string-templates/src/helpers/Helper.ts
diff --git a/packages/string-templates/src/helpers/constants.js b/packages/string-templates/src/helpers/constants.ts
similarity index 100%
rename from packages/string-templates/src/helpers/constants.js
rename to packages/string-templates/src/helpers/constants.ts
diff --git a/packages/string-templates/src/helpers/date.js b/packages/string-templates/src/helpers/date.ts
similarity index 100%
rename from packages/string-templates/src/helpers/date.js
rename to packages/string-templates/src/helpers/date.ts
diff --git a/packages/string-templates/src/helpers/external.js b/packages/string-templates/src/helpers/external.ts
similarity index 100%
rename from packages/string-templates/src/helpers/external.js
rename to packages/string-templates/src/helpers/external.ts
diff --git a/packages/string-templates/src/helpers/index.js b/packages/string-templates/src/helpers/index.ts
similarity index 100%
rename from packages/string-templates/src/helpers/index.js
rename to packages/string-templates/src/helpers/index.ts
diff --git a/packages/string-templates/src/helpers/javascript.js b/packages/string-templates/src/helpers/javascript.ts
similarity index 100%
rename from packages/string-templates/src/helpers/javascript.js
rename to packages/string-templates/src/helpers/javascript.ts
diff --git a/packages/string-templates/src/helpers/list.js b/packages/string-templates/src/helpers/list.ts
similarity index 100%
rename from packages/string-templates/src/helpers/list.js
rename to packages/string-templates/src/helpers/list.ts
diff --git a/packages/string-templates/src/index.js b/packages/string-templates/src/index.ts
similarity index 99%
rename from packages/string-templates/src/index.js
rename to packages/string-templates/src/index.ts
index 4299e9d5b2..3a38c7868f 100644
--- a/packages/string-templates/src/index.js
+++ b/packages/string-templates/src/index.ts
@@ -3,7 +3,7 @@ import { create } from "handlebars"
 import { registerAll, registerMinimum } from "./helpers/index"
 import { preprocess, postprocess } from "./processors"
 import { atob, btoa, isBackendService } from "./utilities"
-import manifest from "../manifest.json"
+const manifest = require("../manifest.json")
 import {
   FIND_HBS_REGEX,
   FIND_ANY_HBS_REGEX,
diff --git a/packages/string-templates/src/processors/index.js b/packages/string-templates/src/processors/index.ts
similarity index 100%
rename from packages/string-templates/src/processors/index.js
rename to packages/string-templates/src/processors/index.ts
diff --git a/packages/string-templates/src/processors/postprocessor.js b/packages/string-templates/src/processors/postprocessor.ts
similarity index 100%
rename from packages/string-templates/src/processors/postprocessor.js
rename to packages/string-templates/src/processors/postprocessor.ts
diff --git a/packages/string-templates/src/processors/preprocessor.js b/packages/string-templates/src/processors/preprocessor.ts
similarity index 95%
rename from packages/string-templates/src/processors/preprocessor.js
rename to packages/string-templates/src/processors/preprocessor.ts
index a7210fe520..39cfc07359 100644
--- a/packages/string-templates/src/processors/preprocessor.js
+++ b/packages/string-templates/src/processors/preprocessor.ts
@@ -11,12 +11,15 @@ export const PreprocessorNames = {
 
 /* eslint-disable no-unused-vars */
 class Preprocessor {
+  private name: string
+  private fn: any
+
   constructor(name, fn) {
     this.name = name
     this.fn = fn
   }
 
-  process(fullString, statement, opts) {
+  process(fullString: string, statement: string, opts: Object) {
     const output = this.fn(statement, opts)
     const idx = fullString.indexOf(statement)
     return swapStrings(fullString, idx, statement.length, output)
diff --git a/packages/string-templates/src/utilities.js b/packages/string-templates/src/utilities.ts
similarity index 100%
rename from packages/string-templates/src/utilities.js
rename to packages/string-templates/src/utilities.ts

From a572cc980fef85ae1d520b7a3837b35104293942 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 21:10:53 +0100
Subject: [PATCH 13/75] Fix ts

---
 packages/string-templates/rollup.config.js    |  2 +-
 .../string-templates/src/conversion/index.ts  |  2 +-
 packages/string-templates/src/errors.ts       |  4 ---
 .../string-templates/src/helpers/Helper.ts    |  4 +++
 packages/string-templates/src/helpers/date.ts | 30 ++++++++++++-------
 .../string-templates/src/helpers/index.ts     |  5 ++--
 packages/string-templates/src/helpers/list.ts |  2 +-
 .../string-templates/src/processors/index.ts  |  2 +-
 .../src/processors/postprocessor.ts           |  3 ++
 .../src/processors/preprocessor.ts            |  2 +-
 packages/string-templates/src/utilities.ts    | 19 +++++++-----
 packages/string-templates/tsconfig.json       |  3 ++
 12 files changed, 50 insertions(+), 28 deletions(-)

diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index cb17fd893f..8b5f7a32e4 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -18,7 +18,7 @@ export default [
       file: "./dist/bundle.cjs",
     },
     plugins: [
-      typescript({ tsconfig: "tsconfig.build.json" }),
+      typescript({ tsconfig: "tsconfig.json" }),
       resolve({
         preferBuiltins: true,
         browser: true,
diff --git a/packages/string-templates/src/conversion/index.ts b/packages/string-templates/src/conversion/index.ts
index c6ec012ad9..1fb8d97467 100644
--- a/packages/string-templates/src/conversion/index.ts
+++ b/packages/string-templates/src/conversion/index.ts
@@ -114,7 +114,7 @@ export function convertHBSBlock(block, blockNumber) {
     const parts = splitBySpace(layer)
     if (value || parts.length > 1 || list[parts[0]]) {
       // first of layer should always be the helper
-      const helper = parts.splice(0, 1)
+      const [helper] = parts.splice(0, 1)
       if (list[helper]) {
         value = `helpers.${helper}(${buildList(parts, value)})`
       }
diff --git a/packages/string-templates/src/errors.ts b/packages/string-templates/src/errors.ts
index a0108d5018..79a8a525ef 100644
--- a/packages/string-templates/src/errors.ts
+++ b/packages/string-templates/src/errors.ts
@@ -1,7 +1,3 @@
 export class JsErrorTimeout extends Error {
   code = "ERR_SCRIPT_EXECUTION_TIMEOUT"
-
-  constructor() {
-    super()
-  }
 }
diff --git a/packages/string-templates/src/helpers/Helper.ts b/packages/string-templates/src/helpers/Helper.ts
index e7e7488c0f..e254b2086d 100644
--- a/packages/string-templates/src/helpers/Helper.ts
+++ b/packages/string-templates/src/helpers/Helper.ts
@@ -1,4 +1,8 @@
 export default class Helper {
+  private name
+  private fn
+  private useValueFallback
+
   constructor(name, fn, useValueFallback = true) {
     this.name = name
     this.fn = fn
diff --git a/packages/string-templates/src/helpers/date.ts b/packages/string-templates/src/helpers/date.ts
index 9d663573bd..70dc0bd617 100644
--- a/packages/string-templates/src/helpers/date.ts
+++ b/packages/string-templates/src/helpers/date.ts
@@ -1,12 +1,22 @@
 import dayjs from "dayjs"
-dayjs.extend(require("dayjs/plugin/duration"))
-dayjs.extend(require("dayjs/plugin/advancedFormat"))
-dayjs.extend(require("dayjs/plugin/isoWeek"))
-dayjs.extend(require("dayjs/plugin/weekYear"))
-dayjs.extend(require("dayjs/plugin/weekOfYear"))
-dayjs.extend(require("dayjs/plugin/relativeTime"))
-dayjs.extend(require("dayjs/plugin/utc"))
-dayjs.extend(require("dayjs/plugin/timezone"))
+
+import dayjsDurationPlugin from "dayjs/plugin/duration"
+import dayjsAdvancedFormatPlugin from "dayjs/plugin/advancedFormat"
+import dayjsIsoWeekPlugin from "dayjs/plugin/isoWeek"
+import dayjsWeekYearPlugin from "dayjs/plugin/weekYear"
+import dayjsWeekOfYearPlugin from "dayjs/plugin/weekOfYear"
+import dayjsRelativeTimePlugin from "dayjs/plugin/relativeTime"
+import dayjsUtcPlugin from "dayjs/plugin/utc"
+import dayjsTimezonePlugin from "dayjs/plugin/timezone"
+
+dayjs.extend(dayjsDurationPlugin)
+dayjs.extend(dayjsAdvancedFormatPlugin)
+dayjs.extend(dayjsIsoWeekPlugin)
+dayjs.extend(dayjsWeekYearPlugin)
+dayjs.extend(dayjsWeekOfYearPlugin)
+dayjs.extend(dayjsRelativeTimePlugin)
+dayjs.extend(dayjsUtcPlugin)
+dayjs.extend(dayjsTimezonePlugin)
 
 /**
  * This file was largely taken from the helper-date package - we did this for two reasons:
@@ -58,7 +68,7 @@ function getContext(thisArg, locals, options) {
   return context
 }
 
-function initialConfig(str, pattern, options) {
+function initialConfig(str, pattern, options = {}) {
   if (isOptions(pattern)) {
     options = pattern
     pattern = null
@@ -72,7 +82,7 @@ function initialConfig(str, pattern, options) {
   return { str, pattern, options }
 }
 
-function setLocale(str, pattern, options) {
+function setLocale(str, pattern, options = {}) {
   // if options is null then it'll get updated here
   const config = initialConfig(str, pattern, options)
   const defaults = { lang: "en", date: new Date(config.str) }
diff --git a/packages/string-templates/src/helpers/index.ts b/packages/string-templates/src/helpers/index.ts
index bad861567d..19d4ee3dff 100644
--- a/packages/string-templates/src/helpers/index.ts
+++ b/packages/string-templates/src/helpers/index.ts
@@ -44,8 +44,9 @@ const HELPERS = [
     if (value == null || typeof value !== "string") {
       return value == null ? "" : value
     }
-    if (value && value.string) {
-      value = value.string
+    // 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) {
diff --git a/packages/string-templates/src/helpers/list.ts b/packages/string-templates/src/helpers/list.ts
index 8f08bc6f12..fde42b659a 100644
--- a/packages/string-templates/src/helpers/list.ts
+++ b/packages/string-templates/src/helpers/list.ts
@@ -1,7 +1,7 @@
 import { date, duration } from "./date"
 
 // https://github.com/evanw/esbuild/issues/56
-const externalCollections = {
+const externalCollections: Record<string, () => any> = {
   math: require("@budibase/handlebars-helpers/lib/math"),
   array: require("@budibase/handlebars-helpers/lib/array"),
   number: require("@budibase/handlebars-helpers/lib/number"),
diff --git a/packages/string-templates/src/processors/index.ts b/packages/string-templates/src/processors/index.ts
index a5bcf84eaf..7187bb6fd8 100644
--- a/packages/string-templates/src/processors/index.ts
+++ b/packages/string-templates/src/processors/index.ts
@@ -2,7 +2,7 @@ import { FIND_HBS_REGEX } from "../utilities"
 import * as preprocessor from "./preprocessor"
 import * as postprocessor from "./postprocessor"
 
-function process(output, processors, opts) {
+function process(output, processors, opts = {}) {
   for (let processor of processors) {
     // if a literal statement has occurred stop
     if (typeof output !== "string") {
diff --git a/packages/string-templates/src/processors/postprocessor.ts b/packages/string-templates/src/processors/postprocessor.ts
index 3122d43e53..39125b225a 100644
--- a/packages/string-templates/src/processors/postprocessor.ts
+++ b/packages/string-templates/src/processors/postprocessor.ts
@@ -6,6 +6,9 @@ export const PostProcessorNames = {
 
 /* eslint-disable no-unused-vars */
 class Postprocessor {
+  name
+  private fn
+
   constructor(name, fn) {
     this.name = name
     this.fn = fn
diff --git a/packages/string-templates/src/processors/preprocessor.ts b/packages/string-templates/src/processors/preprocessor.ts
index 39cfc07359..1fcbac629f 100644
--- a/packages/string-templates/src/processors/preprocessor.ts
+++ b/packages/string-templates/src/processors/preprocessor.ts
@@ -11,7 +11,7 @@ export const PreprocessorNames = {
 
 /* eslint-disable no-unused-vars */
 class Preprocessor {
-  private name: string
+  name: string
   private fn: any
 
   constructor(name, fn) {
diff --git a/packages/string-templates/src/utilities.ts b/packages/string-templates/src/utilities.ts
index 017f38db47..bcb9987c89 100644
--- a/packages/string-templates/src/utilities.ts
+++ b/packages/string-templates/src/utilities.ts
@@ -15,14 +15,14 @@ export const isJSAllowed = () => {
 // originally this could be done with a single regex using look behinds
 // but safari does not support this feature
 // original regex: /(?<!{){{[^{}]+}}(?!})/g
-export const findDoubleHbsInstances = string => {
+export const findDoubleHbsInstances = (string: string): string[] => {
   let copied = string
   const doubleRegex = new RegExp(FIND_HBS_REGEX)
   const regex = new RegExp(FIND_TRIPLE_HBS_REGEX)
   const tripleMatches = copied.match(regex)
   // remove triple braces
   if (tripleMatches) {
-    tripleMatches.forEach(match => {
+    tripleMatches.forEach((match: string) => {
       copied = copied.replace(match, "")
     })
   }
@@ -30,16 +30,21 @@ export const findDoubleHbsInstances = string => {
   return doubleMatches ? doubleMatches : []
 }
 
-export const isAlphaNumeric = char => {
+export const isAlphaNumeric = (char: string) => {
   return char.match(ALPHA_NUMERIC_REGEX)
 }
 
-export const swapStrings = (string, start, length, swap) => {
+export const swapStrings = (
+  string: string,
+  start: number,
+  length: number,
+  swap: string
+) => {
   return string.slice(0, start) + swap + string.slice(start + length)
 }
 
 export const removeHandlebarsStatements = (
-  string,
+  string: string,
   replacement = "Invalid binding"
 ) => {
   let regexp = new RegExp(FIND_HBS_REGEX)
@@ -54,10 +59,10 @@ export const removeHandlebarsStatements = (
   return string
 }
 
-export const btoa = plainText => {
+export const btoa = (plainText: string) => {
   return Buffer.from(plainText, "utf-8").toString("base64")
 }
 
-export const atob = base64 => {
+export const atob = (base64: string) => {
   return Buffer.from(base64, "base64").toString("utf-8")
 }
diff --git a/packages/string-templates/tsconfig.json b/packages/string-templates/tsconfig.json
index a7c7a0df67..52e3d78d20 100644
--- a/packages/string-templates/tsconfig.json
+++ b/packages/string-templates/tsconfig.json
@@ -1,6 +1,9 @@
 {
   "include": ["src/**/*"],
   "compilerOptions": {
+    "target": "es6",
+    "moduleResolution": "node",
+    "lib": ["dom"],
     "allowJs": true,
     "declaration": true,
     "emitDeclarationOnly": true,

From 0ad7bde47846a2adb392ad0239db2f004efb3639 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 21:13:50 +0100
Subject: [PATCH 14/75] Don't run tsc

---
 packages/string-templates/package.json  | 5 ++---
 packages/string-templates/tsconfig.json | 2 --
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 5517457d9a..3c9156ec20 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -18,8 +18,8 @@
     "manifest.json"
   ],
   "scripts": {
-    "build": "tsc && rollup -c",
-    "dev": "concurrently \"tsc --watch\" \"rollup -cw\"",
+    "build": "rollup -c",
+    "dev": "rollup -cw",
     "test": "jest",
     "manifest": "node ./scripts/gen-collection-info.js"
   },
@@ -33,7 +33,6 @@
     "@rollup/plugin-commonjs": "^17.1.0",
     "@rollup/plugin-json": "^4.1.0",
     "@rollup/plugin-typescript": "8.3.0",
-    "concurrently": "^8.2.2",
     "doctrine": "^3.0.0",
     "jest": "29.7.0",
     "marked": "^4.0.10",
diff --git a/packages/string-templates/tsconfig.json b/packages/string-templates/tsconfig.json
index 52e3d78d20..07084de469 100644
--- a/packages/string-templates/tsconfig.json
+++ b/packages/string-templates/tsconfig.json
@@ -5,8 +5,6 @@
     "moduleResolution": "node",
     "lib": ["dom"],
     "allowJs": true,
-    "declaration": true,
-    "emitDeclarationOnly": true,
     "outDir": "dist",
     "esModuleInterop": true,
     "types": ["node", "jest"]

From 667a5ab9905b3e94072ad8c12a1b152d5747ec2f Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 21:41:27 +0100
Subject: [PATCH 15/75] Fix package.json refs

---
 packages/string-templates/package.json | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 3c9156ec20..842932b021 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -3,12 +3,15 @@
   "type": "module",
   "version": "0.0.0",
   "description": "Handlebars wrapper for Budibase templating.",
-  "main": "dist/index.cjs",
-  "module": "src/index.mjs",
+  "main": "dist/bundle.cjs",
+  "module": "src/index.ts",
   "license": "MPL-2.0",
   "types": "dist/index.d.ts",
   "exports": {
-    ".": "./src/index.mjs",
+    ".": {
+      "require": "./dist/bundle.cjs",
+      "import": "./src/index.ts"
+    },
     "./package.json": "./package.json",
     "./test/utils": "./test/utils.js"
   },

From 2339030fe28e9d1308706f271a0ac34e9947a14b Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 22:35:02 +0100
Subject: [PATCH 16/75] Build both cjs and mjs versions

---
 packages/string-templates/package.json     |  5 +--
 packages/string-templates/rollup.config.js | 49 ++++++++++++----------
 2 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 842932b021..002c5e8ab4 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -4,13 +4,12 @@
   "version": "0.0.0",
   "description": "Handlebars wrapper for Budibase templating.",
   "main": "dist/bundle.cjs",
-  "module": "src/index.ts",
+  "module": "dist/bundle.mjs",
   "license": "MPL-2.0",
-  "types": "dist/index.d.ts",
   "exports": {
     ".": {
       "require": "./dist/bundle.cjs",
-      "import": "./src/index.ts"
+      "import": "./dist/bundle.mjs"
     },
     "./package.json": "./package.json",
     "./test/utils": "./test/utils.js"
diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index 8b5f7a32e4..ddc770fde1 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -9,28 +9,31 @@ import injectProcessEnv from "rollup-plugin-inject-process-env"
 
 const production = !process.env.ROLLUP_WATCH
 
-export default [
-  {
-    input: "src/index.ts",
-    output: {
-      sourcemap: !production,
-      format: "cjs",
-      file: "./dist/bundle.cjs",
-    },
-    plugins: [
-      typescript({ tsconfig: "tsconfig.json" }),
-      resolve({
-        preferBuiltins: true,
-        browser: true,
-      }),
-      commonjs(),
-      globals(),
-      builtins(),
-      json(),
-      injectProcessEnv({
-        NO_JS: process.env.NO_JS,
-      }),
-      production && terser(),
-    ],
+const config = (format, outputFile) => ({
+  input: "src/index.ts",
+  output: {
+    sourcemap: !production,
+    format,
+    file: outputFile,
   },
+  plugins: [
+    typescript({ tsconfig: "tsconfig.json" }),
+    resolve({
+      preferBuiltins: true,
+      browser: true,
+    }),
+    commonjs(),
+    globals(),
+    builtins(),
+    json(),
+    injectProcessEnv({
+      NO_JS: process.env.NO_JS,
+    }),
+    // production && terser(),
+  ],
+})
+
+export default [
+  config("cjs", "./dist/bundle.cjs"),
+  config("esm", "./dist/bundle.mjs"),
 ]

From 16ca7bbc45f06c137bfc4528cf7ee57011201849 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 22:35:30 +0100
Subject: [PATCH 17/75] Fix requires

---
 packages/string-templates/src/helpers/list.ts | 6 +++---
 packages/string-templates/src/index.ts        | 6 +++++-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/packages/string-templates/src/helpers/list.ts b/packages/string-templates/src/helpers/list.ts
index fde42b659a..7b25216976 100644
--- a/packages/string-templates/src/helpers/list.ts
+++ b/packages/string-templates/src/helpers/list.ts
@@ -1,7 +1,7 @@
 import { date, duration } from "./date"
 
 // https://github.com/evanw/esbuild/issues/56
-const externalCollections: Record<string, () => any> = {
+const getExternalCollections = (): Record<string, () => any> => ({
   math: require("@budibase/handlebars-helpers/lib/math"),
   array: require("@budibase/handlebars-helpers/lib/array"),
   number: require("@budibase/handlebars-helpers/lib/number"),
@@ -11,7 +11,7 @@ const externalCollections: Record<string, () => any> = {
   object: require("@budibase/handlebars-helpers/lib/object"),
   regex: require("@budibase/handlebars-helpers/lib/regex"),
   uuid: require("@budibase/handlebars-helpers/lib/uuid"),
-}
+})
 
 export const helpersToRemoveForJs = ["sortBy"]
 
@@ -28,7 +28,7 @@ export function getJsHelperList() {
   }
 
   helpers = {}
-  for (let collection of Object.values(externalCollections)) {
+  for (let collection of Object.values(getExternalCollections())) {
     for (let [key, func] of Object.entries(collection)) {
       // Handlebars injects the hbs options to the helpers by default. We are adding an empty {} as a last parameter to simulate it
       helpers[key] = (...props) => func(...props, {})
diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 3a38c7868f..354af0f612 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -1,9 +1,9 @@
+import fs from "fs"
 import { createContext, runInNewContext } from "vm"
 import { create } from "handlebars"
 import { registerAll, registerMinimum } from "./helpers/index"
 import { preprocess, postprocess } from "./processors"
 import { atob, btoa, isBackendService } from "./utilities"
-const manifest = require("../manifest.json")
 import {
   FIND_HBS_REGEX,
   FIND_ANY_HBS_REGEX,
@@ -252,7 +252,11 @@ export function isValid(string, opts) {
  * This manifest provides information about each of the helpers and how it can be used.
  * @returns The manifest JSON which has been generated from the helpers.
  */
+let manifest
 export function getManifest() {
+  if (!manifest) {
+    manifest = fs.readFileSync(require.resolve("../manifest.json"), "utf-8")
+  }
   return manifest
 }
 

From 52fd8c23699c760eea4407491440f2bbb9db25fe Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 22:38:09 +0100
Subject: [PATCH 18/75] Remove not required rollup plugin

---
 packages/string-templates/package.json     | 1 -
 packages/string-templates/rollup.config.js | 3 +--
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 002c5e8ab4..a2a71ef686 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -33,7 +33,6 @@
   },
   "devDependencies": {
     "@rollup/plugin-commonjs": "^17.1.0",
-    "@rollup/plugin-json": "^4.1.0",
     "@rollup/plugin-typescript": "8.3.0",
     "doctrine": "^3.0.0",
     "jest": "29.7.0",
diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index ddc770fde1..a86a5d0caf 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -1,6 +1,5 @@
 import commonjs from "@rollup/plugin-commonjs"
 import resolve from "rollup-plugin-node-resolve"
-import json from "@rollup/plugin-json"
 import { terser } from "rollup-plugin-terser"
 import builtins from "rollup-plugin-node-builtins"
 import globals from "rollup-plugin-node-globals"
@@ -29,7 +28,7 @@ const config = (format, outputFile) => ({
     injectProcessEnv({
       NO_JS: process.env.NO_JS,
     }),
-    // production && terser(),
+    production && terser(),
   ],
 })
 

From afe2335ed82c5b2f390781190151612edaf453af Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 22:59:12 +0100
Subject: [PATCH 19/75] Fix rollup config

---
 packages/string-templates/rollup.config.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index a86a5d0caf..056ca58bb1 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -24,7 +24,6 @@ const config = (format, outputFile) => ({
     commonjs(),
     globals(),
     builtins(),
-    json(),
     injectProcessEnv({
       NO_JS: process.env.NO_JS,
     }),

From 05c8f9b956ea467253f60192b110c22bd928ba7c Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 23:01:34 +0100
Subject: [PATCH 20/75] Fix js

---
 packages/string-templates/src/helpers/date.ts     | 4 ++--
 packages/string-templates/src/index.ts            | 2 +-
 packages/string-templates/src/processors/index.ts | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/packages/string-templates/src/helpers/date.ts b/packages/string-templates/src/helpers/date.ts
index 70dc0bd617..efcf516dfb 100644
--- a/packages/string-templates/src/helpers/date.ts
+++ b/packages/string-templates/src/helpers/date.ts
@@ -68,7 +68,7 @@ function getContext(thisArg, locals, options) {
   return context
 }
 
-function initialConfig(str, pattern, options = {}) {
+function initialConfig(str, pattern, options?) {
   if (isOptions(pattern)) {
     options = pattern
     pattern = null
@@ -82,7 +82,7 @@ function initialConfig(str, pattern, options = {}) {
   return { str, pattern, options }
 }
 
-function setLocale(str, pattern, options = {}) {
+function setLocale(str, pattern, options?) {
   // if options is null then it'll get updated here
   const config = initialConfig(str, pattern, options)
   const defaults = { lang: "en", date: new Date(config.str) }
diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 354af0f612..5fc9af9573 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -137,7 +137,7 @@ export function processObjectSync(object, context, opts) {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {string} The enriched string, all templates should have been replaced if they can be.
  */
-export function processStringSync(string, context, opts) {
+export function processStringSync(string, context, opts?) {
   // Take a copy of input in case of error
   const input = string
   if (typeof string !== "string") {
diff --git a/packages/string-templates/src/processors/index.ts b/packages/string-templates/src/processors/index.ts
index 7187bb6fd8..e1743b2f4c 100644
--- a/packages/string-templates/src/processors/index.ts
+++ b/packages/string-templates/src/processors/index.ts
@@ -2,7 +2,7 @@ import { FIND_HBS_REGEX } from "../utilities"
 import * as preprocessor from "./preprocessor"
 import * as postprocessor from "./postprocessor"
 
-function process(output, processors, opts = {}) {
+function process(output, processors, opts?) {
   for (let processor of processors) {
     // if a literal statement has occurred stop
     if (typeof output !== "string") {

From c9973b5ecdc1847a973480366e588d3da41d1a1e Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 23:03:54 +0100
Subject: [PATCH 21/75] Remove type

---
 packages/string-templates/package.json | 1 -
 1 file changed, 1 deletion(-)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index a2a71ef686..b867eb7920 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -1,6 +1,5 @@
 {
   "name": "@budibase/string-templates",
-  "type": "module",
   "version": "0.0.0",
   "description": "Handlebars wrapper for Budibase templating.",
   "main": "dist/bundle.cjs",

From f78230521981c31607e2491c606996a55260d596 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 23:11:38 +0100
Subject: [PATCH 22/75] Change to js

---
 .../test/{basic.spec.js => basic.spec.ts}                 | 2 +-
 .../string-templates/test/{constants.js => constants.ts}  | 2 +-
 .../test/{escapes.spec.js => escapes.spec.ts}             | 0
 .../test/{hbsToJs.spec.js => hbsToJs.spec.ts}             | 0
 .../test/{helpers.spec.js => helpers.spec.ts}             | 8 ++++----
 .../test/{javascript.spec.js => javascript.spec.ts}       | 2 +-
 .../test/{manifest.spec.js => manifest.spec.ts}           | 2 +-
 .../test/{renderApp.spec.js => renderApp.spec.ts}         | 2 +-
 packages/string-templates/test/{utils.js => utils.ts}     | 0
 packages/string-templates/test/{vm.spec.js => vm.spec.ts} | 0
 10 files changed, 9 insertions(+), 9 deletions(-)
 rename packages/string-templates/test/{basic.spec.js => basic.spec.ts} (99%)
 rename packages/string-templates/test/{constants.js => constants.ts} (72%)
 rename packages/string-templates/test/{escapes.spec.js => escapes.spec.ts} (100%)
 rename packages/string-templates/test/{hbsToJs.spec.js => hbsToJs.spec.ts} (100%)
 rename packages/string-templates/test/{helpers.spec.js => helpers.spec.ts} (98%)
 rename packages/string-templates/test/{javascript.spec.js => javascript.spec.ts} (99%)
 rename packages/string-templates/test/{manifest.spec.js => manifest.spec.ts} (96%)
 rename packages/string-templates/test/{renderApp.spec.js => renderApp.spec.ts} (94%)
 rename packages/string-templates/test/{utils.js => utils.ts} (100%)
 rename packages/string-templates/test/{vm.spec.js => vm.spec.ts} (100%)

diff --git a/packages/string-templates/test/basic.spec.js b/packages/string-templates/test/basic.spec.ts
similarity index 99%
rename from packages/string-templates/test/basic.spec.js
rename to packages/string-templates/test/basic.spec.ts
index 0b78e3cafd..e096a3fe45 100644
--- a/packages/string-templates/test/basic.spec.js
+++ b/packages/string-templates/test/basic.spec.ts
@@ -8,7 +8,7 @@ const {
   doesContainString,
   disableEscaping,
   findHBSBlocks,
-} = require("../src/index.js")
+} = require("../src/index")
 
 describe("Test that the string processing works correctly", () => {
   it("should process a basic template string", async () => {
diff --git a/packages/string-templates/test/constants.js b/packages/string-templates/test/constants.ts
similarity index 72%
rename from packages/string-templates/test/constants.js
rename to packages/string-templates/test/constants.ts
index aac0291636..b9e31bcfcc 100644
--- a/packages/string-templates/test/constants.js
+++ b/packages/string-templates/test/constants.ts
@@ -1,2 +1,2 @@
-module.exports.UUID_REGEX =
+export const UUID_REGEX =
   /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
diff --git a/packages/string-templates/test/escapes.spec.js b/packages/string-templates/test/escapes.spec.ts
similarity index 100%
rename from packages/string-templates/test/escapes.spec.js
rename to packages/string-templates/test/escapes.spec.ts
diff --git a/packages/string-templates/test/hbsToJs.spec.js b/packages/string-templates/test/hbsToJs.spec.ts
similarity index 100%
rename from packages/string-templates/test/hbsToJs.spec.js
rename to packages/string-templates/test/hbsToJs.spec.ts
diff --git a/packages/string-templates/test/helpers.spec.js b/packages/string-templates/test/helpers.spec.ts
similarity index 98%
rename from packages/string-templates/test/helpers.spec.js
rename to packages/string-templates/test/helpers.spec.ts
index 86fef538d3..0207ee5568 100644
--- a/packages/string-templates/test/helpers.spec.js
+++ b/packages/string-templates/test/helpers.spec.ts
@@ -1,7 +1,7 @@
-const { processString, processObject, isValid } = require("../src/index.js")
-const tableJson = require("./examples/table.json")
-const dayjs = require("dayjs")
-const { UUID_REGEX } = require("./constants")
+import { processString, processObject, isValid } from "../src/index"
+import tableJson from "./examples/table.json"
+import dayjs from "dayjs"
+import { UUID_REGEX } from "./constants"
 
 describe("test the custom helpers we have applied", () => {
   it("should be able to use the object helper", async () => {
diff --git a/packages/string-templates/test/javascript.spec.js b/packages/string-templates/test/javascript.spec.ts
similarity index 99%
rename from packages/string-templates/test/javascript.spec.js
rename to packages/string-templates/test/javascript.spec.ts
index 0e9f196da6..3c9524e165 100644
--- a/packages/string-templates/test/javascript.spec.js
+++ b/packages/string-templates/test/javascript.spec.ts
@@ -4,7 +4,7 @@ const {
   processStringSync,
   encodeJSBinding,
   setJSRunner,
-} = require("../src/index.js")
+} = require("../src/index")
 const { UUID_REGEX } = require("./constants")
 
 const processJS = (js, context) => {
diff --git a/packages/string-templates/test/manifest.spec.js b/packages/string-templates/test/manifest.spec.ts
similarity index 96%
rename from packages/string-templates/test/manifest.spec.js
rename to packages/string-templates/test/manifest.spec.ts
index 81183f13c9..cd2041f5d2 100644
--- a/packages/string-templates/test/manifest.spec.js
+++ b/packages/string-templates/test/manifest.spec.ts
@@ -17,7 +17,7 @@ jest.mock("@budibase/handlebars-helpers/lib/uuid", () => {
   }
 })
 
-const { processString, setJSRunner } = require("../src/index.js")
+const { processString, setJSRunner } = require("../src/index")
 
 const tk = require("timekeeper")
 const { getParsedManifest, runJsHelpersTests } = require("./utils")
diff --git a/packages/string-templates/test/renderApp.spec.js b/packages/string-templates/test/renderApp.spec.ts
similarity index 94%
rename from packages/string-templates/test/renderApp.spec.js
rename to packages/string-templates/test/renderApp.spec.ts
index 582e70701f..f09bc1c2b9 100644
--- a/packages/string-templates/test/renderApp.spec.js
+++ b/packages/string-templates/test/renderApp.spec.ts
@@ -1,4 +1,4 @@
-const { processString } = require("../src/index.js")
+const { processString } = require("../src/index")
 
 describe("specific test case for whether or not full app template can still be rendered", () => {
   it("should be able to render the app template", async () => {
diff --git a/packages/string-templates/test/utils.js b/packages/string-templates/test/utils.ts
similarity index 100%
rename from packages/string-templates/test/utils.js
rename to packages/string-templates/test/utils.ts
diff --git a/packages/string-templates/test/vm.spec.js b/packages/string-templates/test/vm.spec.ts
similarity index 100%
rename from packages/string-templates/test/vm.spec.js
rename to packages/string-templates/test/vm.spec.ts

From 0b292f2e824ab6f04de82dfbc6c8216829793bd3 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 23:16:54 +0100
Subject: [PATCH 23/75] Allow ts tests

---
 packages/string-templates/jest.config.js     | 1 +
 packages/string-templates/src/index.ts       | 6 +++++-
 packages/string-templates/test/basic.spec.ts | 2 +-
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/packages/string-templates/jest.config.js b/packages/string-templates/jest.config.js
index c6391cdb92..4916ebf894 100644
--- a/packages/string-templates/jest.config.js
+++ b/packages/string-templates/jest.config.js
@@ -4,6 +4,7 @@
  */
 
 module.exports = {
+  preset: "ts-jest",
   // All imported modules in your tests should be mocked automatically
   // automock: false,
 
diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 5fc9af9573..bf5a250c21 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -102,7 +102,11 @@ export async function processObject(object, context, opts) {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {Promise<string>} The enriched string, all templates should have been replaced if they can be.
  */
-export async function processString(string, context, opts) {
+export async function processString(
+  string: string,
+  context: object,
+  opts?: { noHelpers: boolean }
+) {
   // TODO: carry out any async calls before carrying out async call
   return processStringSync(string, context, opts)
 }
diff --git a/packages/string-templates/test/basic.spec.ts b/packages/string-templates/test/basic.spec.ts
index e096a3fe45..b1e2865486 100644
--- a/packages/string-templates/test/basic.spec.ts
+++ b/packages/string-templates/test/basic.spec.ts
@@ -76,7 +76,7 @@ describe("Test that the object processing works correctly", () => {
   it("should fail gracefully when object passed in has cycles", async () => {
     let error = null
     try {
-      const innerObj = { a: "thing {{ a }}" }
+      const innerObj: any = { a: "thing {{ a }}" }
       innerObj.b = innerObj
       await processObject(innerObj, { a: 1 })
     } catch (err) {

From b05dc6ab498dc39b513e193c68125745959f0132 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 23:43:12 +0100
Subject: [PATCH 24/75] Fix typings

---
 packages/string-templates/src/index.ts        |  9 +--
 .../string-templates/test/helpers.spec.ts     |  6 +-
 .../string-templates/test/javascript.spec.ts  |  2 +-
 .../string-templates/test/manifest.spec.ts    |  8 +--
 packages/string-templates/test/utils.ts       | 56 +++++++++++--------
 packages/string-templates/tsconfig.json       |  3 +-
 6 files changed, 46 insertions(+), 38 deletions(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index bf5a250c21..2549d0b34c 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -79,7 +79,7 @@ function createTemplate(string, opts) {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {Promise<object|array>} The structure input, as fully updated as possible.
  */
-export async function processObject(object, context, opts) {
+export async function processObject(object, context, opts?) {
   testObject(object)
   for (let key of Object.keys(object || {})) {
     if (object[key] != null) {
@@ -214,7 +214,7 @@ export function makePropSafe(property) {
  * @param [opts] optional - specify some options for processing.
  * @returns {boolean} Whether or not the input string is valid.
  */
-export function isValid(string, opts) {
+export function isValid(string, opts?) {
   const validCases = [
     "string",
     "number",
@@ -256,11 +256,8 @@ export function isValid(string, opts) {
  * This manifest provides information about each of the helpers and how it can be used.
  * @returns The manifest JSON which has been generated from the helpers.
  */
-let manifest
+import manifest from "../manifest.json"
 export function getManifest() {
-  if (!manifest) {
-    manifest = fs.readFileSync(require.resolve("../manifest.json"), "utf-8")
-  }
   return manifest
 }
 
diff --git a/packages/string-templates/test/helpers.spec.ts b/packages/string-templates/test/helpers.spec.ts
index 0207ee5568..efa6b0fdc3 100644
--- a/packages/string-templates/test/helpers.spec.ts
+++ b/packages/string-templates/test/helpers.spec.ts
@@ -188,9 +188,7 @@ describe("test the date helpers", () => {
         time: date.toUTCString(),
       }
     )
-    const formatted = new dayjs(date)
-      .tz("America/New_York")
-      .format("HH-mm-ss Z")
+    const formatted = dayjs(date).tz("America/New_York").format("HH-mm-ss Z")
     expect(output).toBe(formatted)
   })
 
@@ -200,7 +198,7 @@ describe("test the date helpers", () => {
       time: date.toUTCString(),
     })
     const timezone = dayjs.tz.guess()
-    const offset = new dayjs(date).tz(timezone).format("Z")
+    const offset = dayjs(date).tz(timezone).format("Z")
     expect(output).toBe(offset)
   })
 })
diff --git a/packages/string-templates/test/javascript.spec.ts b/packages/string-templates/test/javascript.spec.ts
index 3c9524e165..ab68e70830 100644
--- a/packages/string-templates/test/javascript.spec.ts
+++ b/packages/string-templates/test/javascript.spec.ts
@@ -7,7 +7,7 @@ const {
 } = require("../src/index")
 const { UUID_REGEX } = require("./constants")
 
-const processJS = (js, context) => {
+const processJS = (js, context?) => {
   return processStringSync(encodeJSBinding(js), context)
 }
 
diff --git a/packages/string-templates/test/manifest.spec.ts b/packages/string-templates/test/manifest.spec.ts
index cd2041f5d2..9fbf4e8019 100644
--- a/packages/string-templates/test/manifest.spec.ts
+++ b/packages/string-templates/test/manifest.spec.ts
@@ -1,4 +1,4 @@
-const vm = require("vm")
+import vm from "vm"
 
 jest.mock("@budibase/handlebars-helpers/lib/math", () => {
   const actual = jest.requireActual("@budibase/handlebars-helpers/lib/math")
@@ -17,10 +17,10 @@ jest.mock("@budibase/handlebars-helpers/lib/uuid", () => {
   }
 })
 
-const { processString, setJSRunner } = require("../src/index")
+import { processString, setJSRunner } from "../src/index"
 
-const tk = require("timekeeper")
-const { getParsedManifest, runJsHelpersTests } = require("./utils")
+import tk from "timekeeper"
+import { getParsedManifest, runJsHelpersTests } from "./utils"
 
 tk.freeze("2021-01-21T12:00:00")
 
diff --git a/packages/string-templates/test/utils.ts b/packages/string-templates/test/utils.ts
index 927a6e3aeb..64622305f9 100644
--- a/packages/string-templates/test/utils.ts
+++ b/packages/string-templates/test/utils.ts
@@ -1,11 +1,7 @@
-const { getManifest } = require("../src")
-const { getJsHelperList } = require("../src/helpers")
+import { getManifest } from "../src"
+import { getJsHelperList } from "../src/helpers"
 
-const {
-  convertToJS,
-  processStringSync,
-  encodeJSBinding,
-} = require("../src/index.js")
+import { convertToJS, processStringSync, encodeJSBinding } from "../src/index"
 
 function tryParseJson(str) {
   if (typeof str !== "string") {
@@ -19,23 +15,35 @@ function tryParseJson(str) {
   }
 }
 
-const getParsedManifest = () => {
+type ExampleType = [
+  string,
+  {
+    hbs: string
+    js: string
+    requiresHbsBody: boolean
+  }
+]
+
+export const getParsedManifest = () => {
   const manifest = getManifest()
   const collections = Object.keys(manifest)
+
   const examples = collections.reduce((acc, collection) => {
-    const functions = Object.entries(manifest[collection])
-      .filter(([_, details]) => details.example)
-      .map(([name, details]) => {
+    const functions = Object.entries<{
+      example: string
+      requiresBlock: boolean
+    }>(manifest[collection])
+      .filter(
+        ([_, details]) =>
+          details.example?.split("->").map(x => x.trim()).length > 1
+      )
+      .map(([name, details]): ExampleType => {
         const example = details.example
         let [hbs, js] = example.split("->").map(x => x.trim())
-        if (!js) {
-          // The function has no return value
-          return
-        }
 
         // Trim 's
         js = js.replace(/^'|'$/g, "")
-        let parsedExpected
+        let parsedExpected: string
         if ((parsedExpected = tryParseJson(js))) {
           if (Array.isArray(parsedExpected)) {
             if (typeof parsedExpected[0] === "object") {
@@ -48,19 +56,23 @@ const getParsedManifest = () => {
         const requiresHbsBody = details.requiresBlock
         return [name, { hbs, js, requiresHbsBody }]
       })
-      .filter(x => !!x)
 
-    if (Object.keys(functions).length) {
+    if (functions.length) {
       acc[collection] = functions
     }
     return acc
-  }, {})
+  }, {} as Record<string, ExampleType[]>)
 
   return examples
 }
-module.exports.getParsedManifest = getParsedManifest
 
-module.exports.runJsHelpersTests = ({ funcWrap, testsToSkip } = {}) => {
+export const runJsHelpersTests = ({
+  funcWrap,
+  testsToSkip,
+}: {
+  funcWrap?: any
+  testsToSkip?: any
+} = {}) => {
   funcWrap = funcWrap || (delegate => delegate())
   const manifest = getParsedManifest()
 
@@ -73,7 +85,7 @@ module.exports.runJsHelpersTests = ({ funcWrap, testsToSkip } = {}) => {
   }
 
   describe("can be parsed and run as js", () => {
-    const jsHelpers = getJsHelperList()
+    const jsHelpers = getJsHelperList()!
     const jsExamples = Object.keys(manifest).reduce((acc, v) => {
       acc[v] = manifest[v].filter(([key]) => jsHelpers[key])
       return acc
diff --git a/packages/string-templates/tsconfig.json b/packages/string-templates/tsconfig.json
index 07084de469..06cfa67b03 100644
--- a/packages/string-templates/tsconfig.json
+++ b/packages/string-templates/tsconfig.json
@@ -7,6 +7,7 @@
     "allowJs": true,
     "outDir": "dist",
     "esModuleInterop": true,
-    "types": ["node", "jest"]
+    "types": ["node", "jest"],
+    "resolveJsonModule": true
   }
 }

From bbe5f0041da221f499ca5bad033b4564ddf279ec Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Wed, 21 Feb 2024 23:59:46 +0100
Subject: [PATCH 25/75] Types

---
 packages/string-templates/test/utils.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/string-templates/test/utils.ts b/packages/string-templates/test/utils.ts
index 64622305f9..8c7aa43b21 100644
--- a/packages/string-templates/test/utils.ts
+++ b/packages/string-templates/test/utils.ts
@@ -89,7 +89,7 @@ export const runJsHelpersTests = ({
     const jsExamples = Object.keys(manifest).reduce((acc, v) => {
       acc[v] = manifest[v].filter(([key]) => jsHelpers[key])
       return acc
-    }, {})
+    }, {} as typeof manifest)
 
     describe.each(Object.keys(jsExamples))("%s", collection => {
       const examplesToRun = jsExamples[collection]

From af3c4285f09c72a9a60f99c36524551fb4142b3e Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 22 Feb 2024 00:24:57 +0100
Subject: [PATCH 26/75] Fix build

---
 packages/string-templates/rollup.config.js | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index 056ca58bb1..a6e45acb4b 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -1,5 +1,6 @@
 import commonjs from "@rollup/plugin-commonjs"
 import resolve from "rollup-plugin-node-resolve"
+import json from "@rollup/plugin-json"
 import { terser } from "rollup-plugin-terser"
 import builtins from "rollup-plugin-node-builtins"
 import globals from "rollup-plugin-node-globals"
@@ -16,7 +17,7 @@ const config = (format, outputFile) => ({
     file: outputFile,
   },
   plugins: [
-    typescript({ tsconfig: "tsconfig.json" }),
+    typescript({ tsconfig: "tsconfig.json", resolveJsonModule: false }),
     resolve({
       preferBuiltins: true,
       browser: true,
@@ -24,6 +25,7 @@ const config = (format, outputFile) => ({
     commonjs(),
     globals(),
     builtins(),
+    json(),
     injectProcessEnv({
       NO_JS: process.env.NO_JS,
     }),

From d24ea36c64181adf73c1053aa4e5932b13dbbafa Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 22 Feb 2024 00:26:18 +0100
Subject: [PATCH 27/75] Fixes

---
 packages/string-templates/src/index.ts         | 4 ++--
 packages/string-templates/test/escapes.spec.ts | 2 +-
 packages/string-templates/test/hbsToJs.spec.ts | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 2549d0b34c..b5d5590050 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -105,7 +105,7 @@ export async function processObject(object, context, opts?) {
 export async function processString(
   string: string,
   context: object,
-  opts?: { noHelpers: boolean }
+  opts?: { noHelpers?: boolean; escapeNewlines?: boolean }
 ) {
   // TODO: carry out any async calls before carrying out async call
   return processStringSync(string, context, opts)
@@ -367,7 +367,7 @@ export function doesContainString(template, string) {
 export function convertToJS(hbs) {
   const blocks = findHBSBlocks(hbs)
   let js = "return `",
-    prevBlock = null
+    prevBlock: string | null = null
   const variables = {}
   if (blocks.length === 0) {
     js += hbs
diff --git a/packages/string-templates/test/escapes.spec.ts b/packages/string-templates/test/escapes.spec.ts
index caa2f7d0c1..ffc72a6b92 100644
--- a/packages/string-templates/test/escapes.spec.ts
+++ b/packages/string-templates/test/escapes.spec.ts
@@ -1,4 +1,4 @@
-const { processString } = require("../src/index.js")
+import { processString } from "../src/index"
 
 describe("Handling context properties with spaces in their name", () => {
   it("should allow through literal specifiers", async () => {
diff --git a/packages/string-templates/test/hbsToJs.spec.ts b/packages/string-templates/test/hbsToJs.spec.ts
index 08d8ff5f67..f8b4c2fca9 100644
--- a/packages/string-templates/test/hbsToJs.spec.ts
+++ b/packages/string-templates/test/hbsToJs.spec.ts
@@ -1,4 +1,4 @@
-const { convertToJS } = require("../src/index.js")
+import { convertToJS } from "../src/index"
 
 function checkLines(response, lines) {
   const toCheck = response.split("\n")

From 38f64aa7046b928d9926a26c56e6004f305d0a60 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 22 Feb 2024 00:39:27 +0100
Subject: [PATCH 28/75] Lint

---
 packages/string-templates/src/helpers/index.ts | 1 +
 packages/string-templates/src/index.ts         | 8 +++++---
 packages/string-templates/test/vm.spec.ts      | 6 ++++--
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/packages/string-templates/src/helpers/index.ts b/packages/string-templates/src/helpers/index.ts
index 19d4ee3dff..b375426c0b 100644
--- a/packages/string-templates/src/helpers/index.ts
+++ b/packages/string-templates/src/helpers/index.ts
@@ -7,6 +7,7 @@ import {
   HelperFunctionBuiltin,
   LITERAL_MARKER,
 } from "./constants"
+
 export { getJsHelperList } from "./list"
 
 const HTML_SWAPS = {
diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index b5d5590050..a3eb890211 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -1,10 +1,11 @@
-import fs from "fs"
 import { createContext, runInNewContext } from "vm"
 import { create } from "handlebars"
 import { registerAll, registerMinimum } from "./helpers/index"
 import { preprocess, postprocess } from "./processors"
-import { atob, btoa, isBackendService } from "./utilities"
 import {
+  atob,
+  btoa,
+  isBackendService,
   FIND_HBS_REGEX,
   FIND_ANY_HBS_REGEX,
   findDoubleHbsInstances,
@@ -13,6 +14,8 @@ import { convertHBSBlock } from "./conversion"
 import { setJSRunner, removeJSRunner } from "./helpers/javascript"
 import { helpersToRemoveForJs } from "./helpers/list"
 
+import manifest from "../manifest.json"
+
 export { setJSRunner, setOnErrorLog } from "./helpers/javascript"
 
 const hbsInstance = create()
@@ -256,7 +259,6 @@ export function isValid(string, opts?) {
  * This manifest provides information about each of the helpers and how it can be used.
  * @returns The manifest JSON which has been generated from the helpers.
  */
-import manifest from "../manifest.json"
 export function getManifest() {
   return manifest
 }
diff --git a/packages/string-templates/test/vm.spec.ts b/packages/string-templates/test/vm.spec.ts
index 7bf1612386..0581736af2 100644
--- a/packages/string-templates/test/vm.spec.ts
+++ b/packages/string-templates/test/vm.spec.ts
@@ -5,8 +5,10 @@ jest.mock("../src/utilities", () => {
     isBackendService: jest.fn().mockReturnValue(true),
   }
 })
-const { defaultJSSetup, processStringSync, encodeJSBinding } = require("../src")
-const { isBackendService } = require("../src/utilities")
+
+import { defaultJSSetup, processStringSync, encodeJSBinding } from "../src"
+import { isBackendService } from "../src/utilities"
+
 const mockedBackendService = jest.mocked(isBackendService)
 
 const binding = encodeJSBinding("return 1")

From 8bbf318f4a21ba61de46d037cfa67d471688de9c Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 22 Feb 2024 00:46:22 +0100
Subject: [PATCH 29/75] Fixes

---
 packages/string-templates/src/index.ts            |  2 +-
 packages/string-templates/test/basic.spec.ts      |  6 +++---
 packages/string-templates/test/javascript.spec.ts | 10 +++-------
 packages/string-templates/test/renderApp.spec.ts  |  2 +-
 4 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index a3eb890211..7d0f198772 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -108,7 +108,7 @@ export async function processObject(object, context, opts?) {
 export async function processString(
   string: string,
   context: object,
-  opts?: { noHelpers?: boolean; escapeNewlines?: boolean }
+  opts?: { noHelpers?: boolean; escapeNewlines?: boolean; onlyFound?: boolean }
 ) {
   // TODO: carry out any async calls before carrying out async call
   return processStringSync(string, context, opts)
diff --git a/packages/string-templates/test/basic.spec.ts b/packages/string-templates/test/basic.spec.ts
index b1e2865486..278cd9de40 100644
--- a/packages/string-templates/test/basic.spec.ts
+++ b/packages/string-templates/test/basic.spec.ts
@@ -1,4 +1,4 @@
-const {
+import {
   processObject,
   processString,
   isValid,
@@ -8,7 +8,7 @@ const {
   doesContainString,
   disableEscaping,
   findHBSBlocks,
-} = require("../src/index")
+} from "../src/index"
 
 describe("Test that the string processing works correctly", () => {
   it("should process a basic template string", async () => {
@@ -28,7 +28,7 @@ describe("Test that the string processing works correctly", () => {
   it("should fail gracefully when wrong type passed in", async () => {
     let error = null
     try {
-      await processString(null, null)
+      await processString(null as any, null as any)
     } catch (err) {
       error = err
     }
diff --git a/packages/string-templates/test/javascript.spec.ts b/packages/string-templates/test/javascript.spec.ts
index ab68e70830..fd961446da 100644
--- a/packages/string-templates/test/javascript.spec.ts
+++ b/packages/string-templates/test/javascript.spec.ts
@@ -1,11 +1,7 @@
-const vm = require("vm")
+import vm from "vm"
 
-const {
-  processStringSync,
-  encodeJSBinding,
-  setJSRunner,
-} = require("../src/index")
-const { UUID_REGEX } = require("./constants")
+import { processStringSync, encodeJSBinding, setJSRunner } from "../src/index"
+import { UUID_REGEX } from "./constants"
 
 const processJS = (js, context?) => {
   return processStringSync(encodeJSBinding(js), context)
diff --git a/packages/string-templates/test/renderApp.spec.ts b/packages/string-templates/test/renderApp.spec.ts
index f09bc1c2b9..7570d1a8ec 100644
--- a/packages/string-templates/test/renderApp.spec.ts
+++ b/packages/string-templates/test/renderApp.spec.ts
@@ -1,4 +1,4 @@
-const { processString } = require("../src/index")
+import { processString } from "../src/index"
 
 describe("specific test case for whether or not full app template can still be rendered", () => {
   it("should be able to render the app template", async () => {

From 9e0e9297f5027764e7bccff44f9b4255b64ab8d6 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 22 Feb 2024 00:50:00 +0100
Subject: [PATCH 30/75] Fixes

---
 packages/cli/package.json              | 14 ++++++++++++++
 packages/string-templates/package.json |  1 +
 2 files changed, 15 insertions(+)

diff --git a/packages/cli/package.json b/packages/cli/package.json
index c1ba49c5e7..d33dcc9714 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -41,5 +41,19 @@
     "@types/pouchdb": "^6.4.0",
     "ts-node": "10.8.1",
     "typescript": "5.2.2"
+  },
+  "nx": {
+    "targets": {
+      "build": {
+        "dependsOn": [
+          {
+            "projects": [
+              "@budibase/string-templates"
+            ],
+            "target": "build"
+          }
+        ]
+      }
+    }
   }
 }
diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index b867eb7920..79e450187d 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -4,6 +4,7 @@
   "description": "Handlebars wrapper for Budibase templating.",
   "main": "dist/bundle.cjs",
   "module": "dist/bundle.mjs",
+  "types": "src/index.ts",
   "license": "MPL-2.0",
   "exports": {
     ".": {

From c3531ac8ba8112a7229161a233f2a030704b25fc Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 22 Feb 2024 11:16:09 +0100
Subject: [PATCH 31/75] Types

---
 .../string-templates/src/conversion/index.ts  | 18 ++---
 packages/string-templates/src/index.ts        | 51 ++++++++------
 .../string-templates/src/processors/index.ts  |  7 +-
 .../src/processors/postprocessor.ts           | 66 ++++++++++---------
 .../src/processors/preprocessor.ts            | 55 ++++++++--------
 packages/string-templates/src/types.ts        |  7 ++
 6 files changed, 118 insertions(+), 86 deletions(-)
 create mode 100644 packages/string-templates/src/types.ts

diff --git a/packages/string-templates/src/conversion/index.ts b/packages/string-templates/src/conversion/index.ts
index 1fb8d97467..d69576e940 100644
--- a/packages/string-templates/src/conversion/index.ts
+++ b/packages/string-templates/src/conversion/index.ts
@@ -1,11 +1,11 @@
 import { getJsHelperList } from "../helpers"
 
-function getLayers(fullBlock) {
+function getLayers(fullBlock: string): string[] {
   let layers = []
   while (fullBlock.length) {
     const start = fullBlock.lastIndexOf("("),
       end = fullBlock.indexOf(")")
-    let layer
+    let layer: string
     if (start === -1 || end === -1) {
       layer = fullBlock.trim()
       fullBlock = ""
@@ -21,7 +21,7 @@ function getLayers(fullBlock) {
   return layers
 }
 
-function getVariable(variableName) {
+function getVariable(variableName: string) {
   if (!variableName || typeof variableName !== "string") {
     return variableName
   }
@@ -47,10 +47,12 @@ function getVariable(variableName) {
   return `$("${variableName}")`
 }
 
-function buildList(parts, value) {
+function buildList(parts: any[], value: any) {
   function build() {
     return parts
-      .map(part => (part.startsWith("helper") ? part : getVariable(part)))
+      .map((part: string) =>
+        part.startsWith("helper") ? part : getVariable(part)
+      )
       .join(", ")
   }
   if (!value) {
@@ -60,12 +62,12 @@ function buildList(parts, value) {
   }
 }
 
-function splitBySpace(layer) {
+function splitBySpace(layer: string) {
   const parts = []
   let started = null,
     endChar = null,
     last = 0
-  function add(str) {
+  function add(str: string) {
     const startsWith = ["]"]
     while (startsWith.indexOf(str.substring(0, 1)) !== -1) {
       str = str.substring(1, str.length)
@@ -103,7 +105,7 @@ function splitBySpace(layer) {
   return parts
 }
 
-export function convertHBSBlock(block, blockNumber) {
+export function convertHBSBlock(block: string, blockNumber: number) {
   const braceLength = block[2] === "{" ? 3 : 2
   block = block.substring(braceLength, block.length - braceLength).trim()
   const layers = getLayers(block)
diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 7d0f198772..67ec194e84 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -1,4 +1,4 @@
-import { createContext, runInNewContext } from "vm"
+import { Context, createContext, runInNewContext } from "vm"
 import { create } from "handlebars"
 import { registerAll, registerMinimum } from "./helpers/index"
 import { preprocess, postprocess } from "./processors"
@@ -15,6 +15,7 @@ import { setJSRunner, removeJSRunner } from "./helpers/javascript"
 import { helpersToRemoveForJs } from "./helpers/list"
 
 import manifest from "../manifest.json"
+import { ProcessOptions } from "./types"
 
 export { setJSRunner, setOnErrorLog } from "./helpers/javascript"
 
@@ -22,7 +23,7 @@ const hbsInstance = create()
 registerAll(hbsInstance)
 const hbsInstanceNoHelpers = create()
 registerMinimum(hbsInstanceNoHelpers)
-const defaultOpts = {
+const defaultOpts: ProcessOptions = {
   noHelpers: false,
   cacheTemplates: false,
   noEscaping: false,
@@ -33,7 +34,7 @@ const defaultOpts = {
 /**
  * Utility function to check if the object is valid.
  */
-function testObject(object) {
+function testObject(object: any) {
   // JSON stringify will fail if there are any cycles, stops infinite recursion
   try {
     JSON.stringify(object)
@@ -46,7 +47,7 @@ function testObject(object) {
  * Creates a HBS template function for a given string, and optionally caches it.
  */
 let templateCache = {}
-function createTemplate(string, opts) {
+function createTemplate(string: string, opts: ProcessOptions) {
   opts = { ...defaultOpts, ...opts }
 
   // Finalising adds a helper, can't do this with no helpers
@@ -82,7 +83,11 @@ function createTemplate(string, opts) {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {Promise<object|array>} The structure input, as fully updated as possible.
  */
-export async function processObject(object, context, opts?) {
+export async function processObject(
+  object: { [x: string]: any },
+  context: object,
+  opts?: { noHelpers?: boolean; escapeNewlines?: boolean; onlyFound?: boolean }
+) {
   testObject(object)
   for (let key of Object.keys(object || {})) {
     if (object[key] != null) {
@@ -123,7 +128,11 @@ export async function processString(
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {object|array} The structure input, as fully updated as possible.
  */
-export function processObjectSync(object, context, opts) {
+export function processObjectSync(
+  object: { [x: string]: any },
+  context: any,
+  opts: any
+) {
   testObject(object)
   for (let key of Object.keys(object || {})) {
     let val = object[key]
@@ -144,13 +153,17 @@ export function processObjectSync(object, context, opts) {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {string} The enriched string, all templates should have been replaced if they can be.
  */
-export function processStringSync(string, context, opts?) {
+export function processStringSync(
+  string: string,
+  context: object,
+  opts?: { noHelpers?: boolean; escapeNewlines?: boolean; onlyFound: any }
+) {
   // Take a copy of input in case of error
   const input = string
   if (typeof string !== "string") {
     throw "Cannot process non-string types."
   }
-  function process(stringPart) {
+  function process(stringPart: string) {
     const template = createTemplate(stringPart, opts)
     const now = Math.floor(Date.now() / 1000) * 1000
     return postprocess(
@@ -186,7 +199,7 @@ export function processStringSync(string, context, opts?) {
  * this function will find any double braces and switch to triple.
  * @param string the string to have double HBS statements converted to triple.
  */
-export function disableEscaping(string) {
+export function disableEscaping(string: string) {
   const matches = findDoubleHbsInstances(string)
   if (matches == null) {
     return string
@@ -207,7 +220,7 @@ export function disableEscaping(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) {
+export function makePropSafe(property: any) {
   return `[${property}]`.replace("[[", "[").replace("]]", "]")
 }
 
@@ -217,7 +230,7 @@ export function makePropSafe(property) {
  * @param [opts] optional - specify some options for processing.
  * @returns {boolean} Whether or not the input string is valid.
  */
-export function isValid(string, opts?) {
+export function isValid(string: any, opts?: any) {
   const validCases = [
     "string",
     "number",
@@ -268,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) {
+export function isJSBinding(handlebars: any) {
   return decodeJSBinding(handlebars) != null
 }
 
@@ -277,7 +290,7 @@ export function isJSBinding(handlebars) {
  * @param javascript the JS code to encode
  * @returns {string} the JS HBS expression
  */
-export function encodeJSBinding(javascript) {
+export function encodeJSBinding(javascript: string) {
   return `{{ js "${btoa(javascript)}" }}`
 }
 
@@ -286,7 +299,7 @@ export function encodeJSBinding(javascript) {
  * @param handlebars the JS HBS expression
  * @returns {string|null} the raw JS code
  */
-export function decodeJSBinding(handlebars) {
+export function decodeJSBinding(handlebars: string) {
   if (!handlebars || typeof handlebars !== "string") {
     return null
   }
@@ -311,7 +324,7 @@ export function decodeJSBinding(handlebars) {
  * @param {string[]} strings The strings to look for.
  * @returns {boolean} Will return true if all strings found in HBS statement.
  */
-export function doesContainStrings(template, strings) {
+export function doesContainStrings(template: string, strings: any[]) {
   let regexp = new RegExp(FIND_HBS_REGEX)
   let matches = template.match(regexp)
   if (matches == null) {
@@ -341,7 +354,7 @@ export function doesContainStrings(template, strings) {
  * @param {string} string The string to search within.
  * @return {string[]} The found HBS blocks.
  */
-export function findHBSBlocks(string) {
+export function findHBSBlocks(string: string) {
   if (!string || typeof string !== "string") {
     return []
   }
@@ -362,11 +375,11 @@ export function findHBSBlocks(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, string) {
+export function doesContainString(template: any, string: any) {
   return doesContainStrings(template, [string])
 }
 
-export function convertToJS(hbs) {
+export function convertToJS(hbs: string) {
   const blocks = findHBSBlocks(hbs)
   let js = "return `",
     prevBlock: string | null = null
@@ -407,7 +420,7 @@ function defaultJSSetup() {
     /**
      * Use polyfilled vm to run JS scripts in a browser Env
      */
-    setJSRunner((js, context) => {
+    setJSRunner((js: string, context: Context) => {
       context = {
         ...context,
         alert: undefined,
diff --git a/packages/string-templates/src/processors/index.ts b/packages/string-templates/src/processors/index.ts
index e1743b2f4c..308ac5adf4 100644
--- a/packages/string-templates/src/processors/index.ts
+++ b/packages/string-templates/src/processors/index.ts
@@ -1,8 +1,9 @@
 import { FIND_HBS_REGEX } from "../utilities"
 import * as preprocessor from "./preprocessor"
 import * as postprocessor from "./postprocessor"
+import { ProcessOptions } from "../types"
 
-function process(output, processors, opts?) {
+function process(output: string, processors: any[], opts?: ProcessOptions) {
   for (let processor of processors) {
     // if a literal statement has occurred stop
     if (typeof output !== "string") {
@@ -21,7 +22,7 @@ function process(output, processors, opts?) {
   return output
 }
 
-export function preprocess(string, opts) {
+export function preprocess(string: string, opts: ProcessOptions) {
   let processors = preprocessor.processors
   if (opts.noFinalise) {
     processors = processors.filter(
@@ -30,7 +31,7 @@ export function preprocess(string, opts) {
   }
   return process(string, processors, opts)
 }
-export function postprocess(string) {
+export function postprocess(string: string) {
   let processors = postprocessor.processors
   return process(string, processors)
 }
diff --git a/packages/string-templates/src/processors/postprocessor.ts b/packages/string-templates/src/processors/postprocessor.ts
index 39125b225a..6f7260718b 100644
--- a/packages/string-templates/src/processors/postprocessor.ts
+++ b/packages/string-templates/src/processors/postprocessor.ts
@@ -6,45 +6,51 @@ export const PostProcessorNames = {
 
 /* eslint-disable no-unused-vars */
 class Postprocessor {
-  name
-  private fn
+  name: string
+  private fn: any
 
-  constructor(name, fn) {
+  constructor(name: string, fn: any) {
     this.name = name
     this.fn = fn
   }
 
-  process(statement) {
+  process(statement: any) {
     return this.fn(statement)
   }
 }
 
 export const processors = [
-  new Postprocessor(PostProcessorNames.CONVERT_LITERALS, statement => {
-    if (typeof statement !== "string" || !statement.includes(LITERAL_MARKER)) {
-      return statement
+  new Postprocessor(
+    PostProcessorNames.CONVERT_LITERALS,
+    (statement: string) => {
+      if (
+        typeof statement !== "string" ||
+        !statement.includes(LITERAL_MARKER)
+      ) {
+        return statement
+      }
+      const splitMarkerIndex = statement.indexOf("-")
+      const type = statement.substring(12, splitMarkerIndex)
+      const value = statement.substring(
+        splitMarkerIndex + 1,
+        statement.length - 2
+      )
+      switch (type) {
+        case "string":
+          return value
+        case "number":
+          return parseFloat(value)
+        case "boolean":
+          return value === "true"
+        case "object":
+          return JSON.parse(value)
+        case "js_result":
+          // We use the literal helper to process the result of JS expressions
+          // as we want to be able to return any types.
+          // We wrap the value in an abject to be able to use undefined properly.
+          return JSON.parse(value).data
+      }
+      return value
     }
-    const splitMarkerIndex = statement.indexOf("-")
-    const type = statement.substring(12, splitMarkerIndex)
-    const value = statement.substring(
-      splitMarkerIndex + 1,
-      statement.length - 2
-    )
-    switch (type) {
-      case "string":
-        return value
-      case "number":
-        return parseFloat(value)
-      case "boolean":
-        return value === "true"
-      case "object":
-        return JSON.parse(value)
-      case "js_result":
-        // We use the literal helper to process the result of JS expressions
-        // as we want to be able to return any types.
-        // We wrap the value in an abject to be able to use undefined properly.
-        return JSON.parse(value).data
-    }
-    return value
-  }),
+  ),
 ]
diff --git a/packages/string-templates/src/processors/preprocessor.ts b/packages/string-templates/src/processors/preprocessor.ts
index 1fcbac629f..141b2be3a9 100644
--- a/packages/string-templates/src/processors/preprocessor.ts
+++ b/packages/string-templates/src/processors/preprocessor.ts
@@ -14,7 +14,7 @@ class Preprocessor {
   name: string
   private fn: any
 
-  constructor(name, fn) {
+  constructor(name: string, fn: any) {
     this.name = name
     this.fn = fn
   }
@@ -27,7 +27,7 @@ class Preprocessor {
 }
 
 export const processors = [
-  new Preprocessor(PreprocessorNames.SWAP_TO_DOT, statement => {
+  new Preprocessor(PreprocessorNames.SWAP_TO_DOT, (statement: string) => {
     let startBraceIdx = statement.indexOf("[")
     let lastIdx = 0
     while (startBraceIdx !== -1) {
@@ -42,7 +42,7 @@ export const processors = [
     return statement
   }),
 
-  new Preprocessor(PreprocessorNames.FIX_FUNCTIONS, statement => {
+  new Preprocessor(PreprocessorNames.FIX_FUNCTIONS, (statement: string) => {
     for (let specialCase of FUNCTION_CASES) {
       const toFind = `{ ${specialCase}`,
         replacement = `{${specialCase}`
@@ -51,29 +51,32 @@ export const processors = [
     return statement
   }),
 
-  new Preprocessor(PreprocessorNames.FINALISE, (statement, opts) => {
-    const noHelpers = opts && opts.noHelpers
-    let insideStatement = statement.slice(2, statement.length - 2)
-    if (insideStatement.charAt(0) === " ") {
-      insideStatement = insideStatement.slice(1)
-    }
-    if (insideStatement.charAt(insideStatement.length - 1) === " ") {
-      insideStatement = insideStatement.slice(0, insideStatement.length - 1)
-    }
-    const possibleHelper = insideStatement.split(" ")[0]
-    // function helpers can't be wrapped
-    for (let specialCase of FUNCTION_CASES) {
-      if (possibleHelper.includes(specialCase)) {
-        return statement
+  new Preprocessor(
+    PreprocessorNames.FINALISE,
+    (statement: string, opts: { noHelpers: any }) => {
+      const noHelpers = opts && opts.noHelpers
+      let insideStatement = statement.slice(2, statement.length - 2)
+      if (insideStatement.charAt(0) === " ") {
+        insideStatement = insideStatement.slice(1)
       }
+      if (insideStatement.charAt(insideStatement.length - 1) === " ") {
+        insideStatement = insideStatement.slice(0, insideStatement.length - 1)
+      }
+      const possibleHelper = insideStatement.split(" ")[0]
+      // function helpers can't be wrapped
+      for (let specialCase of FUNCTION_CASES) {
+        if (possibleHelper.includes(specialCase)) {
+          return statement
+        }
+      }
+      const testHelper = possibleHelper.trim().toLowerCase()
+      if (
+        !noHelpers &&
+        HelperNames().some(option => testHelper === option.toLowerCase())
+      ) {
+        insideStatement = `(${insideStatement})`
+      }
+      return `{{ all ${insideStatement} }}`
     }
-    const testHelper = possibleHelper.trim().toLowerCase()
-    if (
-      !noHelpers &&
-      HelperNames().some(option => testHelper === option.toLowerCase())
-    ) {
-      insideStatement = `(${insideStatement})`
-    }
-    return `{{ all ${insideStatement} }}`
-  }),
+  ),
 ]
diff --git a/packages/string-templates/src/types.ts b/packages/string-templates/src/types.ts
new file mode 100644
index 0000000000..fc029f3b6a
--- /dev/null
+++ b/packages/string-templates/src/types.ts
@@ -0,0 +1,7 @@
+export interface ProcessOptions {
+  cacheTemplates?: boolean
+  noEscaping?: boolean
+  noHelpers?: boolean
+  noFinalise?: boolean
+  escapeNewlines?: boolean
+}

From 566c4e5c17d22fdc170136a4513a92d1628afea5 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 22 Feb 2024 11:26:22 +0100
Subject: [PATCH 32/75] Fix typings

---
 packages/string-templates/src/index.ts | 6 +++---
 packages/string-templates/src/types.ts | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 67ec194e84..3796d8f155 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -113,7 +113,7 @@ export async function processObject(
 export async function processString(
   string: string,
   context: object,
-  opts?: { noHelpers?: boolean; escapeNewlines?: boolean; onlyFound?: boolean }
+  opts?: ProcessOptions
 ) {
   // TODO: carry out any async calls before carrying out async call
   return processStringSync(string, context, opts)
@@ -156,7 +156,7 @@ export function processObjectSync(
 export function processStringSync(
   string: string,
   context: object,
-  opts?: { noHelpers?: boolean; escapeNewlines?: boolean; onlyFound: any }
+  opts?: ProcessOptions
 ) {
   // Take a copy of input in case of error
   const input = string
@@ -397,7 +397,7 @@ export function convertToJS(hbs: string) {
     prevBlock = block
     const { variable, value } = convertHBSBlock(block, count++)
     variables[variable] = value
-    js += `${stringPart.split()}\${${variable}}`
+    js += `${stringPart.split("")}\${${variable}}`
   }
   let varBlock = ""
   for (let [variable, value] of Object.entries(variables)) {
diff --git a/packages/string-templates/src/types.ts b/packages/string-templates/src/types.ts
index fc029f3b6a..1e1ef048a4 100644
--- a/packages/string-templates/src/types.ts
+++ b/packages/string-templates/src/types.ts
@@ -4,4 +4,5 @@ export interface ProcessOptions {
   noHelpers?: boolean
   noFinalise?: boolean
   escapeNewlines?: boolean
+  onlyFound?: boolean
 }

From c60baaa01209d4fdf061e029fdf9a7971d22c5c6 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 22 Feb 2024 11:52:50 +0100
Subject: [PATCH 33/75] More types

---
 .../string-templates/src/helpers/Helper.ts    | 37 +++++-----
 .../string-templates/src/helpers/external.ts  |  8 +--
 .../string-templates/src/helpers/index.ts     | 69 ++++++++++---------
 packages/string-templates/src/index.ts        | 34 ++++-----
 4 files changed, 77 insertions(+), 71 deletions(-)

diff --git a/packages/string-templates/src/helpers/Helper.ts b/packages/string-templates/src/helpers/Helper.ts
index e254b2086d..a1722ac2c8 100644
--- a/packages/string-templates/src/helpers/Helper.ts
+++ b/packages/string-templates/src/helpers/Helper.ts
@@ -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)
   }
 }
diff --git a/packages/string-templates/src/helpers/external.ts b/packages/string-templates/src/helpers/external.ts
index 7e849c8fc3..efb390ff8b 100644
--- a/packages/string-templates/src/helpers/external.ts
+++ b/packages/string-templates/src/helpers/external.ts
@@ -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[] = []
diff --git a/packages/string-templates/src/helpers/index.ts b/packages/string-templates/src/helpers/index.ts
index b375426c0b..e95ac9d2fd 100644
--- a/packages/string-templates/src/helpers/index.ts
+++ b/packages/string-templates/src/helpers/index.ts
@@ -15,7 +15,7 @@ const HTML_SWAPS = {
   ">": "&gt;",
 }
 
-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(/&amp;/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(/&amp;/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)
   }
diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 3796d8f155..0ec8fdd425 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -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
   }

From 1cb3288531a186df96b44f50fb441589800062c2 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 17:18:45 +0100
Subject: [PATCH 34/75] Update pro ref

---
 packages/pro |  2 +-
 yarn.lock    | 48 ++----------------------------------------------
 2 files changed, 3 insertions(+), 47 deletions(-)

diff --git a/packages/pro b/packages/pro
index c4c98ae70f..29f3417c83 160000
--- a/packages/pro
+++ b/packages/pro
@@ -1 +1 @@
-Subproject commit c4c98ae70f2e936009250893898ecf11f4ddf2c3
+Subproject commit 29f3417c831a804e1c187948b002e924342de488
diff --git a/yarn.lock b/yarn.lock
index 235e28e85e..55b66a2e59 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1988,7 +1988,7 @@
   resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
   integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
 
-"@babel/runtime@^7.10.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.21.0":
+"@babel/runtime@^7.10.5", "@babel/runtime@^7.13.10":
   version "7.23.9"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7"
   integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==
@@ -8462,21 +8462,6 @@ concat-with-sourcemaps@^1.1.0:
   dependencies:
     source-map "^0.6.1"
 
-concurrently@^8.2.2:
-  version "8.2.2"
-  resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-8.2.2.tgz#353141985c198cfa5e4a3ef90082c336b5851784"
-  integrity sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==
-  dependencies:
-    chalk "^4.1.2"
-    date-fns "^2.30.0"
-    lodash "^4.17.21"
-    rxjs "^7.8.1"
-    shell-quote "^1.8.1"
-    spawn-command "0.0.2"
-    supports-color "^8.1.1"
-    tree-kill "^1.2.2"
-    yargs "^17.7.2"
-
 condense-newlines@^0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f"
@@ -9044,13 +9029,6 @@ data-urls@^4.0.0:
     whatwg-mimetype "^3.0.0"
     whatwg-url "^12.0.0"
 
-date-fns@^2.30.0:
-  version "2.30.0"
-  resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
-  integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
-  dependencies:
-    "@babel/runtime" "^7.21.0"
-
 dateformat@^3.0.3:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
@@ -19390,13 +19368,6 @@ rxjs@^7.5.5:
   dependencies:
     tslib "^2.1.0"
 
-rxjs@^7.8.1:
-  version "7.8.1"
-  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
-  integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
-  dependencies:
-    tslib "^2.1.0"
-
 safe-array-concat@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c"
@@ -19672,11 +19643,6 @@ shell-exec@1.0.2:
   resolved "https://registry.yarnpkg.com/shell-exec/-/shell-exec-1.0.2.tgz#2e9361b0fde1d73f476c4b6671fa17785f696756"
   integrity sha512-jyVd+kU2X+mWKMmGhx4fpWbPsjvD53k9ivqetutVW/BQ+WIZoDoP4d8vUMGezV6saZsiNoW2f9GIhg9Dondohg==
 
-shell-quote@^1.8.1:
-  version "1.8.1"
-  resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680"
-  integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==
-
 shortid@2.2.15:
   version "2.2.15"
   resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
@@ -19995,11 +19961,6 @@ sparse-bitfield@^3.0.3:
   dependencies:
     memory-pager "^1.0.2"
 
-spawn-command@0.0.2:
-  version "0.0.2"
-  resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e"
-  integrity sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==
-
 spdx-correct@^3.0.0:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
@@ -20572,7 +20533,7 @@ supports-color@^7.0.0, supports-color@^7.1.0:
   dependencies:
     has-flag "^4.0.0"
 
-supports-color@^8.0.0, supports-color@^8.1.1:
+supports-color@^8.0.0:
   version "8.1.1"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
   integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
@@ -21199,11 +21160,6 @@ tr46@~0.0.3:
   resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
   integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
 
-tree-kill@^1.2.2:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
-  integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
-
 trim-newlines@^3.0.0:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144"

From 379b9a3e8ff324b3013b4859fcd442d639bbc9a6 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 17:28:35 +0100
Subject: [PATCH 35/75] Fix build

---
 packages/string-templates/rollup.config.js | 2 +-
 packages/string-templates/tsconfig.json    | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index a6e45acb4b..e7aa2ced99 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -17,7 +17,7 @@ const config = (format, outputFile) => ({
     file: outputFile,
   },
   plugins: [
-    typescript({ tsconfig: "tsconfig.json", resolveJsonModule: false }),
+    typescript(),
     resolve({
       preferBuiltins: true,
       browser: true,
diff --git a/packages/string-templates/tsconfig.json b/packages/string-templates/tsconfig.json
index 06cfa67b03..4b10f1ecbb 100644
--- a/packages/string-templates/tsconfig.json
+++ b/packages/string-templates/tsconfig.json
@@ -1,6 +1,7 @@
 {
   "include": ["src/**/*"],
   "compilerOptions": {
+    "rootDir": ".",
     "target": "es6",
     "moduleResolution": "node",
     "lib": ["dom"],

From 0627a7f3a8a209b11c16be228245c19db567bd2d Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 17:31:07 +0100
Subject: [PATCH 36/75] Remove json plugin

---
 packages/string-templates/rollup.config.js | 2 --
 1 file changed, 2 deletions(-)

diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index e7aa2ced99..78b5c6f035 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -1,6 +1,5 @@
 import commonjs from "@rollup/plugin-commonjs"
 import resolve from "rollup-plugin-node-resolve"
-import json from "@rollup/plugin-json"
 import { terser } from "rollup-plugin-terser"
 import builtins from "rollup-plugin-node-builtins"
 import globals from "rollup-plugin-node-globals"
@@ -25,7 +24,6 @@ const config = (format, outputFile) => ({
     commonjs(),
     globals(),
     builtins(),
-    json(),
     injectProcessEnv({
       NO_JS: process.env.NO_JS,
     }),

From 68bfa2434ba8fe9cf9fe3878e0661f326a0405a1 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 17:37:25 +0100
Subject: [PATCH 37/75] Add json back

---
 packages/string-templates/rollup.config.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/packages/string-templates/rollup.config.js b/packages/string-templates/rollup.config.js
index 78b5c6f035..e7aa2ced99 100644
--- a/packages/string-templates/rollup.config.js
+++ b/packages/string-templates/rollup.config.js
@@ -1,5 +1,6 @@
 import commonjs from "@rollup/plugin-commonjs"
 import resolve from "rollup-plugin-node-resolve"
+import json from "@rollup/plugin-json"
 import { terser } from "rollup-plugin-terser"
 import builtins from "rollup-plugin-node-builtins"
 import globals from "rollup-plugin-node-globals"
@@ -24,6 +25,7 @@ const config = (format, outputFile) => ({
     commonjs(),
     globals(),
     builtins(),
+    json(),
     injectProcessEnv({
       NO_JS: process.env.NO_JS,
     }),

From a390015757e460699fcdf58063235abd71ece797 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 17:41:30 +0100
Subject: [PATCH 38/75] Fix require

---
 packages/string-templates/src/helpers/external.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/string-templates/src/helpers/external.ts b/packages/string-templates/src/helpers/external.ts
index efb390ff8b..8f0577a945 100644
--- a/packages/string-templates/src/helpers/external.ts
+++ b/packages/string-templates/src/helpers/external.ts
@@ -1,4 +1,4 @@
-const helpers = require("@budibase/handlebars-helpers")
+import helpers from "@budibase/handlebars-helpers"
 import { date, duration } from "./date"
 import { HelperFunctionBuiltin } from "./constants"
 

From 2407ddbcfb5dc6d0375e3ed25b1772d8fc08daee Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 17:49:05 +0100
Subject: [PATCH 39/75] Gen manifest to ts

---
 packages/string-templates/package.json                          | 2 +-
 .../scripts/{gen-collection-info.js => gen-collection-info.ts}  | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename packages/string-templates/scripts/{gen-collection-info.js => gen-collection-info.ts} (100%)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 79e450187d..7e67612205 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -23,7 +23,7 @@
     "build": "rollup -c",
     "dev": "rollup -cw",
     "test": "jest",
-    "manifest": "node ./scripts/gen-collection-info.js"
+    "manifest": "ts-node ./scripts/gen-collection-info.ts"
   },
   "dependencies": {
     "@budibase/handlebars-helpers": "^0.13.1",
diff --git a/packages/string-templates/scripts/gen-collection-info.js b/packages/string-templates/scripts/gen-collection-info.ts
similarity index 100%
rename from packages/string-templates/scripts/gen-collection-info.js
rename to packages/string-templates/scripts/gen-collection-info.ts

From 81f2fb5aa90541897716edf1c6f62e0f6a52b666 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 17:50:17 +0100
Subject: [PATCH 40/75] Move manifest.json

---
 packages/string-templates/package.json                   | 3 +--
 packages/string-templates/scripts/gen-collection-info.ts | 2 +-
 packages/string-templates/src/index.ts                   | 2 +-
 packages/string-templates/{ => src}/manifest.json        | 0
 packages/string-templates/tsconfig.json                  | 2 +-
 5 files changed, 4 insertions(+), 5 deletions(-)
 rename packages/string-templates/{ => src}/manifest.json (100%)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 7e67612205..03e3bf5fa8 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -16,8 +16,7 @@
   },
   "files": [
     "dist",
-    "src",
-    "manifest.json"
+    "src"
   ],
   "scripts": {
     "build": "rollup -c",
diff --git a/packages/string-templates/scripts/gen-collection-info.ts b/packages/string-templates/scripts/gen-collection-info.ts
index ed57fe7fae..3f583d59d2 100644
--- a/packages/string-templates/scripts/gen-collection-info.ts
+++ b/packages/string-templates/scripts/gen-collection-info.ts
@@ -22,7 +22,7 @@ const COLLECTIONS = [
   "object",
   "uuid",
 ]
-const FILENAME = join(__dirname, "..", "manifest.json")
+const FILENAME = join(__dirname, "..", "src", "manifest.json")
 const outputJSON = {}
 const ADDED_HELPERS = {
   date: {
diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 0ec8fdd425..3f54cd17c5 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -14,7 +14,7 @@ import { convertHBSBlock } from "./conversion"
 import { setJSRunner, removeJSRunner } from "./helpers/javascript"
 import { helpersToRemoveForJs } from "./helpers/list"
 
-import manifest from "../manifest.json"
+import manifest from "./manifest.json"
 import { ProcessOptions } from "./types"
 
 export { setJSRunner, setOnErrorLog } from "./helpers/javascript"
diff --git a/packages/string-templates/manifest.json b/packages/string-templates/src/manifest.json
similarity index 100%
rename from packages/string-templates/manifest.json
rename to packages/string-templates/src/manifest.json
diff --git a/packages/string-templates/tsconfig.json b/packages/string-templates/tsconfig.json
index 4b10f1ecbb..2fa760d011 100644
--- a/packages/string-templates/tsconfig.json
+++ b/packages/string-templates/tsconfig.json
@@ -1,7 +1,7 @@
 {
   "include": ["src/**/*"],
   "compilerOptions": {
-    "rootDir": ".",
+    "declaration": true,
     "target": "es6",
     "moduleResolution": "node",
     "lib": ["dom"],

From 215d68715b1e2d662784e858e3307e09cbefd243 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 17:50:31 +0100
Subject: [PATCH 41/75] Declarations

---
 packages/string-templates/package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 03e3bf5fa8..a02172ce14 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -19,7 +19,7 @@
     "src"
   ],
   "scripts": {
-    "build": "rollup -c",
+    "build": "tsc --emitDeclarationOnly && rollup -c",
     "dev": "rollup -cw",
     "test": "jest",
     "manifest": "ts-node ./scripts/gen-collection-info.ts"

From 8bd89a27a57ed439569cbd10dc26e4414feb0237 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 17:51:43 +0100
Subject: [PATCH 42/75] Fix types

---
 packages/string-templates/scripts/gen-collection-info.ts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/packages/string-templates/scripts/gen-collection-info.ts b/packages/string-templates/scripts/gen-collection-info.ts
index 3f583d59d2..ae2a726661 100644
--- a/packages/string-templates/scripts/gen-collection-info.ts
+++ b/packages/string-templates/scripts/gen-collection-info.ts
@@ -126,7 +126,7 @@ const excludeFunctions = { string: ["raw"] }
  * This script is very specific to purpose, parsing the handlebars-helpers files to attempt to get information about them.
  */
 function run() {
-  const foundNames = []
+  const foundNames: string[] = []
   for (let collection of COLLECTIONS) {
     const collectionFile = fs.readFileSync(
       `${path.dirname(require.resolve(HELPER_LIBRARY))}/lib/${collection}.js`,
@@ -147,7 +147,7 @@ function run() {
       }
       foundNames.push(name)
       // this is ridiculous, but it parse the function header
-      const fnc = entry[1].toString()
+      const fnc = entry[1]!.toString()
       const jsDocInfo = getCommentInfo(collectionFile, fnc)
       let args = jsDocInfo.tags
         .filter(tag => tag.title === "param")
@@ -176,8 +176,8 @@ function run() {
   }
 
   // convert all markdown to HTML
-  for (let collection of Object.values(outputJSON)) {
-    for (let helper of Object.values(collection)) {
+  for (let collection of Object.values<any>(outputJSON)) {
+    for (let helper of Object.values<any>(collection)) {
       helper.description = marked.parse(helper.description)
     }
   }

From d4e72e4a0b499bd889ca6a95d50589c857d49d44 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 18:26:14 +0100
Subject: [PATCH 43/75] Fix test/utils exports

---
 packages/server/src/jsRunner/tests/jsRunner.spec.ts | 2 +-
 packages/string-templates/package.json              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts
index 54983aa470..dc6e32f52c 100644
--- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts
+++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts
@@ -1,7 +1,7 @@
 import { validate as isValidUUID } from "uuid"
 import { processStringSync, encodeJSBinding } from "@budibase/string-templates"
 
-const { runJsHelpersTests } = require("@budibase/string-templates/test/utils")
+import { runJsHelpersTests } from "@budibase/string-templates/test/utils"
 
 import tk from "timekeeper"
 import { init } from ".."
diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index a02172ce14..b79a44bc25 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -12,7 +12,7 @@
       "import": "./dist/bundle.mjs"
     },
     "./package.json": "./package.json",
-    "./test/utils": "./test/utils.js"
+    "./test/utils": "./test/utils.ts"
   },
   "files": [
     "dist",

From 029ac07fa2a9bfe840201a20ae05d4d3ad59d604 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 18:37:49 +0100
Subject: [PATCH 44/75] Fix types

---
 packages/string-templates/src/index.ts | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 3f54cd17c5..d17bacb9a9 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -83,20 +83,22 @@ function createTemplate(string: string, opts?: ProcessOptions) {
  * @param {object|undefined} [opts] optional - specify some options for processing.
  * @returns {Promise<object|array>} The structure input, as fully updated as possible.
  */
-export async function processObject(
-  object: { [x: string]: any },
+export async function processObject<T extends Record<string, any>>(
+  object: T,
   context: object,
   opts?: { noHelpers?: boolean; escapeNewlines?: boolean; onlyFound?: boolean }
-): Promise<object | Array<any>> {
+): Promise<T> {
   testObject(object)
-  for (let key of Object.keys(object || {})) {
+  for (const key of Object.keys(object || {})) {
     if (object[key] != null) {
-      let val = object[key]
+      const val = object[key]
+      let parsedValue
       if (typeof val === "string") {
-        object[key] = await processString(object[key], context, opts)
+        parsedValue = await processString(object[key], context, opts)
       } else if (typeof val === "object") {
-        object[key] = await processObject(object[key], context, opts)
+        parsedValue = await processObject(object[key], context, opts)
       }
+      ;(object as any)[key] = parsedValue
     }
   }
   return object

From 03122b464ff3677dfc7905ff677c2aeb5bb95600 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 18:39:08 +0100
Subject: [PATCH 45/75] Types

---
 packages/string-templates/test/basic.spec.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/string-templates/test/basic.spec.ts b/packages/string-templates/test/basic.spec.ts
index 278cd9de40..ae006f06f9 100644
--- a/packages/string-templates/test/basic.spec.ts
+++ b/packages/string-templates/test/basic.spec.ts
@@ -98,7 +98,7 @@ describe("Test that the object processing works correctly", () => {
   it("should be able to handle null objects", async () => {
     let error = null
     try {
-      await processObject(null, null)
+      await processObject(null as any, null as any)
     } catch (err) {
       error = err
     }

From acbb06edf7df9757ae4423ffe31933647812b979 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 22:32:17 +0100
Subject: [PATCH 46/75] Split code

---
 packages/string-templates/src/index.ts | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index d17bacb9a9..77ff1f8d73 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -168,16 +168,15 @@ export function processStringSync(
   function process(stringPart: string) {
     const template = createTemplate(stringPart, opts)
     const now = Math.floor(Date.now() / 1000) * 1000
-    return postprocess(
-      template({
-        now: new Date(now).toISOString(),
-        __opts: {
-          ...opts,
-          input: stringPart,
-        },
-        ...context,
-      })
-    )
+    const processedString = template({
+      now: new Date(now).toISOString(),
+      __opts: {
+        ...opts,
+        input: stringPart,
+      },
+      ...context,
+    })
+    return postprocess(processedString)
   }
   try {
     if (opts && opts.onlyFound) {

From bd4b14e995d879f56c082fdab53a37eaae0d0371 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Thu, 14 Mar 2024 23:51:24 +0100
Subject: [PATCH 47/75] Fix tests

---
 packages/string-templates/src/helpers/index.ts | 4 ++--
 packages/string-templates/test/helpers.spec.ts | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/packages/string-templates/src/helpers/index.ts b/packages/string-templates/src/helpers/index.ts
index e95ac9d2fd..595440ad55 100644
--- a/packages/string-templates/src/helpers/index.ts
+++ b/packages/string-templates/src/helpers/index.ts
@@ -51,11 +51,11 @@ const HELPERS = [
       if (value && (value as any).string) {
         value = (value as any).string
       }
-      let text = value
+      let text: any = value
       if (__opts && __opts.escapeNewlines) {
         text = value.replace(/\n/g, "\\n")
       }
-      text = new SafeString(text.replace(/&amp;/g, "&")).toString()
+      text = new SafeString(text.replace(/&amp;/g, "&"))
       if (text == null || typeof text !== "string") {
         return text
       }
diff --git a/packages/string-templates/test/helpers.spec.ts b/packages/string-templates/test/helpers.spec.ts
index efa6b0fdc3..f66eb9ef33 100644
--- a/packages/string-templates/test/helpers.spec.ts
+++ b/packages/string-templates/test/helpers.spec.ts
@@ -342,14 +342,14 @@ describe("Test the literal helper", () => {
   })
 
   it("should allow use of the literal specifier for an object", async () => {
-    const output = await processString(`{{literal a}}`, {
+    const output: any = await processString(`{{literal a}}`, {
       a: { b: 1 },
     })
     expect(output.b).toBe(1)
   })
 
   it("should allow use of the literal specifier for an object with dashes", async () => {
-    const output = await processString(`{{literal a}}`, {
+    const output: any = await processString(`{{literal a}}`, {
       a: { b: "i-have-dashes" },
     })
     expect(output.b).toBe("i-have-dashes")

From cfb1665ed9d90c720789e570e0f26e8c51b7b588 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 00:00:17 +0100
Subject: [PATCH 48/75] Fix tests

---
 packages/string-templates/src/index.ts            | 2 +-
 packages/string-templates/test/javascript.spec.ts | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 77ff1f8d73..978f8c0556 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -398,7 +398,7 @@ export function convertToJS(hbs: string) {
     prevBlock = block
     const { variable, value } = convertHBSBlock(block, count++)
     variables[variable] = value
-    js += `${stringPart.split("")}\${${variable}}`
+    js += `${[stringPart]}\${${variable}}`
   }
   let varBlock = ""
   for (let [variable, value] of Object.entries(variables)) {
diff --git a/packages/string-templates/test/javascript.spec.ts b/packages/string-templates/test/javascript.spec.ts
index fd961446da..eb12320cd0 100644
--- a/packages/string-templates/test/javascript.spec.ts
+++ b/packages/string-templates/test/javascript.spec.ts
@@ -3,7 +3,7 @@ import vm from "vm"
 import { processStringSync, encodeJSBinding, setJSRunner } from "../src/index"
 import { UUID_REGEX } from "./constants"
 
-const processJS = (js, context?) => {
+const processJS = (js, context?): any => {
   return processStringSync(encodeJSBinding(js), context)
 }
 

From 49cca6d69a19e67bf085a5d7f5404bef05510218 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 00:07:05 +0100
Subject: [PATCH 49/75] Lint

---
 packages/server/src/jsRunner/tests/jsRunner.spec.ts | 2 +-
 packages/string-templates/src/index.ts              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts
index dc6e32f52c..54983aa470 100644
--- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts
+++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts
@@ -1,7 +1,7 @@
 import { validate as isValidUUID } from "uuid"
 import { processStringSync, encodeJSBinding } from "@budibase/string-templates"
 
-import { runJsHelpersTests } from "@budibase/string-templates/test/utils"
+const { runJsHelpersTests } = require("@budibase/string-templates/test/utils")
 
 import tk from "timekeeper"
 import { init } from ".."
diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 978f8c0556..dd16a0f0ac 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -98,7 +98,7 @@ export async function processObject<T extends Record<string, any>>(
       } else if (typeof val === "object") {
         parsedValue = await processObject(object[key], context, opts)
       }
-      ;(object as any)[key] = parsedValue
+      object = { ...object, [key]: parsedValue }
     }
   }
   return object

From 05a169e2fd9dafd1498759b16d7a0c7ce84a2906 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 00:11:22 +0100
Subject: [PATCH 50/75] Remove nx dependencies

---
 packages/account-portal       |  2 +-
 packages/bbui/package.json    |  1 -
 packages/builder/package.json | 28 ----------------------------
 packages/cli/package.json     | 14 --------------
 packages/client/package.json  |  2 --
 packages/pro                  |  2 +-
 6 files changed, 2 insertions(+), 47 deletions(-)

diff --git a/packages/account-portal b/packages/account-portal
index 0c050591c2..3a05f9fcbb 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 0c050591c21d3b67dc0c9225d60cc9e2324c8dac
+Subproject commit 3a05f9fcbb77bb0b1fc6b6485ef49b07bafb2801
diff --git a/packages/bbui/package.json b/packages/bbui/package.json
index a1baa2a38b..2d6e86c2f9 100644
--- a/packages/bbui/package.json
+++ b/packages/bbui/package.json
@@ -94,7 +94,6 @@
         "dependsOn": [
           {
             "projects": [
-              "@budibase/string-templates",
               "@budibase/shared-core"
             ],
             "target": "build"
diff --git a/packages/builder/package.json b/packages/builder/package.json
index e66c747505..ced056bfcf 100644
--- a/packages/builder/package.json
+++ b/packages/builder/package.json
@@ -103,34 +103,6 @@
       "build": {
         "outputs": [
           "{workspaceRoot}/packages/server/builder"
-        ],
-        "dependsOn": [
-          {
-            "projects": [
-              "@budibase/string-templates"
-            ],
-            "target": "build"
-          }
-        ]
-      },
-      "dev": {
-        "dependsOn": [
-          {
-            "projects": [
-              "@budibase/string-templates"
-            ],
-            "target": "build"
-          }
-        ]
-      },
-      "test": {
-        "dependsOn": [
-          {
-            "projects": [
-              "@budibase/string-templates"
-            ],
-            "target": "build"
-          }
         ]
       }
     }
diff --git a/packages/cli/package.json b/packages/cli/package.json
index d33dcc9714..c1ba49c5e7 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -41,19 +41,5 @@
     "@types/pouchdb": "^6.4.0",
     "ts-node": "10.8.1",
     "typescript": "5.2.2"
-  },
-  "nx": {
-    "targets": {
-      "build": {
-        "dependsOn": [
-          {
-            "projects": [
-              "@budibase/string-templates"
-            ],
-            "target": "build"
-          }
-        ]
-      }
-    }
   }
 }
diff --git a/packages/client/package.json b/packages/client/package.json
index 00f89a6445..305706e279 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -69,7 +69,6 @@
           {
             "projects": [
               "@budibase/shared-core",
-              "@budibase/string-templates",
               "@budibase/types"
             ],
             "target": "build"
@@ -81,7 +80,6 @@
           {
             "projects": [
               "@budibase/shared-core",
-              "@budibase/string-templates",
               "@budibase/types"
             ],
             "target": "build"
diff --git a/packages/pro b/packages/pro
index 29f3417c83..61837de57a 160000
--- a/packages/pro
+++ b/packages/pro
@@ -1 +1 @@
-Subproject commit 29f3417c831a804e1c187948b002e924342de488
+Subproject commit 61837de57acdcf05338393bf3e3598f3b1a911ad

From 972cbf43b8c19ea617224307a5ef5e378f73f462 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 09:35:38 +0100
Subject: [PATCH 51/75] Types

---
 .../string-templates/src/conversion/index.ts  |  2 +-
 packages/string-templates/src/helpers/date.ts | 14 +++++------
 .../string-templates/src/helpers/external.ts  |  2 +-
 .../src/helpers/javascript.ts                 | 23 +++++++++++--------
 packages/string-templates/src/helpers/list.ts |  9 ++++----
 packages/string-templates/tsconfig.json       |  2 +-
 6 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/packages/string-templates/src/conversion/index.ts b/packages/string-templates/src/conversion/index.ts
index d69576e940..faf65b6085 100644
--- a/packages/string-templates/src/conversion/index.ts
+++ b/packages/string-templates/src/conversion/index.ts
@@ -63,7 +63,7 @@ function buildList(parts: any[], value: any) {
 }
 
 function splitBySpace(layer: string) {
-  const parts = []
+  const parts: string[] = []
   let started = null,
     endChar = null,
     last = 0
diff --git a/packages/string-templates/src/helpers/date.ts b/packages/string-templates/src/helpers/date.ts
index efcf516dfb..5b85aeedd4 100644
--- a/packages/string-templates/src/helpers/date.ts
+++ b/packages/string-templates/src/helpers/date.ts
@@ -27,11 +27,11 @@ dayjs.extend(dayjsTimezonePlugin)
  * https://github.com/helpers/helper-date
  */
 
-function isOptions(val) {
+function isOptions(val: any) {
   return typeof val === "object" && typeof val.hash === "object"
 }
 
-function isApp(thisArg) {
+function isApp(thisArg: any) {
   return (
     typeof thisArg === "object" &&
     typeof thisArg.options === "object" &&
@@ -39,7 +39,7 @@ function isApp(thisArg) {
   )
 }
 
-function getContext(thisArg, locals, options) {
+function getContext(thisArg: any, locals: any, options: any) {
   if (isOptions(thisArg)) {
     return getContext({}, locals, thisArg)
   }
@@ -68,7 +68,7 @@ function getContext(thisArg, locals, options) {
   return context
 }
 
-function initialConfig(str, pattern, options?) {
+function initialConfig(str: any, pattern: any, options?: any) {
   if (isOptions(pattern)) {
     options = pattern
     pattern = null
@@ -82,7 +82,7 @@ function initialConfig(str, pattern, options?) {
   return { str, pattern, options }
 }
 
-function setLocale(str, pattern, options?) {
+function setLocale(str: any, pattern: any, options?: any) {
   // if options is null then it'll get updated here
   const config = initialConfig(str, pattern, options)
   const defaults = { lang: "en", date: new Date(config.str) }
@@ -93,7 +93,7 @@ function setLocale(str, pattern, options?) {
   dayjs.locale(opts.lang || opts.language)
 }
 
-export const date = (str, pattern, options) => {
+export const date = (str: any, pattern: any, options: any) => {
   const config = initialConfig(str, pattern, options)
 
   // if no args are passed, return a formatted date
@@ -119,7 +119,7 @@ export const date = (str, pattern, options) => {
   return date.format(config.pattern)
 }
 
-export const duration = (str, pattern, format) => {
+export const duration = (str: any, pattern: any, format: any) => {
   const config = initialConfig(str, pattern)
 
   setLocale(config.str, config.pattern)
diff --git a/packages/string-templates/src/helpers/external.ts b/packages/string-templates/src/helpers/external.ts
index 8f0577a945..efb390ff8b 100644
--- a/packages/string-templates/src/helpers/external.ts
+++ b/packages/string-templates/src/helpers/external.ts
@@ -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"
 
diff --git a/packages/string-templates/src/helpers/javascript.ts b/packages/string-templates/src/helpers/javascript.ts
index b75c9f5ac1..c3833cd9a0 100644
--- a/packages/string-templates/src/helpers/javascript.ts
+++ b/packages/string-templates/src/helpers/javascript.ts
@@ -1,20 +1,23 @@
 import { atob, isBackendService, isJSAllowed } from "../utilities"
-import cloneDeep from "lodash.clonedeep"
+import cloneDeep from "lodash/fp/clonedeep"
 import { LITERAL_MARKER } from "../helpers/constants"
 import { getJsHelperList } from "./list"
 
 // The method of executing JS scripts depends on the bundle being built.
 // This setter is used in the entrypoint (either index.js or index.mjs).
-let runJS
-export const setJSRunner = runner => (runJS = runner)
+let runJS: (js: string, context: any) => any
+export const setJSRunner = (runner: typeof runJS) => (runJS = runner)
 
-export const removeJSRunner = () => (runJS = undefined)
+export const removeJSRunner = () => {
+  runJS = undefined
+}
 
-let onErrorLog
-export const setOnErrorLog = delegate => (onErrorLog = delegate)
+let onErrorLog: (message: string) => void
+export const setOnErrorLog = (delegate: typeof onErrorLog) =>
+  (onErrorLog = delegate)
 
 // Helper utility to strip square brackets from a value
-const removeSquareBrackets = value => {
+const removeSquareBrackets = (value: string) => {
   if (!value || typeof value !== "string") {
     return value
   }
@@ -28,7 +31,7 @@ const removeSquareBrackets = value => {
 
 // Our context getter function provided to JS code as $.
 // Extracts a value from context.
-const getContextValue = (path, context) => {
+const getContextValue = (path: string, context: any) => {
   let data = context
   path.split(".").forEach(key => {
     if (data == null || typeof data !== "object") {
@@ -40,7 +43,7 @@ const getContextValue = (path, context) => {
 }
 
 // Evaluates JS code against a certain context
-export function processJS(handlebars, context) {
+export function processJS(handlebars: string, context: any) {
   if (!isJSAllowed() || (isBackendService() && !runJS)) {
     throw new Error("JS disabled in environment.")
   }
@@ -53,7 +56,7 @@ export function processJS(handlebars, context) {
     // We clone the context to avoid mutation in the binding affecting real
     // app context.
     const sandboxContext = {
-      $: path => getContextValue(path, cloneDeep(context)),
+      $: (path: string) => getContextValue(path, cloneDeep(context)),
       helpers: getJsHelperList(),
     }
 
diff --git a/packages/string-templates/src/helpers/list.ts b/packages/string-templates/src/helpers/list.ts
index 7b25216976..010dbe18f3 100644
--- a/packages/string-templates/src/helpers/list.ts
+++ b/packages/string-templates/src/helpers/list.ts
@@ -20,7 +20,7 @@ const addedHelpers = {
   duration: duration,
 }
 
-let helpers = undefined
+let helpers: Record<string, any> = undefined
 
 export function getJsHelperList() {
   if (helpers) {
@@ -31,11 +31,12 @@ export function getJsHelperList() {
   for (let collection of Object.values(getExternalCollections())) {
     for (let [key, func] of Object.entries(collection)) {
       // Handlebars injects the hbs options to the helpers by default. We are adding an empty {} as a last parameter to simulate it
-      helpers[key] = (...props) => func(...props, {})
+      helpers[key] = (...props: any) => func(...props, {})
     }
   }
-  for (let key of Object.keys(addedHelpers)) {
-    helpers[key] = addedHelpers[key]
+  helpers = {
+    ...helpers,
+    addedHelpers,
   }
 
   for (const toRemove of helpersToRemoveForJs) {
diff --git a/packages/string-templates/tsconfig.json b/packages/string-templates/tsconfig.json
index 2fa760d011..585c3bf747 100644
--- a/packages/string-templates/tsconfig.json
+++ b/packages/string-templates/tsconfig.json
@@ -4,8 +4,8 @@
     "declaration": true,
     "target": "es6",
     "moduleResolution": "node",
+    "noImplicitAny": true,
     "lib": ["dom"],
-    "allowJs": true,
     "outDir": "dist",
     "esModuleInterop": true,
     "types": ["node", "jest"],

From 4332034434312beca2f48d3a5aac923d3e83722b Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 09:41:32 +0100
Subject: [PATCH 52/75] Type tests

---
 packages/string-templates/src/index.ts           |  2 +-
 packages/string-templates/test/hbsToJs.spec.ts   |  2 +-
 packages/string-templates/test/helpers.spec.ts   |  2 +-
 .../string-templates/test/javascript.spec.ts     |  2 +-
 packages/string-templates/test/manifest.spec.ts  |  8 ++++----
 packages/string-templates/test/utils.ts          | 16 ++++++++--------
 6 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index dd16a0f0ac..f1a6a1b308 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -157,7 +157,7 @@ export function processObjectSync(
  */
 export function processStringSync(
   string: string,
-  context: object,
+  context?: object,
   opts?: ProcessOptions
 ): string {
   // Take a copy of input in case of error
diff --git a/packages/string-templates/test/hbsToJs.spec.ts b/packages/string-templates/test/hbsToJs.spec.ts
index f8b4c2fca9..ea375064a1 100644
--- a/packages/string-templates/test/hbsToJs.spec.ts
+++ b/packages/string-templates/test/hbsToJs.spec.ts
@@ -1,6 +1,6 @@
 import { convertToJS } from "../src/index"
 
-function checkLines(response, lines) {
+function checkLines(response: string, lines: string[]) {
   const toCheck = response.split("\n")
   let count = 0
   for (let line of lines) {
diff --git a/packages/string-templates/test/helpers.spec.ts b/packages/string-templates/test/helpers.spec.ts
index f66eb9ef33..5f1855535d 100644
--- a/packages/string-templates/test/helpers.spec.ts
+++ b/packages/string-templates/test/helpers.spec.ts
@@ -271,7 +271,7 @@ describe("test the string helpers", () => {
 })
 
 describe("test the comparison helpers", () => {
-  async function compare(func, a, b) {
+  async function compare(func: string, a: any, b: any) {
     const output = await processString(
       `{{ #${func} a b }}Success{{ else }}Fail{{ /${func} }}`,
       {
diff --git a/packages/string-templates/test/javascript.spec.ts b/packages/string-templates/test/javascript.spec.ts
index eb12320cd0..cb2f765007 100644
--- a/packages/string-templates/test/javascript.spec.ts
+++ b/packages/string-templates/test/javascript.spec.ts
@@ -3,7 +3,7 @@ import vm from "vm"
 import { processStringSync, encodeJSBinding, setJSRunner } from "../src/index"
 import { UUID_REGEX } from "./constants"
 
-const processJS = (js, context?): any => {
+const processJS = (js: string, context?: object): any => {
   return processStringSync(encodeJSBinding(js), context)
 }
 
diff --git a/packages/string-templates/test/manifest.spec.ts b/packages/string-templates/test/manifest.spec.ts
index 9fbf4e8019..d8fee0fb1a 100644
--- a/packages/string-templates/test/manifest.spec.ts
+++ b/packages/string-templates/test/manifest.spec.ts
@@ -24,7 +24,7 @@ import { getParsedManifest, runJsHelpersTests } from "./utils"
 
 tk.freeze("2021-01-21T12:00:00")
 
-function escapeRegExp(string) {
+function escapeRegExp(string: string) {
   return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") // $& means the whole matched string
 }
 
@@ -40,9 +40,9 @@ describe("manifest", () => {
   describe("examples are valid", () => {
     describe.each(Object.keys(manifest))("%s", collection => {
       it.each(manifest[collection])("%s", async (_, { hbs, js }) => {
-        const context = {
-          double: i => i * 2,
-          isString: x => typeof x === "string",
+        const context: any = {
+          double: (i: number) => i * 2,
+          isString: (x: any) => typeof x === "string",
         }
 
         const arrays = hbs.match(/\[[^/\]]+\]/)
diff --git a/packages/string-templates/test/utils.ts b/packages/string-templates/test/utils.ts
index 8c7aa43b21..c683acf5b3 100644
--- a/packages/string-templates/test/utils.ts
+++ b/packages/string-templates/test/utils.ts
@@ -3,7 +3,7 @@ import { getJsHelperList } from "../src/helpers"
 
 import { convertToJS, processStringSync, encodeJSBinding } from "../src/index"
 
-function tryParseJson(str) {
+function tryParseJson(str: string) {
   if (typeof str !== "string") {
     return
   }
@@ -25,7 +25,7 @@ type ExampleType = [
 ]
 
 export const getParsedManifest = () => {
-  const manifest = getManifest()
+  const manifest: any = getManifest()
   const collections = Object.keys(manifest)
 
   const examples = collections.reduce((acc, collection) => {
@@ -73,14 +73,14 @@ export const runJsHelpersTests = ({
   funcWrap?: any
   testsToSkip?: any
 } = {}) => {
-  funcWrap = funcWrap || (delegate => delegate())
+  funcWrap = funcWrap || ((delegate: () => any) => delegate())
   const manifest = getParsedManifest()
 
-  const processJS = (js, context) => {
+  const processJS = (js: string, context: object | undefined) => {
     return funcWrap(() => processStringSync(encodeJSBinding(js), context))
   }
 
-  function escapeRegExp(string) {
+  function escapeRegExp(string: string) {
     return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") // $& means the whole matched string
   }
 
@@ -98,9 +98,9 @@ export const runJsHelpersTests = ({
 
       examplesToRun.length &&
         it.each(examplesToRun)("%s", async (_, { hbs, js }) => {
-          const context = {
-            double: i => i * 2,
-            isString: x => typeof x === "string",
+          const context: any = {
+            double: (i: number) => i * 2,
+            isString: (x: any) => typeof x === "string",
           }
 
           const arrays = hbs.match(/\[[^/\]]+\]/)

From e1512f15de9dc0040ab67515f36f1f9a53579de4 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 09:47:48 +0100
Subject: [PATCH 53/75] Add nx dependencies back

---
 packages/builder/package.json           | 28 +++++++++++++++++++++++++
 packages/string-templates/tsconfig.json |  1 +
 2 files changed, 29 insertions(+)

diff --git a/packages/builder/package.json b/packages/builder/package.json
index ced056bfcf..e66c747505 100644
--- a/packages/builder/package.json
+++ b/packages/builder/package.json
@@ -103,6 +103,34 @@
       "build": {
         "outputs": [
           "{workspaceRoot}/packages/server/builder"
+        ],
+        "dependsOn": [
+          {
+            "projects": [
+              "@budibase/string-templates"
+            ],
+            "target": "build"
+          }
+        ]
+      },
+      "dev": {
+        "dependsOn": [
+          {
+            "projects": [
+              "@budibase/string-templates"
+            ],
+            "target": "build"
+          }
+        ]
+      },
+      "test": {
+        "dependsOn": [
+          {
+            "projects": [
+              "@budibase/string-templates"
+            ],
+            "target": "build"
+          }
         ]
       }
     }
diff --git a/packages/string-templates/tsconfig.json b/packages/string-templates/tsconfig.json
index 585c3bf747..7fc13ace8e 100644
--- a/packages/string-templates/tsconfig.json
+++ b/packages/string-templates/tsconfig.json
@@ -5,6 +5,7 @@
     "target": "es6",
     "moduleResolution": "node",
     "noImplicitAny": true,
+    "incremental": true,
     "lib": ["dom"],
     "outDir": "dist",
     "esModuleInterop": true,

From e3033b5e507901ff695bd717d606b86f726c746f Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 09:53:30 +0100
Subject: [PATCH 54/75] Add nx build dependencies back

---
 packages/account-portal      | 2 +-
 packages/bbui/package.json   | 1 +
 packages/client/package.json | 2 ++
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/packages/account-portal b/packages/account-portal
index 3a05f9fcbb..267944a9d4 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 3a05f9fcbb77bb0b1fc6b6485ef49b07bafb2801
+Subproject commit 267944a9d4be2c4e545e886d11449470607f34b6
diff --git a/packages/bbui/package.json b/packages/bbui/package.json
index 2d6e86c2f9..a1baa2a38b 100644
--- a/packages/bbui/package.json
+++ b/packages/bbui/package.json
@@ -94,6 +94,7 @@
         "dependsOn": [
           {
             "projects": [
+              "@budibase/string-templates",
               "@budibase/shared-core"
             ],
             "target": "build"
diff --git a/packages/client/package.json b/packages/client/package.json
index 305706e279..00f89a6445 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -69,6 +69,7 @@
           {
             "projects": [
               "@budibase/shared-core",
+              "@budibase/string-templates",
               "@budibase/types"
             ],
             "target": "build"
@@ -80,6 +81,7 @@
           {
             "projects": [
               "@budibase/shared-core",
+              "@budibase/string-templates",
               "@budibase/types"
             ],
             "target": "build"

From c698b684e47d537c3713f594713d56d7f90bda00 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 09:59:18 +0100
Subject: [PATCH 55/75] Lint

---
 packages/string-templates/src/helpers/external.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/packages/string-templates/src/helpers/external.ts b/packages/string-templates/src/helpers/external.ts
index efb390ff8b..73cc377b53 100644
--- a/packages/string-templates/src/helpers/external.ts
+++ b/packages/string-templates/src/helpers/external.ts
@@ -1,4 +1,5 @@
 const helpers = require("@budibase/handlebars-helpers")
+
 import { date, duration } from "./date"
 import { HelperFunctionBuiltin } from "./constants"
 

From 9671399ca8b2300b72580f84e22dd1d103b1c97e Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 10:04:45 +0100
Subject: [PATCH 56/75] Bundle build

---
 packages/string-templates/src/handlebars-helpers.d.ts | 1 +
 packages/string-templates/src/helpers/external.ts     | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 packages/string-templates/src/handlebars-helpers.d.ts

diff --git a/packages/string-templates/src/handlebars-helpers.d.ts b/packages/string-templates/src/handlebars-helpers.d.ts
new file mode 100644
index 0000000000..90f8b6cb16
--- /dev/null
+++ b/packages/string-templates/src/handlebars-helpers.d.ts
@@ -0,0 +1 @@
+declare module "@budibase/handlebars-helpers"
diff --git a/packages/string-templates/src/helpers/external.ts b/packages/string-templates/src/helpers/external.ts
index 73cc377b53..ca0d0a9c6d 100644
--- a/packages/string-templates/src/helpers/external.ts
+++ b/packages/string-templates/src/helpers/external.ts
@@ -1,4 +1,4 @@
-const helpers = require("@budibase/handlebars-helpers")
+import helpers from "@budibase/handlebars-helpers"
 
 import { date, duration } from "./date"
 import { HelperFunctionBuiltin } from "./constants"

From 9dac9d0a3ddf2231da2cdcb0bd302917ffe35688 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 10:18:47 +0100
Subject: [PATCH 57/75] Types

---
 packages/string-templates/src/helpers/javascript.ts | 4 ++--
 packages/string-templates/src/helpers/list.ts       | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/packages/string-templates/src/helpers/javascript.ts b/packages/string-templates/src/helpers/javascript.ts
index c3833cd9a0..827a8c95aa 100644
--- a/packages/string-templates/src/helpers/javascript.ts
+++ b/packages/string-templates/src/helpers/javascript.ts
@@ -12,7 +12,7 @@ export const removeJSRunner = () => {
   runJS = undefined
 }
 
-let onErrorLog: (message: string) => void
+let onErrorLog: (message: Error) => void
 export const setOnErrorLog = (delegate: typeof onErrorLog) =>
   (onErrorLog = delegate)
 
@@ -63,7 +63,7 @@ export function processJS(handlebars: string, context: any) {
     // Create a sandbox with our context and run the JS
     const res = { data: runJS(js, sandboxContext) }
     return `{{${LITERAL_MARKER} js_result-${JSON.stringify(res)}}}`
-  } catch (error) {
+  } catch (error: any) {
     onErrorLog && onErrorLog(error)
 
     if (error.code === "ERR_SCRIPT_EXECUTION_TIMEOUT") {
diff --git a/packages/string-templates/src/helpers/list.ts b/packages/string-templates/src/helpers/list.ts
index 010dbe18f3..361558e04d 100644
--- a/packages/string-templates/src/helpers/list.ts
+++ b/packages/string-templates/src/helpers/list.ts
@@ -20,7 +20,7 @@ const addedHelpers = {
   duration: duration,
 }
 
-let helpers: Record<string, any> = undefined
+let helpers: Record<string, any>
 
 export function getJsHelperList() {
   if (helpers) {

From 987ea6053770c0efdbed19442687f2388f331015 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 10:29:47 +0100
Subject: [PATCH 58/75] Add string-templates check:types

---
 packages/string-templates/package.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index b79a44bc25..df86a2c30c 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -21,6 +21,7 @@
   "scripts": {
     "build": "tsc --emitDeclarationOnly && rollup -c",
     "dev": "rollup -cw",
+    "check:types": "tsc -p tsconfig.json --noEmit --paths null",
     "test": "jest",
     "manifest": "ts-node ./scripts/gen-collection-info.ts"
   },

From 204aadc8e6053c994256f480d258ec05ecf21772 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 10:29:59 +0100
Subject: [PATCH 59/75] Fix

---
 packages/string-templates/src/helpers/javascript.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/string-templates/src/helpers/javascript.ts b/packages/string-templates/src/helpers/javascript.ts
index 827a8c95aa..21a556a3bc 100644
--- a/packages/string-templates/src/helpers/javascript.ts
+++ b/packages/string-templates/src/helpers/javascript.ts
@@ -1,5 +1,5 @@
 import { atob, isBackendService, isJSAllowed } from "../utilities"
-import cloneDeep from "lodash/fp/clonedeep"
+import cloneDeep from "lodash/fp/cloneDeep"
 import { LITERAL_MARKER } from "../helpers/constants"
 import { getJsHelperList } from "./list"
 

From 69ecf5183b7b2ed8fcb61d729a0f7286c684f422 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 10:38:51 +0100
Subject: [PATCH 60/75] Fix cli check:types

---
 packages/cli/tsconfig.build.json              | 3 ++-
 packages/cli/tsconfig.json                    | 8 --------
 packages/string-templates/src/helpers/date.ts | 2 +-
 3 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/packages/cli/tsconfig.build.json b/packages/cli/tsconfig.build.json
index 9fbccadd31..f89ad95c28 100644
--- a/packages/cli/tsconfig.build.json
+++ b/packages/cli/tsconfig.build.json
@@ -15,7 +15,8 @@
       "@budibase/types": ["../types/src"],
       "@budibase/backend-core": ["../backend-core/src"],
       "@budibase/backend-core/*": ["../backend-core/*"],
-      "@budibase/shared-core": ["../shared-core/src"]
+      "@budibase/shared-core": ["../shared-core/src"],
+      "@budibase/string-templates": ["../string-templates/src"]
     }
   },
   "include": ["src/**/*"],
diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json
index 6ca641e214..bf51d7ed76 100644
--- a/packages/cli/tsconfig.json
+++ b/packages/cli/tsconfig.json
@@ -1,16 +1,8 @@
 {
   "extends": "./tsconfig.build.json",
-  "compilerOptions": {
-    "composite": true,
-    "declaration": true,
-    "sourceMap": true,
-    "baseUrl": ".",
-    "resolveJsonModule": true
-  },
   "ts-node": {
     "require": ["tsconfig-paths/register"],
     "swc": true
   },
-  "include": ["src/**/*", "package.json"],
   "exclude": ["node_modules", "dist"]
 }
diff --git a/packages/string-templates/src/helpers/date.ts b/packages/string-templates/src/helpers/date.ts
index 5b85aeedd4..589cb3d978 100644
--- a/packages/string-templates/src/helpers/date.ts
+++ b/packages/string-templates/src/helpers/date.ts
@@ -82,7 +82,7 @@ function initialConfig(str: any, pattern: any, options?: any) {
   return { str, pattern, options }
 }
 
-function setLocale(str: any, pattern: any, options?: any) {
+function setLocale(this: any, str: any, pattern: any, options?: any) {
   // if options is null then it'll get updated here
   const config = initialConfig(str, pattern, options)
   const defaults = { lang: "en", date: new Date(config.str) }

From 7d6377fa14777ee58babbf59ce2ba659e85e850f Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 13:01:33 +0100
Subject: [PATCH 61/75] Fix types

---
 packages/string-templates/src/handlebars-helpers.d.ts | 1 -
 packages/string-templates/src/helpers/external.ts     | 1 +
 packages/string-templates/src/helpers/javascript.ts   | 6 +++---
 3 files changed, 4 insertions(+), 4 deletions(-)
 delete mode 100644 packages/string-templates/src/handlebars-helpers.d.ts

diff --git a/packages/string-templates/src/handlebars-helpers.d.ts b/packages/string-templates/src/handlebars-helpers.d.ts
deleted file mode 100644
index 90f8b6cb16..0000000000
--- a/packages/string-templates/src/handlebars-helpers.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare module "@budibase/handlebars-helpers"
diff --git a/packages/string-templates/src/helpers/external.ts b/packages/string-templates/src/helpers/external.ts
index ca0d0a9c6d..3a95406549 100644
--- a/packages/string-templates/src/helpers/external.ts
+++ b/packages/string-templates/src/helpers/external.ts
@@ -1,3 +1,4 @@
+// @ts-ignore we don't have types for it
 import helpers from "@budibase/handlebars-helpers"
 
 import { date, duration } from "./date"
diff --git a/packages/string-templates/src/helpers/javascript.ts b/packages/string-templates/src/helpers/javascript.ts
index 21a556a3bc..7078cbb6c7 100644
--- a/packages/string-templates/src/helpers/javascript.ts
+++ b/packages/string-templates/src/helpers/javascript.ts
@@ -1,11 +1,11 @@
-import { atob, isBackendService, isJSAllowed } from "../utilities"
+import { atob, isJSAllowed } from "../utilities"
 import cloneDeep from "lodash/fp/cloneDeep"
 import { LITERAL_MARKER } from "../helpers/constants"
 import { getJsHelperList } from "./list"
 
 // The method of executing JS scripts depends on the bundle being built.
 // This setter is used in the entrypoint (either index.js or index.mjs).
-let runJS: (js: string, context: any) => any
+let runJS: ((js: string, context: any) => any) | undefined = undefined
 export const setJSRunner = (runner: typeof runJS) => (runJS = runner)
 
 export const removeJSRunner = () => {
@@ -44,7 +44,7 @@ const getContextValue = (path: string, context: any) => {
 
 // Evaluates JS code against a certain context
 export function processJS(handlebars: string, context: any) {
-  if (!isJSAllowed() || (isBackendService() && !runJS)) {
+  if (!isJSAllowed() || !runJS) {
     throw new Error("JS disabled in environment.")
   }
   try {

From 8b36419f1f6441cba8ea70d386ee2618bbd518ef Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 13:02:54 +0100
Subject: [PATCH 62/75] Pro check:types

---
 packages/pro | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/pro b/packages/pro
index 61837de57a..8879bc61b7 160000
--- a/packages/pro
+++ b/packages/pro
@@ -1 +1 @@
-Subproject commit 61837de57acdcf05338393bf3e3598f3b1a911ad
+Subproject commit 8879bc61b750ae0b9dd7a7c5d07f2c3c6f5a1686

From 8cbd0cf29d687809437d3b28a1502a39dd55a3e8 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 13:18:24 +0100
Subject: [PATCH 63/75] Fix pro types

---
 packages/pro | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/pro b/packages/pro
index 8879bc61b7..fe18ed3f34 160000
--- a/packages/pro
+++ b/packages/pro
@@ -1 +1 @@
-Subproject commit 8879bc61b750ae0b9dd7a7c5d07f2c3c6f5a1686
+Subproject commit fe18ed3f3416c5478fbfc039a0ea6e983695d327

From 08a86bdd77b15f53e69735020d32f3ef7ec0c930 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 13:40:14 +0100
Subject: [PATCH 64/75] Fix tests

---
 packages/account-portal        | 2 +-
 packages/worker/jest.config.ts | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/account-portal b/packages/account-portal
index 267944a9d4..3ba0205eed 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 267944a9d4be2c4e545e886d11449470607f34b6
+Subproject commit 3ba0205eede16ec567311c0fa909d57697641fb7
diff --git a/packages/worker/jest.config.ts b/packages/worker/jest.config.ts
index 0a640766f4..1eb17f100f 100644
--- a/packages/worker/jest.config.ts
+++ b/packages/worker/jest.config.ts
@@ -15,6 +15,7 @@ const config: Config.InitialOptions = {
     "@budibase/backend-core": "<rootDir>/../backend-core/src",
     "@budibase/types": "<rootDir>/../types/src",
     "@budibase/shared-core": ["<rootDir>/../shared-core/src"],
+    "@budibase/string-templates": ["<rootDir>/../string-templates/src"],
   },
 }
 

From f41874190c9e7166dd22adc7c6ba08f20357038e Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 13:41:38 +0100
Subject: [PATCH 65/75] Test pro like the other libraries

---
 .github/workflows/budibase_ci.yml | 29 ++---------------------------
 1 file changed, 2 insertions(+), 27 deletions(-)

diff --git a/.github/workflows/budibase_ci.yml b/.github/workflows/budibase_ci.yml
index 3060660d47..5c474aa826 100644
--- a/.github/workflows/budibase_ci.yml
+++ b/.github/workflows/budibase_ci.yml
@@ -107,9 +107,9 @@ jobs:
       - name: Test
         run: |
           if ${{ env.USE_NX_AFFECTED }}; then
-            yarn test --ignore=@budibase/worker --ignore=@budibase/server --ignore=@budibase/pro --since=${{ env.NX_BASE_BRANCH }}
+            yarn test --ignore=@budibase/worker --ignore=@budibase/server --since=${{ env.NX_BASE_BRANCH }}
           else
-            yarn test --ignore=@budibase/worker --ignore=@budibase/server --ignore=@budibase/pro
+            yarn test --ignore=@budibase/worker --ignore=@budibase/server
           fi
 
   test-worker:
@@ -160,31 +160,6 @@ jobs:
             yarn test --scope=@budibase/server
           fi
 
-  test-pro:
-    runs-on: ubuntu-latest
-    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase'
-    steps:
-      - name: Checkout repo and submodules
-        uses: actions/checkout@v4
-        with:
-          submodules: true
-          token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
-          fetch-depth: 0
-
-      - name: Use Node.js 20.x
-        uses: actions/setup-node@v4
-        with:
-          node-version: 20.x
-          cache: yarn
-      - run: yarn --frozen-lockfile
-      - name: Test
-        run: |
-          if ${{ env.USE_NX_AFFECTED }}; then
-            yarn test --scope=@budibase/pro --since=${{ env.NX_BASE_BRANCH }}
-          else
-            yarn test --scope=@budibase/pro
-          fi
-
   integration-test:
     runs-on: ubuntu-latest
     steps:

From 21fbd5304108c1613d20faa395e9eab9c4f57a44 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 14:53:25 +0100
Subject: [PATCH 66/75] Fix test mapper

---
 packages/account-portal        | 2 +-
 packages/server/jest.config.ts | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/account-portal b/packages/account-portal
index 3ba0205eed..34e35aae93 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 3ba0205eede16ec567311c0fa909d57697641fb7
+Subproject commit 34e35aae93791629fa168a655237bf8f0530acac
diff --git a/packages/server/jest.config.ts b/packages/server/jest.config.ts
index 80b187966c..fbc5167853 100644
--- a/packages/server/jest.config.ts
+++ b/packages/server/jest.config.ts
@@ -30,6 +30,7 @@ const baseConfig: Config.InitialProjectOptions = {
     "@budibase/backend-core": "<rootDir>/../backend-core/src",
     "@budibase/shared-core": "<rootDir>/../shared-core/src",
     "@budibase/types": "<rootDir>/../types/src",
+    "@budibase/string-templates": ["<rootDir>/../string-templates/src"],
   },
 }
 

From cda2b3c8eb535316110302539c084cf0b4627d4b Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 13:55:29 +0100
Subject: [PATCH 67/75] Clean single image dockerfile

---
 hosting/single/Dockerfile | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile
index ee98b0729d..4f37e95854 100644
--- a/hosting/single/Dockerfile
+++ b/hosting/single/Dockerfile
@@ -12,8 +12,6 @@ COPY .yarnrc .
 
 COPY packages/server/package.json packages/server/package.json
 COPY packages/worker/package.json packages/worker/package.json
-# string-templates does not get bundled during the esbuild process, so we want to use the local version
-COPY packages/string-templates/package.json packages/string-templates/package.json
 
 
 COPY scripts/removeWorkspaceDependencies.sh scripts/removeWorkspaceDependencies.sh
@@ -35,7 +33,6 @@ COPY packages/server/client packages/server/client
 COPY packages/server/builder packages/server/builder
 COPY packages/worker/dist packages/worker/dist
 COPY packages/worker/pm2.config.js packages/worker/pm2.config.js
-COPY packages/string-templates packages/string-templates
 
 
 FROM budibase/couchdb:v3.3.3 as runner
@@ -52,11 +49,11 @@ RUN apt-get update && \
 
 # Install postgres client for pg_dump utils
 RUN apt install -y software-properties-common apt-transport-https ca-certificates gnupg \
-    && curl -fsSl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/postgresql.gpg > /dev/null \
-    && echo deb [arch=amd64,arm64,ppc64el signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main | tee /etc/apt/sources.list.d/postgresql.list \
-    && apt update -y \
-    && apt install postgresql-client-15 -y \
-    && apt remove software-properties-common apt-transport-https gpg -y
+  && curl -fsSl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/postgresql.gpg > /dev/null \
+  && echo deb [arch=amd64,arm64,ppc64el signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main | tee /etc/apt/sources.list.d/postgresql.list \
+  && apt update -y \
+  && apt install postgresql-client-15 -y \
+  && apt remove software-properties-common apt-transport-https gpg -y
 
 # We use pm2 in order to run multiple node processes in a single container
 RUN npm install --global pm2
@@ -100,9 +97,6 @@ COPY --from=build /app/node_modules /node_modules
 COPY --from=build /app/package.json /package.json
 COPY --from=build /app/packages/server /app
 COPY --from=build /app/packages/worker /worker
-COPY --from=build /app/packages/string-templates /string-templates
-
-RUN cd /string-templates && yarn link && cd ../app && yarn link @budibase/string-templates && cd ../worker && yarn link @budibase/string-templates
 
 
 EXPOSE 80

From 2d641a967299f79e29178887440ec8ac21affa54 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 14:02:04 +0100
Subject: [PATCH 68/75] Clean worker and server dockerfile string-templates
 injection

---
 hosting/single/Dockerfile  |  2 +-
 packages/server/Dockerfile | 10 +---------
 packages/worker/Dockerfile |  8 +-------
 3 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile
index 4f37e95854..be01056b53 100644
--- a/hosting/single/Dockerfile
+++ b/hosting/single/Dockerfile
@@ -24,7 +24,7 @@ RUN ./scripts/removeWorkspaceDependencies.sh packages/worker/package.json
 RUN echo '' > scripts/syncProPackage.js
 RUN jq 'del(.scripts.postinstall)' package.json > temp.json && mv temp.json package.json
 RUN ./scripts/removeWorkspaceDependencies.sh package.json
-RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production
+RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production --frozen-lockfile
 
 # copy the actual code
 COPY packages/server/dist packages/server/dist
diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile
index 3aae395bc5..42a4b92597 100644
--- a/packages/server/Dockerfile
+++ b/packages/server/Dockerfile
@@ -41,23 +41,15 @@ COPY scripts/removeWorkspaceDependencies.sh scripts/removeWorkspaceDependencies.
 RUN chmod +x ./scripts/removeWorkspaceDependencies.sh
 
 
-WORKDIR /string-templates
-COPY packages/string-templates/package.json package.json
-RUN ../scripts/removeWorkspaceDependencies.sh package.json
-RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000
-COPY packages/string-templates .
-
-
 WORKDIR /app
 COPY packages/server/package.json .
 COPY packages/server/dist/yarn.lock .
-RUN cd ../string-templates && yarn link && cd - && yarn link @budibase/string-templates
 
 COPY scripts/removeWorkspaceDependencies.sh scripts/removeWorkspaceDependencies.sh
 RUN chmod +x ./scripts/removeWorkspaceDependencies.sh
 RUN ./scripts/removeWorkspaceDependencies.sh  package.json
 
-RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000 \
+RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000 --frozen-lockfile \
     # Remove unneeded data from file system to reduce image size
     && yarn cache clean && apt-get remove -y --purge --auto-remove g++ make python jq \
     && rm -rf /tmp/* /root/.node-gyp /usr/local/lib/node_modules/npm/node_modules/node-gyp
diff --git a/packages/worker/Dockerfile b/packages/worker/Dockerfile
index 77869c48f1..037e9107b2 100644
--- a/packages/worker/Dockerfile
+++ b/packages/worker/Dockerfile
@@ -16,21 +16,15 @@ COPY scripts/removeWorkspaceDependencies.sh scripts/removeWorkspaceDependencies.
 RUN chmod +x ./scripts/removeWorkspaceDependencies.sh
 
 
-WORKDIR /string-templates
-COPY packages/string-templates/package.json package.json
-RUN ../scripts/removeWorkspaceDependencies.sh package.json
-RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000
-COPY packages/string-templates .
 
 
 WORKDIR /app
 COPY packages/worker/package.json .
 COPY packages/worker/dist/yarn.lock .
-RUN cd ../string-templates && yarn link && cd - && yarn link @budibase/string-templates
 
 RUN ../scripts/removeWorkspaceDependencies.sh package.json
 
-RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000
+RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000 --frozen-lockfile
 # Remove unneeded data from file system to reduce image size
 RUN apk del .gyp \
     && yarn cache clean

From dff96b88a23e64e9ac21e3d509514b0cceb089e7 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 14:07:26 +0100
Subject: [PATCH 69/75] Remove --frozen-lockfile

---
 packages/server/Dockerfile | 2 +-
 packages/worker/Dockerfile | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile
index 42a4b92597..7c0e6e59bc 100644
--- a/packages/server/Dockerfile
+++ b/packages/server/Dockerfile
@@ -49,7 +49,7 @@ COPY scripts/removeWorkspaceDependencies.sh scripts/removeWorkspaceDependencies.
 RUN chmod +x ./scripts/removeWorkspaceDependencies.sh
 RUN ./scripts/removeWorkspaceDependencies.sh  package.json
 
-RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000 --frozen-lockfile \
+RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000 \
     # Remove unneeded data from file system to reduce image size
     && yarn cache clean && apt-get remove -y --purge --auto-remove g++ make python jq \
     && rm -rf /tmp/* /root/.node-gyp /usr/local/lib/node_modules/npm/node_modules/node-gyp
diff --git a/packages/worker/Dockerfile b/packages/worker/Dockerfile
index 037e9107b2..28796ea666 100644
--- a/packages/worker/Dockerfile
+++ b/packages/worker/Dockerfile
@@ -24,7 +24,7 @@ COPY packages/worker/dist/yarn.lock .
 
 RUN ../scripts/removeWorkspaceDependencies.sh package.json
 
-RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000 --frozen-lockfile
+RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production=true --network-timeout 1000000
 # Remove unneeded data from file system to reduce image size
 RUN apk del .gyp \
     && yarn cache clean

From 8f3c21f045841adfb03ba3719475eed0d3b530b3 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 16:40:30 +0100
Subject: [PATCH 70/75] Fix server jest mappers

---
 eslint-local-rules/index.js                         | 5 +++--
 packages/server/jest.config.ts                      | 1 +
 packages/server/src/jsRunner/tests/jsRunner.spec.ts | 2 +-
 packages/string-templates/package.json              | 1 -
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/eslint-local-rules/index.js b/eslint-local-rules/index.js
index 177b0a129c..202e52e70e 100644
--- a/eslint-local-rules/index.js
+++ b/eslint-local-rules/index.js
@@ -7,11 +7,12 @@ module.exports = {
 
           if (
             /^@budibase\/[^/]+\/.*$/.test(importPath) &&
-            importPath !== "@budibase/backend-core/tests"
+            importPath !== "@budibase/backend-core/tests" &&
+            importPath !== "@budibase/string-templates/test/utils"
           ) {
             context.report({
               node,
-              message: `Importing from @budibase is not allowed, except for @budibase/backend-core/tests.`,
+              message: `Importing from @budibase is not allowed, except for @budibase/backend-core/tests and @budibase/string-templates/test/utils.`,
             })
           }
         },
diff --git a/packages/server/jest.config.ts b/packages/server/jest.config.ts
index fbc5167853..6c6d6a20d3 100644
--- a/packages/server/jest.config.ts
+++ b/packages/server/jest.config.ts
@@ -30,6 +30,7 @@ const baseConfig: Config.InitialProjectOptions = {
     "@budibase/backend-core": "<rootDir>/../backend-core/src",
     "@budibase/shared-core": "<rootDir>/../shared-core/src",
     "@budibase/types": "<rootDir>/../types/src",
+    "@budibase/string-templates/(.*)": ["<rootDir>/../string-templates/$1"],
     "@budibase/string-templates": ["<rootDir>/../string-templates/src"],
   },
 }
diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts
index 54983aa470..dc6e32f52c 100644
--- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts
+++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts
@@ -1,7 +1,7 @@
 import { validate as isValidUUID } from "uuid"
 import { processStringSync, encodeJSBinding } from "@budibase/string-templates"
 
-const { runJsHelpersTests } = require("@budibase/string-templates/test/utils")
+import { runJsHelpersTests } from "@budibase/string-templates/test/utils"
 
 import tk from "timekeeper"
 import { init } from ".."
diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 4a92a25150..aa3aa5adec 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -12,7 +12,6 @@
       "import": "./dist/bundle.mjs"
     },
     "./package.json": "./package.json",
-    "./test/utils": "./test/utils.ts",
     "./iife": "./src/iife.js"
   },
   "files": [

From b1689b38c2c6408298b58d7e1bdb1b4caf329de1 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 16:56:53 +0100
Subject: [PATCH 71/75] Remove any

---
 packages/string-templates/src/conversion/index.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/string-templates/src/conversion/index.ts b/packages/string-templates/src/conversion/index.ts
index faf65b6085..7eb5ea71af 100644
--- a/packages/string-templates/src/conversion/index.ts
+++ b/packages/string-templates/src/conversion/index.ts
@@ -47,7 +47,7 @@ function getVariable(variableName: string) {
   return `$("${variableName}")`
 }
 
-function buildList(parts: any[], value: any) {
+function buildList(parts: string[], value: any) {
   function build() {
     return parts
       .map((part: string) =>

From 21a387f4fed7cf78711ccee1585223412ceb6be2 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 19:57:04 +0100
Subject: [PATCH 72/75] Mutate input

---
 packages/string-templates/src/index.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 7864f3196e..5bbc6b65eb 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -99,7 +99,8 @@ export async function processObject<T extends Record<string, any>>(
       } else if (typeof val === "object") {
         parsedValue = await processObject(object[key], context, opts)
       }
-      object = { ...object, [key]: parsedValue }
+
+      ;(object as Record<string, any>)[key] = parsedValue
     }
   }
   return object

From a78485e32520a32d82f10b720c6b4012d2bd6edb Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 20:08:59 +0100
Subject: [PATCH 73/75] Lint

---
 packages/string-templates/src/index.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 5bbc6b65eb..2fdf228964 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -100,7 +100,7 @@ export async function processObject<T extends Record<string, any>>(
         parsedValue = await processObject(object[key], context, opts)
       }
 
-      ;(object as Record<string, any>)[key] = parsedValue
+      (object as Record<string, any>)[key] = parsedValue
     }
   }
   return object

From e34f24e2f1b298d44ba9f65c68895b2fd8f668ff Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Fri, 15 Mar 2024 20:12:41 +0100
Subject: [PATCH 74/75] Lint

---
 packages/string-templates/src/index.ts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts
index 2fdf228964..3b0d7c0115 100644
--- a/packages/string-templates/src/index.ts
+++ b/packages/string-templates/src/index.ts
@@ -90,6 +90,7 @@ export async function processObject<T extends Record<string, any>>(
   opts?: { noHelpers?: boolean; escapeNewlines?: boolean; onlyFound?: boolean }
 ): Promise<T> {
   testObject(object)
+
   for (const key of Object.keys(object || {})) {
     if (object[key] != null) {
       const val = object[key]
@@ -100,7 +101,8 @@ export async function processObject<T extends Record<string, any>>(
         parsedValue = await processObject(object[key], context, opts)
       }
 
-      (object as Record<string, any>)[key] = parsedValue
+      // @ts-ignore
+      object[key] = parsedValue
     }
   }
   return object

From 749d4116312acba016c1152f0ecc6cdf8fc81723 Mon Sep 17 00:00:00 2001
From: Adria Navarro <adria@budibase.com>
Date: Mon, 18 Mar 2024 09:58:04 +0100
Subject: [PATCH 75/75] Update submodules

---
 packages/account-portal | 2 +-
 packages/pro            | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/account-portal b/packages/account-portal
index 34e35aae93..23a1219732 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 34e35aae93791629fa168a655237bf8f0530acac
+Subproject commit 23a1219732bd778654c0bcc4f49910c511e2d51f
diff --git a/packages/pro b/packages/pro
index fe18ed3f34..65ac3fc8a2 160000
--- a/packages/pro
+++ b/packages/pro
@@ -1 +1 @@
-Subproject commit fe18ed3f3416c5478fbfc039a0ea6e983695d327
+Subproject commit 65ac3fc8a20a5244fbe47629cf79678db2d9ae8a