Merge pull request #9828 from Budibase/fix/9778

Fix for operationId in OpenAPI specs
This commit is contained in:
Michael Drury 2023-03-01 13:09:16 +00:00 committed by GitHub
commit 4abb2801f0
23 changed files with 650 additions and 235 deletions

View File

@ -25,7 +25,7 @@
"dev:stack:down": "node scripts/dev/manage.js down",
"dev:stack:nuke": "node scripts/dev/manage.js nuke",
"dev:builder": "yarn run dev:stack:up && nodemon",
"specs": "node specs/generate.js && openapi-typescript specs/openapi.yaml --output src/definitions/openapi.ts",
"specs": "ts-node specs/generate.ts && openapi-typescript specs/openapi.yaml --output src/definitions/openapi.ts",
"initialise": "node scripts/initialise.js",
"env:multi:enable": "node scripts/multiTenancy.js enable",
"env:multi:disable": "node scripts/multiTenancy.js disable",

View File

@ -1,9 +1,9 @@
import { join } from "path"
import { writeFileSync } from "fs"
import { examples, schemas } from "./resources"
import * as parameters from "./parameters"
import * as security from "./security"
const swaggerJsdoc = require("swagger-jsdoc")
const { join } = require("path")
const { writeFileSync } = require("fs")
const { examples, schemas } = require("./resources")
const parameters = require("./parameters")
const security = require("./security")
const VARIABLES = {}
@ -60,7 +60,7 @@ const options = {
apis: [join(__dirname, "..", "src", "api", "routes", "public", "*.ts")],
}
function writeFile(output, filename) {
function writeFile(output: any, filename: string) {
try {
const path = join(__dirname, filename)
let spec = output
@ -79,7 +79,7 @@ function writeFile(output, filename) {
}
}
function run() {
export function run() {
const outputJSON = swaggerJsdoc(options)
options.format = ".yaml"
const outputYAML = swaggerJsdoc(options)
@ -90,5 +90,3 @@ function run() {
if (require.main === module) {
run()
}
module.exports = run

View File

@ -1829,7 +1829,7 @@
"paths": {
"/applications": {
"post": {
"operationId": "create",
"operationId": "appCreate",
"summary": "Create an application",
"tags": [
"applications"
@ -1870,7 +1870,7 @@
},
"/applications/{appId}": {
"put": {
"operationId": "update",
"operationId": "appUpdate",
"summary": "Update an application",
"tags": [
"applications"
@ -1909,7 +1909,7 @@
}
},
"delete": {
"operationId": "destroy",
"operationId": "appDestroy",
"summary": "Delete an application",
"tags": [
"applications"
@ -1938,7 +1938,7 @@
}
},
"get": {
"operationId": "getById",
"operationId": "appGetById",
"summary": "Retrieve an application",
"tags": [
"applications"
@ -1969,7 +1969,7 @@
},
"/applications/{appId}/unpublish": {
"post": {
"operationId": "unpublish",
"operationId": "appUnpublish",
"summary": "Unpublish an application",
"tags": [
"applications"
@ -1988,7 +1988,7 @@
},
"/applications/{appId}/publish": {
"post": {
"operationId": "publish",
"operationId": "appPublish",
"summary": "Unpublish an application",
"tags": [
"applications"
@ -2019,7 +2019,7 @@
},
"/applications/search": {
"post": {
"operationId": "search",
"operationId": "appSearch",
"summary": "Search for applications",
"description": "Based on application properties (currently only name) search for applications.",
"tags": [
@ -2056,7 +2056,7 @@
},
"/queries/{queryId}": {
"post": {
"operationId": "execute",
"operationId": "queryExecute",
"summary": "Execute a query",
"description": "Queries which have been created within a Budibase app can be executed using this,",
"tags": [
@ -2104,7 +2104,7 @@
},
"/queries/search": {
"post": {
"operationId": "search",
"operationId": "querySearch",
"summary": "Search for queries",
"description": "Based on query properties (currently only name) search for queries.",
"tags": [
@ -2146,7 +2146,7 @@
},
"/tables/{tableId}/rows": {
"post": {
"operationId": "create",
"operationId": "rowCreate",
"summary": "Create a row",
"description": "Creates a row within the specified table.",
"tags": [
@ -2196,7 +2196,7 @@
},
"/tables/{tableId}/rows/{rowId}": {
"put": {
"operationId": "update",
"operationId": "rowUpdate",
"summary": "Update a row",
"description": "Updates a row within the specified table.",
"tags": [
@ -2247,7 +2247,7 @@
}
},
"delete": {
"operationId": "destroy",
"operationId": "rowDestroy",
"summary": "Delete a row",
"description": "Deletes a row within the specified table.",
"tags": [
@ -2283,7 +2283,7 @@
}
},
"get": {
"operationId": "getById",
"operationId": "rowGetById",
"summary": "Retrieve a row",
"description": "This gets a single row, it will be enriched with the full related rows, rather than the squashed \"primaryDisplay\" format returned by the search endpoint.",
"tags": [
@ -2321,7 +2321,7 @@
},
"/tables/{tableId}/rows/search": {
"post": {
"operationId": "search",
"operationId": "rowSearch",
"summary": "Search for rows",
"tags": [
"rows"
@ -2365,7 +2365,7 @@
},
"/tables": {
"post": {
"operationId": "create",
"operationId": "tableCreate",
"summary": "Create a table",
"description": "Create a table, this could be internal or external.",
"tags": [
@ -2411,7 +2411,7 @@
},
"/tables/{tableId}": {
"put": {
"operationId": "update",
"operationId": "tableUpdate",
"summary": "Update a table",
"description": "Update a table, this could be internal or external.",
"tags": [
@ -2458,7 +2458,7 @@
}
},
"delete": {
"operationId": "destroy",
"operationId": "tableDestroy",
"summary": "Delete a table",
"description": "Delete a table, this could be internal or external.",
"tags": [
@ -2491,7 +2491,7 @@
}
},
"get": {
"operationId": "getById",
"operationId": "tableGetById",
"summary": "Retrieve a table",
"description": "Lookup a table, this could be internal or external.",
"tags": [
@ -2526,7 +2526,7 @@
},
"/tables/search": {
"post": {
"operationId": "search",
"operationId": "tableSearch",
"summary": "Search for tables",
"description": "Based on table properties (currently only name) search for tables. This could be an internal or an external table.",
"tags": [
@ -2568,7 +2568,7 @@
},
"/users": {
"post": {
"operationId": "create",
"operationId": "userCreate",
"summary": "Create a user",
"tags": [
"users"
@ -2604,7 +2604,7 @@
},
"/users/{userId}": {
"put": {
"operationId": "update",
"operationId": "userUpdate",
"summary": "Update a user",
"tags": [
"users"
@ -2643,7 +2643,7 @@
}
},
"delete": {
"operationId": "destroy",
"operationId": "userDestroy",
"summary": "Delete a user",
"tags": [
"users"
@ -2672,7 +2672,7 @@
}
},
"get": {
"operationId": "getById",
"operationId": "userGetById",
"summary": "Retrieve a user",
"tags": [
"users"
@ -2703,7 +2703,7 @@
},
"/users/search": {
"post": {
"operationId": "search",
"operationId": "userSearch",
"summary": "Search for users",
"description": "Based on user properties (currently only name) search for users.",
"tags": [

View File

@ -1397,7 +1397,7 @@ security:
paths:
/applications:
post:
operationId: create
operationId: appCreate
summary: Create an application
tags:
- applications
@ -1421,7 +1421,7 @@ paths:
$ref: "#/components/examples/application"
"/applications/{appId}":
put:
operationId: update
operationId: appUpdate
summary: Update an application
tags:
- applications
@ -1444,7 +1444,7 @@ paths:
application:
$ref: "#/components/examples/application"
delete:
operationId: destroy
operationId: appDestroy
summary: Delete an application
tags:
- applications
@ -1461,7 +1461,7 @@ paths:
application:
$ref: "#/components/examples/application"
get:
operationId: getById
operationId: appGetById
summary: Retrieve an application
tags:
- applications
@ -1479,7 +1479,7 @@ paths:
$ref: "#/components/examples/application"
"/applications/{appId}/unpublish":
post:
operationId: unpublish
operationId: appUnpublish
summary: Unpublish an application
tags:
- applications
@ -1490,7 +1490,7 @@ paths:
description: The app was published successfully.
"/applications/{appId}/publish":
post:
operationId: publish
operationId: appPublish
summary: Unpublish an application
tags:
- applications
@ -1508,7 +1508,7 @@ paths:
$ref: "#/components/examples/deploymentOutput"
/applications/search:
post:
operationId: search
operationId: appSearch
summary: Search for applications
description: Based on application properties (currently only name) search for
applications.
@ -1533,7 +1533,7 @@ paths:
$ref: "#/components/examples/applications"
"/queries/{queryId}":
post:
operationId: execute
operationId: queryExecute
summary: Execute a query
description: Queries which have been created within a Budibase app can be
executed using this,
@ -1562,7 +1562,7 @@ paths:
$ref: "#/components/examples/sqlResponse"
/queries/search:
post:
operationId: search
operationId: querySearch
summary: Search for queries
description: Based on query properties (currently only name) search for queries.
tags:
@ -1587,7 +1587,7 @@ paths:
$ref: "#/components/examples/queries"
"/tables/{tableId}/rows":
post:
operationId: create
operationId: rowCreate
summary: Create a row
description: Creates a row within the specified table.
tags:
@ -1618,7 +1618,7 @@ paths:
$ref: "#/components/examples/row"
"/tables/{tableId}/rows/{rowId}":
put:
operationId: update
operationId: rowUpdate
summary: Update a row
description: Updates a row within the specified table.
tags:
@ -1648,7 +1648,7 @@ paths:
row:
$ref: "#/components/examples/row"
delete:
operationId: destroy
operationId: rowDestroy
summary: Delete a row
description: Deletes a row within the specified table.
tags:
@ -1669,7 +1669,7 @@ paths:
row:
$ref: "#/components/examples/row"
get:
operationId: getById
operationId: rowGetById
summary: Retrieve a row
description: This gets a single row, it will be enriched with the full related
rows, rather than the squashed "primaryDisplay" format returned by the
@ -1692,7 +1692,7 @@ paths:
$ref: "#/components/examples/enrichedRow"
"/tables/{tableId}/rows/search":
post:
operationId: search
operationId: rowSearch
summary: Search for rows
tags:
- rows
@ -1718,7 +1718,7 @@ paths:
$ref: "#/components/examples/rows"
/tables:
post:
operationId: create
operationId: tableCreate
summary: Create a table
description: Create a table, this could be internal or external.
tags:
@ -1746,7 +1746,7 @@ paths:
$ref: "#/components/examples/table"
"/tables/{tableId}":
put:
operationId: update
operationId: tableUpdate
summary: Update a table
description: Update a table, this could be internal or external.
tags:
@ -1773,7 +1773,7 @@ paths:
table:
$ref: "#/components/examples/table"
delete:
operationId: destroy
operationId: tableDestroy
summary: Delete a table
description: Delete a table, this could be internal or external.
tags:
@ -1792,7 +1792,7 @@ paths:
table:
$ref: "#/components/examples/table"
get:
operationId: getById
operationId: tableGetById
summary: Retrieve a table
description: Lookup a table, this could be internal or external.
tags:
@ -1812,7 +1812,7 @@ paths:
$ref: "#/components/examples/table"
/tables/search:
post:
operationId: search
operationId: tableSearch
summary: Search for tables
description: Based on table properties (currently only name) search for tables.
This could be an internal or an external table.
@ -1838,7 +1838,7 @@ paths:
$ref: "#/components/examples/tables"
/users:
post:
operationId: create
operationId: userCreate
summary: Create a user
tags:
- users
@ -1860,7 +1860,7 @@ paths:
$ref: "#/components/examples/user"
"/users/{userId}":
put:
operationId: update
operationId: userUpdate
summary: Update a user
tags:
- users
@ -1883,7 +1883,7 @@ paths:
user:
$ref: "#/components/examples/user"
delete:
operationId: destroy
operationId: userDestroy
summary: Delete a user
tags:
- users
@ -1900,7 +1900,7 @@ paths:
user:
$ref: "#/components/examples/user"
get:
operationId: getById
operationId: userGetById
summary: Retrieve a user
tags:
- users
@ -1918,7 +1918,7 @@ paths:
$ref: "#/components/examples/user"
/users/search:
post:
operationId: search
operationId: userSearch
summary: Search for users
description: Based on user properties (currently only name) search for users.
tags:

View File

@ -1,4 +1,4 @@
exports.tableId = {
export const tableId = {
in: "path",
name: "tableId",
required: true,
@ -8,7 +8,7 @@ exports.tableId = {
},
}
exports.rowId = {
export const rowId = {
in: "path",
name: "rowId",
required: true,
@ -18,7 +18,7 @@ exports.rowId = {
},
}
exports.appId = {
export const appId = {
in: "header",
name: "x-budibase-app-id",
required: true,
@ -28,7 +28,7 @@ exports.appId = {
},
}
exports.appIdUrl = {
export const appIdUrl = {
in: "path",
name: "appId",
required: true,
@ -38,7 +38,7 @@ exports.appIdUrl = {
},
}
exports.queryId = {
export const queryId = {
in: "path",
name: "queryId",
required: true,
@ -48,7 +48,7 @@ exports.queryId = {
},
}
exports.userId = {
export const userId = {
in: "path",
name: "userId",
required: true,

View File

@ -1,6 +1,6 @@
const userResource = require("./user")
const { object } = require("./utils")
const Resource = require("./utils/Resource")
import userResource from "./user"
import { object } from "./utils"
import Resource from "./utils/Resource"
const application = {
_id: "app_metadata",
@ -96,7 +96,7 @@ const deploymentOutputSchema = object({
},
})
module.exports = new Resource()
export default new Resource()
.setExamples({
application: {
value: {

View File

@ -1,11 +1,11 @@
const application = require("./application")
const row = require("./row")
const table = require("./table")
const query = require("./query")
const user = require("./user")
const misc = require("./misc")
import application from "./application"
import row from "./row"
import table from "./table"
import query from "./query"
import user from "./user"
import misc from "./misc"
exports.examples = {
export const examples = {
...application.getExamples(),
...row.getExamples(),
...table.getExamples(),
@ -14,7 +14,7 @@ exports.examples = {
...misc.getExamples(),
}
exports.schemas = {
export const schemas = {
...application.getSchemas(),
...row.getSchemas(),
...table.getSchemas(),

View File

@ -1,7 +1,7 @@
const { object } = require("./utils")
const Resource = require("./utils/Resource")
import { object } from "./utils"
import Resource from "./utils/Resource"
module.exports = new Resource().setSchemas({
export default new Resource().setSchemas({
rowSearch: object(
{
query: {

View File

@ -1,6 +1,6 @@
const Resource = require("./utils/Resource")
const { object } = require("./utils")
const { BaseQueryVerbs } = require("../../src/constants")
import Resource from "./utils/Resource"
import { object } from "./utils"
import { BaseQueryVerbs } from "../../src/constants"
const query = {
_id: "query_datasource_plus_4d8be0c506b9465daf4bf84d890fdab6_454854487c574d45bc4029b1e153219e",
@ -189,7 +189,7 @@ const executeQueryOutputSchema = object(
{ required: ["data"] }
)
module.exports = new Resource()
export default new Resource()
.setExamples({
query: {
value: {

View File

@ -1,5 +1,5 @@
const { object } = require("./utils")
const Resource = require("./utils/Resource")
import { object } from "./utils"
import Resource from "./utils/Resource"
const baseRow = {
_id: "ro_ta_5b1649e42a5b41dea4ef7742a36a7a70_e6dc7e38cf1343b2b56760265201cda4",
@ -56,7 +56,6 @@ const rowSchema = {
const rowOutputSchema = {
...rowSchema,
properties: {
...rowSchema.properties,
_id: {
description: "The ID of the row.",
type: "string",
@ -93,7 +92,7 @@ const searchOutputSchema = {
},
}
module.exports = new Resource()
export default new Resource()
.setExamples({
inputRow: {
value: inputRow,

View File

@ -1,10 +1,10 @@
const {
import {
FieldTypes,
RelationshipTypes,
FormulaTypes,
} = require("../../src/constants")
const { object } = require("./utils")
const Resource = require("./utils/Resource")
} from "../../src/constants"
import { object } from "./utils"
import Resource from "./utils/Resource"
const table = {
_id: "ta_5b1649e42a5b41dea4ef7742a36a7a70",
@ -170,7 +170,7 @@ const tableOutputSchema = {
required: [...tableSchema.required, "_id"],
}
module.exports = new Resource()
export default new Resource()
.setExamples({
table: {
value: {

View File

@ -1,5 +1,5 @@
const { object } = require("./utils")
const Resource = require("./utils/Resource")
import { object } from "./utils"
import Resource from "./utils/Resource"
const user = {
_id: "us_693a73206518477283a8d5ae31103252",
@ -105,7 +105,7 @@ const userOutputSchema = {
required: [...userSchema.required, "_id"],
}
module.exports = new Resource()
export default new Resource()
.setExamples({
user: {
value: {

View File

@ -1,26 +0,0 @@
class Resource {
constructor() {
this.examples = {}
this.schemas = {}
}
setExamples(examples) {
this.examples = examples
return this
}
setSchemas(schemas) {
this.schemas = schemas
return this
}
getExamples() {
return this.examples
}
getSchemas() {
return this.schemas
}
}
module.exports = Resource

View File

@ -0,0 +1,39 @@
type Example = {
[key: string]: {
[key: string]: any
}
}
type Schema = {
[key: string]: {
[key: string]: any
}
}
export default class Resource {
examples: Example
schemas: Schema
constructor() {
this.examples = {}
this.schemas = {}
}
setExamples(examples: Example) {
this.examples = examples
return this
}
setSchemas(schemas: Schema) {
this.schemas = schemas
return this
}
getExamples() {
return this.examples
}
getSchemas() {
return this.schemas
}
}

View File

@ -1,4 +1,4 @@
exports.object = (props, opts) => {
export const object = (props: any, opts?: any) => {
const base = {
type: "object",
properties: props,

View File

@ -1,4 +1,4 @@
exports.ApiKeyAuth = {
export const ApiKeyAuth = {
type: "apiKey",
in: "header",
name: "x-budibase-api-key",

View File

@ -9,7 +9,7 @@ const read = [],
* @openapi
* /applications:
* post:
* operationId: create
* operationId: appCreate
* summary: Create an application
* tags:
* - applications
@ -42,7 +42,7 @@ write.push(
* @openapi
* /applications/{appId}:
* put:
* operationId: update
* operationId: appUpdate
* summary: Update an application
* tags:
* - applications
@ -75,7 +75,7 @@ write.push(
* @openapi
* /applications/{appId}:
* delete:
* operationId: destroy
* operationId: appDestroy
* summary: Delete an application
* tags:
* - applications
@ -98,7 +98,7 @@ write.push(new Endpoint("delete", "/applications/:appId", controller.destroy))
* @openapi
* /applications/{appId}/unpublish:
* post:
* operationId: unpublish
* operationId: appUnpublish
* summary: Unpublish an application
* tags:
* - applications
@ -116,7 +116,7 @@ write.push(
* @openapi
* /applications/{appId}/publish:
* post:
* operationId: publish
* operationId: appPublish
* summary: Unpublish an application
* tags:
* - applications
@ -141,7 +141,7 @@ write.push(
* @openapi
* /applications/{appId}:
* get:
* operationId: getById
* operationId: appGetById
* summary: Retrieve an application
* tags:
* - applications
@ -164,7 +164,7 @@ read.push(new Endpoint("get", "/applications/:appId", controller.read))
* @openapi
* /applications/search:
* post:
* operationId: search
* operationId: appSearch
* summary: Search for applications
* description: Based on application properties (currently only name) search for applications.
* tags:

View File

@ -9,7 +9,7 @@ const read = [],
* @openapi
* /queries/{queryId}:
* post:
* operationId: execute
* operationId: queryExecute
* summary: Execute a query
* description: Queries which have been created within a Budibase app can be executed using this,
* tags:
@ -43,7 +43,7 @@ write.push(new Endpoint("post", "/queries/:queryId", controller.execute))
* @openapi
* /queries/search:
* post:
* operationId: search
* operationId: querySearch
* summary: Search for queries
* description: Based on query properties (currently only name) search for queries.
* tags:

View File

@ -9,7 +9,7 @@ const read = [],
* @openapi
* /tables/{tableId}/rows:
* post:
* operationId: create
* operationId: rowCreate
* summary: Create a row
* description: Creates a row within the specified table.
* tags:
@ -44,7 +44,7 @@ write.push(new Endpoint("post", "/tables/:tableId/rows", controller.create))
* @openapi
* /tables/{tableId}/rows/{rowId}:
* put:
* operationId: update
* operationId: rowUpdate
* summary: Update a row
* description: Updates a row within the specified table.
* tags:
@ -81,7 +81,7 @@ write.push(
* @openapi
* /tables/{tableId}/rows/{rowId}:
* delete:
* operationId: destroy
* operationId: rowDestroy
* summary: Delete a row
* description: Deletes a row within the specified table.
* tags:
@ -109,7 +109,7 @@ write.push(
* @openapi
* /tables/{tableId}/rows/{rowId}:
* get:
* operationId: getById
* operationId: rowGetById
* summary: Retrieve a row
* description: This gets a single row, it will be enriched with the full related rows, rather than
* the squashed "primaryDisplay" format returned by the search endpoint.
@ -136,7 +136,7 @@ read.push(new Endpoint("get", "/tables/:tableId/rows/:rowId", controller.read))
* @openapi
* /tables/{tableId}/rows/search:
* post:
* operationId: search
* operationId: rowSearch
* summary: Search for rows
* tags:
* - rows

View File

@ -9,7 +9,7 @@ const read = [],
* @openapi
* /tables:
* post:
* operationId: create
* operationId: tableCreate
* summary: Create a table
* description: Create a table, this could be internal or external.
* tags:
@ -46,7 +46,7 @@ write.push(
* @openapi
* /tables/{tableId}:
* put:
* operationId: update
* operationId: tableUpdate
* summary: Update a table
* description: Update a table, this could be internal or external.
* tags:
@ -83,7 +83,7 @@ write.push(
* @openapi
* /tables/{tableId}:
* delete:
* operationId: destroy
* operationId: tableDestroy
* summary: Delete a table
* description: Delete a table, this could be internal or external.
* tags:
@ -108,7 +108,7 @@ write.push(new Endpoint("delete", "/tables/:tableId", controller.destroy))
* @openapi
* /tables/{tableId}:
* get:
* operationId: getById
* operationId: tableGetById
* summary: Retrieve a table
* description: Lookup a table, this could be internal or external.
* tags:
@ -133,7 +133,7 @@ read.push(new Endpoint("get", "/tables/:tableId", controller.read))
* @openapi
* /tables/search:
* post:
* operationId: search
* operationId: tableSearch
* summary: Search for tables
* description: Based on table properties (currently only name) search for tables. This could be
* an internal or an external table.

View File

@ -1,13 +1,14 @@
const jestOpenAPI = require("jest-openapi").default
const generateSchema = require("../../../../../specs/generate")
const setup = require("../../tests/utilities")
const { generateMakeRequest } = require("./utils")
import jestOpenAPI from "jest-openapi"
import { run as generateSchema } from "../../../../../specs/generate"
import * as setup from "../../tests/utilities"
import { generateMakeRequest } from "./utils"
import { Table, App, Row, User } from "@budibase/types"
const yamlPath = generateSchema()
jestOpenAPI(yamlPath)
jestOpenAPI(yamlPath!)
let config = setup.getConfig()
let apiKey, table, app, makeRequest
let apiKey: string, table: Table, app: App, makeRequest: any
beforeAll(async () => {
app = await config.init()
@ -25,19 +26,29 @@ describe("check the applications endpoints", () => {
})
it("should allow creating an application", async () => {
const res = await makeRequest("post", "/applications", {
name: "new App"
}, null)
const res = await makeRequest(
"post",
"/applications",
{
name: "new App",
},
null
)
expect(res).toSatisfyApiSpec()
})
it("should allow updating an application", async () => {
const app = config.getApp()
const appId = config.getAppId()
const res = await makeRequest("put", `/applications/${appId}`, {
...app,
name: "updated app name",
}, appId)
const res = await makeRequest(
"put",
`/applications/${appId}`,
{
...app,
name: "updated app name",
},
appId
)
expect(res).toSatisfyApiSpec()
})
@ -47,7 +58,10 @@ describe("check the applications endpoints", () => {
})
it("should allow deleting an application", async () => {
const res = await makeRequest("delete", `/applications/${config.getAppId()}`)
const res = await makeRequest(
"delete",
`/applications/${config.getAppId()}`
)
expect(res).toSatisfyApiSpec()
})
})
@ -68,8 +82,8 @@ describe("check the tables endpoints", () => {
column1: {
type: "string",
constraints: {},
}
}
},
},
})
expect(res).toSatisfyApiSpec()
})
@ -92,12 +106,11 @@ describe("check the tables endpoints", () => {
})
describe("check the rows endpoints", () => {
let row
let row: Row
it("should allow retrieving rows through search", async () => {
table = await config.updateTable()
const res = await makeRequest("post", `/tables/${table._id}/rows/search`, {
query: {
},
query: {},
})
expect(res).toSatisfyApiSpec()
})
@ -111,9 +124,13 @@ describe("check the rows endpoints", () => {
})
it("should allow updating a row", async () => {
const res = await makeRequest("put", `/tables/${table._id}/rows/${row._id}`, {
name: "test row updated",
})
const res = await makeRequest(
"put",
`/tables/${table._id}/rows/${row._id}`,
{
name: "test row updated",
}
)
expect(res).toSatisfyApiSpec()
})
@ -123,13 +140,16 @@ describe("check the rows endpoints", () => {
})
it("should allow deleting a row", async () => {
const res = await makeRequest("delete", `/tables/${table._id}/rows/${row._id}`)
const res = await makeRequest(
"delete",
`/tables/${table._id}/rows/${row._id}`
)
expect(res).toSatisfyApiSpec()
})
})
describe("check the users endpoints", () => {
let user
let user: User
it("should allow retrieving users through search", async () => {
user = await config.createUser()
const res = await makeRequest("post", "/users/search")
@ -163,4 +183,3 @@ describe("check the queries endpoints", () => {
expect(res).toSatisfyApiSpec()
})
})

View File

@ -9,7 +9,7 @@ const read = [],
* @openapi
* /users:
* post:
* operationId: create
* operationId: userCreate
* summary: Create a user
* tags:
* - users
@ -36,7 +36,7 @@ write.push(new Endpoint("post", "/users", controller.create))
* @openapi
* /users/{userId}:
* put:
* operationId: update
* operationId: userUpdate
* summary: Update a user
* tags:
* - users
@ -65,7 +65,7 @@ write.push(new Endpoint("put", "/users/:userId", controller.update))
* @openapi
* /users/{userId}:
* delete:
* operationId: destroy
* operationId: userDestroy
* summary: Delete a user
* tags:
* - users
@ -88,7 +88,7 @@ write.push(new Endpoint("delete", "/users/:userId", controller.destroy))
* @openapi
* /users/{userId}:
* get:
* operationId: getById
* operationId: userGetById
* summary: Retrieve a user
* tags:
* - users
@ -111,7 +111,7 @@ read.push(new Endpoint("get", "/users/:userId", controller.read))
* @openapi
* /users/search:
* post:
* operationId: search
* operationId: userSearch
* summary: Search for users
* description: Based on user properties (currently only name) search for users.
* tags:

View File

@ -5,67 +5,73 @@
export interface paths {
"/applications": {
post: operations["create"];
post: operations["appCreate"];
};
"/applications/{appId}": {
get: operations["getById"];
put: operations["update"];
delete: operations["destroy"];
get: operations["appGetById"];
put: operations["appUpdate"];
delete: operations["appDestroy"];
};
"/applications/{appId}/unpublish": {
post: operations["appUnpublish"];
};
"/applications/{appId}/publish": {
post: operations["appPublish"];
};
"/applications/search": {
/** Based on application properties (currently only name) search for applications. */
post: operations["search"];
post: operations["appSearch"];
};
"/queries/{queryId}": {
/** Queries which have been created within a Budibase app can be executed using this, */
post: operations["execute"];
post: operations["queryExecute"];
};
"/queries/search": {
/** Based on query properties (currently only name) search for queries. */
post: operations["search"];
post: operations["querySearch"];
};
"/tables/{tableId}/rows": {
/** Creates a row within the specified table. */
post: operations["create"];
post: operations["rowCreate"];
};
"/tables/{tableId}/rows/{rowId}": {
/** This gets a single row, it will be enriched with the full related rows, rather than the squashed "primaryDisplay" format returned by the search endpoint. */
get: operations["getById"];
get: operations["rowGetById"];
/** Updates a row within the specified table. */
put: operations["update"];
put: operations["rowUpdate"];
/** Deletes a row within the specified table. */
delete: operations["destroy"];
delete: operations["rowDestroy"];
};
"/tables/{tableId}/rows/search": {
post: operations["search"];
post: operations["rowSearch"];
};
"/tables": {
/** Create a table, this could be internal or external. */
post: operations["create"];
post: operations["tableCreate"];
};
"/tables/{tableId}": {
/** Lookup a table, this could be internal or external. */
get: operations["getById"];
get: operations["tableGetById"];
/** Update a table, this could be internal or external. */
put: operations["update"];
put: operations["tableUpdate"];
/** Delete a table, this could be internal or external. */
delete: operations["destroy"];
delete: operations["tableDestroy"];
};
"/tables/search": {
/** Based on table properties (currently only name) search for tables. This could be an internal or an external table. */
post: operations["search"];
post: operations["tableSearch"];
};
"/users": {
post: operations["create"];
post: operations["userCreate"];
};
"/users/{userId}": {
get: operations["getById"];
put: operations["update"];
delete: operations["destroy"];
get: operations["userGetById"];
put: operations["userUpdate"];
delete: operations["userDestroy"];
};
"/users/search": {
/** Based on user properties (currently only name) search for users. */
post: operations["search"];
post: operations["userSearch"];
};
}
@ -102,16 +108,6 @@ export interface components {
lockedBy?: { [key: string]: unknown };
};
};
deploymentOutput: {
data: {
/** @description The ID of the deployment. */
_id: string;
/** @description The status of the deployment. */
status: "SUCCESS" | "FAILURE";
/** @description The URL by which the published app is accessed. */
appUrl?: string;
}
};
applicationSearch: {
data: {
/** @description The name of the app. */
@ -137,6 +133,19 @@ export interface components {
lockedBy?: { [key: string]: unknown };
}[];
};
deploymentOutput: {
data: {
/** @description The ID of the app. */
_id: string;
/**
* @description Status of the deployment, whether it succeeded or failed
* @enum {string}
*/
status: "SUCCESS" | "FAILURE";
/** @description The URL of the published app */
appUrl: string;
};
};
/** @description The row to be created/updated, based on the table schema. */
row: { [key: string]: unknown };
searchOutput: {
@ -231,7 +240,6 @@ export interface components {
*/
type?:
| "string"
| "barcodeqr"
| "longform"
| "options"
| "number"
@ -243,7 +251,8 @@ export interface components {
| "formula"
| "auto"
| "json"
| "internal";
| "internal"
| "barcodeqr";
/** @description A constraint can be applied to the column which will be validated against when a row is saved. */
constraints?: {
/** @enum {string} */
@ -337,7 +346,6 @@ export interface components {
*/
type?:
| "string"
| "barcodeqr"
| "longform"
| "options"
| "number"
@ -349,7 +357,8 @@ export interface components {
| "formula"
| "auto"
| "json"
| "internal";
| "internal"
| "barcodeqr";
/** @description A constraint can be applied to the column which will be validated against when a row is saved. */
constraints?: {
/** @enum {string} */
@ -445,7 +454,6 @@ export interface components {
*/
type?:
| "string"
| "barcodeqr"
| "longform"
| "options"
| "number"
@ -457,7 +465,8 @@ export interface components {
| "formula"
| "auto"
| "json"
| "internal";
| "internal"
| "barcodeqr";
/** @description A constraint can be applied to the column which will be validated against when a row is saved. */
constraints?: {
/** @enum {string} */
@ -717,81 +726,115 @@ export interface components {
}
export interface operations {
create: {
appCreate: {
parameters: {
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the created user. */
/** Returns the created application. */
200: {
content: {
"application/json": components["schemas"]["userOutput"];
"application/json": components["schemas"]["applicationOutput"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["user"];
"application/json": components["schemas"]["application"];
};
};
};
getById: {
appGetById: {
parameters: {
path: {
/** The ID of the user which this request is targeting. */
userId: components["parameters"]["userId"];
/** The ID of the app which this request is targeting. */
appId: components["parameters"]["appIdUrl"];
};
};
responses: {
/** Returns the retrieved user. */
/** Returns the retrieved application. */
200: {
content: {
"application/json": components["schemas"]["userOutput"];
"application/json": components["schemas"]["applicationOutput"];
};
};
};
};
update: {
appUpdate: {
parameters: {
path: {
/** The ID of the user which this request is targeting. */
userId: components["parameters"]["userId"];
/** The ID of the app which this request is targeting. */
appId: components["parameters"]["appIdUrl"];
};
};
responses: {
/** Returns the updated user. */
/** Returns the updated application. */
200: {
content: {
"application/json": components["schemas"]["userOutput"];
"application/json": components["schemas"]["applicationOutput"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["user"];
"application/json": components["schemas"]["application"];
};
};
};
destroy: {
appDestroy: {
parameters: {
path: {
/** The ID of the user which this request is targeting. */
userId: components["parameters"]["userId"];
/** The ID of the app which this request is targeting. */
appId: components["parameters"]["appIdUrl"];
};
};
responses: {
/** Returns the deleted user. */
/** Returns the deleted application. */
200: {
content: {
"application/json": components["schemas"]["userOutput"];
"application/json": components["schemas"]["applicationOutput"];
};
};
};
};
/** Based on user properties (currently only name) search for users. */
search: {
appUnpublish: {
parameters: {
path: {
/** The ID of the app which this request is targeting. */
appId: components["parameters"]["appIdUrl"];
};
};
responses: {
/** Returns the found users based on search parameters. */
/** The app was published successfully. */
204: never;
};
};
appPublish: {
parameters: {
path: {
/** The ID of the app which this request is targeting. */
appId: components["parameters"]["appIdUrl"];
};
};
responses: {
/** Returns the deployment object. */
200: {
content: {
"application/json": components["schemas"]["userSearch"];
"application/json": components["schemas"]["deploymentOutput"];
};
};
};
};
/** Based on application properties (currently only name) search for applications. */
appSearch: {
responses: {
/** Returns the applications that were found based on the search parameters. */
200: {
content: {
"application/json": components["schemas"]["applicationSearch"];
};
};
};
@ -802,7 +845,7 @@ export interface operations {
};
};
/** Queries which have been created within a Budibase app can be executed using this, */
execute: {
queryExecute: {
parameters: {
path: {
/** The ID of the query which this request is targeting. */
@ -827,6 +870,349 @@ export interface operations {
};
};
};
/** Based on query properties (currently only name) search for queries. */
querySearch: {
parameters: {
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the queries found based on the search parameters. */
200: {
content: {
"application/json": components["schemas"]["querySearch"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["nameSearch"];
};
};
};
/** Creates a row within the specified table. */
rowCreate: {
parameters: {
path: {
/** The ID of the table which this request is targeting. */
tableId: components["parameters"]["tableId"];
};
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the created row, including the ID which has been generated for it. This can be found in the Budibase portal, viewed under the developer information. */
200: {
content: {
"application/json": components["schemas"]["rowOutput"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["row"];
};
};
};
/** This gets a single row, it will be enriched with the full related rows, rather than the squashed "primaryDisplay" format returned by the search endpoint. */
rowGetById: {
parameters: {
path: {
/** The ID of the table which this request is targeting. */
tableId: components["parameters"]["tableId"];
/** The ID of the row which this request is targeting. */
rowId: components["parameters"]["rowId"];
};
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the retrieved row. */
200: {
content: {
"application/json": components["schemas"]["rowOutput"];
};
};
};
};
/** Updates a row within the specified table. */
rowUpdate: {
parameters: {
path: {
/** The ID of the table which this request is targeting. */
tableId: components["parameters"]["tableId"];
/** The ID of the row which this request is targeting. */
rowId: components["parameters"]["rowId"];
};
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the created row, including the ID which has been generated for it. */
200: {
content: {
"application/json": components["schemas"]["rowOutput"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["row"];
};
};
};
/** Deletes a row within the specified table. */
rowDestroy: {
parameters: {
path: {
/** The ID of the table which this request is targeting. */
tableId: components["parameters"]["tableId"];
/** The ID of the row which this request is targeting. */
rowId: components["parameters"]["rowId"];
};
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the deleted row, including the ID which has been generated for it. */
200: {
content: {
"application/json": components["schemas"]["rowOutput"];
};
};
};
};
rowSearch: {
parameters: {
path: {
/** The ID of the table which this request is targeting. */
tableId: components["parameters"]["tableId"];
};
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** The response will contain an array of rows that match the search parameters. */
200: {
content: {
"application/json": components["schemas"]["searchOutput"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["rowSearch"];
};
};
};
/** Create a table, this could be internal or external. */
tableCreate: {
parameters: {
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the created table, including the ID which has been generated for it. This can be internal or external datasources. */
200: {
content: {
"application/json": components["schemas"]["tableOutput"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["table"];
};
};
};
/** Lookup a table, this could be internal or external. */
tableGetById: {
parameters: {
path: {
/** The ID of the table which this request is targeting. */
tableId: components["parameters"]["tableId"];
};
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the retrieved table. */
200: {
content: {
"application/json": components["schemas"]["tableOutput"];
};
};
};
};
/** Update a table, this could be internal or external. */
tableUpdate: {
parameters: {
path: {
/** The ID of the table which this request is targeting. */
tableId: components["parameters"]["tableId"];
};
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the updated table. */
200: {
content: {
"application/json": components["schemas"]["tableOutput"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["table"];
};
};
};
/** Delete a table, this could be internal or external. */
tableDestroy: {
parameters: {
path: {
/** The ID of the table which this request is targeting. */
tableId: components["parameters"]["tableId"];
};
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the deleted table. */
200: {
content: {
"application/json": components["schemas"]["tableOutput"];
};
};
};
};
/** Based on table properties (currently only name) search for tables. This could be an internal or an external table. */
tableSearch: {
parameters: {
header: {
/** The ID of the app which this request is targeting. */
"x-budibase-app-id": components["parameters"]["appId"];
};
};
responses: {
/** Returns the found tables, based on the search parameters. */
200: {
content: {
"application/json": components["schemas"]["tableSearch"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["nameSearch"];
};
};
};
userCreate: {
responses: {
/** Returns the created user. */
200: {
content: {
"application/json": components["schemas"]["userOutput"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["user"];
};
};
};
userGetById: {
parameters: {
path: {
/** The ID of the user which this request is targeting. */
userId: components["parameters"]["userId"];
};
};
responses: {
/** Returns the retrieved user. */
200: {
content: {
"application/json": components["schemas"]["userOutput"];
};
};
};
};
userUpdate: {
parameters: {
path: {
/** The ID of the user which this request is targeting. */
userId: components["parameters"]["userId"];
};
};
responses: {
/** Returns the updated user. */
200: {
content: {
"application/json": components["schemas"]["userOutput"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["user"];
};
};
};
userDestroy: {
parameters: {
path: {
/** The ID of the user which this request is targeting. */
userId: components["parameters"]["userId"];
};
};
responses: {
/** Returns the deleted user. */
200: {
content: {
"application/json": components["schemas"]["userOutput"];
};
};
};
};
/** Based on user properties (currently only name) search for users. */
userSearch: {
responses: {
/** Returns the found users based on search parameters. */
200: {
content: {
"application/json": components["schemas"]["userSearch"];
};
};
};
requestBody: {
content: {
"application/json": components["schemas"]["nameSearch"];
};
};
};
}
export interface external {}