diff --git a/.eslintignore b/.eslintignore index a79f9e2879..8d4c64d960 100644 --- a/.eslintignore +++ b/.eslintignore @@ -10,4 +10,5 @@ packages/builder/.routify packages/sdk/sdk packages/account-portal/packages/server/build packages/account-portal/packages/ui/.routify -packages/account-portal/packages/ui/build \ No newline at end of file +packages/account-portal/packages/ui/build +**/*.ivm.bundle.js \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 917443014b..3de9d13046 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -43,7 +43,8 @@ "no-useless-escape": "off", "no-undef": "off", "no-prototype-builtins": "off", - "local-rules/no-budibase-imports": "error" + "local-rules/no-budibase-imports": "error", + "local-rules/no-test-com": "error" } }, { @@ -53,7 +54,7 @@ "packages/frontend-core/**/*" ], "rules": { - "no-console": ["error", { "allow": ["warn", "error", "debug"] } ] + "no-console": ["error", { "allow": ["warn", "error", "debug"] }] } } ], diff --git a/.prettierignore b/.prettierignore index 2444f0e753..87f0191a94 100644 --- a/.prettierignore +++ b/.prettierignore @@ -11,4 +11,5 @@ packages/sdk/sdk packages/pro/coverage packages/account-portal/packages/ui/build packages/account-portal/packages/ui/.routify -packages/account-portal/packages/server/build \ No newline at end of file +packages/account-portal/packages/server/build +**/*.ivm.bundle.js \ No newline at end of file diff --git a/eslint-local-rules/index.js b/eslint-local-rules/index.js index af02599c90..71bb5068da 100644 --- a/eslint-local-rules/index.js +++ b/eslint-local-rules/index.js @@ -18,4 +18,37 @@ module.exports = { } }, }, + "no-test-com": { + meta: { + type: "problem", + docs: { + description: + "disallow the use of 'test.com' in strings and replace it with 'example.com'", + category: "Possible Errors", + recommended: false, + }, + schema: [], // no options + fixable: "code", // Indicates that this rule supports automatic fixing + }, + create: function (context) { + return { + Literal(node) { + if ( + typeof node.value === "string" && + node.value.includes("test.com") + ) { + context.report({ + node, + message: + "test.com is a privately owned domain and could point anywhere, use example.com instead.", + fix: function (fixer) { + const newText = node.raw.replace(/test\.com/g, "example.com") + return fixer.replaceText(node, newText) + }, + }) + } + }, + } + }, + }, } diff --git a/hosting/docker-compose.yaml b/hosting/docker-compose.yaml index 36b88466fe..a72b36aef1 100644 --- a/hosting/docker-compose.yaml +++ b/hosting/docker-compose.yaml @@ -98,7 +98,6 @@ services: couchdb-service: restart: unless-stopped image: budibase/couchdb - pull_policy: always environment: - COUCHDB_PASSWORD=${COUCH_DB_PASSWORD} - COUCHDB_USER=${COUCH_DB_USER} diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile index 67ac677984..f9044cd124 100644 --- a/hosting/single/Dockerfile +++ b/hosting/single/Dockerfile @@ -124,6 +124,8 @@ HEALTHCHECK --interval=15s --timeout=15s --start-period=45s CMD "/healthcheck.sh # must set this just before running ENV NODE_ENV=production +# this is required for isolated-vm to work on Node 20+ +ENV NODE_OPTIONS="--no-node-snapshot" WORKDIR / CMD ["./runner.sh"] diff --git a/lerna.json b/lerna.json index 0f02995ac0..62068e25a8 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.17.3", + "version": "2.19.6", "npmClient": "yarn", "packages": [ "packages/*", diff --git a/package.json b/package.json index af4c540604..4407fd33f3 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "lint": "yarn run lint:eslint && yarn run lint:prettier", "lint:fix:eslint": "eslint --fix --max-warnings=0 packages qa-core", "lint:fix:prettier": "prettier --write \"packages/**/*.{js,ts,svelte}\" && prettier --write \"examples/**/*.{js,ts,svelte}\" && prettier --write \"qa-core/**/*.{js,ts,svelte}\"", - "lint:fix": "yarn run lint:fix:prettier && yarn run lint:fix:eslint", + "lint:fix": "yarn run lint:fix:eslint && yarn run lint:fix:prettier", "build:specs": "lerna run --stream specs", "build:docker:airgap": "node hosting/scripts/airgapped/airgappedDockerBuild", "build:docker:airgap:single": "SINGLE_IMAGE=1 node hosting/scripts/airgapped/airgappedDockerBuild", @@ -97,7 +97,16 @@ "@budibase/backend-core": "0.0.0", "@budibase/shared-core": "0.0.0", "@budibase/string-templates": "0.0.0", - "@budibase/types": "0.0.0" + "@budibase/types": "0.0.0", + "tough-cookie": "4.1.3", + "node-fetch": "2.6.7", + "semver": "7.5.3", + "http-cache-semantics": "4.1.1", + "msgpackr": "1.10.1", + "axios": "1.6.3", + "xml2js": "0.6.2", + "unset-value": "2.0.1", + "passport": "0.6.0" }, "engines": { "node": ">=20.0.0 <21.0.0" diff --git a/packages/account-portal b/packages/account-portal index cc12291732..8c446c4ba3 160000 --- a/packages/account-portal +++ b/packages/account-portal @@ -1 +1 @@ -Subproject commit cc12291732ee902dc832bc7d93cf2086ffdf0cff +Subproject commit 8c446c4ba385592127fa31755d3b64467b291882 diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 85644488f5..3f8c34f823 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -25,19 +25,19 @@ "@budibase/pouchdb-replication-stream": "1.2.10", "@budibase/shared-core": "0.0.0", "@budibase/types": "0.0.0", - "@techpass/passport-openidconnect": "0.3.2", + "@govtechsg/passport-openidconnect": "^1.0.2", "aws-cloudfront-sign": "3.0.2", "aws-sdk": "2.1030.0", "bcrypt": "5.1.0", "bcryptjs": "2.4.3", "bull": "4.10.1", "correlation-id": "4.0.0", - "dd-trace": "5.0.0", + "dd-trace": "5.2.0", "dotenv": "16.0.1", "ioredis": "5.3.2", "joi": "17.6.0", "jsonwebtoken": "9.0.2", - "koa-passport": "4.1.4", + "koa-passport": "^6.0.0", "koa-pino-logger": "4.0.0", "lodash": "4.17.21", "node-fetch": "2.6.7", @@ -52,9 +52,9 @@ "redlock": "4.2.0", "rotating-file-stream": "3.1.0", "sanitize-s3-objectkey": "0.0.1", - "semver": "7.3.7", + "semver": "^7.5.4", "tar-fs": "2.1.1", - "uuid": "8.3.2" + "uuid": "^8.3.2" }, "devDependencies": { "@shopify/jest-koa-mocks": "5.1.1", diff --git a/packages/backend-core/src/context/types.ts b/packages/backend-core/src/context/types.ts index f73dc9f5c7..6fb9f44fad 100644 --- a/packages/backend-core/src/context/types.ts +++ b/packages/backend-core/src/context/types.ts @@ -1,4 +1,4 @@ -import { IdentityContext } from "@budibase/types" +import { IdentityContext, VM } from "@budibase/types" import { ExecutionTimeTracker } from "../timers" // keep this out of Budibase types, don't want to expose context info @@ -11,4 +11,5 @@ export type ContextMap = { automationId?: string isMigrating?: boolean jsExecutionTracker?: ExecutionTimeTracker + vm?: VM } diff --git a/packages/backend-core/src/events/publishers/query.ts b/packages/backend-core/src/events/publishers/query.ts index 7d28129cf6..48603257d2 100644 --- a/packages/backend-core/src/events/publishers/query.ts +++ b/packages/backend-core/src/events/publishers/query.ts @@ -3,6 +3,7 @@ import { Event, Datasource, Query, + QueryPreview, QueryCreatedEvent, QueryUpdatedEvent, QueryDeletedEvent, @@ -68,9 +69,9 @@ const run = async (count: number, timestamp?: string | number) => { await publishEvent(Event.QUERIES_RUN, properties, timestamp) } -const previewed = async (datasource: Datasource, query: Query) => { +const previewed = async (datasource: Datasource, query: QueryPreview) => { const properties: QueryPreviewedEvent = { - queryId: query._id, + queryId: query.queryId, datasourceId: datasource._id as string, source: datasource.source, queryVerb: query.queryVerb, diff --git a/packages/backend-core/src/installation.ts b/packages/backend-core/src/installation.ts index ca35b926fb..83166880cc 100644 --- a/packages/backend-core/src/installation.ts +++ b/packages/backend-core/src/installation.ts @@ -6,6 +6,7 @@ import * as context from "./context" import semver from "semver" import { bustCache, withCache, TTL, CacheKey } from "./cache/generic" import environment from "./environment" +import { logAlert } from "./logging" export const getInstall = async (): Promise => { return withCache(CacheKey.INSTALLATION, TTL.ONE_DAY, getInstallFromDB, { @@ -80,27 +81,35 @@ export const checkInstallVersion = async (): Promise => { const currentVersion = install.version const newVersion = environment.VERSION - if (currentVersion !== newVersion) { - const isUpgrade = semver.gt(newVersion, currentVersion) - const isDowngrade = semver.lt(newVersion, currentVersion) + try { + if (currentVersion !== newVersion) { + const isUpgrade = semver.gt(newVersion, currentVersion) + const isDowngrade = semver.lt(newVersion, currentVersion) - const success = await updateVersion(newVersion) + const success = await updateVersion(newVersion) - if (success) { - await context.doInIdentityContext( - { - _id: install.installId, - type: IdentityType.INSTALLATION, - }, - async () => { - if (isUpgrade) { - await events.installation.upgraded(currentVersion, newVersion) - } else if (isDowngrade) { - await events.installation.downgraded(currentVersion, newVersion) + if (success) { + await context.doInIdentityContext( + { + _id: install.installId, + type: IdentityType.INSTALLATION, + }, + async () => { + if (isUpgrade) { + await events.installation.upgraded(currentVersion, newVersion) + } else if (isDowngrade) { + await events.installation.downgraded(currentVersion, newVersion) + } } - } - ) - await events.identification.identifyInstallationGroup(install.installId) + ) + await events.identification.identifyInstallationGroup(install.installId) + } + } + } catch (err: any) { + if (err?.message?.includes("Invalid Version")) { + logAlert(`Invalid version "${newVersion}" - is it semver?`) + } else { + logAlert("Failed to retrieve version", err) } } } diff --git a/packages/backend-core/src/logging/correlation/correlation.ts b/packages/backend-core/src/logging/correlation/correlation.ts index 0498bd43d5..13cc7aff8f 100644 --- a/packages/backend-core/src/logging/correlation/correlation.ts +++ b/packages/backend-core/src/logging/correlation/correlation.ts @@ -2,11 +2,12 @@ import { Header } from "../../constants" const correlator = require("correlation-id") -export const setHeader = (headers: any) => { +export const setHeader = (headers: Record) => { const correlationId = correlator.getId() - if (correlationId) { - headers[Header.CORRELATION_ID] = correlationId + if (!correlationId) { + return } + headers[Header.CORRELATION_ID] = correlationId } export function getId() { diff --git a/packages/backend-core/src/objectStore/objectStore.ts b/packages/backend-core/src/objectStore/objectStore.ts index 3a3b9cdaab..8d18fb97fd 100644 --- a/packages/backend-core/src/objectStore/objectStore.ts +++ b/packages/backend-core/src/objectStore/objectStore.ts @@ -255,7 +255,8 @@ export async function listAllObjects(bucketName: string, path: string) { objects = objects.concat(response.Contents) } isTruncated = !!response.IsTruncated - } while (isTruncated) + token = response.NextContinuationToken + } while (isTruncated && token) return objects } diff --git a/packages/backend-core/src/queue/queue.ts b/packages/backend-core/src/queue/queue.ts index b95dace5b2..0bcb25a35f 100644 --- a/packages/backend-core/src/queue/queue.ts +++ b/packages/backend-core/src/queue/queue.ts @@ -2,7 +2,7 @@ import env from "../environment" import { getRedisOptions } from "../redis/utils" import { JobQueue } from "./constants" import InMemoryQueue from "./inMemoryQueue" -import BullQueue, { QueueOptions } from "bull" +import BullQueue, { QueueOptions, JobOptions } from "bull" import { addListeners, StalledFn } from "./listeners" import { Duration } from "../utils" import * as timers from "../timers" @@ -24,17 +24,24 @@ async function cleanup() { export function createQueue( jobQueue: JobQueue, - opts: { removeStalledCb?: StalledFn } = {} + opts: { + removeStalledCb?: StalledFn + maxStalledCount?: number + jobOptions?: JobOptions + } = {} ): BullQueue.Queue { const redisOpts = getRedisOptions() const queueConfig: QueueOptions = { redis: redisOpts, settings: { - maxStalledCount: 0, + maxStalledCount: opts.maxStalledCount ? opts.maxStalledCount : 0, lockDuration: QUEUE_LOCK_MS, lockRenewTime: QUEUE_LOCK_RENEW_INTERNAL_MS, }, } + if (opts.jobOptions) { + queueConfig.defaultJobOptions = opts.jobOptions + } let queue: any if (!env.isTest()) { queue = new BullQueue(jobQueue, queueConfig) diff --git a/packages/backend-core/src/utils/tests/utils.spec.ts b/packages/backend-core/src/utils/tests/utils.spec.ts index 7b411e801c..4dc3855c35 100644 --- a/packages/backend-core/src/utils/tests/utils.spec.ts +++ b/packages/backend-core/src/utils/tests/utils.spec.ts @@ -44,11 +44,11 @@ describe("utils", () => { it("gets appId from url", async () => { await config.doInTenant(async () => { - const url = "http://test.com" + const url = "http://example.com" env._set("PLATFORM_URL", url) const ctx = structures.koa.newContext() - ctx.host = `${config.tenantId}.test.com` + ctx.host = `${config.tenantId}.example.com` const expected = db.generateAppID(config.tenantId) const app = structures.apps.app(expected) @@ -89,7 +89,7 @@ describe("utils", () => { const ctx = structures.koa.newContext() const expected = db.generateAppID() ctx.request.headers = { - referer: `http://test.com/builder/app/${expected}/design/screen_123/screens`, + referer: `http://example.com/builder/app/${expected}/design/screen_123/screens`, } const actual = await utils.getAppIdFromCtx(ctx) @@ -100,7 +100,7 @@ describe("utils", () => { const ctx = structures.koa.newContext() const appId = db.generateAppID() ctx.request.headers = { - referer: `http://test.com/foo/app/${appId}/bar`, + referer: `http://example.com/foo/app/${appId}/bar`, } const actual = await utils.getAppIdFromCtx(ctx) diff --git a/packages/backend-core/tests/core/utilities/structures/common.ts b/packages/backend-core/tests/core/utilities/structures/common.ts index 05b879f36b..9b1b178f0b 100644 --- a/packages/backend-core/tests/core/utilities/structures/common.ts +++ b/packages/backend-core/tests/core/utilities/structures/common.ts @@ -3,5 +3,5 @@ import { v4 as uuid } from "uuid" export { v4 as uuid } from "uuid" export const email = () => { - return `${uuid()}@test.com` + return `${uuid()}@example.com` } diff --git a/packages/backend-core/tests/core/utilities/structures/sso.ts b/packages/backend-core/tests/core/utilities/structures/sso.ts index 2e3af712a9..6492283e6a 100644 --- a/packages/backend-core/tests/core/utilities/structures/sso.ts +++ b/packages/backend-core/tests/core/utilities/structures/sso.ts @@ -61,7 +61,7 @@ export function ssoProfile(user?: User): SSOProfile { }, _json: { email: user.email, - picture: "http://test.com", + picture: "http://example.com", }, provider: generator.string(), } diff --git a/packages/backend-core/tests/core/utilities/structures/users.ts b/packages/backend-core/tests/core/utilities/structures/users.ts index 8f4096d401..db90887af2 100644 --- a/packages/backend-core/tests/core/utilities/structures/users.ts +++ b/packages/backend-core/tests/core/utilities/structures/users.ts @@ -25,7 +25,7 @@ export const user = (userProps?: Partial>): User => { roles: { app_test: "admin" }, firstName: generator.first(), lastName: generator.last(), - pictureUrl: "http://test.com", + pictureUrl: "http://example.com", tenantId: tenant.id(), ...userProps, } diff --git a/packages/bbui/src/Form/Core/EnvDropdown.svelte b/packages/bbui/src/Form/Core/EnvDropdown.svelte index 2edf8a5f9d..c690ffbc6b 100644 --- a/packages/bbui/src/Form/Core/EnvDropdown.svelte +++ b/packages/bbui/src/Form/Core/EnvDropdown.svelte @@ -184,7 +184,7 @@ {#if environmentVariablesEnabled}
showModal()} class="add-variable">
handleUpgradePanel()} class="add-variable">
zapier diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/AutomationBlockTagline.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/AutomationBlockTagline.svelte index c18368b1b1..8732623dcf 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/AutomationBlockTagline.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/AutomationBlockTagline.svelte @@ -1,7 +1,7 @@ diff --git a/packages/builder/src/components/automation/AutomationPanel/AutomationList.svelte b/packages/builder/src/components/automation/AutomationPanel/AutomationList.svelte index cce0f4eeab..9d946fe55d 100644 --- a/packages/builder/src/components/automation/AutomationPanel/AutomationList.svelte +++ b/packages/builder/src/components/automation/AutomationPanel/AutomationList.svelte @@ -4,7 +4,7 @@ automationStore, selectedAutomation, userSelectedResourceMap, - } from "builderStore" + } from "stores/builder" import NavItem from "components/common/NavItem.svelte" import EditAutomationPopover from "./EditAutomationPopover.svelte" import { notifications } from "@budibase/bbui" diff --git a/packages/builder/src/components/automation/AutomationPanel/AutomationPanel.svelte b/packages/builder/src/components/automation/AutomationPanel/AutomationPanel.svelte index d8651f238a..582db950fe 100644 --- a/packages/builder/src/components/automation/AutomationPanel/AutomationPanel.svelte +++ b/packages/builder/src/components/automation/AutomationPanel/AutomationPanel.svelte @@ -7,7 +7,7 @@ automationStore, selectedAutomation, userSelectedResourceMap, - } from "builderStore" + } from "stores/builder" import NavItem from "components/common/NavItem.svelte" import EditAutomationPopover from "./EditAutomationPopover.svelte" diff --git a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte index 9f279427d9..41bffba19e 100644 --- a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte +++ b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte @@ -1,5 +1,5 @@ diff --git a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte index 23697bf2c7..23081c92c4 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte @@ -3,13 +3,13 @@ import { Layout } from "@budibase/bbui" import { BUDIBASE_INTERNAL_DB_ID } from "constants/backend" import { - database, datasources, queries, tables, views, viewsV2, - } from "stores/backend" + userSelectedResourceMap, + } from "stores/builder" import EditDatasourcePopover from "./popovers/EditDatasourcePopover.svelte" import EditQueryPopover from "./popovers/EditQueryPopover.svelte" import NavItem from "components/common/NavItem.svelte" @@ -21,7 +21,6 @@ } from "helpers/data/utils" import IntegrationIcon from "./IntegrationIcon.svelte" import { TableNames } from "constants" - import { userSelectedResourceMap } from "builderStore" import { enrichDatasources } from "./datasourceUtils" import { onMount } from "svelte" @@ -75,69 +74,67 @@ searchTerm && !showAppUsersTable && !enrichedDataSources.find(ds => ds.show) -{#if $database?._id} -
- {#if showAppUsersTable} - selectTable(TableNames.USERS)} - selectedBy={$userSelectedResourceMap[TableNames.USERS]} - /> - {/if} - {#each enrichedDataSources.filter(ds => ds.show) as datasource} - selectDatasource(datasource)} - on:iconClick={() => toggleNode(datasource)} - selectedBy={$userSelectedResourceMap[datasource._id]} - > -
- -
- {#if datasource._id !== BUDIBASE_INTERNAL_DB_ID} - - {/if} -
- - {#if datasource.open} - - {#each datasource.queries as query} - $goto(`./query/${query._id}`)} - selectedBy={$userSelectedResourceMap[query._id]} - > - - - {/each} +
+ {#if showAppUsersTable} + selectTable(TableNames.USERS)} + selectedBy={$userSelectedResourceMap[TableNames.USERS]} + /> + {/if} + {#each enrichedDataSources.filter(ds => ds.show) as datasource} + selectDatasource(datasource)} + on:iconClick={() => toggleNode(datasource)} + selectedBy={$userSelectedResourceMap[datasource._id]} + > +
+ +
+ {#if datasource._id !== BUDIBASE_INTERNAL_DB_ID} + {/if} - {/each} - {#if showNoResults} - -
- There aren't any datasources matching that name -
-
+
+ + {#if datasource.open} + + {#each datasource.queries as query} + $goto(`./query/${query._id}`)} + selectedBy={$userSelectedResourceMap[query._id]} + > + + + {/each} {/if} -
-{/if} + {/each} + {#if showNoResults} + +
+ There aren't any datasources matching that name +
+
+ {/if} +
diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/DeleteRow.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/DeleteRow.svelte index 1e79c51051..b8459ac0eb 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/DeleteRow.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/DeleteRow.svelte @@ -1,6 +1,6 @@ diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte index 9f70272d78..a1fe773455 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte @@ -1,8 +1,12 @@ - + diff --git a/packages/builder/src/components/design/settings/controls/ColumnEditor/CellDrawer.svelte b/packages/builder/src/components/design/settings/controls/ColumnEditor/CellDrawer.svelte index 9e53f7f1cf..f5167e3657 100644 --- a/packages/builder/src/components/design/settings/controls/ColumnEditor/CellDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/ColumnEditor/CellDrawer.svelte @@ -7,7 +7,7 @@ Layout, Label, } from "@budibase/bbui" - import { store } from "builderStore" + import { themeStore } from "stores/builder" import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte" export let column @@ -46,7 +46,7 @@ (column.background = e.detail)} - spectrumTheme={$store.theme} + spectrumTheme={$themeStore.theme} /> @@ -54,7 +54,7 @@ (column.color = e.detail)} - spectrumTheme={$store.theme} + spectrumTheme={$themeStore.theme} /> diff --git a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte index cebb429ac4..2b9fa573c2 100644 --- a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte @@ -3,11 +3,8 @@ import { createEventDispatcher } from "svelte" import ColumnDrawer from "./ColumnDrawer.svelte" import { cloneDeep } from "lodash/fp" - import { - getDatasourceForProvider, - getSchemaForDatasource, - } from "builderStore/dataBinding" - import { currentAsset } from "builderStore" + import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding" + import { selectedScreen } from "stores/builder" import { getFields } from "helpers/searchFields" export let componentInstance @@ -21,8 +18,8 @@ let boundValue $: text = getText(value) - $: datasource = getDatasourceForProvider($currentAsset, componentInstance) - $: schema = getSchema($currentAsset, datasource) + $: datasource = getDatasourceForProvider($selectedScreen, componentInstance) + $: schema = getSchema($selectedScreen, datasource) $: options = allowCellEditing ? Object.keys(schema || {}) : enrichedSchemaFields?.map(field => field.name) diff --git a/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte b/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte index 9fd220e798..2e74cac0f4 100644 --- a/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte @@ -1,14 +1,14 @@ diff --git a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte index 3eb69e9a3b..0e01c264fc 100644 --- a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte @@ -2,7 +2,7 @@ import { readableToRuntimeBinding, runtimeToReadableBinding, - } from "builderStore/dataBinding" + } from "dataBinding" import { Button, Popover, @@ -17,19 +17,20 @@ notifications, } from "@budibase/bbui" import { createEventDispatcher } from "svelte" - import { store, currentAsset } from "builderStore" import { tables as tablesStore, queries as queriesStore, viewsV2 as viewsV2Store, views as viewsStore, + selectedScreen, + componentStore, datasources, integrations, - } from "stores/backend" + } from "stores/builder" import BindingBuilder from "components/integration/QueryBindingBuilder.svelte" import IntegrationQueryEditor from "components/integration/index.svelte" import { makePropSafe as safe } from "@budibase/string-templates" - import { findAllComponents } from "builderStore/componentUtils" + import { findAllComponents } from "helpers/components" import ClientBindingPanel from "components/common/bindings/ClientBindingPanel.svelte" import DataSourceCategory from "components/design/settings/controls/DataSourceSelect/DataSourceCategory.svelte" import { API } from "api" @@ -75,11 +76,11 @@ ...query, type: "query", })) - $: dataProviders = findAllComponents($currentAsset.props) + $: dataProviders = findAllComponents($selectedScreen.props) .filter(component => { return ( component._component?.endsWith("/dataprovider") && - component._id !== $store.selectedComponentId + component._id !== $componentStore.selectedComponentId ) }) .map(provider => ({ @@ -126,10 +127,14 @@ } }) $: jsonArrays = bindings - .filter(x => x.fieldSchema?.type === "jsonarray") + .filter( + x => + x.fieldSchema?.type === "jsonarray" || + (x.fieldSchema?.type === "json" && x.fieldSchema?.subtype === "array") + ) .map(binding => { const { providerId, readableBinding, runtimeBinding, tableId } = binding - const { name, type, prefixKeys } = binding.fieldSchema + const { name, type, prefixKeys, subtype } = binding.fieldSchema return { providerId, label: readableBinding, @@ -137,7 +142,8 @@ fieldType: type, tableId, prefixKeys, - type: "jsonarray", + type: type === "jsonarray" ? "jsonarray" : "queryarray", + subtype, value: `{{ literal ${runtimeBinding} }}`, } }) diff --git a/packages/builder/src/components/design/settings/controls/EditComponentPopover.svelte b/packages/builder/src/components/design/settings/controls/EditComponentPopover.svelte index 04bb925873..4e645fe343 100644 --- a/packages/builder/src/components/design/settings/controls/EditComponentPopover.svelte +++ b/packages/builder/src/components/design/settings/controls/EditComponentPopover.svelte @@ -1,9 +1,9 @@
diff --git a/packages/builder/src/components/design/settings/controls/FieldSelect.svelte b/packages/builder/src/components/design/settings/controls/FieldSelect.svelte index 7d1741df17..e50a0e8030 100644 --- a/packages/builder/src/components/design/settings/controls/FieldSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/FieldSelect.svelte @@ -1,10 +1,7 @@
@@ -42,7 +45,7 @@ on:change >
- + {item.field}
diff --git a/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte b/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte index 4286328367..439bf5e261 100644 --- a/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte +++ b/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte @@ -1,9 +1,6 @@ diff --git a/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/PrimaryColumnFieldSetting.svelte b/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/PrimaryColumnFieldSetting.svelte index 1cb29ac6e7..57423e8667 100644 --- a/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/PrimaryColumnFieldSetting.svelte +++ b/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/PrimaryColumnFieldSetting.svelte @@ -4,7 +4,7 @@ import { setContext } from "svelte" import { writable } from "svelte/store" import { FieldTypeToComponentMap } from "../FieldConfiguration/utils" - import { store } from "builderStore" + import { componentStore } from "stores/builder" export let item export let anchor @@ -35,7 +35,7 @@ const component = `@budibase/standard-components/${ FieldTypeToComponentMap[item.columnType] }` - return store.actions.components.getDefinition(component)?.icon + return componentStore.getDefinition(component)?.icon } $: icon = getIcon(item) diff --git a/packages/builder/src/components/design/settings/controls/LayoutSelect.svelte b/packages/builder/src/components/design/settings/controls/LayoutSelect.svelte index eed01c0d94..a7966eb671 100644 --- a/packages/builder/src/components/design/settings/controls/LayoutSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/LayoutSelect.svelte @@ -1,5 +1,5 @@ diff --git a/packages/builder/src/components/design/settings/controls/RelationshipFilterEditor.svelte b/packages/builder/src/components/design/settings/controls/RelationshipFilterEditor.svelte index 0eb93732c3..43f158bef3 100644 --- a/packages/builder/src/components/design/settings/controls/RelationshipFilterEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/RelationshipFilterEditor.svelte @@ -1,14 +1,10 @@ diff --git a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte index 25c7651d35..3a98de94cd 100644 --- a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte @@ -10,12 +10,9 @@ Input, DatePicker, } from "@budibase/bbui" - import { currentAsset, selectedComponent } from "builderStore" - import { findClosestMatchingComponent } from "builderStore/componentUtils" - import { - getSchemaForDatasource, - getDatasourceForProvider, - } from "builderStore/dataBinding" + import { selectedScreen, selectedComponent } from "stores/builder" + import { findClosestMatchingComponent } from "helpers/components" + import { getSchemaForDatasource, getDatasourceForProvider } from "dataBinding" import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte" import { generate } from "shortid" @@ -127,13 +124,14 @@ ], } - const resolveDatasource = (currentAsset, componentInstance, parent) => { + const resolveDatasource = (selectedScreen, componentInstance, parent) => { return ( - getDatasourceForProvider(currentAsset, parent || componentInstance) || {} + getDatasourceForProvider(selectedScreen, parent || componentInstance) || + {} ) } - $: dataSourceSchema = getDataSourceSchema($currentAsset, $selectedComponent) + $: dataSourceSchema = getDataSourceSchema($selectedScreen, $selectedComponent) $: field = fieldName || $selectedComponent?.field $: schemaRules = parseRulesFromSchema(field, dataSourceSchema || {}) $: fieldType = type?.split("/")[1] || "string" diff --git a/packages/builder/src/components/integration/AccessLevelSelect.svelte b/packages/builder/src/components/integration/AccessLevelSelect.svelte index 3dc24983d3..05b336c3b3 100644 --- a/packages/builder/src/components/integration/AccessLevelSelect.svelte +++ b/packages/builder/src/components/integration/AccessLevelSelect.svelte @@ -1,6 +1,6 @@ @@ -112,7 +122,9 @@ bind:value={field.name} on:blur={changed} /> - {#if options} + {#if isJsonArray(field.value)} + import { goto } from "@roxi/routify" - import { datasources, integrations, queries } from "stores/backend" + import { datasources, integrations, queries } from "stores/builder" import { Icon, Select, @@ -40,7 +40,9 @@ let schemaType let autoSchema = {} + let nestedSchemaFields = {} let rows = [] + let keys = {} const parseQuery = query => { modified = false @@ -82,18 +84,25 @@ return } + nestedSchemaFields = response.nestedSchemaFields + if (Object.keys(newQuery.schema).length === 0) { // Assign this to a variable instead of directly to the newQuery.schema so that a user // can change the table they're querying and have the schema update until they first // edit it autoSchema = response.schema } - rows = response.rows notifications.success("Query executed successfully") } catch (error) { - notifications.error(`Query Error: ${error.message}`) + if (typeof error.message === "string") { + notifications.error(`Query Error: ${error.message}`) + } else if (typeof error.message?.code === "string") { + notifications.error(`Query Error: ${error.message.code}`) + } else { + notifications.error(`Query Error: ${JSON.stringify(error.message)}`) + } if (!suppressErrors) { throw error @@ -113,6 +122,7 @@ Object.keys(newQuery.schema).length === 0 ? autoSchema : newQuery.schema, + nestedSchemaFields, }) notifications.success("Query saved successfully") @@ -137,8 +147,20 @@ const handleScroll = e => { scrolling = e.target.scrollTop !== 0 } + + async function handleKeyDown(evt) { + keys[evt.key] = true + if ((keys["Meta"] || keys["Control"]) && keys["Enter"]) { + await runQuery({ suppressErrors: false }) + } + } + + function handleKeyUp(evt) { + delete keys[evt.key] + } + checkIsModified(newQuery)} attemptSave={() => runQuery({ suppressErrors: false }).then(saveQuery)} diff --git a/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte b/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte index f8a14a6dd1..7e79209d8b 100644 --- a/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte +++ b/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte @@ -1,10 +1,8 @@