Merge branch 'feature/json-backend' of github.com:Budibase/budibase into feature/json-backend
This commit is contained in:
commit
1aa6b0bdd6
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "0.9.190-alpha.11",
|
"version": "0.9.190-alpha.12",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/auth",
|
"name": "@budibase/auth",
|
||||||
"version": "0.9.190-alpha.11",
|
"version": "0.9.190-alpha.12",
|
||||||
"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",
|
||||||
|
|
|
@ -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": "0.9.190-alpha.11",
|
"version": "0.9.190-alpha.12",
|
||||||
"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",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "0.9.190-alpha.11",
|
"version": "0.9.190-alpha.12",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -65,10 +65,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^0.9.190-alpha.11",
|
"@budibase/bbui": "^0.9.190-alpha.12",
|
||||||
"@budibase/client": "^0.9.190-alpha.11",
|
"@budibase/client": "^0.9.190-alpha.12",
|
||||||
"@budibase/colorpicker": "1.1.2",
|
"@budibase/colorpicker": "1.1.2",
|
||||||
"@budibase/string-templates": "^0.9.190-alpha.11",
|
"@budibase/string-templates": "^0.9.190-alpha.12",
|
||||||
"@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",
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { FIELDS } from "constants/backend"
|
||||||
|
|
||||||
|
function baseConversion(type) {
|
||||||
|
if (type === "string") {
|
||||||
|
return {
|
||||||
|
type: FIELDS.STRING.type,
|
||||||
|
}
|
||||||
|
} else if (type === "boolean") {
|
||||||
|
return {
|
||||||
|
type: FIELDS.BOOLEAN.type,
|
||||||
|
}
|
||||||
|
} else if (type === "number") {
|
||||||
|
return {
|
||||||
|
type: FIELDS.NUMBER.type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function recurse(schemaLevel = {}, objectLevel) {
|
||||||
|
if (!objectLevel) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const baseType = typeof objectLevel
|
||||||
|
if (baseType !== "object") {
|
||||||
|
return baseConversion(baseType)
|
||||||
|
}
|
||||||
|
for (let [key, value] of Object.entries(objectLevel)) {
|
||||||
|
const type = typeof value
|
||||||
|
// check array first, since arrays are objects
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
const schema = recurse(schemaLevel[key], value[0])
|
||||||
|
if (schema) {
|
||||||
|
schemaLevel[key] = {
|
||||||
|
type: FIELDS.ARRAY.type,
|
||||||
|
schema,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type === "object") {
|
||||||
|
const schema = recurse(schemaLevel[key], objectLevel[key])
|
||||||
|
if (schema) {
|
||||||
|
schemaLevel[key] = schema
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
schemaLevel[key] = baseConversion(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!schemaLevel.type) {
|
||||||
|
return { type: FIELDS.JSON.type, schema: schemaLevel }
|
||||||
|
} else {
|
||||||
|
return schemaLevel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generate(object) {
|
||||||
|
return recurse({}, object).schema
|
||||||
|
}
|
|
@ -524,7 +524,7 @@ export const getFrontendStore = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
paste: async (targetComponent, mode) => {
|
paste: async (targetComponent, mode, preserveBindings = false) => {
|
||||||
let promises = []
|
let promises = []
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
// Stop if we have nothing to paste
|
// Stop if we have nothing to paste
|
||||||
|
@ -536,7 +536,7 @@ export const getFrontendStore = () => {
|
||||||
const cut = state.componentToPaste.isCut
|
const cut = state.componentToPaste.isCut
|
||||||
|
|
||||||
// immediately need to remove bindings, currently these aren't valid when pasted
|
// immediately need to remove bindings, currently these aren't valid when pasted
|
||||||
if (!cut) {
|
if (!cut && !preserveBindings) {
|
||||||
state.componentToPaste = removeBindings(state.componentToPaste)
|
state.componentToPaste = removeBindings(state.componentToPaste)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,20 @@
|
||||||
Toggle,
|
Toggle,
|
||||||
TextArea,
|
TextArea,
|
||||||
Multiselect,
|
Multiselect,
|
||||||
|
Label,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import Dropzone from "components/common/Dropzone.svelte"
|
import Dropzone from "components/common/Dropzone.svelte"
|
||||||
import { capitalise } from "helpers"
|
import { capitalise } from "helpers"
|
||||||
import LinkedRowSelector from "components/common/LinkedRowSelector.svelte"
|
import LinkedRowSelector from "components/common/LinkedRowSelector.svelte"
|
||||||
|
import Editor from "../../integration/QueryEditor.svelte"
|
||||||
|
|
||||||
export let defaultValue
|
export let defaultValue
|
||||||
export let meta
|
export let meta
|
||||||
export let value = defaultValue || (meta.type === "boolean" ? false : "")
|
export let value = defaultValue || (meta.type === "boolean" ? false : "")
|
||||||
export let readonly
|
export let readonly
|
||||||
|
|
||||||
|
$: stringVal =
|
||||||
|
typeof value === "object" ? JSON.stringify(value, null, 2) : value
|
||||||
$: type = meta?.type
|
$: type = meta?.type
|
||||||
$: label = meta.name ? capitalise(meta.name) : ""
|
$: label = meta.name ? capitalise(meta.name) : ""
|
||||||
</script>
|
</script>
|
||||||
|
@ -40,6 +44,14 @@
|
||||||
<LinkedRowSelector bind:linkedRows={value} schema={meta} />
|
<LinkedRowSelector bind:linkedRows={value} schema={meta} />
|
||||||
{:else if type === "longform"}
|
{:else if type === "longform"}
|
||||||
<TextArea {label} bind:value />
|
<TextArea {label} bind:value />
|
||||||
|
{:else if type === "json"}
|
||||||
|
<Label>{label}</Label>
|
||||||
|
<Editor
|
||||||
|
editorHeight="250"
|
||||||
|
mode="json"
|
||||||
|
on:change={({ detail }) => (value = detail.value)}
|
||||||
|
value={stringVal}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<Input
|
<Input
|
||||||
{label}
|
{label}
|
||||||
|
|
|
@ -87,7 +87,10 @@
|
||||||
field.subtype !== AUTO_COLUMN_SUB_TYPES.CREATED_BY &&
|
field.subtype !== AUTO_COLUMN_SUB_TYPES.CREATED_BY &&
|
||||||
field.subtype !== AUTO_COLUMN_SUB_TYPES.UPDATED_BY &&
|
field.subtype !== AUTO_COLUMN_SUB_TYPES.UPDATED_BY &&
|
||||||
field.type !== FORMULA_TYPE
|
field.type !== FORMULA_TYPE
|
||||||
$: canBeDisplay = field.type !== LINK_TYPE && field.type !== AUTO_TYPE
|
$: canBeDisplay =
|
||||||
|
field.type !== LINK_TYPE &&
|
||||||
|
field.type !== AUTO_TYPE &&
|
||||||
|
field.type !== JSON_TYPE
|
||||||
$: canBeRequired =
|
$: canBeRequired =
|
||||||
field.type !== LINK_TYPE && !uneditable && field.type !== AUTO_TYPE
|
field.type !== LINK_TYPE && !uneditable && field.type !== AUTO_TYPE
|
||||||
$: relationshipOptions = getRelationshipOptions(field)
|
$: relationshipOptions = getRelationshipOptions(field)
|
||||||
|
@ -452,7 +455,14 @@
|
||||||
</div>
|
</div>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
<Modal bind:this={jsonSchemaModal}>
|
<Modal bind:this={jsonSchemaModal}>
|
||||||
<JSONSchemaModal on:save={({ detail }) => console.log(detail)} />
|
<JSONSchemaModal
|
||||||
|
schema={field.schema}
|
||||||
|
json={field.json}
|
||||||
|
on:save={({ detail }) => {
|
||||||
|
field.schema = detail.schema
|
||||||
|
field.json = detail.json
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
bind:this={confirmDeleteDialog}
|
bind:this={confirmDeleteDialog}
|
||||||
|
|
|
@ -9,36 +9,42 @@
|
||||||
Select,
|
Select,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { onMount, createEventDispatcher } from "svelte"
|
import { onMount, createEventDispatcher } from "svelte"
|
||||||
|
import { FIELDS } from "constants/backend"
|
||||||
|
import { generate } from "builderStore/schemaGenerator"
|
||||||
|
|
||||||
export let schema = {}
|
export let schema = {}
|
||||||
|
export let json
|
||||||
|
|
||||||
let dispatcher = createEventDispatcher()
|
let dispatcher = createEventDispatcher()
|
||||||
let mode = "Key/Value"
|
let mode = "Key/Value"
|
||||||
let json
|
|
||||||
let fieldCount = 0
|
let fieldCount = 0
|
||||||
let fieldKeys = {},
|
let fieldKeys = {},
|
||||||
fieldTypes = {}
|
fieldTypes = {}
|
||||||
let keyValueOptions = ["String", "Number", "Boolean", "Object", "Array"]
|
let keyValueOptions = [
|
||||||
|
{ label: "String", value: FIELDS.STRING.type },
|
||||||
|
{ label: "Number", value: FIELDS.NUMBER.type },
|
||||||
|
{ label: "Boolean", value: FIELDS.BOOLEAN.type },
|
||||||
|
{ label: "Object", value: FIELDS.JSON.type },
|
||||||
|
{ label: "Array", value: FIELDS.ARRAY.type },
|
||||||
|
]
|
||||||
|
let invalid = false
|
||||||
|
|
||||||
$: invalid = false
|
async function onJsonUpdate({ detail }) {
|
||||||
|
|
||||||
function onJsonUpdate({ detail }) {
|
|
||||||
// TODO: make request
|
|
||||||
const input = detail.value
|
const input = detail.value
|
||||||
console.log(input)
|
json = input
|
||||||
}
|
try {
|
||||||
|
// check json valid first
|
||||||
function saveSchema() {
|
let inputJson = JSON.parse(input)
|
||||||
for (let i of Object.keys(fieldKeys)) {
|
schema = generate(inputJson)
|
||||||
const key = fieldKeys[i]
|
updateCounts()
|
||||||
schema[key] = {
|
invalid = false
|
||||||
type: fieldTypes[i],
|
} catch (err) {
|
||||||
}
|
// json not currently valid
|
||||||
|
invalid = true
|
||||||
}
|
}
|
||||||
dispatcher("save", schema)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
function updateCounts() {
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
schema = {}
|
schema = {}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +55,24 @@
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
fieldCount = i
|
fieldCount = i
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSchema() {
|
||||||
|
for (let i of Object.keys(fieldKeys)) {
|
||||||
|
const key = fieldKeys[i]
|
||||||
|
// they were added to schema, rather than generated
|
||||||
|
if (!schema[key]) {
|
||||||
|
schema[key] = {
|
||||||
|
type: fieldTypes[i],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatcher("save", { schema, json })
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
updateCounts()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -56,7 +80,7 @@
|
||||||
title={"Key/Value Schema Editor"}
|
title={"Key/Value Schema Editor"}
|
||||||
confirmText="Save Column"
|
confirmText="Save Column"
|
||||||
onConfirm={saveSchema}
|
onConfirm={saveSchema}
|
||||||
disabled={invalid}
|
bind:disabled={invalid}
|
||||||
size="L"
|
size="L"
|
||||||
>
|
>
|
||||||
<Tabs selected={mode} noPadding>
|
<Tabs selected={mode} noPadding>
|
||||||
|
@ -68,7 +92,8 @@
|
||||||
label="Type"
|
label="Type"
|
||||||
options={keyValueOptions}
|
options={keyValueOptions}
|
||||||
bind:value={fieldTypes[i]}
|
bind:value={fieldTypes[i]}
|
||||||
getOptionValue={field => field.toLowerCase()}
|
getOptionValue={field => field.value}
|
||||||
|
getOptionLabel={field => field.label}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
|
|
||||||
const duplicateComponent = () => {
|
const duplicateComponent = () => {
|
||||||
storeComponentForCopy(false)
|
storeComponentForCopy(false)
|
||||||
pasteComponent("below")
|
pasteComponent("below", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteComponent = async () => {
|
const deleteComponent = async () => {
|
||||||
|
@ -69,9 +69,9 @@
|
||||||
store.actions.components.copy(component, cut)
|
store.actions.components.copy(component, cut)
|
||||||
}
|
}
|
||||||
|
|
||||||
const pasteComponent = mode => {
|
const pasteComponent = (mode, preserveBindings = false) => {
|
||||||
// lives in store - also used by drag drop
|
// lives in store - also used by drag drop
|
||||||
store.actions.components.paste(component, mode)
|
store.actions.components.paste(component, mode, preserveBindings)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,15 @@
|
||||||
import { Button, ActionButton, Drawer } from "@budibase/bbui"
|
import { Button, ActionButton, Drawer } from "@budibase/bbui"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import NavigationDrawer from "./NavigationDrawer.svelte"
|
import NavigationDrawer from "./NavigationDrawer.svelte"
|
||||||
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
|
||||||
export let value = []
|
export let value = []
|
||||||
let drawer
|
let drawer
|
||||||
|
let links = cloneDeep(value)
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const save = () => {
|
const save = () => {
|
||||||
dispatch("change", value)
|
dispatch("change", links)
|
||||||
drawer.hide()
|
drawer.hide()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -19,5 +21,5 @@
|
||||||
Configure the links in your navigation bar.
|
Configure the links in your navigation bar.
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<Button cta slot="buttons" on:click={save}>Save</Button>
|
<Button cta slot="buttons" on:click={save}>Save</Button>
|
||||||
<NavigationDrawer slot="body" bind:links={value} />
|
<NavigationDrawer slot="body" bind:links />
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/cli",
|
"name": "@budibase/cli",
|
||||||
"version": "0.9.190-alpha.11",
|
"version": "0.9.190-alpha.12",
|
||||||
"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": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "0.9.190-alpha.11",
|
"version": "0.9.190-alpha.12",
|
||||||
"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": "^0.9.190-alpha.11",
|
"@budibase/bbui": "^0.9.190-alpha.12",
|
||||||
"@budibase/standard-components": "^0.9.139",
|
"@budibase/standard-components": "^0.9.139",
|
||||||
"@budibase/string-templates": "^0.9.190-alpha.11",
|
"@budibase/string-templates": "^0.9.190-alpha.12",
|
||||||
"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"
|
||||||
|
|
|
@ -313,6 +313,9 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
.desktop.layout--left .links {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.desktop .nav--left {
|
.desktop .nav--left {
|
||||||
width: 250px;
|
width: 250px;
|
||||||
|
@ -379,6 +382,7 @@
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.mobile .link {
|
.mobile .link {
|
||||||
width: calc(100% - 30px);
|
width: calc(100% - 30px);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/server",
|
"name": "@budibase/server",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.9.190-alpha.11",
|
"version": "0.9.190-alpha.12",
|
||||||
"description": "Budibase Web Server",
|
"description": "Budibase Web Server",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -69,9 +69,9 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/auth": "^0.9.190-alpha.11",
|
"@budibase/auth": "^0.9.190-alpha.12",
|
||||||
"@budibase/client": "^0.9.190-alpha.11",
|
"@budibase/client": "^0.9.190-alpha.12",
|
||||||
"@budibase/string-templates": "^0.9.190-alpha.11",
|
"@budibase/string-templates": "^0.9.190-alpha.12",
|
||||||
"@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",
|
||||||
|
|
|
@ -50,10 +50,10 @@ exports.validate = async ({ appId, tableId, row, table }) => {
|
||||||
const errors = {}
|
const errors = {}
|
||||||
for (let fieldName of Object.keys(table.schema)) {
|
for (let fieldName of Object.keys(table.schema)) {
|
||||||
const constraints = cloneDeep(table.schema[fieldName].constraints)
|
const constraints = cloneDeep(table.schema[fieldName].constraints)
|
||||||
|
const type = table.schema[fieldName].type
|
||||||
// special case for options, need to always allow unselected (null)
|
// special case for options, need to always allow unselected (null)
|
||||||
if (
|
if (
|
||||||
table.schema[fieldName].type ===
|
(type === FieldTypes.OPTIONS || type === FieldTypes.ARRAY) &&
|
||||||
(FieldTypes.OPTIONS || FieldTypes.ARRAY) &&
|
|
||||||
constraints.inclusion
|
constraints.inclusion
|
||||||
) {
|
) {
|
||||||
constraints.inclusion.push(null)
|
constraints.inclusion.push(null)
|
||||||
|
@ -61,17 +61,20 @@ exports.validate = async ({ appId, tableId, row, table }) => {
|
||||||
let res
|
let res
|
||||||
|
|
||||||
// Validate.js doesn't seem to handle array
|
// Validate.js doesn't seem to handle array
|
||||||
if (
|
if (type === FieldTypes.ARRAY && row[fieldName] && row[fieldName].length) {
|
||||||
table.schema[fieldName].type === FieldTypes.ARRAY &&
|
|
||||||
row[fieldName] &&
|
|
||||||
row[fieldName].length
|
|
||||||
) {
|
|
||||||
row[fieldName].map(val => {
|
row[fieldName].map(val => {
|
||||||
if (!constraints.inclusion.includes(val)) {
|
if (!constraints.inclusion.includes(val)) {
|
||||||
errors[fieldName] = "Field not in list"
|
errors[fieldName] = "Field not in list"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else if (table.schema[fieldName].type === FieldTypes.FORMULA) {
|
} else if (type === FieldTypes.JSON && typeof row[fieldName] === "string") {
|
||||||
|
// this should only happen if there is an error
|
||||||
|
try {
|
||||||
|
JSON.parse(row[fieldName])
|
||||||
|
} catch (err) {
|
||||||
|
errors[fieldName] = [`Contains invalid JSON`]
|
||||||
|
}
|
||||||
|
} else if (type === FieldTypes.FORMULA) {
|
||||||
res = validateJs.single(
|
res = validateJs.single(
|
||||||
processStringSync(table.schema[fieldName].formula, row),
|
processStringSync(table.schema[fieldName].formula, row),
|
||||||
constraints
|
constraints
|
||||||
|
|
|
@ -81,6 +81,18 @@ const TYPE_TRANSFORM_MAP = {
|
||||||
[FieldTypes.AUTO]: {
|
[FieldTypes.AUTO]: {
|
||||||
parse: () => undefined,
|
parse: () => undefined,
|
||||||
},
|
},
|
||||||
|
[FieldTypes.JSON]: {
|
||||||
|
parse: input => {
|
||||||
|
try {
|
||||||
|
if (input === "") {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return JSON.parse(input)
|
||||||
|
} catch (err) {
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/string-templates",
|
"name": "@budibase/string-templates",
|
||||||
"version": "0.9.190-alpha.11",
|
"version": "0.9.190-alpha.12",
|
||||||
"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",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/worker",
|
"name": "@budibase/worker",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.9.190-alpha.11",
|
"version": "0.9.190-alpha.12",
|
||||||
"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": "^0.9.190-alpha.11",
|
"@budibase/auth": "^0.9.190-alpha.12",
|
||||||
"@budibase/string-templates": "^0.9.190-alpha.11",
|
"@budibase/string-templates": "^0.9.190-alpha.12",
|
||||||
"@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",
|
||||||
|
|
Loading…
Reference in New Issue