From 659efe67d7859ad87fa7534d54cd968dfface9e3 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 19 Apr 2024 16:40:45 +0100 Subject: [PATCH 1/4] Adding edge case handling to the binding readable/runtime conversion, checking if it is trying to replace a binding which a substring of a helper name, which causes the helper to become un-usable. --- packages/builder/src/dataBinding.js | 19 +++++++++++++++++++ packages/string-templates/src/index.ts | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/dataBinding.js b/packages/builder/src/dataBinding.js index 8fdf71c156..17acd48764 100644 --- a/packages/builder/src/dataBinding.js +++ b/packages/builder/src/dataBinding.js @@ -22,12 +22,14 @@ import { isJSBinding, decodeJSBinding, encodeJSBinding, + getJsHelperList, } from "@budibase/string-templates" import { TableNames } from "./constants" import { JSONUtils, Constants } from "@budibase/frontend-core" import ActionDefinitions from "components/design/settings/controls/ButtonActionEditor/manifest.json" import { environment, licensing } from "stores/portal" import { convertOldFieldFormat } from "components/design/settings/controls/FieldConfiguration/utils" +import { helpersToCompletion } from "components/common/CodeEditor" const { ContextScopes } = Constants @@ -1210,6 +1212,23 @@ const shouldReplaceBinding = (currentValue, from, convertTo, binding) => { if (!currentValue?.includes(from)) { return false } + const helperNames = Object.keys(getJsHelperList()) + const matchedHelperNames = helperNames.filter( + name => name.includes(from) && currentValue.includes(name) + ) + // edge case - if the binding is part of a helper it may accidentally replace it + if (matchedHelperNames.length > 0) { + const indexStart = currentValue.indexOf(from), + indexEnd = indexStart + from.length + for (let helperName of matchedHelperNames) { + const helperIndexStart = currentValue.indexOf(helperName), + helperIndexEnd = helperIndexStart + helperName.length + if (indexStart >= helperIndexStart && indexEnd <= helperIndexEnd) { + return false + } + } + } + if (convertTo === "readableBinding") { // Dont replace if the value already matches the readable binding return currentValue.indexOf(binding.readableBinding) === -1 diff --git a/packages/string-templates/src/index.ts b/packages/string-templates/src/index.ts index 847567cb5a..0992813e9d 100644 --- a/packages/string-templates/src/index.ts +++ b/packages/string-templates/src/index.ts @@ -16,7 +16,7 @@ import { setJSRunner, removeJSRunner } from "./helpers/javascript" import manifest from "./manifest.json" import { ProcessOptions } from "./types" -export { helpersToRemoveForJs } from "./helpers/list" +export { helpersToRemoveForJs, getJsHelperList } from "./helpers/list" export { FIND_ANY_HBS_REGEX } from "./utilities" export { setJSRunner, setOnErrorLog } from "./helpers/javascript" export { iifeWrapper } from "./iife" From d3286474476f415919419476d0fc256240c2a7d5 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 19 Apr 2024 16:49:58 +0100 Subject: [PATCH 2/4] Removing accidental import. --- packages/builder/src/dataBinding.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/dataBinding.js b/packages/builder/src/dataBinding.js index 17acd48764..316b111f35 100644 --- a/packages/builder/src/dataBinding.js +++ b/packages/builder/src/dataBinding.js @@ -29,7 +29,6 @@ import { JSONUtils, Constants } from "@budibase/frontend-core" import ActionDefinitions from "components/design/settings/controls/ButtonActionEditor/manifest.json" import { environment, licensing } from "stores/portal" import { convertOldFieldFormat } from "components/design/settings/controls/FieldConfiguration/utils" -import { helpersToCompletion } from "components/common/CodeEditor" const { ContextScopes } = Constants From 0b830ae2e20f4561659f702085b833bdaf760918 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 19 Apr 2024 17:05:34 +0100 Subject: [PATCH 3/4] Fixing formulas not being converted back to readable. --- packages/builder/src/dataBinding.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/dataBinding.js b/packages/builder/src/dataBinding.js index 316b111f35..388b2411f5 100644 --- a/packages/builder/src/dataBinding.js +++ b/packages/builder/src/dataBinding.js @@ -1211,6 +1211,9 @@ const shouldReplaceBinding = (currentValue, from, convertTo, binding) => { if (!currentValue?.includes(from)) { return false } + // some cases we have the same binding for readable/runtime, specific logic for this + const sameBindings = binding.runtimeBinding.includes(binding.readableBinding) + const convertingToReadable = convertTo === "readableBinding" const helperNames = Object.keys(getJsHelperList()) const matchedHelperNames = helperNames.filter( name => name.includes(from) && currentValue.includes(name) @@ -1228,9 +1231,12 @@ const shouldReplaceBinding = (currentValue, from, convertTo, binding) => { } } - if (convertTo === "readableBinding") { - // Dont replace if the value already matches the readable binding + if (convertingToReadable && !sameBindings) { + // Don't replace if the value already matches the readable binding return currentValue.indexOf(binding.readableBinding) === -1 + } else if (convertingToReadable) { + // if the runtime and readable bindings are very similar, all we can do is check runtime is there + return currentValue.indexOf(binding.runtimeBinding) !== -1 } // remove all the spaces, if the input is surrounded by spaces e.g. [ Auto ID ] then // this makes sure it is detected From 0266be8138b93ccc867fd36f64902a84d803ceca Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 22 Apr 2024 12:26:30 +0100 Subject: [PATCH 4/4] Quick fix - no need to double check. --- packages/builder/src/dataBinding.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/dataBinding.js b/packages/builder/src/dataBinding.js index 388b2411f5..5efbb79611 100644 --- a/packages/builder/src/dataBinding.js +++ b/packages/builder/src/dataBinding.js @@ -1235,8 +1235,8 @@ const shouldReplaceBinding = (currentValue, from, convertTo, binding) => { // Don't replace if the value already matches the readable binding return currentValue.indexOf(binding.readableBinding) === -1 } else if (convertingToReadable) { - // if the runtime and readable bindings are very similar, all we can do is check runtime is there - return currentValue.indexOf(binding.runtimeBinding) !== -1 + // if the runtime and readable bindings are very similar we have to assume it should be replaced + return true } // remove all the spaces, if the input is surrounded by spaces e.g. [ Auto ID ] then // this makes sure it is detected