diff --git a/lerna.json b/lerna.json index f4c90c684f..c121deafe8 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.0.81-alpha.4", + "version": "1.0.81-alpha.5", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 25d98ec2a4..7d6866f6d3 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.0.80-alpha.5", + "version": "1.0.81-alpha.5", "description": "Budibase backend core libraries used in server and worker", "main": "src/index.js", "author": "Budibase", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 3cb109748a..18ee34c16b 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", - "version": "1.0.80-alpha.5", + "version": "1.0.81-alpha.5", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,7 +38,7 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "^1.2.1", - "@budibase/string-templates": "^1.0.80-alpha.5", + "@budibase/string-templates": "^1.0.81-alpha.5", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/builder/package.json b/packages/builder/package.json index 1558d05894..bfca5af718 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "1.0.80-alpha.5", + "version": "1.0.81-alpha.5", "license": "GPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^1.0.80-alpha.5", - "@budibase/client": "^1.0.80-alpha.5", - "@budibase/frontend-core": "^1.0.80-alpha.5", - "@budibase/string-templates": "^1.0.80-alpha.5", + "@budibase/bbui": "^1.0.81-alpha.5", + "@budibase/client": "^1.0.81-alpha.5", + "@budibase/frontend-core": "^1.0.81-alpha.5", + "@budibase/string-templates": "^1.0.81-alpha.5", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/stores/backend/tables.js b/packages/builder/src/stores/backend/tables.js index f6d20037cb..c6362aa3b2 100644 --- a/packages/builder/src/stores/backend/tables.js +++ b/packages/builder/src/stores/backend/tables.js @@ -14,6 +14,7 @@ export function createTablesStore() { ...state, list: tables, })) + return tables } async function select(table) { diff --git a/packages/cli/package.json b/packages/cli/package.json index 2264689e74..0d73e36353 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "1.0.80-alpha.5", + "version": "1.0.81-alpha.5", "description": "Budibase CLI, for developers, self hosting and migrations.", "main": "src/index.js", "bin": { diff --git a/packages/client/package.json b/packages/client/package.json index ccd67be70b..ca5b46208e 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "1.0.80-alpha.5", + "version": "1.0.81-alpha.5", "license": "MPL-2.0", "module": "dist/budibase-client.js", "main": "dist/budibase-client.js", @@ -19,9 +19,9 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/bbui": "^1.0.80-alpha.5", - "@budibase/frontend-core": "^1.0.80-alpha.5", - "@budibase/string-templates": "^1.0.80-alpha.5", + "@budibase/bbui": "^1.0.81-alpha.5", + "@budibase/frontend-core": "^1.0.81-alpha.5", + "@budibase/string-templates": "^1.0.81-alpha.5", "@spectrum-css/button": "^3.0.3", "@spectrum-css/card": "^3.0.3", "@spectrum-css/divider": "^1.0.3", diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index 7b093f32fc..f58d3a7553 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "1.0.80-alpha.5", + "version": "1.0.81-alpha.5", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "^1.0.80-alpha.5", + "@budibase/bbui": "^1.0.81-alpha.5", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/server/package.json b/packages/server/package.json index 1f829d26c3..a248d3c1f3 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "1.0.80-alpha.5", + "version": "1.0.81-alpha.5", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -71,9 +71,9 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "^10.0.3", - "@budibase/backend-core": "^1.0.80-alpha.5", - "@budibase/client": "^1.0.80-alpha.5", - "@budibase/string-templates": "^1.0.80-alpha.5", + "@budibase/backend-core": "^1.0.81-alpha.5", + "@budibase/client": "^1.0.81-alpha.5", + "@budibase/string-templates": "^1.0.81-alpha.5", "@bull-board/api": "^3.7.0", "@bull-board/koa": "^3.7.0", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/server/specs/openapi.json b/packages/server/specs/openapi.json index 229c82230f..756846a501 100644 --- a/packages/server/specs/openapi.json +++ b/packages/server/specs/openapi.json @@ -503,6 +503,71 @@ "data" ] }, + "applicationSearch": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "The name of the app.", + "type": "string" + }, + "url": { + "description": "The URL by which the app is accessed, this must be URL encoded.", + "type": "string" + }, + "_id": { + "description": "The ID of the app.", + "type": "string" + }, + "status": { + "description": "The status of the app, stating it if is the development or published version.", + "type": "string", + "enum": [ + "development", + "published" + ] + }, + "createdAt": { + "description": "States when the app was created, will be constant. Stored in ISO format.", + "type": "string" + }, + "updatedAt": { + "description": "States the last time the app was updated - stored in ISO format.", + "type": "string" + }, + "version": { + "description": "States the version of the Budibase client this app is currently based on.", + "type": "string" + }, + "tenantId": { + "description": "In a multi-tenant environment this will state the tenant this app is within.", + "type": "string" + }, + "lockedBy": { + "description": "The user this app is currently being built by.", + "type": "object" + } + }, + "required": [ + "_id", + "name", + "url", + "status", + "createdAt", + "updatedAt", + "version" + ] + } + } + }, + "required": [ + "data" + ] + }, "row": { "description": "The row to be created/updated, based on the table schema.", "type": "object", @@ -980,6 +1045,221 @@ "data" ] }, + "tableSearch": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "description": "The table to be created/updated.", + "type": "object", + "required": [ + "name", + "schema", + "_id" + ], + "properties": { + "name": { + "description": "The name of the table.", + "type": "string" + }, + "primaryDisplay": { + "type": "string", + "description": "The name of the column which should be used in relationship tags when relating to this table." + }, + "schema": { + "type": "object", + "additionalProperties": { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "link" + ], + "description": "A relationship column." + }, + "constraints": { + "type": "object", + "description": "A constraint can be applied to the column which will be validated against when a row is saved.", + "properties": { + "type": { + "type": "string", + "enum": [ + "string", + "number", + "object", + "boolean" + ] + }, + "presence": { + "type": "boolean", + "description": "Defines whether the column is required or not." + } + } + }, + "name": { + "type": "string", + "description": "The name of the column." + }, + "autocolumn": { + "type": "boolean", + "description": "Defines whether the column is automatically generated." + }, + "fieldName": { + "type": "string", + "description": "The name of the column which a relationship column is related to in another table." + }, + "tableId": { + "type": "string", + "description": "The ID of the table which a relationship column is related to." + }, + "relationshipType": { + "type": "string", + "enum": [ + "one-to-many", + "many-to-one", + "many-to-many" + ], + "description": "Defines the type of relationship that this column will be used for." + }, + "through": { + "type": "string", + "description": "When using a SQL table that contains many to many relationships this defines the table the relationships are linked through." + }, + "foreignKey": { + "type": "string", + "description": "When using a SQL table that contains a one to many relationship this defines the foreign key." + }, + "throughFrom": { + "type": "string", + "description": "When using a SQL table that utilises a through table, this defines the primary key in the through table for this table." + }, + "throughTo": { + "type": "string", + "description": "When using a SQL table that utilises a through table, this defines the primary key in the through table for the related table." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "formula" + ], + "description": "A formula column." + }, + "constraints": { + "type": "object", + "description": "A constraint can be applied to the column which will be validated against when a row is saved.", + "properties": { + "type": { + "type": "string", + "enum": [ + "string", + "number", + "object", + "boolean" + ] + }, + "presence": { + "type": "boolean", + "description": "Defines whether the column is required or not." + } + } + }, + "name": { + "type": "string", + "description": "The name of the column." + }, + "autocolumn": { + "type": "boolean", + "description": "Defines whether the column is automatically generated." + }, + "formula": { + "type": "string", + "description": "Defines a Handlebars or JavaScript formula to use, note that Javascript formulas are expected to be provided in the base64 format." + }, + "formulaType": { + "type": "string", + "enum": [ + "static", + "dynamic" + ], + "description": "Defines whether this is a static or dynamic formula." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "string", + "longform", + "options", + "number", + "boolean", + "array", + "datetime", + "attachment", + "link", + "formula", + "auto", + "json", + "internal" + ], + "description": "Defines the type of the column, most explain themselves, a link column is a relationship." + }, + "constraints": { + "type": "object", + "description": "A constraint can be applied to the column which will be validated against when a row is saved.", + "properties": { + "type": { + "type": "string", + "enum": [ + "string", + "number", + "object", + "boolean" + ] + }, + "presence": { + "type": "boolean", + "description": "Defines whether the column is required or not." + } + } + }, + "name": { + "type": "string", + "description": "The name of the column." + }, + "autocolumn": { + "type": "boolean", + "description": "Defines whether the column is automatically generated." + } + } + } + ] + } + }, + "_id": { + "description": "The ID of the table.", + "type": "string" + } + } + } + } + }, + "required": [ + "data" + ] + }, "executeQuery": { "description": "The query body must contain the required parameters for the query, this depends on query type, setup and bindings.", "type": "object", @@ -1074,6 +1354,71 @@ "_id" ] }, + "querySearch": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_id": { + "description": "The ID of the query.", + "type": "string" + }, + "datasourceId": { + "description": "The ID of the data source the query belongs to.", + "type": "string" + }, + "parameters": { + "description": "The bindings which are required to perform this query.", + "type": "array", + "items": { + "type": "string" + } + }, + "fields": { + "description": "The fields that are used to perform this query, e.g. the sql statement", + "type": "object" + }, + "queryVerb": { + "description": "The verb that describes this query.", + "enum": [ + "create", + "read", + "update", + "delete" + ] + }, + "name": { + "description": "The name of the query.", + "type": "string" + }, + "schema": { + "description": "The schema of the data returned when the query is executed.", + "type": "object" + }, + "transformer": { + "description": "The JavaScript transformer function, applied after the query responds with data.", + "type": "string" + }, + "readable": { + "description": "Whether the query has readable data.", + "type": "boolean" + } + }, + "required": [ + "name", + "schema", + "_id" + ] + } + } + }, + "required": [ + "data" + ] + }, "user": { "type": "object", "properties": { @@ -1215,6 +1560,86 @@ "data" ] }, + "userSearch": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "email": { + "description": "The email address of the user, this must be unique.", + "type": "string" + }, + "password": { + "description": "The password of the user if using password based login - this will never be returned. This can be left out of subsequent requests (updates) and will be enriched back into the user structure.", + "type": "string" + }, + "status": { + "description": "The status of the user, if they are active.", + "type": "string", + "enum": [ + "active" + ] + }, + "firstName": { + "description": "The first name of the user", + "type": "string" + }, + "lastName": { + "description": "The last name of the user", + "type": "string" + }, + "forceResetPassword": { + "description": "If set to true forces the user to reset their password on first login.", + "type": "boolean" + }, + "builder": { + "description": "Describes if the user is a builder user or not.", + "type": "object", + "properties": { + "global": { + "description": "If set to true the user will be able to build any app in the system.", + "type": "boolean" + } + } + }, + "admin": { + "description": "Describes if the user is an admin user or not.", + "type": "object", + "properties": { + "global": { + "description": "If set to true the user will be able to administrate the system.", + "type": "boolean" + } + } + }, + "roles": { + "description": "Contains the roles of the user per app (assuming they are not a builder user).", + "type": "object", + "additionalProperties": { + "type": "string", + "description": "A map of app ID (production app ID, minus the _dev component) to a role ID, e.g. ADMIN." + } + }, + "_id": { + "description": "The ID of the user.", + "type": "string" + } + }, + "required": [ + "email", + "roles", + "_id" + ] + } + } + }, + "required": [ + "data" + ] + }, "nameSearch": { "type": "object", "properties": { @@ -1399,18 +1824,7 @@ "content": { "application/json": { "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/application" - } - } - } + "$ref": "#/components/schemas/applicationSearch" }, "examples": { "applications": { @@ -1498,18 +1912,7 @@ "content": { "application/json": { "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/query" - } - } - } + "$ref": "#/components/schemas/querySearch" }, "examples": { "queries": { @@ -2025,18 +2428,7 @@ "content": { "application/json": { "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/table" - } - } - } + "$ref": "#/components/schemas/tableSearch" }, "examples": { "tables": { @@ -2203,18 +2595,7 @@ "content": { "application/json": { "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/user" - } - } - } + "$ref": "#/components/schemas/userSearch" }, "examples": { "users": { diff --git a/packages/server/specs/openapi.yaml b/packages/server/specs/openapi.yaml index 6dd1607ae8..85441a6938 100644 --- a/packages/server/specs/openapi.yaml +++ b/packages/server/specs/openapi.yaml @@ -360,6 +360,58 @@ components: - version required: - data + applicationSearch: + type: object + properties: + data: + type: array + items: + type: object + properties: + name: + description: The name of the app. + type: string + url: + description: The URL by which the app is accessed, this must be URL encoded. + type: string + _id: + description: The ID of the app. + type: string + status: + description: The status of the app, stating it if is the development or + published version. + type: string + enum: + - development + - published + createdAt: + description: States when the app was created, will be constant. Stored in ISO + format. + type: string + updatedAt: + description: States the last time the app was updated - stored in ISO format. + type: string + version: + description: States the version of the Budibase client this app is currently + based on. + type: string + tenantId: + description: In a multi-tenant environment this will state the tenant this app + is within. + type: string + lockedBy: + description: The user this app is currently being built by. + type: object + required: + - _id + - name + - url + - status + - createdAt + - updatedAt + - version + required: + - data row: description: The row to be created/updated, based on the table schema. type: object @@ -730,6 +782,175 @@ components: type: string required: - data + tableSearch: + type: object + properties: + data: + type: array + items: + description: The table to be created/updated. + type: object + required: + - name + - schema + - _id + properties: + name: + description: The name of the table. + type: string + primaryDisplay: + type: string + description: The name of the column which should be used in relationship tags + when relating to this table. + schema: + type: object + additionalProperties: + oneOf: + - type: object + properties: + type: + type: string + enum: + - link + description: A relationship column. + constraints: + type: object + description: A constraint can be applied to the column which will be validated + against when a row is saved. + properties: + type: + type: string + enum: + - string + - number + - object + - boolean + presence: + type: boolean + description: Defines whether the column is required or not. + name: + type: string + description: The name of the column. + autocolumn: + type: boolean + description: Defines whether the column is automatically generated. + fieldName: + type: string + description: The name of the column which a relationship column is related to in + another table. + tableId: + type: string + description: The ID of the table which a relationship column is related to. + relationshipType: + type: string + enum: + - one-to-many + - many-to-one + - many-to-many + description: Defines the type of relationship that this column will be used for. + through: + type: string + description: When using a SQL table that contains many to many relationships + this defines the table the relationships are linked + through. + foreignKey: + type: string + description: When using a SQL table that contains a one to many relationship + this defines the foreign key. + throughFrom: + type: string + description: When using a SQL table that utilises a through table, this defines + the primary key in the through table for this table. + throughTo: + type: string + description: When using a SQL table that utilises a through table, this defines + the primary key in the through table for the related + table. + - type: object + properties: + type: + type: string + enum: + - formula + description: A formula column. + constraints: + type: object + description: A constraint can be applied to the column which will be validated + against when a row is saved. + properties: + type: + type: string + enum: + - string + - number + - object + - boolean + presence: + type: boolean + description: Defines whether the column is required or not. + name: + type: string + description: The name of the column. + autocolumn: + type: boolean + description: Defines whether the column is automatically generated. + formula: + type: string + description: Defines a Handlebars or JavaScript formula to use, note that + Javascript formulas are expected to be provided in + the base64 format. + formulaType: + type: string + enum: + - static + - dynamic + description: Defines whether this is a static or dynamic formula. + - type: object + properties: + type: + type: string + enum: + - string + - longform + - options + - number + - boolean + - array + - datetime + - attachment + - link + - formula + - auto + - json + - internal + description: Defines the type of the column, most explain themselves, a link + column is a relationship. + constraints: + type: object + description: A constraint can be applied to the column which will be validated + against when a row is saved. + properties: + type: + type: string + enum: + - string + - number + - object + - boolean + presence: + type: boolean + description: Defines whether the column is required or not. + name: + type: string + description: The name of the column. + autocolumn: + type: boolean + description: Defines whether the column is automatically generated. + _id: + description: The ID of the table. + type: string + required: + - data executeQuery: description: The query body must contain the required parameters for the query, this depends on query type, setup and bindings. @@ -803,6 +1024,55 @@ components: - name - schema - _id + querySearch: + type: object + properties: + data: + type: array + items: + type: object + properties: + _id: + description: The ID of the query. + type: string + datasourceId: + description: The ID of the data source the query belongs to. + type: string + parameters: + description: The bindings which are required to perform this query. + type: array + items: + type: string + fields: + description: The fields that are used to perform this query, e.g. the sql + statement + type: object + queryVerb: + description: The verb that describes this query. + enum: + - create + - read + - update + - delete + name: + description: The name of the query. + type: string + schema: + description: The schema of the data returned when the query is executed. + type: object + transformer: + description: The JavaScript transformer function, applied after the query + responds with data. + type: string + readable: + description: Whether the query has readable data. + type: boolean + required: + - name + - schema + - _id + required: + - data user: type: object properties: @@ -916,6 +1186,69 @@ components: - _id required: - data + userSearch: + type: object + properties: + data: + type: array + items: + type: object + properties: + email: + description: The email address of the user, this must be unique. + type: string + password: + description: The password of the user if using password based login - this will + never be returned. This can be left out of subsequent requests + (updates) and will be enriched back into the user structure. + type: string + status: + description: The status of the user, if they are active. + type: string + enum: + - active + firstName: + description: The first name of the user + type: string + lastName: + description: The last name of the user + type: string + forceResetPassword: + description: If set to true forces the user to reset their password on first + login. + type: boolean + builder: + description: Describes if the user is a builder user or not. + type: object + properties: + global: + description: If set to true the user will be able to build any app in the + system. + type: boolean + admin: + description: Describes if the user is an admin user or not. + type: object + properties: + global: + description: If set to true the user will be able to administrate the system. + type: boolean + roles: + description: Contains the roles of the user per app (assuming they are not a + builder user). + type: object + additionalProperties: + type: string + description: A map of app ID (production app ID, minus the _dev component) to a + role ID, e.g. ADMIN. + _id: + description: The ID of the user. + type: string + required: + - email + - roles + - _id + required: + - data nameSearch: type: object properties: @@ -1028,14 +1361,7 @@ paths: content: application/json: schema: - type: object - required: - - data - properties: - data: - type: array - items: - $ref: "#/components/schemas/application" + $ref: "#/components/schemas/applicationSearch" examples: applications: $ref: "#/components/examples/applications" @@ -1087,14 +1413,7 @@ paths: content: application/json: schema: - type: object - required: - - data - properties: - data: - type: array - items: - $ref: "#/components/schemas/query" + $ref: "#/components/schemas/querySearch" examples: queries: $ref: "#/components/examples/queries" @@ -1419,14 +1738,7 @@ paths: content: application/json: schema: - type: object - required: - - data - properties: - data: - type: array - items: - $ref: "#/components/schemas/table" + $ref: "#/components/schemas/tableSearch" examples: tables: $ref: "#/components/examples/tables" @@ -1524,14 +1836,7 @@ paths: content: application/json: schema: - type: object - required: - - data - properties: - data: - type: array - items: - $ref: "#/components/schemas/user" + $ref: "#/components/schemas/userSearch" examples: users: $ref: "#/components/examples/users" diff --git a/packages/server/specs/resources/application.js b/packages/server/specs/resources/application.js index e7688cab28..7129ca1535 100644 --- a/packages/server/specs/resources/application.js +++ b/packages/server/specs/resources/application.js @@ -98,4 +98,10 @@ module.exports = new Resource() applicationOutput: object({ data: applicationOutputSchema, }), + applicationSearch: object({ + data: { + type: "array", + items: applicationOutputSchema, + }, + }), }) diff --git a/packages/server/specs/resources/query.js b/packages/server/specs/resources/query.js index 46498ddd27..df532c9a3a 100644 --- a/packages/server/specs/resources/query.js +++ b/packages/server/specs/resources/query.js @@ -186,4 +186,10 @@ module.exports = new Resource() executeQuery: executeQuerySchema, executeQueryOutput: executeQueryOutputSchema, query: querySchema, + querySearch: object({ + data: { + type: "array", + items: querySchema, + }, + }), }) diff --git a/packages/server/specs/resources/table.js b/packages/server/specs/resources/table.js index 03d07530ee..523a3a9dfd 100644 --- a/packages/server/specs/resources/table.js +++ b/packages/server/specs/resources/table.js @@ -188,4 +188,10 @@ module.exports = new Resource() tableOutput: object({ data: tableOutputSchema, }), + tableSearch: object({ + data: { + type: "array", + items: tableOutputSchema, + }, + }), }) diff --git a/packages/server/specs/resources/user.js b/packages/server/specs/resources/user.js index d1b539c44c..8fb505dfb5 100644 --- a/packages/server/specs/resources/user.js +++ b/packages/server/specs/resources/user.js @@ -123,4 +123,10 @@ module.exports = new Resource() userOutput: object({ data: userOutputSchema, }), + userSearch: object({ + data: { + type: "array", + items: userOutputSchema, + }, + }), }) diff --git a/packages/server/src/api/controllers/public/rows.ts b/packages/server/src/api/controllers/public/rows.ts index e73bcf9b49..4a3b255a36 100644 --- a/packages/server/src/api/controllers/public/rows.ts +++ b/packages/server/src/api/controllers/public/rows.ts @@ -1,6 +1,7 @@ import { default as rowController } from "../row" import { addRev } from "./utils" import { Row } from "../../../definitions/common" +import { convertBookmark } from "../../../utilities" // makes sure that the user doesn't need to pass in the type, tableId or _id params for // the call to be correct @@ -30,7 +31,7 @@ export async function search(ctx: any, next: any) { sort: sort.column, sortType: sort.type, sortOrder: sort.order, - bookmark, + bookmark: convertBookmark(bookmark), paginate, limit, query, diff --git a/packages/server/src/api/controllers/row/external.js b/packages/server/src/api/controllers/row/external.js index b7c7a2bc6e..aebcfce724 100644 --- a/packages/server/src/api/controllers/row/external.js +++ b/packages/server/src/api/controllers/row/external.js @@ -33,11 +33,11 @@ exports.handleRequest = handleRequest exports.patch = async ctx => { const inputs = ctx.request.body const tableId = ctx.params.tableId - const id = breakRowIdField(inputs._id) + const id = inputs._id // don't save the ID to db delete inputs._id return handleRequest(DataSourceOperation.UPDATE, tableId, { - id, + id: breakRowIdField(id), row: inputs, }) } @@ -67,7 +67,7 @@ exports.find = async ctx => { const id = ctx.params.rowId const tableId = ctx.params.tableId const response = await handleRequest(DataSourceOperation.READ, tableId, { - id, + id: breakRowIdField(id), }) return response ? response[0] : response } @@ -76,7 +76,7 @@ exports.destroy = async ctx => { const tableId = ctx.params.tableId const id = ctx.request.body._id const { row } = await handleRequest(DataSourceOperation.DELETE, tableId, { - id, + id: breakRowIdField(id), }) return { response: { ok: true }, row } } diff --git a/packages/server/src/api/routes/public/applications.ts b/packages/server/src/api/routes/public/applications.ts index 34225ced1a..3ce45627ad 100644 --- a/packages/server/src/api/routes/public/applications.ts +++ b/packages/server/src/api/routes/public/applications.ts @@ -135,14 +135,7 @@ read.push(new Endpoint("get", "/applications/:appId", controller.read)) * content: * application/json: * schema: - * type: object - * required: - * - data - * properties: - * data: - * type: array - * items: - * $ref: '#/components/schemas/application' + * $ref: '#/components/schemas/applicationSearch' * examples: * applications: * $ref: '#/components/examples/applications' diff --git a/packages/server/src/api/routes/public/queries.ts b/packages/server/src/api/routes/public/queries.ts index 0a480f7a43..9e5d73714e 100644 --- a/packages/server/src/api/routes/public/queries.ts +++ b/packages/server/src/api/routes/public/queries.ts @@ -60,14 +60,7 @@ write.push(new Endpoint("post", "/queries/:queryId", controller.execute)) * content: * application/json: * schema: - * type: object - * required: - * - data - * properties: - * data: - * type: array - * items: - * $ref: '#/components/schemas/query' + * $ref: '#/components/schemas/querySearch' * examples: * queries: * $ref: '#/components/examples/queries' diff --git a/packages/server/src/api/routes/public/tables.ts b/packages/server/src/api/routes/public/tables.ts index 67ded72e4c..b57425e08f 100644 --- a/packages/server/src/api/routes/public/tables.ts +++ b/packages/server/src/api/routes/public/tables.ts @@ -148,14 +148,7 @@ read.push(new Endpoint("get", "/tables/:tableId", controller.read)) * content: * application/json: * schema: - * type: object - * required: - * - data - * properties: - * data: - * type: array - * items: - * $ref: '#/components/schemas/table' + * $ref: '#/components/schemas/tableSearch' * examples: * tables: * $ref: '#/components/examples/tables' diff --git a/packages/server/src/api/routes/public/users.ts b/packages/server/src/api/routes/public/users.ts index a299c1f53f..06e17fba42 100644 --- a/packages/server/src/api/routes/public/users.ts +++ b/packages/server/src/api/routes/public/users.ts @@ -123,14 +123,7 @@ read.push(new Endpoint("get", "/users/:userId", controller.read)) * content: * application/json: * schema: - * type: object - * required: - * - data - * properties: - * data: - * type: array - * items: - * $ref: '#/components/schemas/user' + * $ref: '#/components/schemas/userSearch' * examples: * users: * $ref: '#/components/examples/users' diff --git a/packages/server/src/definitions/openapi.ts b/packages/server/src/definitions/openapi.ts index 71a9298040..4f4ad45fc6 100644 --- a/packages/server/src/definitions/openapi.ts +++ b/packages/server/src/definitions/openapi.ts @@ -95,9 +95,7 @@ export interface paths { /** Returns the applications that were found based on the search parameters. */ 200: { content: { - "application/json": { - data: components["schemas"]["application"][] - } + "application/json": components["schemas"]["applicationSearch"] } } } @@ -149,9 +147,7 @@ export interface paths { /** Returns the queries found based on the search parameters. */ 200: { content: { - "application/json": { - data: components["schemas"]["query"][] - } + "application/json": components["schemas"]["querySearch"] } } } @@ -449,9 +445,7 @@ export interface paths { /** Returns the found tables, based on the search parameters. */ 200: { content: { - "application/json": { - data: components["schemas"]["table"][] - } + "application/json": components["schemas"]["tableSearch"] } } } @@ -541,9 +535,7 @@ export interface paths { /** Returns the found users based on search parameters. */ 200: { content: { - "application/json": { - data: components["schemas"]["user"][] - } + "application/json": components["schemas"]["userSearch"] } } } @@ -589,6 +581,31 @@ export interface components { lockedBy?: { [key: string]: unknown } } } + applicationSearch: { + data: { + /** @description The name of the app. */ + name: string + /** @description The URL by which the app is accessed, this must be URL encoded. */ + url: string + /** @description The ID of the app. */ + _id: string + /** + * @description The status of the app, stating it if is the development or published version. + * @enum {string} + */ + status: "development" | "published" + /** @description States when the app was created, will be constant. Stored in ISO format. */ + createdAt: string + /** @description States the last time the app was updated - stored in ISO format. */ + updatedAt: string + /** @description States the version of the Budibase client this app is currently based on. */ + version: string + /** @description In a multi-tenant environment this will state the tenant this app is within. */ + tenantId?: string + /** @description The user this app is currently being built by. */ + lockedBy?: { [key: string]: unknown } + }[] + } /** @description The row to be created/updated, based on the table schema. */ row: { [key: string]: unknown } searchOutput: { @@ -817,6 +834,113 @@ export interface components { _id: string } } + tableSearch: { + data: { + /** @description The name of the table. */ + name: string + /** @description The name of the column which should be used in relationship tags when relating to this table. */ + primaryDisplay?: string + schema: { + [key: string]: + | { + /** + * @description A relationship column. + * @enum {string} + */ + type?: "link" + /** @description A constraint can be applied to the column which will be validated against when a row is saved. */ + constraints?: { + /** @enum {string} */ + type?: "string" | "number" | "object" | "boolean" + /** @description Defines whether the column is required or not. */ + presence?: boolean + } + /** @description The name of the column. */ + name?: string + /** @description Defines whether the column is automatically generated. */ + autocolumn?: boolean + /** @description The name of the column which a relationship column is related to in another table. */ + fieldName?: string + /** @description The ID of the table which a relationship column is related to. */ + tableId?: string + /** + * @description Defines the type of relationship that this column will be used for. + * @enum {string} + */ + relationshipType?: + | "one-to-many" + | "many-to-one" + | "many-to-many" + /** @description When using a SQL table that contains many to many relationships this defines the table the relationships are linked through. */ + through?: string + /** @description When using a SQL table that contains a one to many relationship this defines the foreign key. */ + foreignKey?: string + /** @description When using a SQL table that utilises a through table, this defines the primary key in the through table for this table. */ + throughFrom?: string + /** @description When using a SQL table that utilises a through table, this defines the primary key in the through table for the related table. */ + throughTo?: string + } + | { + /** + * @description A formula column. + * @enum {string} + */ + type?: "formula" + /** @description A constraint can be applied to the column which will be validated against when a row is saved. */ + constraints?: { + /** @enum {string} */ + type?: "string" | "number" | "object" | "boolean" + /** @description Defines whether the column is required or not. */ + presence?: boolean + } + /** @description The name of the column. */ + name?: string + /** @description Defines whether the column is automatically generated. */ + autocolumn?: boolean + /** @description Defines a Handlebars or JavaScript formula to use, note that Javascript formulas are expected to be provided in the base64 format. */ + formula?: string + /** + * @description Defines whether this is a static or dynamic formula. + * @enum {string} + */ + formulaType?: "static" | "dynamic" + } + | { + /** + * @description Defines the type of the column, most explain themselves, a link column is a relationship. + * @enum {string} + */ + type?: + | "string" + | "longform" + | "options" + | "number" + | "boolean" + | "array" + | "datetime" + | "attachment" + | "link" + | "formula" + | "auto" + | "json" + | "internal" + /** @description A constraint can be applied to the column which will be validated against when a row is saved. */ + constraints?: { + /** @enum {string} */ + type?: "string" | "number" | "object" | "boolean" + /** @description Defines whether the column is required or not. */ + presence?: boolean + } + /** @description The name of the column. */ + name?: string + /** @description Defines whether the column is automatically generated. */ + autocolumn?: boolean + } + } + /** @description The ID of the table. */ + _id: string + }[] + } /** @description The query body must contain the required parameters for the query, this depends on query type, setup and bindings. */ executeQuery: { [key: string]: unknown } executeQueryOutput: { @@ -855,6 +979,31 @@ export interface components { /** @description Whether the query has readable data. */ readable?: boolean } + querySearch: { + data: { + /** @description The ID of the query. */ + _id: string + /** @description The ID of the data source the query belongs to. */ + datasourceId?: string + /** @description The bindings which are required to perform this query. */ + parameters?: string[] + /** @description The fields that are used to perform this query, e.g. the sql statement */ + fields?: { [key: string]: unknown } + /** + * @description The verb that describes this query. + * @enum {undefined} + */ + queryVerb?: "create" | "read" | "update" | "delete" + /** @description The name of the query. */ + name: string + /** @description The schema of the data returned when the query is executed. */ + schema: { [key: string]: unknown } + /** @description The JavaScript transformer function, applied after the query responds with data. */ + transformer?: string + /** @description Whether the query has readable data. */ + readable?: boolean + }[] + } user: { /** @description The email address of the user, this must be unique. */ email: string @@ -917,6 +1066,39 @@ export interface components { _id: string } } + userSearch: { + data: { + /** @description The email address of the user, this must be unique. */ + email: string + /** @description The password of the user if using password based login - this will never be returned. This can be left out of subsequent requests (updates) and will be enriched back into the user structure. */ + password?: string + /** + * @description The status of the user, if they are active. + * @enum {string} + */ + status?: "active" + /** @description The first name of the user */ + firstName?: string + /** @description The last name of the user */ + lastName?: string + /** @description If set to true forces the user to reset their password on first login. */ + forceResetPassword?: boolean + /** @description Describes if the user is a builder user or not. */ + builder?: { + /** @description If set to true the user will be able to build any app in the system. */ + global?: boolean + } + /** @description Describes if the user is an admin user or not. */ + admin?: { + /** @description If set to true the user will be able to administrate the system. */ + global?: boolean + } + /** @description Contains the roles of the user per app (assuming they are not a builder user). */ + roles: { [key: string]: string } + /** @description The ID of the user. */ + _id: string + }[] + } nameSearch: { /** @description The name to be used when searching - this will be used in a case insensitive starts with match. */ name: string diff --git a/packages/server/src/utilities/index.js b/packages/server/src/utilities/index.js index d1e277541a..221c2ff18b 100644 --- a/packages/server/src/utilities/index.js +++ b/packages/server/src/utilities/index.js @@ -151,3 +151,11 @@ exports.formatBytes = bytes => { } return `${size.toFixed(size < 10 && unit > 0 ? 1 : 0)}${units[unit]}` } + +exports.convertBookmark = bookmark => { + const IS_NUMBER = /^\d+\.?\d*$/ + if (typeof bookmark === "string" && bookmark.match(IS_NUMBER)) { + return parseFloat(bookmark) + } + return bookmark +} diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index f4a6d28fec..78b80e62f3 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "1.0.80-alpha.5", + "version": "1.0.81-alpha.5", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", diff --git a/packages/worker/package.json b/packages/worker/package.json index 5130f310e7..a575a2c696 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "1.0.80-alpha.5", + "version": "1.0.81-alpha.5", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -34,8 +34,8 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "^1.0.80-alpha.5", - "@budibase/string-templates": "^1.0.80-alpha.5", + "@budibase/backend-core": "^1.0.81-alpha.5", + "@budibase/string-templates": "^1.0.81-alpha.5", "@koa/router": "^8.0.0", "@sentry/node": "^6.0.0", "@techpass/passport-openidconnect": "^0.3.0",