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"}