diff --git a/packages/server/src/api/controllers/row/ExternalRequest.ts b/packages/server/src/api/controllers/row/ExternalRequest.ts index 064e4d1792..9ab96fba69 100644 --- a/packages/server/src/api/controllers/row/ExternalRequest.ts +++ b/packages/server/src/api/controllers/row/ExternalRequest.ts @@ -269,13 +269,25 @@ function isEditableColumn(column: FieldSchema) { return !(isExternalAutoColumn || isFormula) } -export class ExternalRequest { - private operation: Operation - private tableId: string +export type ExternalRequestReturnType = T extends Operation.READ + ? + | Row[] + | { + row: Row + table: Table + } + : { + row: Row + table: Table + } + +export class ExternalRequest { + private readonly operation: T + private readonly tableId: string private datasource?: Datasource private tables: { [key: string]: Table } = {} - constructor(operation: Operation, tableId: string, datasource?: Datasource) { + constructor(operation: T, tableId: string, datasource?: Datasource) { this.operation = operation this.tableId = tableId this.datasource = datasource @@ -739,7 +751,7 @@ export class ExternalRequest { return fields } - async run(config: RunConfig) { + async run(config: RunConfig): Promise> { const { operation, tableId } = this let { datasourceId, tableName } = breakExternalTableId(tableId) if (!tableName) { @@ -830,8 +842,11 @@ export class ExternalRequest { } const output = this.outputProcessing(response, table, relationships) // if reading it'll just be an array of rows, return whole thing - return operation === Operation.READ && Array.isArray(response) - ? output - : { row: output[0], table } + const result = ( + operation === Operation.READ && Array.isArray(response) + ? output + : { row: output[0], table } + ) as ExternalRequestReturnType + return result } } diff --git a/packages/server/src/api/controllers/row/external.ts b/packages/server/src/api/controllers/row/external.ts index 1e57416cd1..7d78f5da37 100644 --- a/packages/server/src/api/controllers/row/external.ts +++ b/packages/server/src/api/controllers/row/external.ts @@ -1,9 +1,13 @@ -import { FieldTypes, NoEmptyFilterStrings } from "../../../constants" +import { FieldTypes } from "../../../constants" import { breakExternalTableId, breakRowIdField, } from "../../../integrations/utils" -import { ExternalRequest, RunConfig } from "./ExternalRequest" +import { + ExternalRequest, + ExternalRequestReturnType, + RunConfig, +} from "./ExternalRequest" import { Datasource, IncludeRelationship, @@ -24,11 +28,11 @@ import { } from "../../../utilities/rowProcessor" import { cloneDeep, isEqual } from "lodash" -export async function handleRequest( - operation: Operation, +export async function handleRequest( + operation: T, tableId: string, opts?: RunConfig -) { +): Promise> { // make sure the filters are cleaned up, no empty strings for equals, fuzzy or string if (opts && opts.filters) { opts.filters = sdk.rows.removeEmptyFilters(opts.filters) @@ -37,7 +41,7 @@ export async function handleRequest( !dataFilters.hasFilters(opts?.filters) && opts?.filters?.onEmptyFilter === EmptyFilterOption.RETURN_NONE ) { - return [] + return [] as any } return new ExternalRequest(operation, tableId, opts?.datasource).run( @@ -68,12 +72,10 @@ export async function patch(ctx: UserCtx) { id: breakRowIdField(_id), row: dataToUpdate, }) - const row = await sdk.rows.external.getRow(tableId, _id, { - relationships: true, - }) + const row = await outputProcessing(table, response.row) return { ...response, - row: await outputProcessing(table, row), + row, table, } } diff --git a/packages/server/src/integrations/googlesheets.ts b/packages/server/src/integrations/googlesheets.ts index c386ba4e34..7697b55243 100644 --- a/packages/server/src/integrations/googlesheets.ts +++ b/packages/server/src/integrations/googlesheets.ts @@ -1,6 +1,5 @@ import { ConnectionInfo, - Datasource, DatasourceFeature, DatasourceFieldType, DatasourcePlus, @@ -23,7 +22,6 @@ import fetch from "node-fetch" import { cache, configs, context, HTTPError } from "@budibase/backend-core" import { dataFilters, utils } from "@budibase/shared-core" import { GOOGLE_SHEETS_PRIMARY_KEY } from "../constants" -import sdk from "../sdk" interface GoogleSheetsConfig { spreadsheetId: string @@ -56,6 +54,7 @@ const ALLOWED_TYPES = [ FieldType.OPTIONS, FieldType.BOOLEAN, FieldType.BARCODEQR, + FieldType.BB_REFERENCE, ] const SCHEMA: Integration = { @@ -213,7 +212,7 @@ class GoogleSheetsIntegration implements DatasourcePlus { await setupCreationAuth(this.config) // Initialise oAuth client - let googleConfig = await configs.getGoogleDatasourceConfig() + const googleConfig = await configs.getGoogleDatasourceConfig() if (!googleConfig) { throw new HTTPError("Google config not found", 400) } @@ -552,6 +551,10 @@ class GoogleSheetsIntegration implements DatasourcePlus { typeof query.row === "string" ? JSON.parse(query.row) : query.row for (let key in updateValues) { row[key] = updateValues[key] + + if (row[key] === null) { + row[key] = "" + } } await row.save() return [