From ed28bf664dfe460490bcaa3bf82818d54613cbc6 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 26 Nov 2021 17:39:18 +0000 Subject: [PATCH] Adding server functionality to determine schema for JSON data type, some basic UI around an editor for getting JSON to determine schema from and the key/value mechanism for flat structures. --- .../DataTable/modals/CreateEditColumn.svelte | 5 +- .../DataTable/modals/JSONSchemaModal.svelte | 54 +++++++++++++------ .../server/src/api/controllers/table/index.js | 33 ++++++++++++ packages/server/src/api/routes/table.js | 18 +++++++ 4 files changed, 93 insertions(+), 17 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte index fc597b658e..f4c0422304 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte @@ -452,7 +452,10 @@ - console.log(detail)} /> + (field.schema = detail)} + /> { - if (!schema) { - schema = {} - } - let i = 0 - for (let [key, value] of Object.entries(schema)) { - fieldKeys[i] = key - fieldTypes[i] = value.type - i++ - } - fieldCount = i + updateCounts() }) @@ -56,7 +78,7 @@ title={"Key/Value Schema Editor"} confirmText="Save Column" onConfirm={saveSchema} - disabled={invalid} + bind:disabled={invalid} size="L" > diff --git a/packages/server/src/api/controllers/table/index.js b/packages/server/src/api/controllers/table/index.js index abbb4d6ff9..bd404f3da8 100644 --- a/packages/server/src/api/controllers/table/index.js +++ b/packages/server/src/api/controllers/table/index.js @@ -9,6 +9,7 @@ const { BudibaseInternalDB, } = require("../../../db/utils") const { getTable } = require("./utils") +const { FieldTypes } = require("../../../constants") function pickApi({ tableId, table }) { if (table && !tableId) { @@ -81,6 +82,38 @@ exports.destroy = async function (ctx) { ctx.body = { message: `Table ${tableId} deleted.` } } +exports.schemaGenerate = function (ctx) { + const { json } = ctx.request.body + function recurse(schemaLevel, objectLevel) { + for (let [key, value] of Object.entries(objectLevel)) { + const type = typeof value + // check array first, since arrays are objects + if (Array.isArray(value)) { + schemaLevel[key] = { + type: FieldTypes.ARRAY, + } + } else if (type === "object") { + schemaLevel[key] = recurse(schemaLevel[key], objectLevel) + } else if (type === "string") { + schemaLevel[key] = { + type: FieldTypes.STRING, + } + } else if (type === "boolean") { + schemaLevel[key] = { + type: FieldTypes.BOOLEAN, + } + } else if (type === "number") { + schemaLevel[key] = { + type: FieldTypes.NUMBER, + } + } + } + return schemaLevel + } + + ctx.body = recurse({}, json) || {} +} + exports.bulkImport = async function (ctx) { const tableId = ctx.params.tableId await pickApi({ tableId }).bulkImport(ctx) diff --git a/packages/server/src/api/routes/table.js b/packages/server/src/api/routes/table.js index d8ddbe8133..a4575b3572 100644 --- a/packages/server/src/api/routes/table.js +++ b/packages/server/src/api/routes/table.js @@ -139,6 +139,24 @@ router generateSaveValidator(), tableController.save ) + /** + * @api {post} /api/tables/schema/generate Generate schema from JSON + * @apiName Generate schema from JSON + * @apiGroup tables + * @apiPermission builder + * @apiDescription Given a JSON structure this will generate a nested schema that can be used for a key/value data + * type in a table. + * + * @apiParam (Body) {object} json The JSON structure from which a nest schema should be generated. + * + * @apiSuccess {object} schema The response body will contain the schema, which can now be used for a key/value + * data type. + */ + .post( + "/api/tables/schema/generate", + authorized(BUILDER), + tableController.schemaGenerate + ) /** * @api {post} /api/tables/csv/validate Validate a CSV for a table * @apiName Validate a CSV for a table