diff --git a/packages/server/src/api/controllers/row/views.ts b/packages/server/src/api/controllers/row/views.ts index d8835c4837..455a4c0aa2 100644 --- a/packages/server/src/api/controllers/row/views.ts +++ b/packages/server/src/api/controllers/row/views.ts @@ -24,15 +24,7 @@ export async function searchView( ctx.throw(400, `This method only supports viewsV2`) } - const table = await sdk.tables.getTable(view?.tableId) - - const viewFields = - (view.schema && - Object.entries(view.schema).length && - Object.keys(sdk.views.enrichSchema(view, table.schema).schema)) || - undefined - - ctx.status = 200 + const viewFields = Object.keys(view.schema || {}) const { body } = ctx.request const query = dataFilters.buildLuceneQuery(view.query || []) diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index cacdff317b..a9675e4a66 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -985,6 +985,7 @@ describe("/rows", () => { }) describe("view search", () => { + const viewSchema = { age: { visible: true }, name: { visible: true } } function userTable(): Table { return { name: "user", @@ -1041,6 +1042,7 @@ describe("/rows", () => { const createViewResponse = await config.api.viewV2.create({ query: [{ operator: "equal", field: "age", value: 40 }], + schema: viewSchema, }) const response = await config.api.viewV2.search(createViewResponse.id) @@ -1141,6 +1143,7 @@ describe("/rows", () => { const createViewResponse = await config.api.viewV2.create({ sort: sortParams, + schema: viewSchema, }) const response = await config.api.viewV2.search(createViewResponse.id) @@ -1175,6 +1178,7 @@ describe("/rows", () => { order: SortOrder.ASCENDING, type: SortType.STRING, }, + schema: viewSchema, }) const response = await config.api.viewV2.search( @@ -1207,7 +1211,7 @@ describe("/rows", () => { } const view = await config.api.viewV2.create({ - schema: { name: {} }, + schema: { name: { visible: true } }, }) const response = await config.api.viewV2.search(view.id) @@ -1224,7 +1228,7 @@ describe("/rows", () => { }) it("views without data can be returned", async () => { - const table = await config.createTable(userTable()) + await config.createTable(userTable()) const createViewResponse = await config.api.viewV2.create() const response = await config.api.viewV2.search(createViewResponse.id) diff --git a/packages/server/src/middleware/trimViewRowInfo.ts b/packages/server/src/middleware/trimViewRowInfo.ts index 39587d1882..cedcb31640 100644 --- a/packages/server/src/middleware/trimViewRowInfo.ts +++ b/packages/server/src/middleware/trimViewRowInfo.ts @@ -37,11 +37,7 @@ export async function trimViewFields( viewId: string ): Promise { const view = await sdk.views.get(viewId) - const allowedKeys = [ - ...Object.keys(view?.schema || {}), - ...db.CONSTANT_EXTERNAL_ROW_COLS, - ...db.CONSTANT_INTERNAL_ROW_COLS, - ] + const allowedKeys = sdk.views.allowedFields(view) // have to mutate the context, can't update reference const toBeRemoved = Object.keys(body).filter( key => !allowedKeys.includes(key) diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index 5f2a001ddc..03c8b6aef5 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -1,15 +1,19 @@ import { RenameColumn, TableSchema, View, ViewV2 } from "@budibase/types" -import { context, HTTPError } from "@budibase/backend-core" +import { context, db as dbCore, HTTPError } from "@budibase/backend-core" import { cloneDeep } from "lodash" import sdk from "../../../sdk" import * as utils from "../../../db/utils" -export async function get(viewId: string): Promise { +export async function get(viewId: string): Promise { const { tableId } = utils.extractViewInfoFromID(viewId) const table = await sdk.tables.getTable(tableId) const views = Object.values(table.views!) - return views.find(v => isV2(v) && v.id === viewId) as ViewV2 | undefined + const found = views.find(v => isV2(v) && v.id === viewId) + if (!found) { + throw new Error("No view found") + } + return found as ViewV2 } export async function create( @@ -68,6 +72,14 @@ export async function remove(viewId: string): Promise { return view } +export function allowedFields(view: View | ViewV2) { + return [ + ...Object.keys(view?.schema || {}), + ...dbCore.CONSTANT_EXTERNAL_ROW_COLS, + ...dbCore.CONSTANT_INTERNAL_ROW_COLS, + ] +} + export function enrichSchema(view: View | ViewV2, tableSchema: TableSchema) { if (!sdk.views.isV2(view)) { return view diff --git a/packages/server/src/tests/utilities/api/viewV2.ts b/packages/server/src/tests/utilities/api/viewV2.ts index 1520154641..f3b15afd38 100644 --- a/packages/server/src/tests/utilities/api/viewV2.ts +++ b/packages/server/src/tests/utilities/api/viewV2.ts @@ -23,7 +23,8 @@ export class ViewV2API extends TestAPI { if (!tableId && !this.config.table) { throw "Test requires table to be configured." } - tableId = this.config.table!._id! + const table = this.config.table + tableId = table!._id! const view = { tableId, name: generator.guid(),