diff --git a/lerna.json b/lerna.json
index 5988c50af4..664712d568 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "version": "2.6.8-alpha.7",
+ "version": "2.6.8-alpha.11",
"npmClient": "yarn",
"packages": [
"packages/backend-core",
diff --git a/packages/backend-core/src/utils/tests/utils.spec.ts b/packages/backend-core/src/utils/tests/utils.spec.ts
index ededa48628..5a0ac4f283 100644
--- a/packages/backend-core/src/utils/tests/utils.spec.ts
+++ b/packages/backend-core/src/utils/tests/utils.spec.ts
@@ -5,6 +5,7 @@ import * as db from "../../db"
import { Header } from "../../constants"
import { newid } from "../../utils"
import env from "../../environment"
+import { BBContext } from "@budibase/types"
describe("utils", () => {
const config = new DBTestConfiguration()
@@ -106,4 +107,85 @@ describe("utils", () => {
expect(actual).toBe(undefined)
})
})
+
+ describe("isServingBuilder", () => {
+ let ctx: BBContext
+
+ const expectResult = (result: boolean) =>
+ expect(utils.isServingBuilder(ctx)).toBe(result)
+
+ beforeEach(() => {
+ ctx = structures.koa.newContext()
+ })
+
+ it("returns true if current path is in builder", async () => {
+ ctx.path = "/builder/app/app_"
+ expectResult(true)
+ })
+
+ it("returns false if current path doesn't have '/' suffix", async () => {
+ ctx.path = "/builder/app"
+ expectResult(false)
+
+ ctx.path = "/xx"
+ expectResult(false)
+ })
+ })
+
+ describe("isServingBuilderPreview", () => {
+ let ctx: BBContext
+
+ const expectResult = (result: boolean) =>
+ expect(utils.isServingBuilderPreview(ctx)).toBe(result)
+
+ beforeEach(() => {
+ ctx = structures.koa.newContext()
+ })
+
+ it("returns true if current path is in builder preview", async () => {
+ ctx.path = "/app/preview/xx"
+ expectResult(true)
+ })
+
+ it("returns false if current path is not in builder preview", async () => {
+ ctx.path = "/builder"
+ expectResult(false)
+
+ ctx.path = "/xx"
+ expectResult(false)
+ })
+ })
+
+ describe("isPublicAPIRequest", () => {
+ let ctx: BBContext
+
+ const expectResult = (result: boolean) =>
+ expect(utils.isPublicApiRequest(ctx)).toBe(result)
+
+ beforeEach(() => {
+ ctx = structures.koa.newContext()
+ })
+
+ it("returns true if current path remains to public API", async () => {
+ ctx.path = "/api/public/v1/invoices"
+ expectResult(true)
+
+ ctx.path = "/api/public/v1"
+ expectResult(true)
+
+ ctx.path = "/api/public/v2"
+ expectResult(true)
+
+ ctx.path = "/api/public/v21"
+ expectResult(true)
+ })
+
+ it("returns false if current path doesn't remain to public API", async () => {
+ ctx.path = "/api/public"
+ expectResult(false)
+
+ ctx.path = "/xx"
+ expectResult(false)
+ })
+ })
})
diff --git a/packages/backend-core/src/utils/utils.ts b/packages/backend-core/src/utils/utils.ts
index 75b098093b..82da95983a 100644
--- a/packages/backend-core/src/utils/utils.ts
+++ b/packages/backend-core/src/utils/utils.ts
@@ -1,11 +1,5 @@
-import { getAllApps, queryGlobalView } from "../db"
-import {
- Header,
- MAX_VALID_DATE,
- DocumentType,
- SEPARATOR,
- ViewName,
-} from "../constants"
+import { getAllApps } from "../db"
+import { Header, MAX_VALID_DATE, DocumentType, SEPARATOR } from "../constants"
import env from "../environment"
import * as tenancy from "../tenancy"
import * as context from "../context"
@@ -23,7 +17,9 @@ const APP_PREFIX = DocumentType.APP + SEPARATOR
const PROD_APP_PREFIX = "/app/"
const BUILDER_PREVIEW_PATH = "/app/preview"
-const BUILDER_REFERER_PREFIX = "/builder/app/"
+const BUILDER_PREFIX = "/builder"
+const BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`
+const PUBLIC_API_PREFIX = "/api/public/v"
function confirmAppId(possibleAppId: string | undefined) {
return possibleAppId && possibleAppId.startsWith(APP_PREFIX)
@@ -69,6 +65,18 @@ export function isServingApp(ctx: Ctx) {
return false
}
+export function isServingBuilder(ctx: Ctx): boolean {
+ return ctx.path.startsWith(BUILDER_APP_PREFIX)
+}
+
+export function isServingBuilderPreview(ctx: Ctx): boolean {
+ return ctx.path.startsWith(BUILDER_PREVIEW_PATH)
+}
+
+export function isPublicApiRequest(ctx: Ctx): boolean {
+ return ctx.path.startsWith(PUBLIC_API_PREFIX)
+}
+
/**
* Given a request tries to find the appId, which can be located in various places
* @param {object} ctx The main request body to look through.
@@ -110,7 +118,7 @@ export async function getAppIdFromCtx(ctx: Ctx) {
// make sure this is performed after prod app url resolution, in case the
// referer header is present from a builder redirect
const referer = ctx.request.headers.referer
- if (!appId && referer?.includes(BUILDER_REFERER_PREFIX)) {
+ if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {
const refererId = parseAppIdFromUrl(ctx.request.headers.referer)
appId = confirmAppId(refererId)
}
diff --git a/packages/bbui/src/Form/Core/DatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker.svelte
index 2c89a538a3..ad39136142 100644
--- a/packages/bbui/src/Form/Core/DatePicker.svelte
+++ b/packages/bbui/src/Form/Core/DatePicker.svelte
@@ -18,10 +18,14 @@
export let ignoreTimezones = false
export let time24hr = false
export let range = false
+ export let flatpickr
+ export let useKeyboardShortcuts = true
+
const dispatch = createEventDispatcher()
const flatpickrId = `${uuid()}-wrapper`
+
let open = false
- let flatpickr, flatpickrOptions
+ let flatpickrOptions
// Another classic flatpickr issue. Errors were randomly being thrown due to
// flatpickr internal code. Making sure that "destroy" is a valid function
@@ -59,6 +63,8 @@
dispatch("change", timestamp.toISOString())
}
},
+ onOpen: () => dispatch("open"),
+ onClose: () => dispatch("close"),
}
$: redrawOptions = {
@@ -113,12 +119,16 @@
const onOpen = () => {
open = true
- document.addEventListener("keyup", clearDateOnBackspace)
+ if (useKeyboardShortcuts) {
+ document.addEventListener("keyup", clearDateOnBackspace)
+ }
}
const onClose = () => {
open = false
- document.removeEventListener("keyup", clearDateOnBackspace)
+ if (useKeyboardShortcuts) {
+ document.removeEventListener("keyup", clearDateOnBackspace)
+ }
// Manually blur all input fields since flatpickr creates a second
// duplicate input field.
diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
index 70cb56c77d..35c9c6ad6d 100644
--- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
+++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
@@ -61,11 +61,63 @@
$: isTrigger = block?.type === "TRIGGER"
$: isUpdateRow = stepId === ActionStepID.UPDATE_ROW
+ /**
+ * TODO - Remove after November 2023
+ * *******************************
+ * Code added to provide backwards compatibility between Values 1,2,3,4,5
+ * and the new JSON body.
+ */
+ let deprecatedSchemaProperties
+ $: {
+ if (block?.stepId === "integromat" || block?.stepId === "zapier") {
+ deprecatedSchemaProperties = schemaProperties.filter(
+ prop => !prop[0].startsWith("value")
+ )
+ if (!deprecatedSchemaProperties.map(entry => entry[0]).includes("body")) {
+ deprecatedSchemaProperties.push([
+ "body",
+ {
+ title: "Payload",
+ type: "json",
+ },
+ ])
+ }
+ } else {
+ deprecatedSchemaProperties = schemaProperties
+ }
+ }
+ /****************************************************/
+
const getInputData = (testData, blockInputs) => {
let newInputData = testData || blockInputs
if (block.event === "app:trigger" && !newInputData?.fields) {
newInputData = cloneDeep(blockInputs)
}
+
+ /**
+ * TODO - Remove after November 2023
+ * *******************************
+ * Code added to provide backwards compatibility between Values 1,2,3,4,5
+ * and the new JSON body.
+ */
+ if (
+ (block?.stepId === "integromat" || block?.stepId === "zapier") &&
+ !newInputData?.body?.value
+ ) {
+ let deprecatedValues = {
+ ...newInputData,
+ }
+ delete deprecatedValues.url
+ delete deprecatedValues.body
+ newInputData = {
+ url: newInputData.url,
+ body: {
+ value: JSON.stringify(deprecatedValues),
+ },
+ }
+ }
+ /**********************************/
+
inputData = newInputData
setDefaultEnumValues()
}
@@ -239,7 +291,7 @@
- {#each schemaProperties as [key, value]}
+ {#each deprecatedSchemaProperties as [key, value]}
{#if key !== "fields"}