diff --git a/packages/server/src/api/controllers/row/index.ts b/packages/server/src/api/controllers/row/index.ts index a1f5664754..7183aa6cd7 100644 --- a/packages/server/src/api/controllers/row/index.ts +++ b/packages/server/src/api/controllers/row/index.ts @@ -2,7 +2,7 @@ import { quotas } from "@budibase/pro" import * as internal from "./internal" import * as external from "./external" import { isExternalTable } from "../../../integrations/utils" -import { Ctx } from "@budibase/types" +import { Ctx, UserCtx, DeleteRowRequest, Row } from "@budibase/types" import * as utils from "./utils" import { gridSocket } from "../../../websockets" import { addRev } from "../public/utils" @@ -100,25 +100,24 @@ export async function find(ctx: any) { }) } -export async function destroy(ctx: any) { +export async function destroy(ctx: UserCtx) { const appId = ctx.appId - const inputs = ctx.request.body + const inputs: DeleteRowRequest = ctx.request.body + const tableId = utils.getTableId(ctx) let response, row - if (inputs.rows) { - const targetRows = inputs.rows.map( - (row: { [key: string]: string | string }) => { - let processedRow = typeof row == "string" ? { _id: row } : row - return !processedRow._rev - ? addRev(fixRow(processedRow, ctx.params), tableId) - : fixRow(processedRow, ctx.params) - } - ) + if ("rows" in inputs && Array.isArray(inputs?.rows)) { + const targetRows = inputs.rows.map(row => { + let processedRow: Row = typeof row == "string" ? { _id: row } : row + return !processedRow._rev + ? addRev(fixRow(processedRow, ctx.params), tableId) + : fixRow(processedRow, ctx.params) + }) - const rowDeletes = await Promise.all(targetRows) + const rowDeletes: Row[] = await Promise.all(targetRows) if (rowDeletes) { - ctx.request.body.rows = rowDeletes + inputs.rows = rowDeletes } let { rows } = await quotas.addQuery( diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index 8e99c30246..aef5ac57ac 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -517,6 +517,46 @@ describe("/rows", () => { await assertRowUsage(rowUsage - 2) await assertQueryUsage(queryUsage + 1) }) + + it("should be able to delete a variety of row set types", async () => { + const row1 = await config.createRow() + const row2 = await config.createRow() + const row3 = await config.createRow() + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() + + const res = await request + .delete(`/api/${table._id}/rows`) + .send({ + rows: [row1, row2._id, { _id: row3._id }], + }) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + + expect(res.body.length).toEqual(3) + await loadRow(row1._id!, table._id!, 404) + await assertRowUsage(rowUsage - 3) + await assertQueryUsage(queryUsage + 1) + }) + + it("should accept a valid row object and delete the row", async () => { + const row1 = await config.createRow() + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() + + const res = await request + .delete(`/api/${table._id}/rows`) + .send(row1) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + + expect(res.body.id).toEqual(row1._id) + await loadRow(row1._id!, table._id!, 404) + await assertRowUsage(rowUsage - 1) + await assertQueryUsage(queryUsage + 1) + }) }) describe("fetchView", () => {