Fixes for datasource authentication parsing. Mapping UX updates
This commit is contained in:
parent
ac8513bd4c
commit
31b51e1ecf
|
@ -40,5 +40,6 @@
|
||||||
on:change={onChange}
|
on:change={onChange}
|
||||||
on:pick
|
on:pick
|
||||||
on:type
|
on:type
|
||||||
|
on:blur
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -52,7 +52,10 @@
|
||||||
{id}
|
{id}
|
||||||
type="text"
|
type="text"
|
||||||
on:focus={() => (focus = true)}
|
on:focus={() => (focus = true)}
|
||||||
on:blur={() => (focus = false)}
|
on:blur={() => {
|
||||||
|
focus = false
|
||||||
|
dispatch("blur")
|
||||||
|
}}
|
||||||
on:change={onType}
|
on:change={onType}
|
||||||
value={value || ""}
|
value={value || ""}
|
||||||
placeholder={placeholder || ""}
|
placeholder={placeholder || ""}
|
||||||
|
|
|
@ -54,7 +54,56 @@ export const getBindableProperties = (asset, componentId) => {
|
||||||
*/
|
*/
|
||||||
export const getRestBindings = () => {
|
export const getRestBindings = () => {
|
||||||
const userBindings = getUserBindings()
|
const userBindings = getUserBindings()
|
||||||
return [...userBindings]
|
return [...userBindings, ...getAuthBindings()]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all rest bindable auth fields
|
||||||
|
*/
|
||||||
|
export const getAuthBindings = () => {
|
||||||
|
let bindings = []
|
||||||
|
const safeUser = makePropSafe("user")
|
||||||
|
const safeOAuth2 = makePropSafe("oauth2")
|
||||||
|
const safeAccessToken = makePropSafe("accessToken")
|
||||||
|
|
||||||
|
const authBindings = [
|
||||||
|
{
|
||||||
|
runtime: `${safeUser}.${safeOAuth2}.${safeAccessToken}`,
|
||||||
|
readable: `Current User.OAuthToken`,
|
||||||
|
key: "accessToken",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
bindings = Object.keys(authBindings).map(key => {
|
||||||
|
const fieldBinding = authBindings[key]
|
||||||
|
return {
|
||||||
|
type: "context",
|
||||||
|
runtimeBinding: fieldBinding.runtime,
|
||||||
|
readableBinding: fieldBinding.readable,
|
||||||
|
fieldSchema: { type: "string", name: fieldBinding.key },
|
||||||
|
providerId: "user",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return bindings
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility - convert a key/value map to an array of custom 'context' bindings
|
||||||
|
* @param {object} valueMap Key/value pairings
|
||||||
|
* @param {string} prefix A contextual string prefix/path for a user readable binding
|
||||||
|
* @return {object[]} An array containing readable/runtime binding objects
|
||||||
|
*/
|
||||||
|
export const toBindingsArray = (valueMap, prefix) => {
|
||||||
|
if (!valueMap) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return Object.keys(valueMap).map(binding => {
|
||||||
|
return {
|
||||||
|
type: "context",
|
||||||
|
runtimeBinding: binding,
|
||||||
|
readableBinding: `${prefix}.${binding}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { ModalContent, Layout, Select, Body, Input } from "@budibase/bbui"
|
import { ModalContent, Layout, Select, Body, Input } from "@budibase/bbui"
|
||||||
import { AUTH_TYPE_LABELS, AUTH_TYPES } from "./authTypes"
|
import { AUTH_TYPE_LABELS, AUTH_TYPES } from "./authTypes"
|
||||||
|
import DrawerBindableCombobox from "components/common/bindings/DrawerBindableCombobox.svelte"
|
||||||
|
import { getAuthBindings } from "builderStore/dataBinding"
|
||||||
|
|
||||||
export let configs
|
export let configs
|
||||||
export let currentConfig
|
export let currentConfig
|
||||||
|
@ -203,11 +205,23 @@
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
{#if form.type === AUTH_TYPES.BEARER}
|
{#if form.type === AUTH_TYPES.BEARER}
|
||||||
<Input
|
<DrawerBindableCombobox
|
||||||
label="Token"
|
label="Token"
|
||||||
bind:value={form.bearer.token}
|
value={form.bearer.token}
|
||||||
on:change={onFieldChange}
|
bindings={getAuthBindings()}
|
||||||
on:blur={() => (blurred.bearer.token = true)}
|
on:change={e => {
|
||||||
|
form.bearer.token = e.detail
|
||||||
|
console.log(e.detail)
|
||||||
|
onFieldChange()
|
||||||
|
}}
|
||||||
|
on:blur={() => {
|
||||||
|
blurred.bearer.token = true
|
||||||
|
onFieldChange()
|
||||||
|
}}
|
||||||
|
allowJS={false}
|
||||||
|
placeholder="Token"
|
||||||
|
appendBindingsAsOptions={true}
|
||||||
|
drawerEnabled={false}
|
||||||
error={blurred.bearer.token ? errors.bearer.token : null}
|
error={blurred.bearer.token ? errors.bearer.token : null}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
export let options
|
export let options
|
||||||
export let allowJS = true
|
export let allowJS = true
|
||||||
export let appendBindingsAsOptions = true
|
export let appendBindingsAsOptions = true
|
||||||
|
export let drawerEnabled = false
|
||||||
|
export let error
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
let bindingDrawer
|
let bindingDrawer
|
||||||
|
@ -59,10 +61,12 @@
|
||||||
value={isJS ? "(JavaScript function)" : readableValue}
|
value={isJS ? "(JavaScript function)" : readableValue}
|
||||||
on:type={e => onChange(e.detail, false)}
|
on:type={e => onChange(e.detail, false)}
|
||||||
on:pick={e => onChange(e.detail, true)}
|
on:pick={e => onChange(e.detail, true)}
|
||||||
|
on:blur={() => dispatch("blur")}
|
||||||
{placeholder}
|
{placeholder}
|
||||||
options={allOptions}
|
options={allOptions}
|
||||||
|
{error}
|
||||||
/>
|
/>
|
||||||
{#if !disabled}
|
{#if !disabled && drawerEnabled}
|
||||||
<div
|
<div
|
||||||
class="icon"
|
class="icon"
|
||||||
on:click={bindingDrawer.show}
|
on:click={bindingDrawer.show}
|
||||||
|
@ -72,7 +76,8 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<Drawer bind:this={bindingDrawer} {title}>
|
{#if !drawerEnabled}
|
||||||
|
<Drawer bind:this={bindingDrawer} {title}>
|
||||||
<svelte:fragment slot="description">
|
<svelte:fragment slot="description">
|
||||||
Add the objects on the left to enrich your text.
|
Add the objects on the left to enrich your text.
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
@ -86,7 +91,8 @@
|
||||||
{bindings}
|
{bindings}
|
||||||
{allowJS}
|
{allowJS}
|
||||||
/>
|
/>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.control {
|
.control {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { lowercase } from "helpers"
|
import { lowercase } from "helpers"
|
||||||
|
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte"
|
||||||
|
|
||||||
let dispatch = createEventDispatcher()
|
let dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
export let tooltip
|
export let tooltip
|
||||||
export let menuItems
|
export let menuItems
|
||||||
export let showMenu = false
|
export let showMenu = false
|
||||||
|
export let bindings = []
|
||||||
|
|
||||||
let fields = Object.entries(object || {}).map(([name, value]) => ({
|
let fields = Object.entries(object || {}).map(([name, value]) => ({
|
||||||
name,
|
name,
|
||||||
|
@ -108,6 +110,16 @@
|
||||||
/>
|
/>
|
||||||
{#if options}
|
{#if options}
|
||||||
<Select bind:value={field.value} on:change={changed} {options} />
|
<Select bind:value={field.value} on:change={changed} {options} />
|
||||||
|
{:else if bindings && bindings.length}
|
||||||
|
<DrawerBindableInput
|
||||||
|
{bindings}
|
||||||
|
placeholder="Value"
|
||||||
|
on:change={e => (field.value = e.detail)}
|
||||||
|
disabled={readOnly}
|
||||||
|
value={field.value}
|
||||||
|
allowJS={false}
|
||||||
|
fillWidth={true}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<Input
|
<Input
|
||||||
placeholder={valuePlaceholder}
|
placeholder={valuePlaceholder}
|
||||||
|
|
|
@ -42,8 +42,9 @@
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getRestBindings,
|
getRestBindings,
|
||||||
readableToRuntimeBinding,
|
toBindingsArray,
|
||||||
runtimeToReadableBinding,
|
runtimeToReadableBinding,
|
||||||
|
readableToRuntimeBinding,
|
||||||
runtimeToReadableMap,
|
runtimeToReadableMap,
|
||||||
readableToRuntimeMap,
|
readableToRuntimeMap,
|
||||||
} from "builderStore/dataBinding"
|
} from "builderStore/dataBinding"
|
||||||
|
@ -57,6 +58,25 @@
|
||||||
let dynamicVariables, addVariableModal, varBinding
|
let dynamicVariables, addVariableModal, varBinding
|
||||||
let restBindings = getRestBindings()
|
let restBindings = getRestBindings()
|
||||||
|
|
||||||
|
$: staticVariables = datasource?.config?.staticVariables || {}
|
||||||
|
$: customRequestBindings = toBindingsArray(requestBindings, "Binding")
|
||||||
|
$: dynamicRequestBindings = toBindingsArray(dynamicVariables, "Dynamic")
|
||||||
|
$: dataSourceStaticBindings = toBindingsArray(
|
||||||
|
staticVariables,
|
||||||
|
"Datasource.Static"
|
||||||
|
)
|
||||||
|
|
||||||
|
$: mergedBindings = [
|
||||||
|
...restBindings,
|
||||||
|
...customRequestBindings,
|
||||||
|
...dynamicRequestBindings,
|
||||||
|
...dataSourceStaticBindings,
|
||||||
|
]
|
||||||
|
|
||||||
|
$: mergedAndCompleteBindings = mergedBindings.filter(binding => {
|
||||||
|
return binding.runtimeBinding && binding.readableBinding
|
||||||
|
})
|
||||||
|
|
||||||
$: datasourceType = datasource?.source
|
$: datasourceType = datasource?.source
|
||||||
$: integrationInfo = $integrations[datasourceType]
|
$: integrationInfo = $integrations[datasourceType]
|
||||||
$: queryConfig = integrationInfo?.query
|
$: queryConfig = integrationInfo?.query
|
||||||
|
@ -72,7 +92,10 @@
|
||||||
Object.keys(schema || {}).length !== 0 ||
|
Object.keys(schema || {}).length !== 0 ||
|
||||||
Object.keys(query?.schema || {}).length !== 0
|
Object.keys(query?.schema || {}).length !== 0
|
||||||
|
|
||||||
$: runtimeUrlQueries = readableToRuntimeMap(restBindings, breakQs)
|
$: runtimeUrlQueries = readableToRuntimeMap(
|
||||||
|
mergedAndCompleteBindings,
|
||||||
|
breakQs
|
||||||
|
)
|
||||||
|
|
||||||
function getSelectedQuery() {
|
function getSelectedQuery() {
|
||||||
const cloneQuery = cloneDeep(
|
const cloneQuery = cloneDeep(
|
||||||
|
@ -87,32 +110,18 @@
|
||||||
queryVerb: "read",
|
queryVerb: "read",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (cloneQuery?.fields?.headers) {
|
|
||||||
cloneQuery.fields.headers = runtimeToReadableMap(
|
|
||||||
restBindings,
|
|
||||||
cloneQuery.fields.headers
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cloneQuery?.fields?.requestBody) {
|
if (cloneQuery?.fields?.requestBody) {
|
||||||
cloneQuery.fields.requestBody =
|
cloneQuery.fields.requestBody =
|
||||||
typeof cloneQuery.fields.requestBody === "object"
|
typeof cloneQuery.fields.requestBody === "object"
|
||||||
? runtimeToReadableMap(restBindings, cloneQuery.fields.requestBody)
|
? runtimeToReadableMap(
|
||||||
|
mergedAndCompleteBindings,
|
||||||
|
cloneQuery.fields.requestBody
|
||||||
|
)
|
||||||
: runtimeToReadableBinding(
|
: runtimeToReadableBinding(
|
||||||
restBindings,
|
mergedAndCompleteBindings,
|
||||||
cloneQuery.fields.requestBody
|
cloneQuery.fields.requestBody
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cloneQuery?.parameters) {
|
|
||||||
const flatParams = restUtils.queryParametersToKeyValue(
|
|
||||||
cloneQuery.parameters
|
|
||||||
)
|
|
||||||
const updatedParams = runtimeToReadableMap(restBindings, flatParams)
|
|
||||||
cloneQuery.parameters = restUtils.keyValueToQueryParameters(updatedParams)
|
|
||||||
}
|
|
||||||
|
|
||||||
return cloneQuery
|
return cloneQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +137,7 @@
|
||||||
return base
|
return base
|
||||||
}
|
}
|
||||||
const qs = restUtils.buildQueryString(
|
const qs = restUtils.buildQueryString(
|
||||||
runtimeToReadableMap(restBindings, qsObj)
|
runtimeToReadableMap(mergedAndCompleteBindings, qsObj)
|
||||||
)
|
)
|
||||||
let newUrl = base
|
let newUrl = base
|
||||||
if (base.includes("?")) {
|
if (base.includes("?")) {
|
||||||
|
@ -140,14 +149,17 @@
|
||||||
function buildQuery() {
|
function buildQuery() {
|
||||||
const newQuery = cloneDeep(query)
|
const newQuery = cloneDeep(query)
|
||||||
const queryString = restUtils.buildQueryString(runtimeUrlQueries)
|
const queryString = restUtils.buildQueryString(runtimeUrlQueries)
|
||||||
newQuery.fields.headers = readableToRuntimeMap(
|
|
||||||
restBindings,
|
|
||||||
newQuery.fields.headers
|
|
||||||
)
|
|
||||||
newQuery.fields.requestBody =
|
newQuery.fields.requestBody =
|
||||||
typeof newQuery.fields.requestBody === "object"
|
typeof newQuery.fields.requestBody === "object"
|
||||||
? readableToRuntimeMap(restBindings, newQuery.fields.requestBody)
|
? readableToRuntimeMap(
|
||||||
: readableToRuntimeBinding(restBindings, newQuery.fields.requestBody)
|
mergedAndCompleteBindings,
|
||||||
|
newQuery.fields.requestBody
|
||||||
|
)
|
||||||
|
: readableToRuntimeBinding(
|
||||||
|
mergedAndCompleteBindings,
|
||||||
|
newQuery.fields.requestBody
|
||||||
|
)
|
||||||
|
|
||||||
newQuery.fields.path = url.split("?")[0]
|
newQuery.fields.path = url.split("?")[0]
|
||||||
newQuery.fields.queryString = queryString
|
newQuery.fields.queryString = queryString
|
||||||
|
@ -155,14 +167,6 @@
|
||||||
newQuery.fields.disabledHeaders = restUtils.flipHeaderState(enabledHeaders)
|
newQuery.fields.disabledHeaders = restUtils.flipHeaderState(enabledHeaders)
|
||||||
newQuery.schema = restUtils.fieldsToSchema(schema)
|
newQuery.schema = restUtils.fieldsToSchema(schema)
|
||||||
|
|
||||||
const parsedRequestBindings = readableToRuntimeMap(
|
|
||||||
restBindings,
|
|
||||||
requestBindings
|
|
||||||
)
|
|
||||||
newQuery.parameters = restUtils.keyValueToQueryParameters(
|
|
||||||
parsedRequestBindings
|
|
||||||
)
|
|
||||||
|
|
||||||
return newQuery
|
return newQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,10 +413,20 @@
|
||||||
headings
|
headings
|
||||||
keyPlaceholder="Binding name"
|
keyPlaceholder="Binding name"
|
||||||
valuePlaceholder="Default"
|
valuePlaceholder="Default"
|
||||||
|
bindings={[
|
||||||
|
...restBindings,
|
||||||
|
...dynamicRequestBindings,
|
||||||
|
...dataSourceStaticBindings,
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab title="Params">
|
<Tab title="Params">
|
||||||
<KeyValueBuilder bind:object={breakQs} name="param" headings />
|
<KeyValueBuilder
|
||||||
|
bind:object={breakQs}
|
||||||
|
name="param"
|
||||||
|
headings
|
||||||
|
bindings={mergedAndCompleteBindings}
|
||||||
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab title="Headers">
|
<Tab title="Headers">
|
||||||
<KeyValueBuilder
|
<KeyValueBuilder
|
||||||
|
@ -421,6 +435,7 @@
|
||||||
toggle
|
toggle
|
||||||
name="header"
|
name="header"
|
||||||
headings
|
headings
|
||||||
|
bindings={mergedAndCompleteBindings}
|
||||||
/>
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab title="Body">
|
<Tab title="Body">
|
||||||
|
|
|
@ -36,6 +36,12 @@ class QueryRunner {
|
||||||
if (!Integration) {
|
if (!Integration) {
|
||||||
throw "Integration type does not exist."
|
throw "Integration type does not exist."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
datasource.config.authConfigs = enrichQueryFields(
|
||||||
|
datasource.config.authConfigs,
|
||||||
|
this.ctx
|
||||||
|
)
|
||||||
|
|
||||||
const integration = new Integration(datasource.config)
|
const integration = new Integration(datasource.config)
|
||||||
|
|
||||||
// pre-query, make sure datasource variables are added to parameters
|
// pre-query, make sure datasource variables are added to parameters
|
||||||
|
|
Loading…
Reference in New Issue