Merge branch 'feature/query-variables' of github.com:Budibase/budibase into rest-pagination

This commit is contained in:
Andrew Kingston 2022-01-05 09:21:25 +00:00
commit abc02d812a
29 changed files with 310 additions and 158 deletions

View File

@ -1,5 +1,5 @@
{ {
"version": "1.0.27-alpha.1", "version": "1.0.27-alpha.2",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/*" "packages/*"

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/auth", "name": "@budibase/auth",
"version": "1.0.27-alpha.1", "version": "1.0.27-alpha.2",
"description": "Authentication middlewares for budibase builder and apps", "description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js", "main": "src/index.js",
"author": "Budibase", "author": "Budibase",

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/bbui", "name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.", "description": "A UI solution used in the different Budibase projects.",
"version": "1.0.27-alpha.1", "version": "1.0.27-alpha.2",
"license": "MPL-2.0", "license": "MPL-2.0",
"svelte": "src/index.js", "svelte": "src/index.js",
"module": "dist/bbui.es.js", "module": "dist/bbui.es.js",

View File

@ -0,0 +1,11 @@
<script>
export let value
</script>
<div class="bold">{value}</div>
<style>
.bold {
font-weight: bold;
}
</style>

View File

@ -0,0 +1,5 @@
<script>
export let value
</script>
<code>{value}</code>

View File

@ -61,6 +61,10 @@ export { default as ColorPicker } from "./ColorPicker/ColorPicker.svelte"
export { default as InlineAlert } from "./InlineAlert/InlineAlert.svelte" export { default as InlineAlert } from "./InlineAlert/InlineAlert.svelte"
export { default as Banner } from "./Banner/Banner.svelte" export { default as Banner } from "./Banner/Banner.svelte"
// Renderers
export { default as BoldRenderer } from "./Table/BoldRenderer.svelte"
export { default as CodeRenderer } from "./Table/CodeRenderer.svelte"
// Typography // Typography
export { default as Body } from "./Typography/Body.svelte" export { default as Body } from "./Typography/Body.svelte"
export { default as Heading } from "./Typography/Heading.svelte" export { default as Heading } from "./Typography/Heading.svelte"

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/builder", "name": "@budibase/builder",
"version": "1.0.27-alpha.1", "version": "1.0.27-alpha.2",
"license": "GPL-3.0", "license": "GPL-3.0",
"private": true, "private": true,
"scripts": { "scripts": {
@ -65,10 +65,10 @@
} }
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^1.0.27-alpha.1", "@budibase/bbui": "^1.0.27-alpha.2",
"@budibase/client": "^1.0.27-alpha.1", "@budibase/client": "^1.0.27-alpha.2",
"@budibase/colorpicker": "1.1.2", "@budibase/colorpicker": "1.1.2",
"@budibase/string-templates": "^1.0.27-alpha.1", "@budibase/string-templates": "^1.0.27-alpha.2",
"@sentry/browser": "5.19.1", "@sentry/browser": "5.19.1",
"@spectrum-css/page": "^3.0.1", "@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1", "@spectrum-css/vars": "^3.0.1",

View File

@ -6,7 +6,7 @@
import ErrorsBox from "components/common/ErrorsBox.svelte" import ErrorsBox from "components/common/ErrorsBox.svelte"
import { roles } from "stores/backend" import { roles } from "stores/backend"
const BASE_ROLE = { _id: "", inherits: "BASIC", permissionId: "Read/Write" } const BASE_ROLE = { _id: "", inherits: "BASIC", permissionId: "write" }
let basePermissions = [] let basePermissions = []
let selectedRole = BASE_ROLE let selectedRole = BASE_ROLE

View File

@ -175,7 +175,8 @@
onConfirm={datasources.removeSchemaError} onConfirm={datasources.removeSchemaError}
/> />
{/if} {/if}
<Table {#if plusTables && Object.values(plusTables).length > 0}
<Table
on:click={({ detail }) => onClickTable(detail)} on:click={({ detail }) => onClickTable(detail)}
schema={tableSchema} schema={tableSchema}
data={Object.values(plusTables)} data={Object.values(plusTables)}
@ -183,7 +184,10 @@
allowEditRows={false} allowEditRows={false}
allowSelectRows={false} allowSelectRows={false}
customRenderers={[{ column: "primary", component: ArrayRenderer }]} customRenderers={[{ column: "primary", component: ArrayRenderer }]}
/> />
{:else}
<Body size="S"><i>No tables found.</i></Body>
{/if}
{#if plusTables?.length !== 0} {#if plusTables?.length !== 0}
<Divider size="S" /> <Divider size="S" />
<div class="query-header"> <div class="query-header">
@ -196,14 +200,18 @@
Tell budibase how your tables are related to get even more smart features. Tell budibase how your tables are related to get even more smart features.
</Body> </Body>
{/if} {/if}
<Table {#if relationshipInfo && relationshipInfo.length > 0}
<Table
on:click={({ detail }) => openRelationshipModal(detail.from, detail.to)} on:click={({ detail }) => openRelationshipModal(detail.from, detail.to)}
schema={relationshipSchema} schema={relationshipSchema}
data={relationshipInfo} data={relationshipInfo}
allowEditColumns={false} allowEditColumns={false}
allowEditRows={false} allowEditRows={false}
allowSelectRows={false} allowSelectRows={false}
/> />
{:else}
<Body size="S"><i>No relationships configured.</i></Body>
{/if}
<style> <style>
.query-header { .query-header {

View File

@ -1,5 +1,5 @@
<script> <script>
import { Body, Table } from "@budibase/bbui" import { Body, Table, BoldRenderer, CodeRenderer } from "@budibase/bbui"
import { queries as queriesStore } from "stores/backend" import { queries as queriesStore } from "stores/backend"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
@ -12,8 +12,8 @@
const dynamicVariableSchema = { const dynamicVariableSchema = {
name: "", name: "",
value: "",
query: "", query: "",
value: "",
} }
const onClick = dynamicVariable => { const onClick = dynamicVariable => {
@ -36,12 +36,19 @@
} }
</script> </script>
<Table {#if dynamicVariables && dynamicVariables.length > 0}
<Table
on:click={({ detail }) => onClick(detail)} on:click={({ detail }) => onClick(detail)}
schema={dynamicVariableSchema} schema={dynamicVariableSchema}
data={dynamicVariables} data={dynamicVariables}
allowEditColumns={false} allowEditColumns={false}
allowEditRows={false} allowEditRows={false}
allowSelectRows={false} allowSelectRows={false}
/> customRenderers={[
<Body size="S" /> { column: "name", component: BoldRenderer },
{ column: "value", component: CodeRenderer },
]}
/>
{:else}
<Body size="S"><i>No dynamic variables specified.</i></Body>
{/if}

View File

@ -120,62 +120,6 @@ export function flipHeaderState(headersActivity) {
return enabled return enabled
} }
// convert dynamic variables list to simple key/val object
export function getDynamicVariables(datasource, queryId) {
const variablesList = datasource?.config?.dynamicVariables
if (variablesList && variablesList.length > 0) {
const filtered = queryId
? variablesList.filter(variable => variable.queryId === queryId)
: variablesList
return filtered.reduce(
(acc, next) => ({ ...acc, [next.name]: next.value }),
{}
)
}
return {}
}
// convert dynamic variables object back to a list, enrich with query id
export function rebuildVariables(datasource, queryId, variables) {
let newVariables = []
if (variables) {
newVariables = Object.entries(variables).map(entry => {
return {
name: entry[0],
value: entry[1],
queryId,
}
})
}
let existing = datasource?.config?.dynamicVariables || []
// filter out any by same name
existing = existing.filter(
variable =>
!newVariables.find(
newVar => newVar.name.toLowerCase() === variable.name.toLowerCase()
)
)
return [...existing, ...newVariables]
}
export function shouldShowVariables(dynamicVariables, variablesReadOnly) {
return !!(
dynamicVariables &&
// show when editable or when read only and not empty
(!variablesReadOnly || Object.keys(dynamicVariables).length > 0)
)
}
export function buildAuthConfigs(datasource) {
if (datasource?.config?.authConfigs) {
return datasource.config.authConfigs.map(c => ({
label: c.name,
value: c._id,
}))
}
return []
}
export default { export default {
breakQueryString, breakQueryString,
buildQueryString, buildQueryString,
@ -184,8 +128,4 @@ export default {
keyValueToQueryParameters, keyValueToQueryParameters,
queryParametersToKeyValue, queryParametersToKeyValue,
schemaToFields, schemaToFields,
getDynamicVariables,
rebuildVariables,
shouldShowVariables,
buildAuthConfigs,
} }

View File

@ -16,17 +16,33 @@
export let query export let query
export let bodyType export let bodyType
let text = ""
let json = ""
$: checkRequestBody(bodyType) $: checkRequestBody(bodyType)
$: updateRequestBody(bodyType, text, json)
function checkRequestBody(type) { function checkRequestBody(type) {
if (!bodyType || !query) { if (!bodyType || !query) {
return return
} }
const currentType = typeof query?.fields.requestBody const currentType = typeof query?.fields.requestBody
if (objectTypes.includes(type) && currentType !== "object") { const isObject = objectTypes.includes(type)
query.fields.requestBody = {} const isText = textTypes.includes(type)
} else if (textTypes.includes(type) && currentType !== "string") { if (isText && currentType === "string") {
query.fields.requestBody = "" text = query.fields.requestBody
} else if (isObject && currentType === "object") {
json = query.fields.requestBody
}
}
function updateRequestBody(type, text, json) {
if (type === RawRestBodyTypes.NONE) {
query.fields.requestBody = null
} else if (objectTypes.includes(type)) {
query.fields.requestBody = json
} else {
query.fields.requestBody = text
} }
} }
@ -49,16 +65,12 @@
<Body size="S" weight="800">THE REQUEST DOES NOT HAVE A BODY</Body> <Body size="S" weight="800">THE REQUEST DOES NOT HAVE A BODY</Body>
</div> </div>
{:else if objectTypes.includes(bodyType)} {:else if objectTypes.includes(bodyType)}
<KeyValueBuilder <KeyValueBuilder bind:object={json} name="param" headings />
bind:object={query.fields.requestBody}
name="param"
headings
/>
{:else if textTypes.includes(bodyType)} {:else if textTypes.includes(bodyType)}
<CodeMirrorEditor <CodeMirrorEditor
height={200} height={200}
mode={editorMode(bodyType)} mode={editorMode(bodyType)}
value={query.fields.requestBody} value={text}
resize="vertical" resize="vertical"
on:change={e => (query.fields.requestBody = e.detail)} on:change={e => (query.fields.requestBody = e.detail)}
/> />

View File

@ -38,6 +38,7 @@
import DynamicVariableModal from "../../_components/DynamicVariableModal.svelte" import DynamicVariableModal from "../../_components/DynamicVariableModal.svelte"
import Placeholder from "assets/bb-spaceship.svg" import Placeholder from "assets/bb-spaceship.svg"
import { cloneDeep } from "lodash/fp" import { cloneDeep } from "lodash/fp"
import { RawRestBodyTypes } from "constants/backend"
let query, datasource let query, datasource
let breakQs = {}, let breakQs = {},
@ -54,13 +55,10 @@
$: checkQueryName(url) $: checkQueryName(url)
$: responseSuccess = response?.info?.code >= 200 && response?.info?.code < 400 $: responseSuccess = response?.info?.code >= 200 && response?.info?.code < 400
$: isGet = query?.queryVerb === "read" $: isGet = query?.queryVerb === "read"
$: authConfigs = restUtils.buildAuthConfigs(datasource) $: authConfigs = buildAuthConfigs(datasource)
$: schemaReadOnly = !responseSuccess $: schemaReadOnly = !responseSuccess
$: variablesReadOnly = !responseSuccess $: variablesReadOnly = !responseSuccess
$: showVariablesTab = restUtils.shouldShowVariables( $: showVariablesTab = shouldShowVariables(dynamicVariables, variablesReadOnly)
dynamicVariables,
variablesReadOnly
)
function getSelectedQuery() { function getSelectedQuery() {
return cloneDeep( return cloneDeep(
@ -117,11 +115,7 @@
notifications.success(`Request saved successfully.`) notifications.success(`Request saved successfully.`)
if (dynamicVariables) { if (dynamicVariables) {
datasource.config.dynamicVariables = restUtils.rebuildVariables( datasource.config.dynamicVariables = rebuildVariables(saveId)
datasource,
saveId,
dynamicVariables
)
datasource = await datasources.save(datasource) datasource = await datasources.save(datasource)
} }
} catch (err) { } catch (err) {
@ -160,6 +154,16 @@
return id return id
} }
const buildAuthConfigs = datasource => {
if (datasource?.config?.authConfigs) {
return datasource.config.authConfigs.map(c => ({
label: c.name,
value: c._id,
}))
}
return []
}
const schemaMenuItems = [ const schemaMenuItems = [
{ {
text: "Create dynamic variable", text: "Create dynamic variable",
@ -179,6 +183,49 @@
}, },
] ]
// convert dynamic variables list to simple key/val object
const getDynamicVariables = (datasource, queryId) => {
const variablesList = datasource?.config?.dynamicVariables
if (variablesList && variablesList.length > 0) {
const filtered = queryId
? variablesList.filter(variable => variable.queryId === queryId)
: variablesList
return filtered.reduce(
(acc, next) => ({ ...acc, [next.name]: next.value }),
{}
)
}
return {}
}
// convert dynamic variables object back to a list, enrich with query id
const rebuildVariables = queryId => {
let variables = []
if (dynamicVariables) {
variables = Object.entries(dynamicVariables).map(entry => {
return {
name: entry[0],
value: entry[1],
queryId,
}
})
}
let existing = datasource?.config?.dynamicVariables || []
// remove existing query variables (for changes and deletions)
existing = existing.filter(variable => variable.queryId !== queryId)
// re-add the new query variables
return [...existing, ...variables]
}
const shouldShowVariables = (dynamicVariables, variablesReadOnly) => {
return !!(
dynamicVariables &&
// show when editable or when read only and not empty
(!variablesReadOnly || Object.keys(dynamicVariables).length > 0)
)
}
onMount(async () => { onMount(async () => {
query = getSelectedQuery() query = getSelectedQuery()
// clear any unsaved changes to the datasource // clear any unsaved changes to the datasource
@ -214,12 +261,16 @@
} }
} }
if (query && !query.fields.bodyType) { if (query && !query.fields.bodyType) {
query.fields.bodyType = "none" if (query.fields.requestBody) {
query.fields.bodyType = RawRestBodyTypes.JSON
} else {
query.fields.bodyType = RawRestBodyTypes.NONE
}
} }
if (query && !query.fields.pagination) { if (query && !query.fields.pagination) {
query.fields.pagination = {} query.fields.pagination = {}
} }
dynamicVariables = restUtils.getDynamicVariables(datasource, query._id) dynamicVariables = getDynamicVariables(datasource, query._id)
}) })
</script> </script>

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/cli", "name": "@budibase/cli",
"version": "1.0.27-alpha.1", "version": "1.0.27-alpha.2",
"description": "Budibase CLI, for developers, self hosting and migrations.", "description": "Budibase CLI, for developers, self hosting and migrations.",
"main": "src/index.js", "main": "src/index.js",
"bin": { "bin": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/client", "name": "@budibase/client",
"version": "1.0.27-alpha.1", "version": "1.0.27-alpha.2",
"license": "MPL-2.0", "license": "MPL-2.0",
"module": "dist/budibase-client.js", "module": "dist/budibase-client.js",
"main": "dist/budibase-client.js", "main": "dist/budibase-client.js",
@ -19,9 +19,9 @@
"dev:builder": "rollup -cw" "dev:builder": "rollup -cw"
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^1.0.27-alpha.1", "@budibase/bbui": "^1.0.27-alpha.2",
"@budibase/standard-components": "^0.9.139", "@budibase/standard-components": "^0.9.139",
"@budibase/string-templates": "^1.0.27-alpha.1", "@budibase/string-templates": "^1.0.27-alpha.2",
"regexparam": "^1.3.0", "regexparam": "^1.3.0",
"shortid": "^2.2.15", "shortid": "^2.2.15",
"svelte-spa-router": "^3.0.5" "svelte-spa-router": "^3.0.5"

View File

@ -57,6 +57,12 @@ module FetchMock {
], ],
bookmark: "test", bookmark: "test",
}) })
} else if (url.includes("google.com")) {
return json({
url,
opts,
value: "<!doctype html><html itemscope=\"\" itemtype=\"http://schema.org/WebPage\" lang=\"en-GB\"></html>",
})
} }
return fetch(url, opts) return fetch(url, opts)
} }

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/server", "name": "@budibase/server",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "1.0.27-alpha.1", "version": "1.0.27-alpha.2",
"description": "Budibase Web Server", "description": "Budibase Web Server",
"main": "src/index.ts", "main": "src/index.ts",
"repository": { "repository": {
@ -70,9 +70,9 @@
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"@apidevtools/swagger-parser": "^10.0.3", "@apidevtools/swagger-parser": "^10.0.3",
"@budibase/auth": "^1.0.27-alpha.1", "@budibase/auth": "^1.0.27-alpha.2",
"@budibase/client": "^1.0.27-alpha.1", "@budibase/client": "^1.0.27-alpha.2",
"@budibase/string-templates": "^1.0.27-alpha.1", "@budibase/string-templates": "^1.0.27-alpha.2",
"@bull-board/api": "^3.7.0", "@bull-board/api": "^3.7.0",
"@bull-board/koa": "^3.7.0", "@bull-board/koa": "^3.7.0",
"@elastic/elasticsearch": "7.10.0", "@elastic/elasticsearch": "7.10.0",

View File

@ -17,8 +17,12 @@ const parseBody = (curl: any) => {
if (curl.data) { if (curl.data) {
const keys = Object.keys(curl.data) const keys = Object.keys(curl.data)
if (keys.length) { if (keys.length) {
const key = keys[0] let key = keys[0]
try { try {
// filter out the dollar syntax used by curl for shell support
if (key.startsWith("$")) {
key = key.substring(1)
}
return JSON.parse(key) return JSON.parse(key)
} catch (e) { } catch (e) {
// do nothing // do nothing

View File

@ -144,8 +144,8 @@ async function execute(ctx, opts = { rowsOnly: false }) {
datasource, datasource,
queryVerb: query.queryVerb, queryVerb: query.queryVerb,
fields: query.fields, fields: query.fields,
parameters: ctx.request.body.parameter,
pagination: ctx.request.body.pagination, pagination: ctx.request.body.pagination,
parameters: ctx.request.body.parameters,
transformer: query.transformer, transformer: query.transformer,
queryId: ctx.params.queryId, queryId: ctx.params.queryId,
}) })

View File

@ -191,7 +191,8 @@ class QueryBuilder {
} }
if (this.query.equal) { if (this.query.equal) {
build(this.query.equal, (key, value) => { build(this.query.equal, (key, value) => {
if (!value) { // 0 evaluates to false, which means we would return all rows if we don't check it
if (!value && value !== 0) {
return null return null
} }
return `${key}:${builder.preprocess(value, allPreProcessingOpts)}` return `${key}:${builder.preprocess(value, allPreProcessingOpts)}`

View File

@ -1,5 +1,6 @@
// Mock out postgres for this // Mock out postgres for this
jest.mock("pg") jest.mock("pg")
jest.mock("node-fetch")
// Mock isProdAppID to we can later mock the implementation and pretend we are // Mock isProdAppID to we can later mock the implementation and pretend we are
// using prod app IDs // using prod app IDs
@ -226,4 +227,76 @@ describe("/queries", () => {
.expect(400) .expect(400)
}) })
}) })
describe("test variables", () => {
async function restDatasource(cfg) {
return await config.createDatasource({
datasource: {
...basicDatasource().datasource,
source: "REST",
config: cfg || {},
},
})
}
it("should work with static variables", async () => {
const datasource = await restDatasource({
staticVariables: {
variable: "google",
variable2: "1",
},
})
const res = await request
.post(`/api/queries/preview`)
.send({
datasourceId: datasource._id,
parameters: {},
fields: {
path: "www.{{ variable }}.com",
queryString: "test={{ variable2 }}",
},
queryVerb: "read",
})
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
// these responses come from the mock
expect(res.body.schemaFields).toEqual(["url", "opts", "value"])
expect(res.body.rows[0].url).toEqual("http://www.google.com?test=1")
})
it("should work with dynamic variables", async () => {
const datasource = await restDatasource()
const basedOnQuery = await config.createQuery({
...basicQuery(datasource._id),
fields: {
path: "www.google.com",
},
})
await config.updateDatasource({
...datasource,
config: {
dynamicVariables: [
{ queryId: basedOnQuery._id, name: "variable3", value: "{{ data.0.[value] }}" }
]
}
})
const res = await request
.post(`/api/queries/preview`)
.send({
datasourceId: datasource._id,
parameters: {},
fields: {
path: "www.google.com",
queryString: "test={{ variable3 }}",
},
queryVerb: "read",
})
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.schemaFields).toEqual(["url", "opts", "value"])
expect(res.body.rows[0].url).toContain("doctype html")
})
})
}) })

View File

@ -242,6 +242,16 @@ export interface RestConfig {
[key: string]: any [key: string]: any
} }
authConfigs: AuthConfig[] authConfigs: AuthConfig[]
staticVariables: {
[key: string]: string
}
dynamicVariables: [
{
name: string
queryId: string
value: string
}
]
} }
export interface PaginationConfig { export interface PaginationConfig {

View File

@ -53,7 +53,10 @@ module RestModule {
const { performance } = require("perf_hooks") const { performance } = require("perf_hooks")
const FormData = require("form-data") const FormData = require("form-data")
const { URLSearchParams } = require("url") const { URLSearchParams } = require("url")
const { parseStringPromise: xmlParser, Builder: XmlBuilder } = require("xml2js") const {
parseStringPromise: xmlParser,
Builder: XmlBuilder,
} = require("xml2js")
const SCHEMA: Integration = { const SCHEMA: Integration = {
docs: "https://github.com/node-fetch/node-fetch", docs: "https://github.com/node-fetch/node-fetch",
@ -238,7 +241,7 @@ module RestModule {
break break
case BodyTypes.XML: case BodyTypes.XML:
if (object != null) { if (object != null) {
string = (new XmlBuilder()).buildObject(object) string = new XmlBuilder().buildObject(object)
} }
input.body = string input.body = string
input.headers["Content-Type"] = "application/xml" input.headers["Content-Type"] = "application/xml"

View File

@ -316,6 +316,16 @@ class TestConfiguration {
return this.datasource return this.datasource
} }
async updateDatasource(datasource) {
const response = await this._req(
datasource,
{ datasourceId: datasource._id },
controllers.datasource.update
)
this.datasource = response.datasource
return this.datasource
}
async createQuery(config = null) { async createQuery(config = null) {
if (!this.datasource && !config) { if (!this.datasource && !config) {
throw "No data source created for query." throw "No data source created for query."

View File

@ -5,6 +5,9 @@ const { integrations } = require("../integrations")
const { processStringSync } = require("@budibase/string-templates") const { processStringSync } = require("@budibase/string-templates")
const CouchDB = require("../db") const CouchDB = require("../db")
const IS_TRIPLE_BRACE = new RegExp(/^{{3}.*}{3}$/)
const IS_HANDLEBARS = new RegExp(/^{{2}.*}{2}$/)
class QueryRunner { class QueryRunner {
constructor(input, flags = { noRecursiveQuery: false }) { constructor(input, flags = { noRecursiveQuery: false }) {
this.appId = input.appId this.appId = input.appId
@ -171,7 +174,12 @@ class QueryRunner {
enrichedQuery[key] = this.enrichQueryFields(fields[key], parameters) enrichedQuery[key] = this.enrichQueryFields(fields[key], parameters)
} else if (typeof fields[key] === "string") { } else if (typeof fields[key] === "string") {
// enrich string value as normal // enrich string value as normal
enrichedQuery[key] = processStringSync(fields[key], parameters, { let value = fields[key]
// add triple brace to avoid escaping e.g. '=' in cookie header
if (IS_HANDLEBARS.test(value) && !IS_TRIPLE_BRACE.test(value)) {
value = `{${value}}`
}
enrichedQuery[key] = processStringSync(value, parameters, {
noHelpers: true, noHelpers: true,
}) })
} else { } else {

View File

@ -3,7 +3,6 @@ const CouchDB = require("../db")
const { init } = require("@budibase/auth") const { init } = require("@budibase/auth")
const redis = require("@budibase/auth/redis") const redis = require("@budibase/auth/redis")
const { SEPARATOR } = require("@budibase/auth/db") const { SEPARATOR } = require("@budibase/auth/db")
const { processStringSync } = require("@budibase/string-templates")
const VARIABLE_TTL_SECONDS = 3600 const VARIABLE_TTL_SECONDS = 3600
let client let client

View File

@ -983,10 +983,10 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@budibase/auth@^1.0.27-alpha.1": "@budibase/auth@^1.0.27-alpha.2":
version "1.0.33" version "1.0.34"
resolved "https://registry.yarnpkg.com/@budibase/auth/-/auth-1.0.33.tgz#bb0c527ebca852c001c7e163a9cdfce49984adab" resolved "https://registry.yarnpkg.com/@budibase/auth/-/auth-1.0.34.tgz#f1daad174d494c5baae29ebfb2d0cf7a26d487bb"
integrity sha512-CJcBspSB6B4UwXenGfzCiBh4wWPq9ZrRZm+Dqo774Yw7dfa/hHisfFiRAuz0vHxZl6AStLUsTBNynrzt7bs7Mg== integrity sha512-RN5xZVqk4D4GIFoTrm6kv6vxIcAyDgoopsGMYj8dQRCYWb6pvWzCKyDw4o1THXiK8BBD8ctFUE/FhtLXRj8F4w==
dependencies: dependencies:
"@techpass/passport-openidconnect" "^0.3.0" "@techpass/passport-openidconnect" "^0.3.0"
aws-sdk "^2.901.0" aws-sdk "^2.901.0"
@ -1056,10 +1056,10 @@
svelte-flatpickr "^3.2.3" svelte-flatpickr "^3.2.3"
svelte-portal "^1.0.0" svelte-portal "^1.0.0"
"@budibase/bbui@^1.0.33": "@budibase/bbui@^1.0.34":
version "1.0.33" version "1.0.34"
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.0.33.tgz#e815c4883dbc9d28d31900160fc74aafc81d02c1" resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.0.34.tgz#3eba93984cd0075aecbf4ca8451b301e623c7afa"
integrity sha512-2W3Ub8J8brSuhwtXhznszTa54cTyUdDNMFDCnRrHseaDV05XrSykdndXYyWi4XC+FveV82AdvSICxgd6alRGzg== integrity sha512-9mVzIWx4dQ8LIy4ncJaJBVwuTx2LEMqZl1XRr/NAI3rsTv+HIULe+zCUJSCYM2MGoR3qKSU7geIzIuwnRa8k4Q==
dependencies: dependencies:
"@adobe/spectrum-css-workflow-icons" "^1.2.1" "@adobe/spectrum-css-workflow-icons" "^1.2.1"
"@spectrum-css/actionbutton" "^1.0.1" "@spectrum-css/actionbutton" "^1.0.1"
@ -1106,14 +1106,14 @@
svelte-flatpickr "^3.2.3" svelte-flatpickr "^3.2.3"
svelte-portal "^1.0.0" svelte-portal "^1.0.0"
"@budibase/client@^1.0.27-alpha.1": "@budibase/client@^1.0.27-alpha.2":
version "1.0.33" version "1.0.34"
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-1.0.33.tgz#715aaaf15f13d9e40960fffea44002e817d8a569" resolved "https://registry.yarnpkg.com/@budibase/client/-/client-1.0.34.tgz#2bdac2030eabf780659481fa751cd7fecf1b609f"
integrity sha512-4+xM/ZTI247JbJc1noQS58VFh8AqfuQK1ZUSZIowuol1TtDu5dLGN7BysUFUe0mJZoDB/L+cB1I//43XqaSWDw== integrity sha512-WGEVjwmKYv+B+J6crbia62BNFCzgKHEggsNAlCN3+IB+w9jxS2oiOJYPpYQnsSM2l4j4/Zbu9W30OhenSiB8kQ==
dependencies: dependencies:
"@budibase/bbui" "^1.0.33" "@budibase/bbui" "^1.0.34"
"@budibase/standard-components" "^0.9.139" "@budibase/standard-components" "^0.9.139"
"@budibase/string-templates" "^1.0.33" "@budibase/string-templates" "^1.0.34"
regexparam "^1.3.0" regexparam "^1.3.0"
shortid "^2.2.15" shortid "^2.2.15"
svelte-spa-router "^3.0.5" svelte-spa-router "^3.0.5"
@ -1163,10 +1163,10 @@
svelte-apexcharts "^1.0.2" svelte-apexcharts "^1.0.2"
svelte-flatpickr "^3.1.0" svelte-flatpickr "^3.1.0"
"@budibase/string-templates@^1.0.27-alpha.1", "@budibase/string-templates@^1.0.33": "@budibase/string-templates@^1.0.27-alpha.2", "@budibase/string-templates@^1.0.34":
version "1.0.33" version "1.0.34"
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.33.tgz#7c39f0821d86ca1b26e8d5e7eca4256f24b09de0" resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.34.tgz#7e5f80a26db5d04063c0e78cdf37af88cff772c6"
integrity sha512-uvDJvVtAaBcMKnVylWlzGk+CzPXH+TIKojGAfgjCqfcBsc9GlyCCBLtANe8osi9Bdr1SsKOW9Fi5u9FTToNMJw== integrity sha512-HWqXxQBXqVwBgCh3ptczVFxWOLHVUhuTShXCafRDgKAVY3d+LJzKGwiD40/oR/nUqeNtBbHgYWu8Z4gMQQYZhA==
dependencies: dependencies:
"@budibase/handlebars-helpers" "^0.11.7" "@budibase/handlebars-helpers" "^0.11.7"
dayjs "^1.10.4" dayjs "^1.10.4"
@ -3304,9 +3304,9 @@ aws-sdk@^2.767.0:
xml2js "0.4.19" xml2js "0.4.19"
aws-sdk@^2.901.0: aws-sdk@^2.901.0:
version "2.1049.0" version "2.1046.0"
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1049.0.tgz#8146dcdf3a1ab603e50ff961169ee8abc537d48e" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1046.0.tgz#9147b0fa1c86acbebd1a061e951ab5012f4499d7"
integrity sha512-+wls9iNlotMeoZepwgR0yPzXsjXzr2ijoi5ERmsPWfMTFMHkm6INndBtSkm6fpu/NZnl+7EaPPES2yhaqnhoJg== integrity sha512-ocwHclMXdIA+NWocUyvp9Ild3/zy2vr5mHp3mTyodf0WU5lzBE8PocCVLSWhMAXLxyia83xv2y5f5AzAcetbqA==
dependencies: dependencies:
buffer "4.9.2" buffer "4.9.2"
events "1.1.1" events "1.1.1"

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/string-templates", "name": "@budibase/string-templates",
"version": "1.0.27-alpha.1", "version": "1.0.27-alpha.2",
"description": "Handlebars wrapper for Budibase templating.", "description": "Handlebars wrapper for Budibase templating.",
"main": "src/index.cjs", "main": "src/index.cjs",
"module": "dist/bundle.mjs", "module": "dist/bundle.mjs",

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/worker", "name": "@budibase/worker",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "1.0.27-alpha.1", "version": "1.0.27-alpha.2",
"description": "Budibase background service", "description": "Budibase background service",
"main": "src/index.js", "main": "src/index.js",
"repository": { "repository": {
@ -29,8 +29,8 @@
"author": "Budibase", "author": "Budibase",
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"@budibase/auth": "^1.0.27-alpha.1", "@budibase/auth": "^1.0.27-alpha.2",
"@budibase/string-templates": "^1.0.27-alpha.1", "@budibase/string-templates": "^1.0.27-alpha.2",
"@koa/router": "^8.0.0", "@koa/router": "^8.0.0",
"@sentry/node": "^6.0.0", "@sentry/node": "^6.0.0",
"@techpass/passport-openidconnect": "^0.3.0", "@techpass/passport-openidconnect": "^0.3.0",