Merge remote-tracking branch 'origin/develop' into feature/delete-multiple-button-action
This commit is contained in:
commit
211bab4cf6
4 changed files with 26 additions and 10 deletions
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "2.8.22-alpha.4",
|
"version": "2.8.22-alpha.5",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
Tab,
|
Tab,
|
||||||
Modal,
|
Modal,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
|
notifications,
|
||||||
|
Divider,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { notifications, Divider } from "@budibase/bbui"
|
|
||||||
import ExtraQueryConfig from "./ExtraQueryConfig.svelte"
|
import ExtraQueryConfig from "./ExtraQueryConfig.svelte"
|
||||||
import IntegrationQueryEditor from "components/integration/index.svelte"
|
import IntegrationQueryEditor from "components/integration/index.svelte"
|
||||||
import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte"
|
import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte"
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
import KeyValueBuilder from "./KeyValueBuilder.svelte"
|
import KeyValueBuilder from "./KeyValueBuilder.svelte"
|
||||||
import { fieldsToSchema, schemaToFields } from "helpers/data/utils"
|
import { fieldsToSchema, schemaToFields } from "helpers/data/utils"
|
||||||
import AccessLevelSelect from "./AccessLevelSelect.svelte"
|
import AccessLevelSelect from "./AccessLevelSelect.svelte"
|
||||||
|
import { ValidQueryNameRegex } from "@budibase/shared-core"
|
||||||
|
|
||||||
export let query
|
export let query
|
||||||
|
|
||||||
|
@ -47,6 +49,7 @@
|
||||||
let saveModal
|
let saveModal
|
||||||
let override = false
|
let override = false
|
||||||
let navigateTo = null
|
let navigateTo = null
|
||||||
|
let nameError = null
|
||||||
|
|
||||||
// seed the transformer
|
// seed the transformer
|
||||||
if (query && !query.transformer) {
|
if (query && !query.transformer) {
|
||||||
|
@ -77,7 +80,7 @@
|
||||||
$: queryConfig = integrationInfo?.query
|
$: queryConfig = integrationInfo?.query
|
||||||
$: shouldShowQueryConfig = queryConfig && query.queryVerb
|
$: shouldShowQueryConfig = queryConfig && query.queryVerb
|
||||||
$: readQuery = query.queryVerb === "read" || query.readable
|
$: readQuery = query.queryVerb === "read" || query.readable
|
||||||
$: queryInvalid = !query.name || (readQuery && data.length === 0)
|
$: queryInvalid = !query.name || nameError || (readQuery && data.length === 0)
|
||||||
|
|
||||||
//Cast field in query preview response to number if specified by schema
|
//Cast field in query preview response to number if specified by schema
|
||||||
$: {
|
$: {
|
||||||
|
@ -139,9 +142,10 @@
|
||||||
queryStr = JSON.stringify(query)
|
queryStr = JSON.stringify(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notifications.success("Query saved successfully")
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error("Error saving query")
|
notifications.error(error.message || "Error saving query")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -183,8 +187,14 @@
|
||||||
value={query.name}
|
value={query.name}
|
||||||
on:input={e => {
|
on:input={e => {
|
||||||
let newValue = e.target.value || ""
|
let newValue = e.target.value || ""
|
||||||
query.name = newValue.trim()
|
if (newValue.match(ValidQueryNameRegex)) {
|
||||||
|
query.name = newValue.trim()
|
||||||
|
nameError = null
|
||||||
|
} else {
|
||||||
|
nameError = "Invalid query name"
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
|
error={nameError}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{#if queryConfig}
|
{#if queryConfig}
|
||||||
|
@ -250,9 +260,9 @@
|
||||||
size="L"
|
size="L"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Body size="S"
|
<Body size="S">
|
||||||
>Add a JavaScript function to transform the query result.</Body
|
Add a JavaScript function to transform the query result.
|
||||||
>
|
</Body>
|
||||||
<CodeMirrorEditor
|
<CodeMirrorEditor
|
||||||
height={200}
|
height={200}
|
||||||
label="Transformer"
|
label="Transformer"
|
||||||
|
@ -264,13 +274,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="viewer-controls">
|
<div class="viewer-controls">
|
||||||
<Heading size="S">Results</Heading>
|
<Heading size="S">Results</Heading>
|
||||||
<ButtonGroup gap="XS">
|
<ButtonGroup gap="S">
|
||||||
<Button
|
<Button
|
||||||
cta
|
cta
|
||||||
disabled={queryInvalid}
|
disabled={queryInvalid}
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
await saveQuery()
|
await saveQuery()
|
||||||
notifications.success(`Query saved successfully`)
|
|
||||||
// Go to the correct URL if we just created a new query
|
// Go to the correct URL if we just created a new query
|
||||||
if (!query._rev) {
|
if (!query._rev) {
|
||||||
$goto(`../../${query._id}`)
|
$goto(`../../${query._id}`)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { events, context, utils, constants } from "@budibase/backend-core"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import { QueryEvent } from "../../../threads/definitions"
|
import { QueryEvent } from "../../../threads/definitions"
|
||||||
import { Query } from "@budibase/types"
|
import { Query } from "@budibase/types"
|
||||||
|
import { ValidQueryNameRegex } from "@budibase/shared-core"
|
||||||
|
|
||||||
const Runner = new Thread(ThreadType.QUERY, {
|
const Runner = new Thread(ThreadType.QUERY, {
|
||||||
timeoutMs: env.QUERY_THREAD_TIMEOUT || 10000,
|
timeoutMs: env.QUERY_THREAD_TIMEOUT || 10000,
|
||||||
|
@ -76,6 +77,11 @@ export async function save(ctx: any) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const query = ctx.request.body
|
const query = ctx.request.body
|
||||||
|
|
||||||
|
// Validate query name
|
||||||
|
if (!query?.name.match(ValidQueryNameRegex)) {
|
||||||
|
ctx.throw(400, "Invalid query name")
|
||||||
|
}
|
||||||
|
|
||||||
const datasource = await sdk.datasources.get(query.datasourceId)
|
const datasource = await sdk.datasources.get(query.datasourceId)
|
||||||
|
|
||||||
let eventFn
|
let eventFn
|
||||||
|
|
|
@ -94,4 +94,5 @@ export enum BuilderSocketEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SocketSessionTTL = 60
|
export const SocketSessionTTL = 60
|
||||||
|
export const ValidQueryNameRegex = /^[^()]*$/
|
||||||
export const ValidColumnNameRegex = /^[_a-zA-Z0-9\s]*$/g
|
export const ValidColumnNameRegex = /^[_a-zA-Z0-9\s]*$/g
|
||||||
|
|
Loading…
Reference in a new issue