2020-10-10 06:49:23 +13:00
|
|
|
const Router = require("@koa/router")
|
|
|
|
const tableController = require("../controllers/table")
|
|
|
|
const authorized = require("../../middleware/authorized")
|
2021-02-09 06:22:07 +13:00
|
|
|
const { paramResource, bodyResource } = require("../../middleware/resourceId")
|
2020-11-12 06:34:15 +13:00
|
|
|
const {
|
|
|
|
BUILDER,
|
|
|
|
PermissionLevels,
|
|
|
|
PermissionTypes,
|
2022-01-11 08:33:00 +13:00
|
|
|
} = require("@budibase/backend-core/permissions")
|
2022-02-25 00:39:38 +13:00
|
|
|
const { tableValidator } = require("./utils/validators")
|
2020-10-10 06:49:23 +13:00
|
|
|
|
|
|
|
const router = Router()
|
|
|
|
|
|
|
|
router
|
2021-11-27 03:13:53 +13:00
|
|
|
/**
|
|
|
|
* @api {get} /api/tables Fetch all tables
|
|
|
|
* @apiName Fetch all tables
|
|
|
|
* @apiGroup tables
|
|
|
|
* @apiPermission table read access
|
|
|
|
* @apiDescription This endpoint retrieves all of the tables which have been created in
|
|
|
|
* an app. This includes all of the external and internal tables; to tell the difference
|
|
|
|
* between these look for the "type" property on each table, either being "internal" or "external".
|
|
|
|
*
|
|
|
|
* @apiSuccess {object[]} body The response body will be the list of tables that was found - as
|
|
|
|
* this does not take any parameters the only error scenario is no access.
|
|
|
|
*/
|
2020-10-10 06:49:23 +13:00
|
|
|
.get("/api/tables", authorized(BUILDER), tableController.fetch)
|
2021-11-27 03:13:53 +13:00
|
|
|
/**
|
|
|
|
* @api {get} /api/tables/:id Fetch a single table
|
|
|
|
* @apiName Fetch a single table
|
|
|
|
* @apiGroup tables
|
|
|
|
* @apiPermission table read access
|
|
|
|
* @apiDescription Retrieves a single table this could be be internal or external based on
|
|
|
|
* the provided table ID.
|
|
|
|
*
|
|
|
|
* @apiParam {string} id The ID of the table which is to be retrieved.
|
|
|
|
*
|
|
|
|
* @apiSuccess {object[]} body The response body will be the table that was found.
|
|
|
|
*/
|
2020-10-10 06:49:23 +13:00
|
|
|
.get(
|
2022-02-24 11:13:16 +13:00
|
|
|
"/api/tables/:tableId",
|
|
|
|
paramResource("tableId"),
|
2020-11-12 06:34:15 +13:00
|
|
|
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
|
2020-10-10 06:49:23 +13:00
|
|
|
tableController.find
|
|
|
|
)
|
2021-11-27 03:13:53 +13:00
|
|
|
/**
|
|
|
|
* @api {post} /api/tables Save a table
|
|
|
|
* @apiName Save a table
|
|
|
|
* @apiGroup tables
|
|
|
|
* @apiPermission builder
|
|
|
|
* @apiDescription Create or update a table with this endpoint, this will function for both internal
|
|
|
|
* external tables.
|
|
|
|
*
|
|
|
|
* @apiParam (Body) {string} [_id] If updating an existing table then the ID of the table must be specified.
|
|
|
|
* @apiParam (Body) {string} [_rev] If updating an existing internal table then the revision must also be specified.
|
|
|
|
* @apiParam (Body) {string} type] This should either be "internal" or "external" depending on the table type -
|
|
|
|
* this will default to internal.
|
|
|
|
* @apiParam (Body) {string} [sourceId] If creating an external table then this should be set to the data source ID. If
|
|
|
|
* building an internal table this does not need to be set, although it will be returned as "bb_internal".
|
|
|
|
* @apiParam (Body) {string} name The name of the table, this will be used in the UI. To rename the table simply
|
|
|
|
* supply the table structure to this endpoint with the name changed.
|
|
|
|
* @apiParam (Body) {object} schema A key value object which has all of the columns in the table as the keys in this
|
|
|
|
* object. For each column a "type" and "constraints" must be specified, with some types requiring further information.
|
|
|
|
* More information about the schema structure can be found in the Typescript definitions.
|
|
|
|
* @apiParam (Body) {string} [primaryDisplay] The name of the column which should be used when displaying rows
|
|
|
|
* from this table as relationships.
|
|
|
|
* @apiParam (Body) {object[]} [indexes] Specifies the search indexes - this is deprecated behaviour with the introduction
|
|
|
|
* of lucene indexes. This functionality is only available for internal tables.
|
|
|
|
* @apiParam (Body) {object} [_rename] If a column is to be renamed then the "old" column name should be set in this
|
|
|
|
* structure, and the "updated", new column name should also be supplied. The schema should also be updated, this field
|
|
|
|
* lets the server know that a field hasn't just been deleted, that the data has moved to a new name, this will fix
|
|
|
|
* the rows in the table. This functionality is only available for internal tables.
|
|
|
|
* @apiParam (Body) {object} [dataImport] When creating an internal table it can be built from a CSV, by using the
|
|
|
|
* CSV validation endpoint. Send the CSV data to the validation endpoint, then put the results of that call
|
|
|
|
* into this property, along with the CSV and a table/rows will be built from it. This is not supported when updating
|
|
|
|
* or for external tables.
|
|
|
|
*
|
|
|
|
* @apiParamExample {json} Example:
|
|
|
|
* {
|
|
|
|
* "_id": "ta_05541307fa0f4044abee071ca2a82119",
|
|
|
|
* "_rev": "10-0fbe4e78f69b255d79f1017e2eeef807",
|
|
|
|
* "type": "internal",
|
|
|
|
* "views": {},
|
|
|
|
* "name": "tableName",
|
|
|
|
* "schema": {
|
|
|
|
* "column": {
|
|
|
|
* "type": "string",
|
|
|
|
* "constraints": {
|
|
|
|
* "type": "string",
|
|
|
|
* "length": {
|
|
|
|
* "maximum": null
|
|
|
|
* },
|
|
|
|
* "presence": false
|
|
|
|
* },
|
|
|
|
* "name": "column"
|
|
|
|
* },
|
|
|
|
* },
|
|
|
|
* "primaryDisplay": "column",
|
|
|
|
* "indexes": [],
|
|
|
|
* "sourceId": "bb_internal",
|
|
|
|
* "_rename": {
|
|
|
|
* "old": "columnName",
|
|
|
|
* "updated": "newColumnName",
|
|
|
|
* },
|
|
|
|
* "dataImport": {
|
|
|
|
* "csvString": "column\nvalue",
|
|
|
|
* "primaryDisplay": "column",
|
|
|
|
* "schema": {
|
|
|
|
* "column": {
|
|
|
|
* "type": "string"
|
|
|
|
* }
|
|
|
|
* }
|
|
|
|
* }
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* @apiSuccess {object} table The response body will contain the table structure after being cleaned up and
|
|
|
|
* saved to the database.
|
|
|
|
*/
|
2021-02-09 06:22:07 +13:00
|
|
|
.post(
|
|
|
|
"/api/tables",
|
|
|
|
// allows control over updating a table
|
|
|
|
bodyResource("_id"),
|
|
|
|
authorized(BUILDER),
|
2022-02-25 00:39:38 +13:00
|
|
|
tableValidator(),
|
2021-02-09 06:22:07 +13:00
|
|
|
tableController.save
|
|
|
|
)
|
2021-11-27 03:13:53 +13:00
|
|
|
/**
|
|
|
|
* @api {post} /api/tables/csv/validate Validate a CSV for a table
|
|
|
|
* @apiName Validate a CSV for a table
|
|
|
|
* @apiGroup tables
|
|
|
|
* @apiPermission builder
|
|
|
|
* @apiDescription When creating a new table, or importing a CSV to an existing table the CSV must be validated and
|
|
|
|
* converted into a Budibase schema; this endpoint does this.
|
|
|
|
*
|
|
|
|
* @apiParam (Body) {string} csvString The CSV which is to be validated as a string.
|
|
|
|
* @apiParam (Body) {object} [schema] When a CSV has been validated it is possible to re-validate after changing the
|
|
|
|
* type of a field, by default everything will be strings as there is no way to infer types. The returned schema can
|
|
|
|
* be updated and then returned to the endpoint to re-validate and check if the type will work for the CSV, e.g.
|
|
|
|
* using a number instead of strings.
|
|
|
|
* @apiParam (Body) {string} [tableId] If importing data to an existing table this will pull the current table and
|
|
|
|
* remove any fields from the CSV schema which do not exist on the table/don't match the type of the table. When
|
|
|
|
* importing a CSV to an existing table only fields that are present on the table can be imported.
|
|
|
|
*
|
|
|
|
* @apiSuccess {object} schema The response body will contain a "schema" object that represents the schema found for
|
|
|
|
* the CSV - this will be in the same format used for table schema.s
|
|
|
|
*/
|
2020-10-10 06:49:23 +13:00
|
|
|
.post(
|
|
|
|
"/api/tables/csv/validate",
|
|
|
|
authorized(BUILDER),
|
|
|
|
tableController.validateCSVSchema
|
|
|
|
)
|
2021-11-27 03:13:53 +13:00
|
|
|
/**
|
|
|
|
* @api {post} /api/tables/:tableId/:revId Delete a table
|
|
|
|
* @apiName Delete a table
|
|
|
|
* @apiGroup tables
|
|
|
|
* @apiPermission builder
|
|
|
|
* @apiDescription This endpoint will delete a table and all of its associated data, for this reason it is
|
|
|
|
* quite dangerous - it will work for internal and external tables.
|
|
|
|
*
|
|
|
|
* @apiParam {string} tableId The ID of the table which is to be deleted.
|
|
|
|
* @apiParam {string} [revId] If deleting an internal table then the revision must also be supplied (_rev), for
|
|
|
|
* external tables this can simply be set to anything, e.g. "external".
|
|
|
|
*
|
|
|
|
* @apiSuccess {string} message A message stating that the table was deleted successfully.
|
|
|
|
*/
|
2020-10-10 06:49:23 +13:00
|
|
|
.delete(
|
|
|
|
"/api/tables/:tableId/:revId",
|
2021-02-09 06:22:07 +13:00
|
|
|
paramResource("tableId"),
|
2020-10-10 06:49:23 +13:00
|
|
|
authorized(BUILDER),
|
|
|
|
tableController.destroy
|
|
|
|
)
|
2021-11-27 03:13:53 +13:00
|
|
|
/**
|
|
|
|
* @api {post} /api/tables/:tableId/:revId Import CSV to existing table
|
|
|
|
* @apiName Import CSV to existing table
|
|
|
|
* @apiGroup tables
|
|
|
|
* @apiPermission builder
|
|
|
|
* @apiDescription This endpoint will import data to existing tables, internal or external. It is used in combination
|
|
|
|
* with the CSV validation endpoint. Take the output of the CSV validation endpoint and pass it to this endpoint to
|
|
|
|
* import the data; please note this will only import fields that already exist on the table/match the type.
|
|
|
|
*
|
|
|
|
* @apiParam {string} tableId The ID of the table which the data should be imported to.
|
|
|
|
*
|
|
|
|
* @apiParam (Body) {object} dataImport This is the same as the structure used when creating an internal table with
|
|
|
|
* a CSV, it will have the "schema" returned from the CSV validation endpoint and the "csvString" which is to be
|
|
|
|
* turned into rows.
|
|
|
|
*
|
|
|
|
* @apiSuccess {string} message A message stating that the data was imported successfully.
|
|
|
|
*/
|
2021-11-13 07:26:57 +13:00
|
|
|
.post(
|
|
|
|
"/api/tables/:tableId/import",
|
|
|
|
paramResource("tableId"),
|
|
|
|
authorized(BUILDER),
|
|
|
|
tableController.bulkImport
|
|
|
|
)
|
2020-10-10 06:49:23 +13:00
|
|
|
|
|
|
|
module.exports = router
|