Throw exception when updating non ui fields
This commit is contained in:
parent
bce75c91a6
commit
d440291ebc
|
@ -9,9 +9,40 @@ import {
|
||||||
RequiredKeys,
|
RequiredKeys,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function create(ctx: Ctx<CreateViewRequest, ViewResponse>) {
|
async function parseSchemaUI(ctx: Ctx, view: CreateViewRequest) {
|
||||||
const view = ctx.request.body
|
if (!view.schema) {
|
||||||
const { tableId } = view
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasOverrides(
|
||||||
|
newObj: Record<string, any>,
|
||||||
|
existingObj: Record<string, any>
|
||||||
|
) {
|
||||||
|
for (const [key, value] of Object.entries(newObj)) {
|
||||||
|
if (typeof value === "object") {
|
||||||
|
if (hasOverrides(value, existingObj[key] || {})) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else if (value !== existingObj[key]) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const table = await sdk.tables.getTable(view.tableId)
|
||||||
|
for (const [
|
||||||
|
fieldName,
|
||||||
|
{ order, width, visible, icon, ...schemaNonUI },
|
||||||
|
] of Object.entries(view.schema)) {
|
||||||
|
const overrides = hasOverrides(schemaNonUI, table.schema[fieldName])
|
||||||
|
if (overrides) {
|
||||||
|
ctx.throw(
|
||||||
|
400,
|
||||||
|
"This endpoint does not support overriding non UI fields in the schema"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const schemaUI =
|
const schemaUI =
|
||||||
view.schema &&
|
view.schema &&
|
||||||
|
@ -24,6 +55,14 @@ export async function create(ctx: Ctx<CreateViewRequest, ViewResponse>) {
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}, {} as Record<string, RequiredKeys<UIFieldMetadata>>)
|
}, {} as Record<string, RequiredKeys<UIFieldMetadata>>)
|
||||||
|
return schemaUI
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function create(ctx: Ctx<CreateViewRequest, ViewResponse>) {
|
||||||
|
const view = ctx.request.body
|
||||||
|
const { tableId } = view
|
||||||
|
|
||||||
|
const schemaUI = await parseSchemaUI(ctx, view)
|
||||||
|
|
||||||
const parsedView: Omit<ViewV2, "id" | "version"> = {
|
const parsedView: Omit<ViewV2, "id" | "version"> = {
|
||||||
name: view.name,
|
name: view.name,
|
||||||
|
|
|
@ -95,15 +95,15 @@ describe("/v2/views", () => {
|
||||||
name: generator.name(),
|
name: generator.name(),
|
||||||
tableId: config.table!._id!,
|
tableId: config.table!._id!,
|
||||||
schema: {
|
schema: {
|
||||||
name: {
|
Price: {
|
||||||
name: "name",
|
name: "Price",
|
||||||
type: FieldType.STRING,
|
type: FieldType.NUMBER,
|
||||||
visible: true,
|
visible: true,
|
||||||
order: 1,
|
order: 1,
|
||||||
width: 100,
|
width: 100,
|
||||||
},
|
},
|
||||||
lastname: {
|
Category: {
|
||||||
name: "lastname",
|
name: "Category",
|
||||||
type: FieldType.STRING,
|
type: FieldType.STRING,
|
||||||
visible: false,
|
visible: false,
|
||||||
icon: "ic",
|
icon: "ic",
|
||||||
|
@ -116,14 +116,14 @@ describe("/v2/views", () => {
|
||||||
expect(await config.api.viewV2.get(createdView.id)).toEqual({
|
expect(await config.api.viewV2.get(createdView.id)).toEqual({
|
||||||
...newView,
|
...newView,
|
||||||
schema: undefined,
|
schema: undefined,
|
||||||
columns: ["name", "lastname"],
|
columns: ["Price", "Category"],
|
||||||
schemaUI: {
|
schemaUI: {
|
||||||
name: {
|
Price: {
|
||||||
visible: true,
|
visible: true,
|
||||||
order: 1,
|
order: 1,
|
||||||
width: 100,
|
width: 100,
|
||||||
},
|
},
|
||||||
lastname: {
|
Category: {
|
||||||
visible: false,
|
visible: false,
|
||||||
icon: "ic",
|
icon: "ic",
|
||||||
},
|
},
|
||||||
|
@ -132,6 +132,54 @@ describe("/v2/views", () => {
|
||||||
version: 2,
|
version: 2,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("throw an exception if the schema overrides a non UI field", async () => {
|
||||||
|
const newView: CreateViewRequest = {
|
||||||
|
name: generator.name(),
|
||||||
|
tableId: config.table!._id!,
|
||||||
|
schema: {
|
||||||
|
Price: {
|
||||||
|
name: "Price",
|
||||||
|
type: FieldType.NUMBER,
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
Category: {
|
||||||
|
name: "Category",
|
||||||
|
type: FieldType.STRING,
|
||||||
|
constraints: {
|
||||||
|
type: "string",
|
||||||
|
presence: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
await config.api.viewV2.create(newView, {
|
||||||
|
expectStatus: 400,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("will not throw an exception if the schema is 'deleting' non UI fields", async () => {
|
||||||
|
const newView: CreateViewRequest = {
|
||||||
|
name: generator.name(),
|
||||||
|
tableId: config.table!._id!,
|
||||||
|
schema: {
|
||||||
|
Price: {
|
||||||
|
name: "Price",
|
||||||
|
type: FieldType.NUMBER,
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
Category: {
|
||||||
|
name: "Category",
|
||||||
|
type: FieldType.STRING,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
await config.api.viewV2.create(newView, {
|
||||||
|
expectStatus: 201,
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("update", () => {
|
describe("update", () => {
|
||||||
|
|
Loading…
Reference in New Issue