Skip to content

Commit

Permalink
Merge branch 'master' into feat/url-binding-default
Browse files Browse the repository at this point in the history
  • Loading branch information
PClmnt authored Feb 12, 2025
2 parents c4a3d94 + 22b5523 commit 398de18
Show file tree
Hide file tree
Showing 21 changed files with 238 additions and 154 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"eslint-plugin-jest": "28.9.0",
"eslint-plugin-local-rules": "3.0.2",
"eslint-plugin-svelte": "2.46.1",
"svelte-preprocess": "^6.0.3",
"husky": "^8.0.3",
"kill-port": "^1.6.1",
"lerna": "7.4.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/backend-core/src/objectStore/objectStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ export async function retrieveDirectory(bucketName: string, path: string) {
stream.pipe(writeStream)
writePromises.push(
new Promise((resolve, reject) => {
stream.on("finish", resolve)
writeStream.on("finish", resolve)
stream.on("error", reject)
writeStream.on("error", reject)
})
Expand Down
Binary file removed packages/frontend-core/assets/covanta.png
Binary file not shown.
Binary file added packages/frontend-core/assets/reworld.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<script>
<script lang="ts">
export let sideNav = false
export let hideDevTools = false
export let hideFooter = false
Expand Down
6 changes: 3 additions & 3 deletions packages/frontend-core/src/components/Testimonial.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<script>
import { Layout } from "@budibase/bbui"
import Bulgaria from "../../assets/bulgaria.png"
import Covanta from "../../assets/covanta.png"
import Reworld from "../../assets/reworld.png"
import Schnellecke from "../../assets/schnellecke.png"
const testimonials = [
{
text: "Budibase was the only solution that checked all the boxes for Covanta. Covanta expects to realize $3.2MM in savings due to the elimination of redundant data entry.",
text: "Budibase was the only solution that checked all the boxes for Reworld. Reworld expects to realize $3.2MM in savings due to the elimination of redundant data entry.",
name: "Charles Link",
role: "Senior Director, Data and Analytics",
image: Covanta,
image: Reworld,
imageSize: 105,
},
{
Expand Down
15 changes: 14 additions & 1 deletion packages/server/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,20 @@ const baseConfig: Config.InitialProjectOptions = {
transform: {
"^.+\\.ts?$": "@swc/jest",
"^.+\\.js?$": "@swc/jest",
"^.+\\.svelte?$": "<rootDir>/scripts/svelteTransformer.js",
"^.+\\.svelte$": [
"jest-chain-transform", // https://github.com/svelteness/svelte-jester/issues/166
{
transformers: [
[
"svelte-jester",
{
preprocess: true,
},
],
"@swc/jest",
],
},
],
},
transformIgnorePatterns: ["/node_modules/(?!svelte/).*"],
moduleNameMapper: {
Expand Down
2 changes: 2 additions & 0 deletions packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"@babel/core": "^7.22.5",
"@babel/preset-env": "7.16.11",
"@jest/types": "^29.6.3",
"@sveltejs/vite-plugin-svelte": "1.4.0",
"@swc/core": "1.3.71",
"@swc/jest": "0.2.27",
"@types/archiver": "6.0.2",
Expand All @@ -164,6 +165,7 @@
"docker-compose": "0.23.17",
"ioredis-mock": "8.9.0",
"jest": "29.7.0",
"jest-chain-transform": "^0.0.8",
"jest-extended": "^4.0.2",
"jest-openapi": "0.14.2",
"nock": "13.5.4",
Expand Down
11 changes: 0 additions & 11 deletions packages/server/scripts/svelteTransformer.js

This file was deleted.

32 changes: 18 additions & 14 deletions packages/server/src/api/controllers/static/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import sdk from "../../../sdk"
import * as pro from "@budibase/pro"
import {
App,
BudibaseAppProps,
Ctx,
DocumentType,
Feature,
Expand Down Expand Up @@ -191,9 +192,14 @@ export const serveApp = async function (ctx: UserCtx<void, ServeAppResponse>) {
const themeVariables = getThemeVariables(appInfo?.theme)

if (!env.isJest()) {
const plugins = objectStore.enrichPluginURLs(appInfo.usedPlugins)

const { head, html, css } = AppComponent.render({
const plugins = await objectStore.enrichPluginURLs(appInfo.usedPlugins)
/*
* Server rendering in svelte sadly does not support type checking, the .render function
* always will just expect "any" when typing - so it is pointless for us to type the
* BudibaseApp.svelte file as we can never detect if the types are correct. To get around this
* I've created a type which expects what the app will expect to receive.
*/
const props: BudibaseAppProps = {
title: branding?.platformTitle || `${appInfo.name}`,
showSkeletonLoader: appInfo.features?.skeletonLoader ?? false,
hideDevTools,
Expand All @@ -205,21 +211,17 @@ export const serveApp = async function (ctx: UserCtx<void, ServeAppResponse>) {
metaDescription: branding?.metaDescription || "",
metaTitle:
branding?.metaTitle || `${appInfo.name} - built with Budibase`,
production: env.isProd(),
appId,
clientLibPath: objectStore.clientLibraryUrl(appId!, appInfo.version),
usedPlugins: plugins,
favicon:
branding.faviconUrl !== ""
? await objectStore.getGlobalFileUrl("settings", "faviconUrl")
: "",
logo:
config?.logoUrl !== ""
? await objectStore.getGlobalFileUrl("settings", "logoUrl")
: "",
appMigrating: needMigrations,
nonce: ctx.state.nonce,
})
}

const { head, html, css } = AppComponent.render({ props })
const appHbs = loadHandlebarsFile(appHbsPath)
ctx.body = await processString(appHbs, {
head,
Expand All @@ -235,9 +237,10 @@ export const serveApp = async function (ctx: UserCtx<void, ServeAppResponse>) {
}
} catch (error) {
if (!env.isJest()) {
const { head, html, css } = AppComponent.render({
title: branding?.metaTitle,
metaTitle: branding?.metaTitle,
const props: BudibaseAppProps = {
usedPlugins: [],
title: branding?.metaTitle || "",
metaTitle: branding?.metaTitle || "",
metaImage:
branding?.metaImageUrl ||
"https://res.cloudinary.com/daog6scxm/image/upload/v1698759482/meta-images/plain-branded-meta-image-coral_ocxmgu.png",
Expand All @@ -246,7 +249,8 @@ export const serveApp = async function (ctx: UserCtx<void, ServeAppResponse>) {
branding.faviconUrl !== ""
? await objectStore.getGlobalFileUrl("settings", "faviconUrl")
: "",
})
}
const { head, html, css } = AppComponent.render({ props })

const appHbs = loadHandlebarsFile(appHbsPath)
ctx.body = await processString(appHbs, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,8 @@
<script>
<script lang="ts">
import ClientAppSkeleton from "@budibase/frontend-core/src/components/ClientAppSkeleton.svelte"
import type { BudibaseAppProps } from "@budibase/types"
export let title = ""
export let favicon = ""
export let metaImage = ""
export let metaTitle = ""
export let metaDescription = ""
export let clientLibPath
export let usedPlugins
export let appMigrating
export let showSkeletonLoader = false
export let hideDevTools
export let sideNav
export let hideFooter
export let nonce
export let props: BudibaseAppProps
</script>

<svelte:head>
Expand All @@ -28,27 +13,27 @@
/>

<!-- Primary Meta Tags -->
<meta name="title" content={metaTitle} />
<meta name="description" content={metaDescription} />
<meta name="title" content={props.metaTitle} />
<meta name="description" content={props.metaDescription} />

<!-- Opengraph Meta Tags -->
<meta property="og:site_name" content="Budibase" />
<meta property="og:title" content={metaTitle} />
<meta property="og:description" content={metaDescription} />
<meta property="og:title" content={props.metaTitle} />
<meta property="og:description" content={props.metaDescription} />
<meta property="og:type" content="website" />
<meta property="og:image" content={metaImage} />
<meta property="og:image" content={props.metaImage} />

<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:site" content="@budibase" />
<meta property="twitter:image" content={metaImage} />
<meta property="twitter:image:alt" content={metaTitle} />
<meta property="twitter:title" content={metaTitle} />
<meta property="twitter:description" content={metaDescription} />
<meta property="twitter:image" content={props.metaImage} />
<meta property="twitter:image:alt" content={props.metaTitle} />
<meta property="twitter:title" content={props.metaTitle} />
<meta property="twitter:description" content={props.metaDescription} />

<title>{title}</title>
{#if favicon !== ""}
<link rel="icon" type="image/png" href={favicon} />
<title>{props.title}</title>
{#if props.favicon !== ""}
<link rel="icon" type="image/png" href={props.favicon} />
{:else}
<link rel="icon" type="image/png" href="/builder/bblogo.png" />
{/if}
Expand Down Expand Up @@ -105,11 +90,15 @@
</svelte:head>

<body id="app">
{#if showSkeletonLoader}
<ClientAppSkeleton {hideDevTools} {sideNav} {hideFooter} />
{#if props.showSkeletonLoader}
<ClientAppSkeleton
hideDevTools={props.hideDevTools}
sideNav={props.sideNav}
hideFooter={props.hideFooter}
/>
{/if}
<div id="error">
{#if clientLibPath}
{#if props.clientLibPath}
<h1>There was an error loading your app</h1>
<h2>
The Budibase client library could not be loaded. Try republishing your
Expand All @@ -120,24 +109,24 @@
<p />
{/if}
</div>
<script type="application/javascript" {nonce}>
<script type="application/javascript" nonce={props.nonce}>
window.INIT_TIME = Date.now()
</script>
{#if appMigrating}
<script type="application/javascript" {nonce}>
{#if props.appMigrating}
<script type="application/javascript" nonce={props.nonce}>
window.MIGRATING_APP = true
</script>
{/if}
<script type="application/javascript" src={clientLibPath}>
<script type="application/javascript" src={props.clientLibPath}>
</script>
<!-- Custom components need inserted after the core client library -->
<!-- But before loadBudibase is called -->
{#if usedPlugins?.length}
{#each usedPlugins as plugin}
{#if props.usedPlugins?.length}
{#each props.usedPlugins as plugin}
<script type="application/javascript" src={plugin.jsUrl}></script>
{/each}
{/if}
<script type="application/javascript" {nonce}>
<script type="application/javascript" nonce={props.nonce}>
if (window.loadBudibase) {
window.loadBudibase()
} else {
Expand Down
50 changes: 23 additions & 27 deletions packages/server/src/automations/tests/steps/executeQuery.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "../../../integrations/tests/utils"
import { Knex } from "knex"
import { generator } from "@budibase/backend-core/tests"
import { createAutomationBuilder } from "../utilities/AutomationTestBuilder"

const descriptions = datasourceDescribe({
exclude: [DatabaseName.MONGODB, DatabaseName.SQS],
Expand Down Expand Up @@ -41,39 +42,34 @@ if (descriptions.length) {
})

it("should be able to execute a query", async () => {
let res = await setup.runStep(
config,
setup.actions.EXECUTE_QUERY.stepId,
{
query: { queryId: query._id },
}
)
expect(res.response).toEqual([{ a: "string", b: 1 }])
expect(res.success).toEqual(true)
const { steps } = await createAutomationBuilder(config)
.onAppAction()
.executeQuery({ query: { queryId: query._id! } })
.test({ fields: {} })

expect(steps[0].outputs.response).toEqual([{ a: "string", b: 1 }])
expect(steps[0].outputs.success).toEqual(true)
})

it("should handle a null query value", async () => {
let res = await setup.runStep(
config,
setup.actions.EXECUTE_QUERY.stepId,
{
query: null,
}
)
expect(res.response.message).toEqual("Invalid inputs")
expect(res.success).toEqual(false)
const { steps } = await createAutomationBuilder(config)
.onAppAction()
// @ts-expect-error - intentionally passing null
.executeQuery({ query: { queryId: null } })
.test({ fields: {} })

expect(steps[0].outputs.response).toStartWith("Error:")
expect(steps[0].outputs.success).toEqual(false)
})

it("should handle an error executing a query", async () => {
let res = await setup.runStep(
config,
setup.actions.EXECUTE_QUERY.stepId,
{
query: { queryId: "wrong_id" },
}
)
expect(res.response).toBeDefined()
expect(res.success).toEqual(false)
const { steps } = await createAutomationBuilder(config)
.onAppAction()
.executeQuery({ query: { queryId: "wrong_id" } })
.test({ fields: {} })

expect(steps[0].outputs.response).toStartWith("Error:")
expect(steps[0].outputs.success).toEqual(false)
})
}
)
Expand Down
23 changes: 14 additions & 9 deletions packages/server/src/automations/tests/steps/sendSmtpEmail.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function generateResponse(to: string, from: string) {
}
}

import * as setup from "../utilities"
import { createAutomationBuilder } from "../utilities/AutomationTestBuilder"

describe("test the outgoing webhook action", () => {
const config = new TestConfiguration()
Expand Down Expand Up @@ -60,13 +60,14 @@ describe("test the outgoing webhook action", () => {
...invite,
}
let resp = generateResponse(inputs.to, inputs.from)
const res = await setup.runStep(
config,
setup.actions.SEND_EMAIL_SMTP.stepId,
inputs
)
expect(res.response).toEqual(resp)
expect(res.success).toEqual(true)

const { steps } = await createAutomationBuilder(config)
.onAppAction()
.sendSmtpEmail(inputs)
.test({ fields: {} })

expect(steps[0].outputs.response).toEqual(resp)
expect(steps[0].outputs.success).toEqual(true)
expect(workerRequests.sendSmtpEmail).toHaveBeenCalledTimes(1)
expect(workerRequests.sendSmtpEmail).toHaveBeenCalledWith({
to: "[email protected]",
Expand All @@ -75,7 +76,11 @@ describe("test the outgoing webhook action", () => {
contents: "testing",
cc: "cc",
bcc: "bcc",
invite,
invite: {
...invite,
startTime: invite.startTime.toISOString(),
endTime: invite.endTime.toISOString(),
},
automation: true,
attachments: [
{ url: "attachment1", filename: "attachment1.txt" },
Expand Down
Loading

0 comments on commit 398de18

Please sign in to comment.