Merge pull request #13681 from Budibase/BUDI-8248/update-googlesheets

Update googlesheets npm package
This commit is contained in:
Adria Navarro 2024-05-14 13:40:58 +02:00 committed by GitHub
commit 180c197054
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 38 additions and 103 deletions

View File

@ -79,8 +79,7 @@
"dotenv": "8.2.0", "dotenv": "8.2.0",
"form-data": "4.0.0", "form-data": "4.0.0",
"global-agent": "3.0.0", "global-agent": "3.0.0",
"google-auth-library": "7.12.0", "google-spreadsheet": "4.1.2",
"google-spreadsheet": "3.2.0",
"ioredis": "5.3.2", "ioredis": "5.3.2",
"isolated-vm": "^4.7.2", "isolated-vm": "^4.7.2",
"jimp": "0.22.10", "jimp": "0.22.10",
@ -125,7 +124,6 @@
"@swc/jest": "0.2.27", "@swc/jest": "0.2.27",
"@types/archiver": "6.0.2", "@types/archiver": "6.0.2",
"@types/global-agent": "2.1.1", "@types/global-agent": "2.1.1",
"@types/google-spreadsheet": "3.1.5",
"@types/jest": "29.5.5", "@types/jest": "29.5.5",
"@types/koa": "2.13.4", "@types/koa": "2.13.4",
"@types/koa-send": "^4.1.6", "@types/koa-send": "^4.1.6",

View File

