- {#if !$appPublished}
+ {#if !$deploymentStore.isPublished}
- import {
- Layout,
- Label,
- ColorPicker,
- notifications,
- Icon,
- Body,
- } from "@budibase/bbui"
- import { themeStore, appStore } from "@/stores/builder"
- import { DefaultAppTheme } from "@/constants"
- import AppThemeSelect from "./AppThemeSelect.svelte"
- import ButtonRoundnessSelect from "./ButtonRoundnessSelect.svelte"
- import PropertyControl from "@/components/design/settings/controls/PropertyControl.svelte"
-
- $: customTheme = $themeStore.customTheme || {}
-
- const update = async (property, value) => {
- try {
- themeStore.saveCustom({ [property]: value }, $appStore.appId)
- } catch (error) {
- notifications.error("Error updating custom theme")
- }
- }
-
-
-
-
-
- These settings apply to all screens. PDFs are always light theme.
-
-
-
-
-
-
-
- Button roundness
- update("buttonBorderRadius", e.detail)}
- />
-
- update("primaryColor", val)}
- props={{
- spectrumTheme: $themeStore.theme,
- }}
- />
- update("primaryColorHover", val)}
- props={{
- spectrumTheme: $themeStore.theme,
- }}
- />
-
-
-
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/index.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/index.svelte
index be7d48f88f..a7452deade 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/index.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/index.svelte
@@ -1,13 +1,8 @@
{#if $selectedScreen}
@@ -17,37 +12,8 @@
borderLeft
wide
>
-
-
- {#each tabs as tab}
-
{
- activeTab = tab
- }}
- >
- {capitalise(tab)}
-
- {/each}
-
-
- {#if activeTab === "theme"}
-
- {:else}
-
- {/if}
+
{/if}
-
-
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte
index be409eff09..4044f089a2 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte
@@ -1,13 +1,27 @@
@@ -17,13 +31,24 @@
@@ -56,7 +81,7 @@
}
.header {
display: flex;
- margin-bottom: 9px;
+ margin: 0 6px 4px 0;
}
.header-left {
@@ -76,4 +101,10 @@
.content {
flex: 1 1 auto;
}
+ .actions {
+ display: flex;
+ flex-direction: row;
+ gap: 4px;
+ align-items: center;
+ }
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/DevicePreviewSelect.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/DevicePreviewSelect.svelte
deleted file mode 100644
index 436571dd2e..0000000000
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/DevicePreviewSelect.svelte
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
- previewStore.setDevice("desktop")}
- />
- previewStore.setDevice("tablet")}
- />
- previewStore.setDevice("mobile")}
- />
-
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/AppThemeSelect.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/Theme/AppThemeSelect.svelte
similarity index 100%
rename from packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/AppThemeSelect.svelte
rename to packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/Theme/AppThemeSelect.svelte
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ButtonRoundnessSelect.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/Theme/ButtonRoundnessSelect.svelte
similarity index 100%
rename from packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ButtonRoundnessSelect.svelte
rename to packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/Theme/ButtonRoundnessSelect.svelte
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/Theme/ThemeSettings.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/Theme/ThemeSettings.svelte
new file mode 100644
index 0000000000..c35831dbd2
--- /dev/null
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/Theme/ThemeSettings.svelte
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+ These settings apply to all screens.
+ PDFs are always light theme.
+
+
+
+
+
+
+
+ Button roundness
+ update("buttonBorderRadius", e.detail)}
+ />
+
+ update("primaryColor", e.detail)}
+ props={{
+ spectrumTheme: $themeStore.theme,
+ }}
+ />
+ update("primaryColorHover", e.detail)}
+ props={{
+ spectrumTheme: $themeStore.theme,
+ }}
+ />
+
+
+
+
diff --git a/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte
index 56c7131891..cf698623a6 100644
--- a/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte
@@ -1,11 +1,7 @@
@@ -14,6 +10,11 @@
+
-
-
-
-
-
- {
- deleteModal.show()
- }}
- />
-
-
@@ -82,19 +52,7 @@
-
-
diff --git a/packages/builder/src/pages/builder/app/[application]/settings/general.svelte b/packages/builder/src/pages/builder/app/[application]/settings/general.svelte
new file mode 100644
index 0000000000..9d55083664
--- /dev/null
+++ b/packages/builder/src/pages/builder/app/[application]/settings/general.svelte
@@ -0,0 +1,220 @@
+
+
+
+
+ General settings
+ Control app version, deployment and settings
+
+
+ App info
+
+
+ Deployment
+ {#if $deploymentStore.isPublished}
+
+
+
+ {$deploymentStore.lastPublished}
+
+
+
+
+ View app
+
+
+
+
+ Unpublish
+ Revert changes
+
+ {:else}
+
+
+
+ Your app hasn't been published yet and isn't available to users
+
+
+
+
+ Publish
+
+
+ {/if}
+
+
+ App version
+ {#if updateAvailable}
+
+ The app is currently using version {$appStore.version}
+ but version {$appStore.upgradableVersion} is available.
+
+ Updates can contain new features, performance improvements and bug fixes.
+
+
+
+ Update version
+
+
+ {:else}
+
+ The app is currently using version {$appStore.version} .
+
+ You're running the latest!
+
+
+
+ Revert version
+
+
+ {/if}
+
+
+
+ Export
+
+ Export your app for backup or to share it with someone else
+
+
+
+ exportApp({ published: false })}>
+ Export latest edited app
+
+ exportApp({ published: true })}
+ >
+ Export latest published app
+
+
+
+
+ Import
+ Import an app export bundle to update this app
+
+
+ Import app
+
+
+ Danger zone
+
+ {
+ deleteModal.show()
+ }}
+ tooltip={$isOnlyUser
+ ? undefined
+ : "Unavailable - another user is editing this app"}
+ >
+ Delete app
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Are you sure you want to unpublish the app {selectedApp?.name} ?
+
+
+
+
+
+
+
diff --git a/packages/builder/src/pages/builder/app/[application]/settings/index.svelte b/packages/builder/src/pages/builder/app/[application]/settings/index.svelte
index 1c763724a1..eeecdfea0e 100644
--- a/packages/builder/src/pages/builder/app/[application]/settings/index.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/settings/index.svelte
@@ -1,5 +1,5 @@
diff --git a/packages/builder/src/pages/builder/app/[application]/settings/name-and-url.svelte b/packages/builder/src/pages/builder/app/[application]/settings/name-and-url.svelte
deleted file mode 100644
index 846dacc002..0000000000
--- a/packages/builder/src/pages/builder/app/[application]/settings/name-and-url.svelte
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- Name and URL
- Edit your app's name and URL
-
-
-
-
diff --git a/packages/builder/src/pages/builder/app/[application]/settings/pwa.svelte b/packages/builder/src/pages/builder/app/[application]/settings/pwa.svelte
index 78080e8640..ea14b2d1b1 100644
--- a/packages/builder/src/pages/builder/app/[application]/settings/pwa.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/settings/pwa.svelte
@@ -107,7 +107,7 @@
-
Progressive Web App
+
Progressive web app
{#if !pwaEnabled}
Enterprise
diff --git a/packages/builder/src/pages/builder/app/[application]/settings/version.svelte b/packages/builder/src/pages/builder/app/[application]/settings/version.svelte
deleted file mode 100644
index 6a780555a9..0000000000
--- a/packages/builder/src/pages/builder/app/[application]/settings/version.svelte
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
- Version
- See the current version of your app and check for updates
-
-
- {#if updateAvailable}
-
- The app is currently using version {$appStore.version}
- but version {$appStore.upgradableVersion} is available.
-
- Updates can contain new features, performance improvements and bug fixes.
-
-
-
- Update app
-
-
- {:else}
-
- The app is currently using version {$appStore.version} .
-
- You're running the latest!
-
-
-
- Revert app
-
-
- {/if}
-
-
-
diff --git a/packages/builder/src/pages/builder/portal/users/users/[userId].svelte b/packages/builder/src/pages/builder/portal/users/users/[userId].svelte
index d479bb52a2..b3b3807853 100644
--- a/packages/builder/src/pages/builder/portal/users/users/[userId].svelte
+++ b/packages/builder/src/pages/builder/portal/users/users/[userId].svelte
@@ -149,7 +149,7 @@
// check if access via group for creator
const foundGroup = $groups?.find(
- group => group.roles[prodAppId] || group.builder?.apps[prodAppId]
+ group => group.roles?.[prodAppId] || group.builder?.apps[prodAppId]
)
if (foundGroup.builder?.apps[prodAppId]) {
return Constants.Roles.CREATOR
diff --git a/packages/builder/src/stores/builder/deployment.ts b/packages/builder/src/stores/builder/deployment.ts
new file mode 100644
index 0000000000..73e6480550
--- /dev/null
+++ b/packages/builder/src/stores/builder/deployment.ts
@@ -0,0 +1,143 @@
+import { type Writable, get, type Readable, derived } from "svelte/store"
+import { API } from "@/api"
+import { notifications } from "@budibase/bbui"
+import { DeploymentProgressResponse, DeploymentStatus } from "@budibase/types"
+import analytics, { Events, EventSource } from "@/analytics"
+import { appsStore } from "@/stores/portal/apps"
+import { DerivedBudiStore } from "@/stores/BudiStore"
+import { appStore } from "./app"
+import { processStringSync } from "@budibase/string-templates"
+
+interface DeploymentState {
+ deployments: DeploymentProgressResponse[]
+ isPublishing: boolean
+}
+
+interface DerivedDeploymentState extends DeploymentState {
+ isPublished: boolean
+ lastPublished?: string
+}
+
+class DeploymentStore extends DerivedBudiStore<
+ DeploymentState,
+ DerivedDeploymentState
+> {
+ constructor() {
+ const makeDerivedStore = (
+ store: Writable
+ ): Readable => {
+ return derived(
+ [store, appStore, appsStore],
+ ([$store, $appStore, $appsStore]) => {
+ // Determine whether the app is published
+ const app = $appsStore.apps.find(app => app.devId === $appStore.appId)
+ const deployments = $store.deployments.filter(
+ x => x.status === DeploymentStatus.SUCCESS
+ )
+ const isPublished =
+ app?.status === "published" && !!deployments.length
+
+ // Generate last published string
+ let lastPublished = undefined
+ if (isPublished) {
+ lastPublished = processStringSync(
+ "Your app was last published {{ duration time 'millisecond' }} ago",
+ {
+ time:
+ new Date().getTime() -
+ new Date(deployments[0].updatedAt).getTime(),
+ }
+ )
+ }
+ return {
+ ...$store,
+ isPublished,
+ lastPublished,
+ }
+ }
+ )
+ }
+ super(
+ {
+ deployments: [],
+ isPublishing: false,
+ },
+ makeDerivedStore
+ )
+ this.load = this.load.bind(this)
+ this.publishApp = this.publishApp.bind(this)
+ this.completePublish = this.completePublish.bind(this)
+ this.unpublishApp = this.unpublishApp.bind(this)
+ }
+
+ async load() {
+ try {
+ const deployments = await API.getAppDeployments()
+ this.update(state => ({
+ ...state,
+ deployments,
+ }))
+ } catch (err) {
+ notifications.error("Error fetching deployments")
+ }
+ }
+
+ async publishApp(showNotification = true) {
+ try {
+ this.update(state => ({ ...state, isPublishing: true }))
+ await API.publishAppChanges(get(appStore).appId)
+ if (showNotification) {
+ notifications.send("App published successfully", {
+ type: "success",
+ icon: "GlobeCheck",
+ })
+ }
+ await this.completePublish()
+ } catch (error: any) {
+ analytics.captureException(error)
+ const message = error?.message ? ` - ${error.message}` : ""
+ notifications.error(`Error publishing app${message}`)
+ }
+ this.update(state => ({ ...state, isPublishing: false }))
+ }
+
+ async completePublish() {
+ try {
+ await appsStore.load()
+ await this.load()
+ } catch (err) {
+ notifications.error("Error refreshing app")
+ }
+ }
+
+ async unpublishApp() {
+ if (!get(this.derivedStore).isPublished) {
+ return
+ }
+ try {
+ await API.unpublishApp(get(appStore).appId)
+ await appsStore.load()
+ notifications.send("App unpublished", {
+ type: "success",
+ icon: "GlobeStrike",
+ })
+ } catch (err) {
+ notifications.error("Error unpublishing app")
+ }
+ }
+
+ viewPublishedApp() {
+ const app = get(appStore)
+ analytics.captureEvent(Events.APP_VIEW_PUBLISHED, {
+ appId: app.appId,
+ eventSource: EventSource.PORTAL,
+ })
+ if (get(appStore).url) {
+ window.open(`/app${app.url}`)
+ } else {
+ window.open(`/${app.appId}`)
+ }
+ }
+}
+
+export const deploymentStore = new DeploymentStore()
diff --git a/packages/builder/src/stores/builder/deployments.ts b/packages/builder/src/stores/builder/deployments.ts
deleted file mode 100644
index 122ee43c20..0000000000
--- a/packages/builder/src/stores/builder/deployments.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { writable, type Writable } from "svelte/store"
-import { API } from "@/api"
-import { notifications } from "@budibase/bbui"
-import { DeploymentProgressResponse } from "@budibase/types"
-
-export const createDeploymentStore = () => {
- let store: Writable = writable([])
-
- const load = async (): Promise => {
- try {
- store.set(await API.getAppDeployments())
- } catch (err) {
- notifications.error("Error fetching deployments")
- }
- }
-
- return {
- subscribe: store.subscribe,
- load,
- }
-}
-
-export const deploymentStore = createDeploymentStore()
diff --git a/packages/builder/src/stores/builder/index.ts b/packages/builder/src/stores/builder/index.ts
index 7b4455216a..75b4dc6313 100644
--- a/packages/builder/src/stores/builder/index.ts
+++ b/packages/builder/src/stores/builder/index.ts
@@ -14,7 +14,7 @@ import {
evaluationContext,
} from "./automations"
import { userStore, userSelectedResourceMap, isOnlyUser } from "./users"
-import { deploymentStore } from "./deployments"
+import { deploymentStore } from "./deployment"
import { contextMenuStore } from "./contextMenu"
import { snippets } from "./snippets"
import {
@@ -36,7 +36,6 @@ import { queries } from "./queries"
import { flags } from "./flags"
import { rowActions } from "./rowActions"
import componentTreeNodesStore from "./componentTreeNodes"
-import { appPublished } from "./published"
import { oauth2 } from "./oauth2"
import { FetchAppPackageResponse } from "@budibase/types"
@@ -75,7 +74,6 @@ export {
hoverStore,
snippets,
rowActions,
- appPublished,
evaluationContext,
screenComponentsList,
screenComponentErrors,
diff --git a/packages/builder/src/stores/builder/published.ts b/packages/builder/src/stores/builder/published.ts
deleted file mode 100644
index c38f3bb718..0000000000
--- a/packages/builder/src/stores/builder/published.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { appStore } from "./app"
-import { appsStore } from "@/stores/portal/apps"
-import { deploymentStore } from "./deployments"
-import { derived, type Readable } from "svelte/store"
-import { DeploymentProgressResponse, DeploymentStatus } from "@budibase/types"
-
-export const appPublished: Readable = derived(
- [appStore, appsStore, deploymentStore],
- ([$appStore, $appsStore, $deploymentStore]) => {
- const app = $appsStore.apps.find(app => app.devId === $appStore.appId)
- const deployments = $deploymentStore.filter(
- (x: DeploymentProgressResponse) => x.status === DeploymentStatus.SUCCESS
- )
- return app?.status === "published" && deployments.length > 0
- }
-)
diff --git a/packages/builder/src/stores/portal/admin.test.js b/packages/builder/src/stores/portal/admin.test.js
index 8924a5e6fb..1ebbcb3dd9 100644
--- a/packages/builder/src/stores/portal/admin.test.js
+++ b/packages/builder/src/stores/portal/admin.test.js
@@ -2,10 +2,10 @@ import { it, expect, describe, beforeEach, vi } from "vitest"
import { AdminStore } from "./admin"
import { writable, get } from "svelte/store"
import { API } from "@/api"
-import { auth } from "@/stores/portal"
+import { auth } from "./auth"
import { banner } from "@budibase/bbui"
-vi.mock("@/stores/portal", () => {
+vi.mock("./auth", () => {
return { auth: vi.fn() }
})
diff --git a/packages/builder/src/stores/portal/admin.ts b/packages/builder/src/stores/portal/admin.ts
index 6ac8b00b73..baeb3a66f0 100644
--- a/packages/builder/src/stores/portal/admin.ts
+++ b/packages/builder/src/stores/portal/admin.ts
@@ -1,6 +1,6 @@
import { get } from "svelte/store"
import { API } from "@/api"
-import { auth } from "@/stores/portal"
+import { auth } from "./auth"
import { banner } from "@budibase/bbui"
import {
ConfigChecklistResponse,
diff --git a/packages/builder/src/stores/portal/auth.ts b/packages/builder/src/stores/portal/auth.ts
index b0b5fc4acb..2684ae8c78 100644
--- a/packages/builder/src/stores/portal/auth.ts
+++ b/packages/builder/src/stores/portal/auth.ts
@@ -1,6 +1,6 @@
import { get } from "svelte/store"
import { API } from "@/api"
-import { admin } from "@/stores/portal"
+import { admin } from "./admin"
import analytics from "@/analytics"
import { BudiStore } from "@/stores/BudiStore"
import {
diff --git a/packages/client/manifest.json b/packages/client/manifest.json
index 46b1251da1..67f2b045b7 100644
--- a/packages/client/manifest.json
+++ b/packages/client/manifest.json
@@ -639,6 +639,7 @@
"hAlign": "center",
"vAlign": "center"
},
+ "styles": ["margin", "background", "font"],
"settings": [
{
"type": "text",
diff --git a/packages/client/src/components/app/Button.svelte b/packages/client/src/components/app/Button.svelte
index 29bdd46a70..6183ed4252 100644
--- a/packages/client/src/components/app/Button.svelte
+++ b/packages/client/src/components/app/Button.svelte
@@ -23,6 +23,9 @@
$: $component.editing && node?.focus()
$: componentText = getComponentText(text, $builderStore, $component)
+ $: customBg =
+ $component.styles?.normal?.background ||
+ $component.styles?.normal?.["background-image"]
const getComponentText = (text, builderState, componentState) => {
if (componentState.editing) {
@@ -49,16 +52,17 @@
{#key $component.editing}
(touched = true)}
+ disabled={disabled || handlingOnClick}
+ contenteditable={$component.editing && !icon}
>
{#if icon}
@@ -75,6 +79,13 @@
overflow: hidden;
text-overflow: ellipsis;
}
+ button.custom {
+ transition: filter 130ms ease-out;
+ border-width: 0;
+ }
+ button.custom:hover {
+ filter: brightness(1.1);
+ }
.spectrum-Button--overBackground:hover {
color: #555;
}
diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile
index 9668804a80..182f690582 100644
--- a/packages/server/Dockerfile
+++ b/packages/server/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:20-alpine
+FROM node:22-alpine
LABEL com.centurylinklabs.watchtower.lifecycle.pre-check="scripts/watchtower-hooks/pre-check.sh"
LABEL com.centurylinklabs.watchtower.lifecycle.pre-update="scripts/watchtower-hooks/pre-update.sh"
diff --git a/packages/server/src/api/controllers/query/index.ts b/packages/server/src/api/controllers/query/index.ts
index b522008cad..20c08e39d3 100644
--- a/packages/server/src/api/controllers/query/index.ts
+++ b/packages/server/src/api/controllers/query/index.ts
@@ -169,8 +169,10 @@ function enrichParameters(
validateQueryInputs(requestParameters)
// make sure parameters are fully enriched with defaults
for (const parameter of query.parameters) {
- let value: string | null =
- requestParameters[parameter.name] || parameter.default
+ let value = requestParameters[parameter.name]
+ if (value == null) {
+ value = parameter.default
+ }
if (query.nullDefaultSupport && paramNotSet(value)) {
value = null
}
diff --git a/packages/server/src/api/routes/tests/queries/generic-sql.spec.ts b/packages/server/src/api/routes/tests/queries/generic-sql.spec.ts
index 59a9b98ff9..33434dad05 100644
--- a/packages/server/src/api/routes/tests/queries/generic-sql.spec.ts
+++ b/packages/server/src/api/routes/tests/queries/generic-sql.spec.ts
@@ -642,6 +642,35 @@ if (descriptions.length) {
expect(rows).toHaveLength(1)
}
)
+
+ it("should be able to create a new row with a JS value of 0 without falling back to the default", async () => {
+ const query = await createQuery({
+ name: "New Query",
+ queryVerb: "create",
+ fields: {
+ sql: client(tableName)
+ .insert({ number: client.raw("{{ number }}") })
+ .toString(),
+ },
+ parameters: [
+ {
+ name: "number",
+ default: "999",
+ },
+ ],
+ })
+
+ await config.api.query.execute(query._id!, {
+ parameters: { number: 0 },
+ })
+
+ const rows = await client(tableName).select("*")
+ expect(rows).toHaveLength(6)
+ expect(rows[5].number).toEqual(0)
+
+ const rowsWith999 = rows.filter(row => row.number === 999)
+ expect(rowsWith999).toHaveLength(0)
+ })
})
describe("read", () => {
diff --git a/packages/server/src/threads/definitions.ts b/packages/server/src/threads/definitions.ts
index 44a76a60a3..344a086741 100644
--- a/packages/server/src/threads/definitions.ts
+++ b/packages/server/src/threads/definitions.ts
@@ -16,7 +16,7 @@ export interface QueryEvent
ctx?: any
}
-export type QueryEventParameters = Record
+export type QueryEventParameters = Record
export interface QueryResponse {
rows: Row[]
diff --git a/packages/types/src/api/web/app/query.ts b/packages/types/src/api/web/app/query.ts
index 14f39ba267..245133a0a5 100644
--- a/packages/types/src/api/web/app/query.ts
+++ b/packages/types/src/api/web/app/query.ts
@@ -34,7 +34,7 @@ export interface PreviewQueryResponse {
}
export interface ExecuteQueryRequest {
- parameters?: Record
+ parameters?: Record
pagination?: any
}
export type ExecuteV1QueryResponse = Record[]
diff --git a/packages/worker/Dockerfile b/packages/worker/Dockerfile
index 3abc54bd48..95a33cc787 100644
--- a/packages/worker/Dockerfile
+++ b/packages/worker/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:20-alpine
+FROM node:22-alpine
LABEL com.centurylinklabs.watchtower.lifecycle.pre-check="scripts/watchtower-hooks/pre-check.sh"
LABEL com.centurylinklabs.watchtower.lifecycle.pre-update="scripts/watchtower-hooks/pre-update.sh"