@budibase/server 1.3.19-alpha.1 → 1.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mocks__/mongodb.ts +1 -1
- package/builder/assets/index.9ce4f8c5.css +6 -0
- package/builder/assets/index.a1f7532b.js +876 -0
- package/builder/assets/vendor.5e1fe644.css +1 -0
- package/builder/assets/vendor.67dbd8fa.js +248 -0
- package/builder/index.html +4 -2
- package/coverage/clover.xml +388 -441
- package/coverage/coverage-final.json +20 -20
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/auth.js.html +8 -41
- package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +11 -68
- package/coverage/lcov-report/api/controllers/datasource.js.html +34 -73
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +46 -46
- package/coverage/lcov-report/api/controllers/integration.js.html +6 -6
- package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
- package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/role.js.html +1 -1
- package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/external.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/index.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/screen.js.html +12 -207
- package/coverage/lcov-report/api/controllers/script.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
- package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +13 -13
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +1 -1
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +1 -1
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/table.js.html +2 -2
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +1 -1
- package/coverage/lcov-report/api/routes/utils/index.html +5 -5
- package/coverage/lcov-report/api/routes/utils/validators.js.html +6 -9
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +1 -1
- package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +1 -1
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +1 -1
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
- package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
- package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
- package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
- package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/triggers.js.html +1 -1
- package/coverage/lcov-report/constants/index.html +1 -1
- package/coverage/lcov-report/constants/index.js.html +1 -1
- package/coverage/lcov-report/constants/layouts.js.html +1 -1
- package/coverage/lcov-report/constants/screens.js.html +1 -1
- package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +18 -18
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
- package/coverage/lcov-report/db/newid.js.html +2 -2
- package/coverage/lcov-report/db/utils.js.html +20 -56
- package/coverage/lcov-report/events/AutomationEmitter.js.html +3 -3
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +1 -1
- package/coverage/lcov-report/index.html +37 -37
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
- package/coverage/lcov-report/middleware/builder.js.html +12 -12
- package/coverage/lcov-report/middleware/currentapp.js.html +40 -46
- package/coverage/lcov-report/middleware/index.html +15 -15
- package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
- package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
- package/coverage/lcov-report/middleware/resourceId.js.html +7 -7
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/utilities/budibaseDir.js.html +3 -3
- package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
- package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
- package/coverage/lcov-report/utilities/global.js.html +16 -16
- package/coverage/lcov-report/utilities/index.html +1 -1
- package/coverage/lcov-report/utilities/index.js.html +24 -24
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +2 -2
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
- package/coverage/lcov.info +667 -780
- package/dist/api/controllers/application.js +5 -5
- package/dist/api/controllers/auth.js +0 -9
- package/dist/api/controllers/component.js +1 -14
- package/dist/api/controllers/datasource.js +8 -21
- package/dist/api/controllers/deploy/index.js +8 -1
- package/dist/api/controllers/integration.js +4 -4
- package/dist/api/controllers/row/external.js +1 -1
- package/dist/api/controllers/screen.js +2 -52
- package/dist/api/controllers/static/index.js +0 -1
- package/dist/api/controllers/static/templates/BudibaseApp.svelte +0 -10
- package/dist/api/controllers/static/templates/preview.hbs +1 -5
- package/dist/api/index.js +1 -1
- package/dist/api/routes/application.js +2 -3
- package/dist/api/routes/index.js +0 -2
- package/dist/api/routes/public/tables.js +1 -1
- package/dist/api/routes/table.js +1 -1
- package/dist/api/routes/utils/validators.js +1 -2
- package/dist/app.js +0 -11
- package/dist/db/utils.js +1 -10
- package/dist/environment.js +0 -1
- package/dist/integrations/airtable.js +129 -126
- package/dist/integrations/arangodb.js +89 -86
- package/dist/integrations/base/query.js +2 -2
- package/dist/integrations/base/sqlTable.js +1 -3
- package/dist/integrations/couchdb.js +83 -80
- package/dist/integrations/dynamodb.js +164 -161
- package/dist/integrations/elasticsearch.js +138 -135
- package/dist/integrations/firebase.js +157 -154
- package/dist/integrations/googlesheets.js +327 -323
- package/dist/integrations/index.js +51 -99
- package/dist/integrations/microsoftSqlServer.js +243 -240
- package/dist/integrations/mongodb.js +242 -239
- package/dist/integrations/mysql.js +219 -215
- package/dist/integrations/oracle.js +322 -318
- package/dist/integrations/postgres.js +265 -262
- package/dist/integrations/redis.js +139 -134
- package/dist/integrations/rest.js +292 -289
- package/dist/integrations/s3.js +64 -61
- package/dist/integrations/snowflake.js +86 -83
- package/dist/middleware/currentapp.js +0 -2
- package/dist/migrations/functions/backfill/global.js +3 -0
- package/dist/migrations/functions/developerQuota.js +49 -0
- package/dist/{api/routes/plugin.js → migrations/functions/publishedAppsQuota.js} +21 -13
- package/dist/{api/controllers/plugin/url.js → migrations/functions/usageQuotas/syncDevelopers.js} +13 -13
- package/dist/{api/controllers/plugin/file.js → migrations/functions/usageQuotas/syncPublishedApps.js} +15 -13
- package/dist/migrations/index.js +10 -0
- package/dist/package.json +6 -9
- package/dist/tests/utilities/TestConfiguration.js +1 -1
- package/dist/threads/query.js +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +1 -110
- package/package.json +7 -10
- package/scripts/dev/manage.js +0 -1
- package/scripts/localdomain.js +1 -3
- package/specs/openapi.json +3 -3
- package/specs/openapi.yaml +3 -3
- package/specs/resources/query.js +1 -1
- package/src/api/controllers/application.ts +2 -1
- package/src/api/controllers/auth.js +0 -11
- package/src/api/controllers/component.js +2 -21
- package/src/api/controllers/datasource.js +8 -21
- package/src/api/controllers/deploy/index.ts +6 -1
- package/src/api/controllers/integration.js +4 -4
- package/src/api/controllers/row/external.js +1 -1
- package/src/api/controllers/screen.js +1 -66
- package/src/api/controllers/static/index.ts +1 -1
- package/src/api/controllers/static/templates/BudibaseApp.svelte +0 -10
- package/src/api/controllers/static/templates/preview.hbs +1 -5
- package/src/api/index.js +1 -1
- package/src/api/routes/application.ts +2 -13
- package/src/api/routes/index.ts +0 -2
- package/src/api/routes/public/tables.ts +1 -1
- package/src/api/routes/table.js +1 -1
- package/src/api/routes/tests/query.spec.js +25 -8
- package/src/api/routes/tests/user.spec.js +2 -0
- package/src/api/routes/utils/validators.js +1 -2
- package/src/app.ts +0 -14
- package/src/db/utils.js +0 -12
- package/src/definitions/openapi.ts +3 -3
- package/src/environment.js +0 -1
- package/src/integrations/airtable.ts +118 -116
- package/src/integrations/arangodb.ts +89 -87
- package/src/integrations/base/query.ts +2 -2
- package/src/integrations/base/sqlTable.ts +1 -3
- package/src/integrations/couchdb.ts +89 -83
- package/src/integrations/dynamodb.ts +175 -173
- package/src/integrations/elasticsearch.ts +122 -120
- package/src/integrations/firebase.ts +159 -157
- package/src/integrations/googlesheets.ts +338 -328
- package/src/integrations/index.ts +21 -64
- package/src/integrations/microsoftSqlServer.ts +251 -249
- package/src/integrations/mongodb.ts +258 -261
- package/src/integrations/mysql.ts +234 -229
- package/src/integrations/oracle.ts +380 -373
- package/src/integrations/postgres.ts +268 -264
- package/src/integrations/redis.ts +132 -128
- package/src/integrations/rest.ts +329 -324
- package/src/integrations/s3.ts +71 -68
- package/src/integrations/snowflake.ts +82 -80
- package/src/integrations/tests/{airtable.spec.ts → airtable.spec.js} +18 -21
- package/src/integrations/tests/{arangodb.spec.ts → arangodb.spec.js} +9 -12
- package/src/integrations/tests/{couchdb.spec.ts → couchdb.spec.js} +27 -33
- package/src/integrations/tests/{dynamodb.spec.ts → dynamodb.spec.js} +41 -45
- package/src/integrations/tests/{elasticsearch.spec.ts → elasticsearch.spec.js} +21 -22
- package/src/integrations/tests/{firebase.spec.ts → firebase.spec.js} +28 -33
- package/src/integrations/tests/{microsoftSqlServer.spec.ts → microsoftSqlServer.spec.js} +11 -12
- package/src/integrations/tests/{mongo.spec.ts → mongo.spec.js} +35 -46
- package/src/integrations/tests/{mysql.spec.ts → mysql.spec.js} +15 -17
- package/src/integrations/tests/{oracle.spec.ts → oracle.spec.js} +17 -19
- package/src/integrations/tests/{postgres.spec.ts → postgres.spec.js} +17 -19
- package/src/integrations/tests/{redis.spec.ts → redis.spec.js} +18 -27
- package/src/integrations/tests/{rest.spec.ts → rest.spec.js} +14 -22
- package/src/integrations/tests/{s3.spec.ts → s3.spec.js} +8 -10
- package/src/integrations/tests/{sql.spec.ts → sql.spec.js} +177 -228
- package/src/middleware/currentapp.js +0 -2
- package/src/migrations/functions/backfill/global.ts +3 -0
- package/src/migrations/functions/developerQuota.ts +15 -0
- package/src/migrations/functions/publishedAppsQuota.ts +13 -0
- package/src/migrations/functions/usageQuotas/syncDevelopers.ts +19 -0
- package/src/migrations/functions/usageQuotas/syncPublishedApps.ts +21 -0
- package/src/migrations/index.ts +16 -0
- package/src/module.d.ts +0 -2
- package/src/tests/utilities/TestConfiguration.js +1 -1
- package/src/threads/query.ts +2 -2
- package/src/utilities/fileSystem/index.js +0 -129
- package/builder/assets/index.1709d1b3.js +0 -1005
- package/builder/assets/index.8f621053.css +0 -6
- package/dist/api/controllers/plugin/github.js +0 -69
- package/dist/api/controllers/plugin/index.js +0 -200
- package/dist/api/controllers/plugin/npm.js +0 -58
- package/dist/api/controllers/plugin/uploaders.js +0 -11
- package/dist/api/controllers/plugin/utils.js +0 -26
- package/dist/watch.js +0 -77
- package/dist/websocket.js +0 -22
- package/src/api/controllers/plugin/file.ts +0 -15
- package/src/api/controllers/plugin/github.ts +0 -75
- package/src/api/controllers/plugin/index.ts +0 -215
- package/src/api/controllers/plugin/npm.ts +0 -56
- package/src/api/controllers/plugin/uploaders.ts +0 -4
- package/src/api/controllers/plugin/url.ts +0 -12
- package/src/api/controllers/plugin/utils.ts +0 -19
- package/src/api/routes/plugin.ts +0 -14
- package/src/watch.ts +0 -38
- package/src/websocket.ts +0 -26
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DatasourceFieldType,
|
|
3
|
-
DatasourcePlus,
|
|
4
3
|
Integration,
|
|
5
|
-
QueryJson,
|
|
6
4
|
QueryType,
|
|
7
5
|
Table,
|
|
8
6
|
TableSchema,
|
|
7
|
+
QueryJson,
|
|
8
|
+
DatasourcePlus,
|
|
9
9
|
} from "@budibase/types"
|
|
10
10
|
import { OAuth2Client } from "google-auth-library"
|
|
11
11
|
import { buildExternalTableId } from "./utils"
|
|
@@ -13,400 +13,410 @@ import { DataSourceOperation, FieldTypes } from "../constants"
|
|
|
13
13
|
import { GoogleSpreadsheet } from "google-spreadsheet"
|
|
14
14
|
import env from "../environment"
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
const {
|
|
18
|
-
const {
|
|
19
|
-
const
|
|
16
|
+
module GoogleSheetsModule {
|
|
17
|
+
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
18
|
+
const { getScopedConfig } = require("@budibase/backend-core/db")
|
|
19
|
+
const { Configs } = require("@budibase/backend-core/constants")
|
|
20
|
+
const fetch = require("node-fetch")
|
|
20
21
|
|
|
21
|
-
interface GoogleSheetsConfig {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
22
|
+
interface GoogleSheetsConfig {
|
|
23
|
+
spreadsheetId: string
|
|
24
|
+
auth: OAuthClientConfig
|
|
25
|
+
}
|
|
25
26
|
|
|
26
|
-
interface OAuthClientConfig {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
27
|
+
interface OAuthClientConfig {
|
|
28
|
+
appId: string
|
|
29
|
+
accessToken: string
|
|
30
|
+
refreshToken: string
|
|
31
|
+
}
|
|
31
32
|
|
|
32
|
-
interface AuthTokenRequest {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
33
|
+
interface AuthTokenRequest {
|
|
34
|
+
client_id: string
|
|
35
|
+
client_secret: string
|
|
36
|
+
refresh_token: string
|
|
37
|
+
}
|
|
37
38
|
|
|
38
|
-
interface AuthTokenResponse {
|
|
39
|
-
|
|
40
|
-
}
|
|
39
|
+
interface AuthTokenResponse {
|
|
40
|
+
access_token: string
|
|
41
|
+
}
|
|
41
42
|
|
|
42
|
-
const SCHEMA: Integration = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
},
|
|
47
|
-
relationships: false,
|
|
48
|
-
docs: "https://developers.google.com/sheets/api/quickstart/nodejs",
|
|
49
|
-
description:
|
|
50
|
-
"Create and collaborate on online spreadsheets in real-time and from any device. ",
|
|
51
|
-
friendlyName: "Google Sheets",
|
|
52
|
-
type: "Spreadsheet",
|
|
53
|
-
datasource: {
|
|
54
|
-
spreadsheetId: {
|
|
55
|
-
display: "Google Sheet URL",
|
|
56
|
-
type: DatasourceFieldType.STRING,
|
|
57
|
-
required: true,
|
|
43
|
+
const SCHEMA: Integration = {
|
|
44
|
+
plus: true,
|
|
45
|
+
auth: {
|
|
46
|
+
type: "google",
|
|
58
47
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
required: true,
|
|
71
|
-
},
|
|
48
|
+
relationships: false,
|
|
49
|
+
docs: "https://developers.google.com/sheets/api/quickstart/nodejs",
|
|
50
|
+
description:
|
|
51
|
+
"Create and collaborate on online spreadsheets in real-time and from any device. ",
|
|
52
|
+
friendlyName: "Google Sheets",
|
|
53
|
+
type: "Spreadsheet",
|
|
54
|
+
datasource: {
|
|
55
|
+
spreadsheetId: {
|
|
56
|
+
display: "Google Sheet URL",
|
|
57
|
+
type: DatasourceFieldType.STRING,
|
|
58
|
+
required: true,
|
|
72
59
|
},
|
|
73
60
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
query: {
|
|
62
|
+
create: {
|
|
63
|
+
type: QueryType.FIELDS,
|
|
64
|
+
fields: {
|
|
65
|
+
sheet: {
|
|
66
|
+
type: DatasourceFieldType.STRING,
|
|
67
|
+
required: true,
|
|
68
|
+
},
|
|
69
|
+
row: {
|
|
70
|
+
type: QueryType.JSON,
|
|
71
|
+
required: true,
|
|
72
|
+
},
|
|
80
73
|
},
|
|
81
74
|
},
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
},
|
|
90
|
-
rowIndex: {
|
|
91
|
-
type: DatasourceFieldType.STRING,
|
|
92
|
-
required: true,
|
|
93
|
-
},
|
|
94
|
-
row: {
|
|
95
|
-
type: QueryType.JSON,
|
|
96
|
-
required: true,
|
|
75
|
+
read: {
|
|
76
|
+
type: QueryType.FIELDS,
|
|
77
|
+
fields: {
|
|
78
|
+
sheet: {
|
|
79
|
+
type: DatasourceFieldType.STRING,
|
|
80
|
+
required: true,
|
|
81
|
+
},
|
|
97
82
|
},
|
|
98
83
|
},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
84
|
+
update: {
|
|
85
|
+
type: QueryType.FIELDS,
|
|
86
|
+
fields: {
|
|
87
|
+
sheet: {
|
|
88
|
+
type: DatasourceFieldType.STRING,
|
|
89
|
+
required: true,
|
|
90
|
+
},
|
|
91
|
+
rowIndex: {
|
|
92
|
+
type: DatasourceFieldType.STRING,
|
|
93
|
+
required: true,
|
|
94
|
+
},
|
|
95
|
+
row: {
|
|
96
|
+
type: QueryType.JSON,
|
|
97
|
+
required: true,
|
|
98
|
+
},
|
|
106
99
|
},
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
100
|
+
},
|
|
101
|
+
delete: {
|
|
102
|
+
type: QueryType.FIELDS,
|
|
103
|
+
fields: {
|
|
104
|
+
sheet: {
|
|
105
|
+
type: DatasourceFieldType.STRING,
|
|
106
|
+
required: true,
|
|
107
|
+
},
|
|
108
|
+
rowIndex: {
|
|
109
|
+
type: DatasourceFieldType.NUMBER,
|
|
110
|
+
required: true,
|
|
111
|
+
},
|
|
110
112
|
},
|
|
111
113
|
},
|
|
112
114
|
},
|
|
113
|
-
},
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
class GoogleSheetsIntegration implements DatasourcePlus {
|
|
117
|
-
private readonly config: GoogleSheetsConfig
|
|
118
|
-
private client: any
|
|
119
|
-
public tables: Record<string, Table> = {}
|
|
120
|
-
public schemaErrors: Record<string, string> = {}
|
|
121
|
-
|
|
122
|
-
constructor(config: GoogleSheetsConfig) {
|
|
123
|
-
this.config = config
|
|
124
|
-
const spreadsheetId = this.cleanSpreadsheetUrl(this.config.spreadsheetId)
|
|
125
|
-
this.client = new GoogleSpreadsheet(spreadsheetId)
|
|
126
115
|
}
|
|
127
116
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
117
|
+
class GoogleSheetsIntegration implements DatasourcePlus {
|
|
118
|
+
private readonly config: GoogleSheetsConfig
|
|
119
|
+
private client: any
|
|
120
|
+
public tables: Record<string, Table> = {}
|
|
121
|
+
public schemaErrors: Record<string, string> = {}
|
|
131
122
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
123
|
+
constructor(config: GoogleSheetsConfig) {
|
|
124
|
+
this.config = config
|
|
125
|
+
const spreadsheetId = this.cleanSpreadsheetUrl(this.config.spreadsheetId)
|
|
126
|
+
this.client = new GoogleSpreadsheet(spreadsheetId)
|
|
127
|
+
}
|
|
135
128
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
* @param spreadsheetId - the URL or standard spreadsheetId of the google sheet
|
|
139
|
-
* @returns spreadsheet Id of the google sheet
|
|
140
|
-
*/
|
|
141
|
-
cleanSpreadsheetUrl(spreadsheetId: string) {
|
|
142
|
-
if (!spreadsheetId) {
|
|
143
|
-
throw new Error(
|
|
144
|
-
"You must set a spreadsheet ID in your configuration to fetch tables."
|
|
145
|
-
)
|
|
129
|
+
getBindingIdentifier() {
|
|
130
|
+
return ""
|
|
146
131
|
}
|
|
147
|
-
const parts = spreadsheetId.split("/")
|
|
148
|
-
return parts.length > 5 ? parts[5] : spreadsheetId
|
|
149
|
-
}
|
|
150
132
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const response = await fetch("https://www.googleapis.com/oauth2/v4/token", {
|
|
155
|
-
method: "POST",
|
|
156
|
-
body: JSON.stringify({
|
|
157
|
-
...payload,
|
|
158
|
-
grant_type: "refresh_token",
|
|
159
|
-
}),
|
|
160
|
-
headers: {
|
|
161
|
-
"Content-Type": "application/json",
|
|
162
|
-
},
|
|
163
|
-
})
|
|
133
|
+
getStringConcat(parts: string[]) {
|
|
134
|
+
return ""
|
|
135
|
+
}
|
|
164
136
|
|
|
165
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Pull the spreadsheet ID out from a valid google sheets URL
|
|
139
|
+
* @param spreadsheetId - the URL or standard spreadsheetId of the google sheet
|
|
140
|
+
* @returns spreadsheet Id of the google sheet
|
|
141
|
+
*/
|
|
142
|
+
cleanSpreadsheetUrl(spreadsheetId: string) {
|
|
143
|
+
if (!spreadsheetId) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
"You must set a spreadsheet ID in your configuration to fetch tables."
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
const parts = spreadsheetId.split("/")
|
|
149
|
+
return parts.length > 5 ? parts[5] : spreadsheetId
|
|
150
|
+
}
|
|
166
151
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
152
|
+
async fetchAccessToken(
|
|
153
|
+
payload: AuthTokenRequest
|
|
154
|
+
): Promise<AuthTokenResponse> {
|
|
155
|
+
const response = await fetch(
|
|
156
|
+
"https://www.googleapis.com/oauth2/v4/token",
|
|
157
|
+
{
|
|
158
|
+
method: "POST",
|
|
159
|
+
body: JSON.stringify({
|
|
160
|
+
...payload,
|
|
161
|
+
grant_type: "refresh_token",
|
|
162
|
+
}),
|
|
163
|
+
headers: {
|
|
164
|
+
"Content-Type": "application/json",
|
|
165
|
+
},
|
|
166
|
+
}
|
|
170
167
|
)
|
|
171
|
-
}
|
|
172
168
|
|
|
173
|
-
|
|
174
|
-
}
|
|
169
|
+
const json = await response.json()
|
|
175
170
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
let googleConfig = await getScopedConfig(db, {
|
|
181
|
-
type: Configs.GOOGLE,
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
if (!googleConfig) {
|
|
185
|
-
googleConfig = {
|
|
186
|
-
clientID: env.GOOGLE_CLIENT_ID,
|
|
187
|
-
clientSecret: env.GOOGLE_CLIENT_SECRET,
|
|
188
|
-
}
|
|
171
|
+
if (response.status !== 200) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`Error authenticating with google sheets. ${json.error_description}`
|
|
174
|
+
)
|
|
189
175
|
}
|
|
190
176
|
|
|
191
|
-
|
|
192
|
-
clientId: googleConfig.clientID,
|
|
193
|
-
clientSecret: googleConfig.clientSecret,
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
const tokenResponse = await this.fetchAccessToken({
|
|
197
|
-
client_id: googleConfig.clientID,
|
|
198
|
-
client_secret: googleConfig.clientSecret,
|
|
199
|
-
refresh_token: this.config.auth.refreshToken,
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
oauthClient.setCredentials({
|
|
203
|
-
refresh_token: this.config.auth.refreshToken,
|
|
204
|
-
access_token: tokenResponse.access_token,
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
this.client.useOAuth2Client(oauthClient)
|
|
208
|
-
await this.client.loadInfo()
|
|
209
|
-
} catch (err) {
|
|
210
|
-
console.error("Error connecting to google sheets", err)
|
|
211
|
-
throw err
|
|
177
|
+
return json
|
|
212
178
|
}
|
|
213
|
-
}
|
|
214
179
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
name: header,
|
|
229
|
-
type: FieldTypes.STRING,
|
|
180
|
+
async connect() {
|
|
181
|
+
try {
|
|
182
|
+
// Initialise oAuth client
|
|
183
|
+
const db = getGlobalDB()
|
|
184
|
+
let googleConfig = await getScopedConfig(db, {
|
|
185
|
+
type: Configs.GOOGLE,
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
if (!googleConfig) {
|
|
189
|
+
googleConfig = {
|
|
190
|
+
clientID: env.GOOGLE_CLIENT_ID,
|
|
191
|
+
clientSecret: env.GOOGLE_CLIENT_SECRET,
|
|
192
|
+
}
|
|
230
193
|
}
|
|
231
|
-
}
|
|
232
194
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
195
|
+
const oauthClient = new OAuth2Client({
|
|
196
|
+
clientId: googleConfig.clientID,
|
|
197
|
+
clientSecret: googleConfig.clientSecret,
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
const tokenResponse = await this.fetchAccessToken({
|
|
201
|
+
client_id: googleConfig.clientID,
|
|
202
|
+
client_secret: googleConfig.clientSecret,
|
|
203
|
+
refresh_token: this.config.auth.refreshToken,
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
oauthClient.setCredentials({
|
|
207
|
+
refresh_token: this.config.auth.refreshToken,
|
|
208
|
+
access_token: tokenResponse.access_token,
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
this.client.useOAuth2Client(oauthClient)
|
|
212
|
+
await this.client.loadInfo()
|
|
213
|
+
} catch (err) {
|
|
214
|
+
console.error("Error connecting to google sheets", err)
|
|
215
|
+
throw err
|
|
239
216
|
}
|
|
240
217
|
}
|
|
241
218
|
|
|
242
|
-
|
|
243
|
-
|
|
219
|
+
async buildSchema(datasourceId: string) {
|
|
220
|
+
await this.connect()
|
|
221
|
+
const sheets = await this.client.sheetsByIndex
|
|
222
|
+
const tables: Record<string, Table> = {}
|
|
223
|
+
for (let sheet of sheets) {
|
|
224
|
+
// must fetch rows to determine schema
|
|
225
|
+
await sheet.getRows()
|
|
226
|
+
// build schema
|
|
227
|
+
const schema: TableSchema = {}
|
|
228
|
+
|
|
229
|
+
// build schema from headers
|
|
230
|
+
for (let header of sheet.headerValues) {
|
|
231
|
+
schema[header] = {
|
|
232
|
+
name: header,
|
|
233
|
+
type: FieldTypes.STRING,
|
|
234
|
+
}
|
|
235
|
+
}
|
|
244
236
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
rowIndex: json.extra?.idFilter?.equal?.rowNumber - 2,
|
|
256
|
-
sheet,
|
|
257
|
-
row: json.body,
|
|
258
|
-
}),
|
|
259
|
-
[DataSourceOperation.DELETE]: () =>
|
|
260
|
-
this.delete({
|
|
261
|
-
// exclude the header row and zero index
|
|
262
|
-
rowIndex: json.extra?.idFilter?.equal?.rowNumber - 2,
|
|
263
|
-
sheet,
|
|
264
|
-
}),
|
|
265
|
-
[DataSourceOperation.CREATE_TABLE]: () =>
|
|
266
|
-
this.createTable(json?.table?.name),
|
|
267
|
-
[DataSourceOperation.UPDATE_TABLE]: () => this.updateTable(json.table),
|
|
268
|
-
[DataSourceOperation.DELETE_TABLE]: () =>
|
|
269
|
-
this.deleteTable(json?.table?.name),
|
|
237
|
+
// create tables
|
|
238
|
+
tables[sheet.title] = {
|
|
239
|
+
_id: buildExternalTableId(datasourceId, sheet.title),
|
|
240
|
+
name: sheet.title,
|
|
241
|
+
primary: ["rowNumber"],
|
|
242
|
+
schema,
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
this.tables = tables
|
|
270
247
|
}
|
|
271
248
|
|
|
272
|
-
|
|
249
|
+
async query(json: QueryJson) {
|
|
250
|
+
const sheet = json.endpoint.entityId
|
|
251
|
+
|
|
252
|
+
const handlers = {
|
|
253
|
+
[DataSourceOperation.CREATE]: () =>
|
|
254
|
+
this.create({ sheet, row: json.body }),
|
|
255
|
+
[DataSourceOperation.READ]: () => this.read({ sheet }),
|
|
256
|
+
[DataSourceOperation.UPDATE]: () =>
|
|
257
|
+
this.update({
|
|
258
|
+
// exclude the header row and zero index
|
|
259
|
+
rowIndex: json.extra?.idFilter?.equal?.rowNumber - 2,
|
|
260
|
+
sheet,
|
|
261
|
+
row: json.body,
|
|
262
|
+
}),
|
|
263
|
+
[DataSourceOperation.DELETE]: () =>
|
|
264
|
+
this.delete({
|
|
265
|
+
// exclude the header row and zero index
|
|
266
|
+
rowIndex: json.extra?.idFilter?.equal?.rowNumber - 2,
|
|
267
|
+
sheet,
|
|
268
|
+
}),
|
|
269
|
+
[DataSourceOperation.CREATE_TABLE]: () =>
|
|
270
|
+
this.createTable(json?.table?.name),
|
|
271
|
+
[DataSourceOperation.UPDATE_TABLE]: () => this.updateTable(json.table),
|
|
272
|
+
[DataSourceOperation.DELETE_TABLE]: () =>
|
|
273
|
+
this.deleteTable(json?.table?.name),
|
|
274
|
+
}
|
|
273
275
|
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
+
const internalQueryMethod = handlers[json.endpoint.operation]
|
|
276
277
|
|
|
277
|
-
|
|
278
|
-
const rowObject: { rowNumber: number; [key: string]: any } = { rowNumber }
|
|
279
|
-
for (let i = 0; i < headers.length; i++) {
|
|
280
|
-
rowObject._id = rowNumber
|
|
281
|
-
rowObject[headers[i]] = values[i]
|
|
278
|
+
return await internalQueryMethod()
|
|
282
279
|
}
|
|
283
|
-
return rowObject
|
|
284
|
-
}
|
|
285
280
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
281
|
+
buildRowObject(headers: string[], values: string[], rowNumber: number) {
|
|
282
|
+
const rowObject: { rowNumber: number; [key: string]: any } = { rowNumber }
|
|
283
|
+
for (let i = 0; i < headers.length; i++) {
|
|
284
|
+
rowObject._id = rowNumber
|
|
285
|
+
rowObject[headers[i]] = values[i]
|
|
286
|
+
}
|
|
287
|
+
return rowObject
|
|
293
288
|
}
|
|
294
|
-
}
|
|
295
289
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
290
|
+
async createTable(name?: string) {
|
|
291
|
+
try {
|
|
292
|
+
await this.connect()
|
|
293
|
+
const sheet = await this.client.addSheet({ title: name })
|
|
294
|
+
return sheet
|
|
295
|
+
} catch (err) {
|
|
296
|
+
console.error("Error creating new table in google sheets", err)
|
|
297
|
+
throw err
|
|
298
|
+
}
|
|
299
|
+
}
|
|
301
300
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
301
|
+
async updateTable(table?: any) {
|
|
302
|
+
try {
|
|
303
|
+
await this.connect()
|
|
304
|
+
const sheet = await this.client.sheetsByTitle[table.name]
|
|
305
|
+
await sheet.loadHeaderRow()
|
|
306
|
+
|
|
307
|
+
if (table._rename) {
|
|
308
|
+
const headers = []
|
|
309
|
+
for (let header of sheet.headerValues) {
|
|
310
|
+
if (header === table._rename.old) {
|
|
311
|
+
headers.push(table._rename.updated)
|
|
312
|
+
} else {
|
|
313
|
+
headers.push(header)
|
|
314
|
+
}
|
|
309
315
|
}
|
|
316
|
+
await sheet.setHeaderRow(headers)
|
|
317
|
+
} else {
|
|
318
|
+
let newField = Object.keys(table.schema).find(
|
|
319
|
+
key => !sheet.headerValues.includes(key)
|
|
320
|
+
)
|
|
321
|
+
await sheet.setHeaderRow([...sheet.headerValues, newField])
|
|
310
322
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
key => !sheet.headerValues.includes(key)
|
|
315
|
-
)
|
|
316
|
-
await sheet.setHeaderRow([...sheet.headerValues, newField])
|
|
323
|
+
} catch (err) {
|
|
324
|
+
console.error("Error updating table in google sheets", err)
|
|
325
|
+
throw err
|
|
317
326
|
}
|
|
318
|
-
} catch (err) {
|
|
319
|
-
console.error("Error updating table in google sheets", err)
|
|
320
|
-
throw err
|
|
321
327
|
}
|
|
322
|
-
}
|
|
323
328
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
329
|
+
async deleteTable(sheet: any) {
|
|
330
|
+
try {
|
|
331
|
+
await this.connect()
|
|
332
|
+
const sheetToDelete = await this.client.sheetsByTitle[sheet]
|
|
333
|
+
return await sheetToDelete.delete()
|
|
334
|
+
} catch (err) {
|
|
335
|
+
console.error("Error deleting table in google sheets", err)
|
|
336
|
+
throw err
|
|
337
|
+
}
|
|
332
338
|
}
|
|
333
|
-
}
|
|
334
339
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
340
|
+
async create(query: { sheet: string; row: any }) {
|
|
341
|
+
try {
|
|
342
|
+
await this.connect()
|
|
343
|
+
const sheet = await this.client.sheetsByTitle[query.sheet]
|
|
344
|
+
const rowToInsert =
|
|
345
|
+
typeof query.row === "string" ? JSON.parse(query.row) : query.row
|
|
346
|
+
const row = await sheet.addRow(rowToInsert)
|
|
347
|
+
return [
|
|
348
|
+
this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber),
|
|
349
|
+
]
|
|
350
|
+
} catch (err) {
|
|
351
|
+
console.error("Error writing to google sheets", err)
|
|
352
|
+
throw err
|
|
353
|
+
}
|
|
348
354
|
}
|
|
349
|
-
}
|
|
350
355
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
356
|
+
async read(query: { sheet: string }) {
|
|
357
|
+
try {
|
|
358
|
+
await this.connect()
|
|
359
|
+
const sheet = await this.client.sheetsByTitle[query.sheet]
|
|
360
|
+
const rows = await sheet.getRows()
|
|
361
|
+
const headerValues = sheet.headerValues
|
|
362
|
+
const response = []
|
|
363
|
+
for (let row of rows) {
|
|
364
|
+
response.push(
|
|
365
|
+
this.buildRowObject(headerValues, row._rawData, row._rowNumber)
|
|
366
|
+
)
|
|
367
|
+
}
|
|
368
|
+
return response
|
|
369
|
+
} catch (err) {
|
|
370
|
+
console.error("Error reading from google sheets", err)
|
|
371
|
+
throw err
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
async update(query: { sheet: string; rowIndex: number; row: any }) {
|
|
376
|
+
try {
|
|
377
|
+
await this.connect()
|
|
378
|
+
const sheet = await this.client.sheetsByTitle[query.sheet]
|
|
379
|
+
const rows = await sheet.getRows()
|
|
380
|
+
const row = rows[query.rowIndex]
|
|
381
|
+
if (row) {
|
|
382
|
+
const updateValues =
|
|
383
|
+
typeof query.row === "string" ? JSON.parse(query.row) : query.row
|
|
384
|
+
for (let key in updateValues) {
|
|
385
|
+
row[key] = updateValues[key]
|
|
386
|
+
}
|
|
387
|
+
await row.save()
|
|
388
|
+
return [
|
|
389
|
+
this.buildRowObject(
|
|
390
|
+
sheet.headerValues,
|
|
391
|
+
row._rawData,
|
|
392
|
+
row._rowNumber
|
|
393
|
+
),
|
|
394
|
+
]
|
|
395
|
+
} else {
|
|
396
|
+
throw new Error("Row does not exist.")
|
|
397
|
+
}
|
|
398
|
+
} catch (err) {
|
|
399
|
+
console.error("Error reading from google sheets", err)
|
|
400
|
+
throw err
|
|
362
401
|
}
|
|
363
|
-
return response
|
|
364
|
-
} catch (err) {
|
|
365
|
-
console.error("Error reading from google sheets", err)
|
|
366
|
-
throw err
|
|
367
402
|
}
|
|
368
|
-
}
|
|
369
403
|
|
|
370
|
-
|
|
371
|
-
try {
|
|
404
|
+
async delete(query: { sheet: string; rowIndex: number }) {
|
|
372
405
|
await this.connect()
|
|
373
406
|
const sheet = await this.client.sheetsByTitle[query.sheet]
|
|
374
407
|
const rows = await sheet.getRows()
|
|
375
408
|
const row = rows[query.rowIndex]
|
|
376
409
|
if (row) {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
for (let key in updateValues) {
|
|
380
|
-
row[key] = updateValues[key]
|
|
381
|
-
}
|
|
382
|
-
await row.save()
|
|
383
|
-
return [
|
|
384
|
-
this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber),
|
|
385
|
-
]
|
|
410
|
+
await row.delete()
|
|
411
|
+
return [{ deleted: query.rowIndex }]
|
|
386
412
|
} else {
|
|
387
413
|
throw new Error("Row does not exist.")
|
|
388
414
|
}
|
|
389
|
-
} catch (err) {
|
|
390
|
-
console.error("Error reading from google sheets", err)
|
|
391
|
-
throw err
|
|
392
415
|
}
|
|
393
416
|
}
|
|
394
417
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
const rows = await sheet.getRows()
|
|
399
|
-
const row = rows[query.rowIndex]
|
|
400
|
-
if (row) {
|
|
401
|
-
await row.delete()
|
|
402
|
-
return [{ deleted: query.rowIndex }]
|
|
403
|
-
} else {
|
|
404
|
-
throw new Error("Row does not exist.")
|
|
405
|
-
}
|
|
418
|
+
module.exports = {
|
|
419
|
+
schema: SCHEMA,
|
|
420
|
+
integration: GoogleSheetsIntegration,
|
|
406
421
|
}
|
|
407
422
|
}
|
|
408
|
-
|
|
409
|
-
export default {
|
|
410
|
-
schema: SCHEMA,
|
|
411
|
-
integration: GoogleSheetsIntegration,
|
|
412
|
-
}
|