@ -158,12 +158,12 @@ const SCHEMA: Integration = {
class GoogleSheetsIntegration implements DatasourcePlus { class GoogleSheetsIntegration implements DatasourcePlus {
private readonly config: GoogleSheetsConfig private readonly config: GoogleSheetsConfig
private client: GoogleSpreadsheet private readonly spreadsheetId: string
private client: GoogleSpreadsheet = undefined!
constructor(config: GoogleSheetsConfig) { constructor(config: GoogleSheetsConfig) {
this.config = config this.config = config
const spreadsheetId = this.cleanSpreadsheetUrl(this.config.spreadsheetId) this.spreadsheetId = this.cleanSpreadsheetUrl(this.config.spreadsheetId)
this.client = new GoogleSpreadsheet(spreadsheetId)
} }
async testConnection(): Promise<ConnectionInfo> { async testConnection(): Promise<ConnectionInfo> {
@ -191,7 +191,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
* @param spreadsheetId - the URL or standard spreadsheetId of the google sheet * @param spreadsheetId - the URL or standard spreadsheetId of the google sheet
* @returns spreadsheet Id of the google sheet * @returns spreadsheet Id of the google sheet
*/ */
cleanSpreadsheetUrl(spreadsheetId: string) { private cleanSpreadsheetUrl(spreadsheetId: string) {
if (!spreadsheetId) { if (!spreadsheetId) {
throw new Error( throw new Error(
"You must set a spreadsheet ID in your configuration to fetch tables." "You must set a spreadsheet ID in your configuration to fetch tables."
@ -201,7 +201,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
return parts.length > 5 ? parts[5] : spreadsheetId return parts.length > 5 ? parts[5] : spreadsheetId
} }
async fetchAccessToken( private async fetchAccessToken(
payload: AuthTokenRequest payload: AuthTokenRequest
): Promise<AuthTokenResponse> { ): Promise<AuthTokenResponse> {
const response = await fetch("https://www.googleapis.com/oauth2/v4/token", { const response = await fetch("https://www.googleapis.com/oauth2/v4/token", {
@ -226,7 +226,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
return json return json
} }
async connect() { private async connect() {
try { try {
await setupCreationAuth(this.config) await setupCreationAuth(this.config)
@ -252,7 +252,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
access_token: tokenResponse.access_token, access_token: tokenResponse.access_token,
}) })
this.client.useOAuth2Client(oauthClient) this.client = new GoogleSpreadsheet(this.spreadsheetId, oauthClient)
await this.client.loadInfo() await this.client.loadInfo()
} catch (err: any) { } catch (err: any) {
// this happens for xlsx imports // this happens for xlsx imports
@ -271,7 +271,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
return sheets.map(s => s.title) return sheets.map(s => s.title)
} }
getTableSchema( private getTableSchema(
title: string, title: string,
headerValues: string[], headerValues: string[],
datasourceId: string, datasourceId: string,
@ -385,18 +385,22 @@ class GoogleSheetsIntegration implements DatasourcePlus {
} }
} }
buildRowObject(headers: string[], values: string[], rowNumber: number) { private buildRowObject(
headers: string[],
values: Record<string, string>,
rowNumber: number
) {
const rowObject: { rowNumber: number } & Row = { const rowObject: { rowNumber: number } & Row = {
rowNumber, rowNumber,
_id: rowNumber.toString(), _id: rowNumber.toString(),
} }
for (let i = 0; i < headers.length; i++) { for (let i = 0; i < headers.length; i++) {
rowObject[headers[i]] = values[i] rowObject[headers[i]] = values[headers[i]]
} }
return rowObject return rowObject
} }
async createTable(name?: string) { private async createTable(name?: string) {
if (!name) { if (!name) {
throw new Error("Must provide name for new sheet.") throw new Error("Must provide name for new sheet.")
} }
@ -409,7 +413,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
} }
} }
async updateTable(table: TableRequest) { private async updateTable(table: TableRequest) {
await this.connect() await this.connect()
const sheet = this.client.sheetsByTitle[table.name] const sheet = this.client.sheetsByTitle[table.name]
await sheet.loadHeaderRow() await sheet.loadHeaderRow()
@ -456,7 +460,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
} }
} }
async deleteTable(sheet: any) { private async deleteTable(sheet: any) {
try { try {
await this.connect() await this.connect()
const sheetToDelete = this.client.sheetsByTitle[sheet] const sheetToDelete = this.client.sheetsByTitle[sheet]
@ -475,7 +479,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
typeof query.row === "string" ? JSON.parse(query.row) : query.row typeof query.row === "string" ? JSON.parse(query.row) : query.row
const row = await sheet.addRow(rowToInsert) const row = await sheet.addRow(rowToInsert)
return [ return [
this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber), this.buildRowObject(sheet.headerValues, row.toObject(), row.rowNumber),
] ]
} catch (err) { } catch (err) {
console.error("Error writing to google sheets", err) console.error("Error writing to google sheets", err)
@ -483,7 +487,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
} }
} }
async createBulk(query: { sheet: string; rows: Row[] }) { private async createBulk(query: { sheet: string; rows: Row[] }) {
try { try {
await this.connect() await this.connect()
const sheet = this.client.sheetsByTitle[query.sheet] const sheet = this.client.sheetsByTitle[query.sheet]
@ -493,7 +497,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
} }
const rows = await sheet.addRows(rowsToInsert) const rows = await sheet.addRows(rowsToInsert)
return rows.map(row => return rows.map(row =>
this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber) this.buildRowObject(sheet.headerValues, row.toObject(), row.rowNumber)
) )
} catch (err) { } catch (err) {
console.error("Error bulk writing to google sheets", err) console.error("Error bulk writing to google sheets", err)
@ -548,7 +552,7 @@ class GoogleSheetsIntegration implements DatasourcePlus {
let response = [] let response = []
for (let row of filtered) { for (let row of filtered) {
response.push( response.push(
this.buildRowObject(headerValues, row._rawData, row._rowNumber) this.buildRowObject(headerValues, row.toObject(), row._rowNumber)
) )
} }
@ -598,10 +602,10 @@ class GoogleSheetsIntegration implements DatasourcePlus {
const updateValues = const updateValues =
typeof query.row === "string" ? JSON.parse(query.row) : query.row typeof query.row === "string" ? JSON.parse(query.row) : query.row
for (let key in updateValues) { for (let key in updateValues) {
row[key] = updateValues[key] row.set(key, updateValues[key])
if (row[key] === null) { if (row.get(key) === null) {
row[key] = "" row.set(key, "")
} }
const { type, subtype, constraints } = query.table.schema[key] const { type, subtype, constraints } = query.table.schema[key]
@ -609,13 +613,17 @@ class GoogleSheetsIntegration implements DatasourcePlus {
type === FieldType.BB_REFERENCE && type === FieldType.BB_REFERENCE &&
subtype === BBReferenceFieldSubType.USER && subtype === BBReferenceFieldSubType.USER &&
constraints?.type !== "array" constraints?.type !== "array"
if (isDeprecatedSingleUser && Array.isArray(row[key])) { if (isDeprecatedSingleUser && Array.isArray(row.get(key))) {
row[key] = row[key][0] row.set(key, row.get(key)[0])
} }
} }
await row.save() await row.save()
return [ return [
this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber), this.buildRowObject(
sheet.headerValues,
row.toObject(),
row.rowNumber
),
] ]
} else { } else {
throw new Error("Row does not exist.") throw new Error("Row does not exist.")

View File

@ -5272,11 +5272,6 @@
resolved "https://registry.yarnpkg.com/@types/global-agent/-/global-agent-2.1.1.tgz#3f93185e48a3a36e377a52a8301320cd162a831b" resolved "https://registry.yarnpkg.com/@types/global-agent/-/global-agent-2.1.1.tgz#3f93185e48a3a36e377a52a8301320cd162a831b"
integrity sha512-sVox8Phk1UKgP6LQPAdeRxfww6vHKt7Bf59dXzYLsQBUEMEn8S10a+ESp/yO0i4fJ3WS4+CIuz42hgJcuA+3mA== integrity sha512-sVox8Phk1UKgP6LQPAdeRxfww6vHKt7Bf59dXzYLsQBUEMEn8S10a+ESp/yO0i4fJ3WS4+CIuz42hgJcuA+3mA==
"@types/google-spreadsheet@3.1.5":
version "3.1.5"
resolved "https://registry.yarnpkg.com/@types/google-spreadsheet/-/google-spreadsheet-3.1.5.tgz#2bdc6f9f5372551e0506cb6ef3f562adcf44fc2e"
integrity sha512-7N+mDtZ1pmya2RRFPPl4KYc2TRgiqCNBLUZfyrKfER+u751JgCO+C24/LzF70UmUm/zhHUbzRZ5mtfaxekQ1ZQ==
"@types/graceful-fs@^4.1.3": "@types/graceful-fs@^4.1.3":
version "4.1.6" version "4.1.6"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae"
@ -6983,7 +6978,7 @@ axios-retry@^3.1.9:
"@babel/runtime" "^7.15.4" "@babel/runtime" "^7.15.4"
is-retry-allowed "^2.2.0" is-retry-allowed "^2.2.0"
axios@0.24.0, axios@1.1.3, axios@1.6.3, axios@^0.21.1, axios@^0.21.4, axios@^0.26.0, axios@^1.0.0, axios@^1.1.3, axios@^1.5.0: axios@0.24.0, axios@1.1.3, axios@1.6.3, axios@^0.21.1, axios@^0.26.0, axios@^1.0.0, axios@^1.1.3, axios@^1.4.0, axios@^1.5.0:
version "1.6.3" version "1.6.3"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.3.tgz#7f50f23b3aa246eff43c54834272346c396613f4" resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.3.tgz#7f50f23b3aa246eff43c54834272346c396613f4"
integrity sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww== integrity sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==
@ -11071,17 +11066,6 @@ gauge@^4.0.3:
strip-ansi "^6.0.1" strip-ansi "^6.0.1"
wide-align "^1.1.5" wide-align "^1.1.5"
gaxios@^4.0.0:
version "4.3.3"
resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-4.3.3.tgz#d44bdefe52d34b6435cc41214fdb160b64abfc22"
integrity sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==
dependencies:
abort-controller "^3.0.0"
extend "^3.0.2"
https-proxy-agent "^5.0.0"
is-stream "^2.0.0"
node-fetch "^2.6.7"
gaxios@^5.0.0, gaxios@^5.0.1: gaxios@^5.0.0, gaxios@^5.0.1:
version "5.1.3" version "5.1.3"
resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-5.1.3.tgz#f7fa92da0fe197c846441e5ead2573d4979e9013" resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-5.1.3.tgz#f7fa92da0fe197c846441e5ead2573d4979e9013"
@ -11092,14 +11076,6 @@ gaxios@^5.0.0, gaxios@^5.0.1:
is-stream "^2.0.0" is-stream "^2.0.0"
node-fetch "^2.6.9" node-fetch "^2.6.9"
gcp-metadata@^4.2.0:
version "4.3.1"
resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-4.3.1.tgz#fb205fe6a90fef2fd9c85e6ba06e5559ee1eefa9"
integrity sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==
dependencies:
gaxios "^4.0.0"
json-bigint "^1.0.0"
gcp-metadata@^5.3.0: gcp-metadata@^5.3.0:
version "5.3.0" version "5.3.0"
resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-5.3.0.tgz#6f45eb473d0cb47d15001476b48b663744d25408" resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-5.3.0.tgz#6f45eb473d0cb47d15001476b48b663744d25408"
@ -11506,36 +11482,6 @@ gonzales-pe@^4.2.3, gonzales-pe@^4.3.0:
dependencies: dependencies:
minimist "^1.2.5" minimist "^1.2.5"
google-auth-library@7.12.0:
version "7.12.0"
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-7.12.0.tgz#7965db6bc20cb31f2df05a08a296bbed6af69426"
integrity sha512-RS/whvFPMoF1hQNxnoVET3DWKPBt1Xgqe2rY0k+Jn7TNhoHlwdnSe7Rlcbo2Nub3Mt2lUVz26X65aDQrWp6x8w==
dependencies:
arrify "^2.0.0"
base64-js "^1.3.0"
ecdsa-sig-formatter "^1.0.11"
fast-text-encoding "^1.0.0"
gaxios "^4.0.0"
gcp-metadata "^4.2.0"
gtoken "^5.0.4"
jws "^4.0.0"
lru-cache "^6.0.0"
google-auth-library@^6.1.3:
version "6.1.6"
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-6.1.6.tgz#deacdcdb883d9ed6bac78bb5d79a078877fdf572"
integrity sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==
dependencies:
arrify "^2.0.0"
base64-js "^1.3.0"
ecdsa-sig-formatter "^1.0.11"
fast-text-encoding "^1.0.0"
gaxios "^4.0.0"
gcp-metadata "^4.2.0"
gtoken "^5.0.4"
jws "^4.0.0"
lru-cache "^6.0.0"
google-auth-library@^8.0.1, google-auth-library@^8.0.2: google-auth-library@^8.0.1, google-auth-library@^8.0.2:
version "8.9.0" version "8.9.0"
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-8.9.0.tgz#15a271eb2ec35d43b81deb72211bd61b1ef14dd0" resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-8.9.0.tgz#15a271eb2ec35d43b81deb72211bd61b1ef14dd0"
@ -11572,13 +11518,6 @@ google-gax@^3.5.7:
protobufjs-cli "1.1.1" protobufjs-cli "1.1.1"
retry-request "^5.0.0" retry-request "^5.0.0"
google-p12-pem@^3.1.3:
version "3.1.4"
resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-3.1.4.tgz#123f7b40da204de4ed1fbf2fd5be12c047fc8b3b"
integrity sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==
dependencies:
node-forge "^1.3.1"
google-p12-pem@^4.0.0: google-p12-pem@^4.0.0:
version "4.0.1" version "4.0.1"
resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-4.0.1.tgz#82841798253c65b7dc2a4e5fe9df141db670172a" resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-4.0.1.tgz#82841798253c65b7dc2a4e5fe9df141db670172a"
@ -11586,13 +11525,12 @@ google-p12-pem@^4.0.0:
dependencies: dependencies:
node-forge "^1.3.1" node-forge "^1.3.1"
google-spreadsheet@3.2.0: google-spreadsheet@4.1.2:
version "3.2.0" version "4.1.2"
resolved "https://registry.yarnpkg.com/google-spreadsheet/-/google-spreadsheet-3.2.0.tgz#ce8aa75c15705aa950ad52b091a6fc4d33dcb329" resolved "https://registry.yarnpkg.com/google-spreadsheet/-/google-spreadsheet-4.1.2.tgz#92e30fdba7e0d78c55d50731528df7835d58bfee"
integrity sha512-z7XMaqb+26rdo8p51r5O03u8aPLAPzn5YhOXYJPcf2hdMVr0dUbIARgdkRdmGiBeoV/QoU/7VNhq1MMCLZv3kQ== integrity sha512-HFBweDAkOcyC2qO9kmWESKbNuOcn+R7UzZN/tj5LLNxVv8FHmg113u0Ow+yaKwwIOt/NnDtPLuptAhaxTs0FYw==
dependencies: dependencies:
axios "^0.21.4" axios "^1.4.0"
google-auth-library "^6.1.3"
lodash "^4.17.21" lodash "^4.17.21"
gopd@^1.0.1: gopd@^1.0.1:
@ -11678,15 +11616,6 @@ graphemer@^1.4.0:
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
gtoken@^5.0.4:
version "5.3.2"
resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.3.2.tgz#deb7dc876abe002178e0515e383382ea9446d58f"
integrity sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==
dependencies:
gaxios "^4.0.0"
google-p12-pem "^3.1.3"
jws "^4.0.0"
gtoken@^6.1.0: gtoken@^6.1.0:
version "6.1.2" version "6.1.2"
resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-6.1.2.tgz#aeb7bdb019ff4c3ba3ac100bbe7b6e74dce0e8bc" resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-6.1.2.tgz#aeb7bdb019ff4c3ba3ac100bbe7b6e74dce0e8bc"