@guayaba/workflow-piece-google-sheets 0.14.6

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.
Files changed (57) hide show
  1. package/.babelrc +3 -0
  2. package/.eslintrc.json +18 -0
  3. package/README.md +5 -0
  4. package/assets/logo.png +0 -0
  5. package/package.json +28 -0
  6. package/src/i18n/ar.json +124 -0
  7. package/src/i18n/bg.json +124 -0
  8. package/src/i18n/ca.json +132 -0
  9. package/src/i18n/de.json +165 -0
  10. package/src/i18n/es.json +165 -0
  11. package/src/i18n/fr.json +165 -0
  12. package/src/i18n/hi.json +132 -0
  13. package/src/i18n/hu.json +124 -0
  14. package/src/i18n/hy.json +124 -0
  15. package/src/i18n/id.json +132 -0
  16. package/src/i18n/it.json +124 -0
  17. package/src/i18n/ja.json +165 -0
  18. package/src/i18n/ko.json +124 -0
  19. package/src/i18n/nl.json +165 -0
  20. package/src/i18n/pl.json +124 -0
  21. package/src/i18n/pt.json +165 -0
  22. package/src/i18n/ru.json +132 -0
  23. package/src/i18n/sv.json +124 -0
  24. package/src/i18n/translation.json +165 -0
  25. package/src/i18n/uk.json +124 -0
  26. package/src/i18n/vi.json +132 -0
  27. package/src/i18n/zh.json +165 -0
  28. package/src/index.ts +93 -0
  29. package/src/lib/actions/clear-sheet.ts +60 -0
  30. package/src/lib/actions/copy-worksheet.ts +32 -0
  31. package/src/lib/actions/create-column.ts +109 -0
  32. package/src/lib/actions/create-spreadsheet.ts +122 -0
  33. package/src/lib/actions/create-worksheet.ts +62 -0
  34. package/src/lib/actions/delete-row.action.ts +40 -0
  35. package/src/lib/actions/delete-worksheet.ts +36 -0
  36. package/src/lib/actions/export-sheet.ts +86 -0
  37. package/src/lib/actions/find-row-by-num.ts +42 -0
  38. package/src/lib/actions/find-rows.ts +135 -0
  39. package/src/lib/actions/find-spreadsheets.ts +83 -0
  40. package/src/lib/actions/find-worksheet.ts +52 -0
  41. package/src/lib/actions/format-spreadsheet-row.ts +112 -0
  42. package/src/lib/actions/get-many-rows.ts +42 -0
  43. package/src/lib/actions/get-rows.ts +207 -0
  44. package/src/lib/actions/insert-multiple-rows.action.ts +542 -0
  45. package/src/lib/actions/insert-row.action.ts +111 -0
  46. package/src/lib/actions/rename-worksheet.ts +44 -0
  47. package/src/lib/actions/update-multiple-rows.ts +177 -0
  48. package/src/lib/actions/update-row.ts +93 -0
  49. package/src/lib/common/common.ts +383 -0
  50. package/src/lib/common/props.ts +274 -0
  51. package/src/lib/triggers/helpers.ts +155 -0
  52. package/src/lib/triggers/new-or-updated-row.trigger.ts +299 -0
  53. package/src/lib/triggers/new-row-added-webhook.ts +182 -0
  54. package/src/lib/triggers/new-spreadsheet.ts +88 -0
  55. package/src/lib/triggers/new-worksheet.ts +96 -0
  56. package/tsconfig.json +16 -0
  57. package/tsconfig.lib.json +15 -0
@@ -0,0 +1,135 @@
1
+ import { createAction, Property } from '@guayaba/workflows-framework';
2
+ import {
3
+ areSheetIdsValid,
4
+ googleSheetsCommon,
5
+ labelToColumn,
6
+ mapRowsToHeaderNames,
7
+ } from '../common/common';
8
+ import { googleSheetsAuth } from '../common/common';
9
+ import { z } from 'zod';
10
+ import { propsValidation } from '@guayaba/workflows-common';
11
+ import { columnNameProp, commonProps } from '../common/props';
12
+
13
+ export const findRowsAction = createAction({
14
+ auth: googleSheetsAuth,
15
+ name: 'find_rows',
16
+ description: 'Look up rows in a worksheet based on a column value.',
17
+ displayName: 'Find Rows',
18
+ props: {
19
+ ...commonProps,
20
+ columnName: columnNameProp(),
21
+ searchValue: Property.ShortText({
22
+ displayName: 'Search Value',
23
+ description: 'The value to look for in the selected column. Leave empty to return all rows.',
24
+ required: false,
25
+ }),
26
+ matchCase: Property.Checkbox({
27
+ displayName: 'Exact Match',
28
+ description: 'Only return rows where the cell value exactly matches the search value.',
29
+ required: true,
30
+ defaultValue: false,
31
+ }),
32
+ startingRow: Property.Number({
33
+ displayName: 'Starting Row',
34
+ description: 'Start searching from this row number.',
35
+ required: false,
36
+ }),
37
+ numberOfRows: Property.Number({
38
+ displayName: 'Number of Rows',
39
+ description: 'How many rows to return. Defaults to 1 if not specified.',
40
+ required: false,
41
+ defaultValue: 1,
42
+ }),
43
+ headerRow: Property.Number({
44
+ displayName: 'Header Row',
45
+ description: 'The row number that contains the column names.',
46
+ required: true,
47
+ defaultValue: 1,
48
+ }),
49
+ useHeaderNames: Property.Checkbox({
50
+ displayName: 'Use Column Names',
51
+ description: 'Use column names as keys instead of A, B, C.',
52
+ required: false,
53
+ defaultValue: false,
54
+ }),
55
+ },
56
+ async run({ propsValue, auth }) {
57
+ await propsValidation.validateZod(propsValue, {
58
+ startingRow: z.number().min(1).optional(),
59
+ numberOfRows: z.number().min(1).optional(),
60
+ });
61
+
62
+ const spreadsheetId = propsValue.spreadsheetId;
63
+ const sheetId = propsValue.sheetId;
64
+ const startingRow = propsValue.startingRow ?? 1;
65
+ const numberOfRowsToReturn = propsValue.numberOfRows ?? 1;
66
+ const headerRow = propsValue.headerRow;
67
+ const useHeaderNames = propsValue.useHeaderNames as boolean;
68
+
69
+ if (!areSheetIdsValid(spreadsheetId, sheetId)) {
70
+ throw new Error('Please select a spreadsheet and sheet first.');
71
+ }
72
+
73
+ const rows = await googleSheetsCommon.getGoogleSheetRows({
74
+ spreadsheetId: spreadsheetId as string,
75
+ auth: auth,
76
+ sheetId: sheetId as number,
77
+ rowIndex_s: startingRow,
78
+ rowIndex_e: undefined,
79
+ headerRow: headerRow,
80
+ });
81
+
82
+ const values = rows.map((row) => {
83
+ return row.values;
84
+ });
85
+
86
+ const matchingRows: any[] = [];
87
+ const columnName = propsValue.columnName ? propsValue.columnName : 'A';
88
+ const columnNumber: number = labelToColumn(columnName);
89
+ const searchValue = propsValue.searchValue ?? '';
90
+
91
+ let matchedRowCount = 0;
92
+
93
+ for (let i = 0; i < values.length; i++) {
94
+ const row: Record<string, any> = values[i];
95
+
96
+ if (matchedRowCount === numberOfRowsToReturn) break;
97
+
98
+ if (searchValue === '') {
99
+ matchingRows.push(rows[i]);
100
+ matchedRowCount += 1;
101
+ continue;
102
+ }
103
+
104
+ const keys = Object.keys(row);
105
+ if (keys.length <= columnNumber) continue;
106
+ const entry_value = row[keys[columnNumber]];
107
+
108
+ if (entry_value === undefined) {
109
+ continue;
110
+ }
111
+ if (propsValue.matchCase) {
112
+ if (entry_value === searchValue) {
113
+ matchedRowCount += 1;
114
+ matchingRows.push(rows[i]);
115
+ }
116
+ } else {
117
+ if (entry_value.toLowerCase().includes(searchValue.toLowerCase())) {
118
+ matchedRowCount += 1;
119
+ matchingRows.push(rows[i]);
120
+ }
121
+ }
122
+ }
123
+
124
+ const finalRows = await mapRowsToHeaderNames(
125
+ matchingRows,
126
+ useHeaderNames,
127
+ spreadsheetId as string,
128
+ sheetId as number,
129
+ headerRow,
130
+ auth,
131
+ );
132
+
133
+ return finalRows;
134
+ },
135
+ });
@@ -0,0 +1,83 @@
1
+ import { createAction, Property } from '@guayaba/workflows-framework';
2
+ import {
3
+ httpClient,
4
+ HttpMethod,
5
+ AuthenticationType,
6
+ HttpRequest,
7
+ } from '@guayaba/workflows-common';
8
+ import { googleSheetsAuth } from '../common/common';
9
+ import { includeTeamDrivesProp } from '../common/props';
10
+ import { getAccessToken } from '../common/common';
11
+
12
+ export const findSpreadsheets = createAction({
13
+ name: 'find_spreadsheets',
14
+ displayName: 'Find Spreadsheet(s)',
15
+ description: 'Find spreadsheet(s) by name.',
16
+ auth: googleSheetsAuth,
17
+ props: {
18
+ includeTeamDrives: includeTeamDrivesProp(),
19
+ spreadsheet_name: Property.ShortText({
20
+ displayName: 'Spreadsheet Name',
21
+ description: 'Enter the name of the spreadsheet to search for',
22
+ required: true,
23
+ }),
24
+ exact_match: Property.Checkbox({
25
+ displayName: 'Exact Match',
26
+ description:
27
+ 'If true, only return spreadsheets that exactly match the name. If false, return spreadsheets that contain the name.',
28
+ required: false,
29
+ defaultValue: false,
30
+ }),
31
+ },
32
+ async run({ propsValue, auth }) {
33
+ const searchValue = propsValue.spreadsheet_name;
34
+ const queries = ["mimeType='application/vnd.google-apps.spreadsheet'", 'trashed=false'];
35
+
36
+ if (propsValue.exact_match) {
37
+ queries.push(`name = '${searchValue}'`);
38
+ } else {
39
+ queries.push(`name contains '${searchValue}'`);
40
+ }
41
+
42
+ const files = [];
43
+ let pageToken = null;
44
+
45
+ do {
46
+ const request: HttpRequest = {
47
+ method: HttpMethod.GET,
48
+ url: 'https://www.googleapis.com/drive/v3/files',
49
+ queryParams: {
50
+ q: queries.join(' and '),
51
+ includeItemsFromAllDrives: propsValue.includeTeamDrives ? 'true' : 'false',
52
+ supportsAllDrives: 'true',
53
+ fields: 'files(id,name,webViewLink,createdTime,modifiedTime),nextPageToken',
54
+ },
55
+ authentication: {
56
+ type: AuthenticationType.BEARER_TOKEN,
57
+ token: await getAccessToken(auth),
58
+ },
59
+ };
60
+ if (pageToken) {
61
+ if (request.queryParams !== undefined) {
62
+ request.queryParams['pageToken'] = pageToken;
63
+ }
64
+ }
65
+ try {
66
+ const response = await httpClient.sendRequest<{
67
+ files: { id: string; name: string }[];
68
+ nextPageToken: string;
69
+ }>(request);
70
+
71
+ files.push(...response.body.files);
72
+ pageToken = response.body.nextPageToken;
73
+ } catch (e) {
74
+ throw new Error(`Failed to get folders\nError:${e}`);
75
+ }
76
+ } while (pageToken);
77
+
78
+ return {
79
+ found: files.length > 0,
80
+ spreadsheets: files,
81
+ };
82
+ },
83
+ });
@@ -0,0 +1,52 @@
1
+ import { googleSheetsAuth } from '../common/common';
2
+ import { createAction, Property } from '@guayaba/workflows-framework';
3
+ import { google } from 'googleapis';
4
+ import { includeTeamDrivesProp, spreadsheetIdProp } from '../common/props';
5
+ import { createGoogleClient } from '../common/common';
6
+
7
+ export const findWorksheetAction = createAction({
8
+ auth: googleSheetsAuth,
9
+ name: 'find-worksheet',
10
+ displayName: 'Find Worksheet(s)',
11
+ description: 'Finds a worksheet(s) by title.',
12
+ props: {
13
+ includeTeamDrives: includeTeamDrivesProp(),
14
+ spreadsheetId: spreadsheetIdProp('Spreadsheet', ''),
15
+ title: Property.ShortText({
16
+ displayName: 'Title',
17
+ required: true,
18
+ }),
19
+ exact_match: Property.Checkbox({
20
+ displayName: 'Exact Match',
21
+ description:
22
+ 'If true, only return worksheets that exactly match the name. If false, return worksheets that contain the name.',
23
+ required: false,
24
+ defaultValue: false,
25
+ }),
26
+ },
27
+ async run(context) {
28
+ const spreadsheetId = context.propsValue.spreadsheetId;
29
+ const title = context.propsValue.title;
30
+ const exactMatch = context.propsValue.exact_match ?? false;
31
+
32
+ const authClient = await createGoogleClient(context.auth);
33
+
34
+ const sheets = google.sheets({ version: 'v4', auth: authClient });
35
+
36
+ const response = await sheets.spreadsheets.get({
37
+ spreadsheetId,
38
+ });
39
+
40
+ const sheetsData = response.data.sheets ?? [];
41
+
42
+ const matchedSheets = sheetsData.filter((sheet) => {
43
+ const sheetTitle = sheet.properties?.title ?? '';
44
+ return exactMatch ? sheetTitle === title : sheetTitle.includes(title);
45
+ });
46
+
47
+ return {
48
+ found: matchedSheets.length > 0,
49
+ worksheets: matchedSheets,
50
+ };
51
+ },
52
+ });
@@ -0,0 +1,112 @@
1
+ import { createAction, Property } from '@guayaba/workflows-framework';
2
+ import { areSheetIdsValid, createGoogleClient } from '../common/common';
3
+ import { googleSheetsAuth } from '../common/common';
4
+ import { commonProps } from '../common/props';
5
+ import { google } from 'googleapis';
6
+ import { isNil } from '@guayaba/workflows-shared';
7
+
8
+ export const formatRowAction = createAction({
9
+ auth: googleSheetsAuth,
10
+ name: 'format-row',
11
+ description: 'Format one or multiple rows in specific spreadsheet.',
12
+ displayName: 'Format Row(s)',
13
+ props: {
14
+ ...commonProps,
15
+ startingRow: Property.Number({
16
+ displayName: 'Starting row',
17
+ description: 'The first row number where formatting should begin.',
18
+ required: true,
19
+ }),
20
+ endingRow: Property.Number({
21
+ displayName: 'Ending row',
22
+ description:
23
+ 'The last row number where formatting should stop (leave empty to format only the starting row).',
24
+ required: false,
25
+ }),
26
+ bgColor: Property.ShortText({
27
+ displayName: 'Background Color',
28
+ description: 'Provide a HEX color code (example: #FFD966)',
29
+ required: false,
30
+ }),
31
+ textColor: Property.ShortText({
32
+ displayName: 'Text Color',
33
+ description: 'Provide a HEX color code (example: #FFD966)',
34
+ required: false,
35
+ }),
36
+ bold: Property.Checkbox({
37
+ displayName: 'Make text bold',
38
+ required: false,
39
+ }),
40
+ italic: Property.Checkbox({
41
+ displayName: 'Make text Italic',
42
+ required: false,
43
+ }),
44
+ strikethrough: Property.Checkbox({
45
+ displayName: 'Make text Strikethrough',
46
+ required: false,
47
+ }),
48
+ },
49
+ async run(context) {
50
+ const { spreadsheetId, sheetId, startingRow,endingRow, bgColor, textColor, italic, bold, strikethrough } =
51
+ context.propsValue;
52
+
53
+ if (!areSheetIdsValid(spreadsheetId, sheetId)) {
54
+ throw new Error('Please select a spreadsheet and sheet first.');
55
+ }
56
+
57
+ const authClient = await createGoogleClient(context.auth);
58
+ const sheets = google.sheets({ version: 'v4', auth: authClient });
59
+
60
+ const response = await sheets.spreadsheets.batchUpdate({
61
+ spreadsheetId: context.propsValue.spreadsheetId,
62
+ requestBody: {
63
+ requests: [
64
+ {
65
+ repeatCell: {
66
+ range: {
67
+ sheetId,
68
+ startRowIndex: startingRow - 1,
69
+ endRowIndex: endingRow ? endingRow : startingRow,
70
+ },
71
+ cell: {
72
+ userEnteredFormat: {
73
+ backgroundColor: hexToRgb(bgColor),
74
+ textFormat: {
75
+ bold,
76
+ italic,
77
+ strikethrough,
78
+ foregroundColor: hexToRgb(textColor),
79
+ },
80
+ },
81
+ },
82
+ fields: 'userEnteredFormat(backgroundColor,textFormat)',
83
+ },
84
+ },
85
+ ],
86
+ },
87
+ });
88
+
89
+ return {
90
+ success: true,
91
+ ...response.data,
92
+ };
93
+ },
94
+ });
95
+
96
+ function hexToRgb(hex?: string) {
97
+ // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
98
+ if (isNil(hex)) return undefined;
99
+ const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
100
+ hex = hex.replace(shorthandRegex, function (m, r, g, b) {
101
+ return r + r + g + g + b + b;
102
+ });
103
+
104
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
105
+ return result
106
+ ? {
107
+ red: parseInt(result[1], 16),
108
+ green: parseInt(result[2], 16),
109
+ blue: parseInt(result[3], 16),
110
+ }
111
+ : undefined;
112
+ }
@@ -0,0 +1,42 @@
1
+ import { createAction } from "@guayaba/workflows-framework";
2
+ import { areSheetIdsValid, googleSheetsAuth, googleSheetsCommon, mapRowsToHeaderNames } from "../common/common";
3
+ import { commonProps, isFirstRowHeaderProp } from "../common/props";
4
+
5
+ export const getManyRowsAction = createAction({
6
+ name: 'get-many-rows',
7
+ auth: googleSheetsAuth,
8
+ displayName: 'Get All Rows',
9
+ description: 'Get all the rows from a specific sheet.',
10
+ props: {
11
+ ...commonProps,
12
+ first_row_headers: isFirstRowHeaderProp()
13
+ },
14
+ async run(context) {
15
+ const {first_row_headers,sheetId,spreadsheetId} = context.propsValue;
16
+
17
+ if (!areSheetIdsValid(spreadsheetId, sheetId)) {
18
+ throw new Error('Please select a spreadsheet and sheet first.');
19
+ }
20
+ const rows = await googleSheetsCommon.getGoogleSheetRows({
21
+ auth:context.auth,
22
+ sheetId: sheetId as number,
23
+ spreadsheetId: spreadsheetId as string,
24
+ rowIndex_s:undefined,
25
+ rowIndex_e:undefined,
26
+ headerRow: 1,
27
+ });
28
+
29
+ const useHeaderNames = first_row_headers;
30
+
31
+ const result = await mapRowsToHeaderNames(
32
+ rows,
33
+ useHeaderNames,
34
+ spreadsheetId as string,
35
+ sheetId as number,
36
+ 1,
37
+ context.auth
38
+ )
39
+
40
+ return result
41
+ }
42
+ })
@@ -0,0 +1,207 @@
1
+ import {
2
+ PiecePropValueSchema,
3
+ Property,
4
+ Store,
5
+ StoreScope,
6
+ createAction,
7
+ } from '@guayaba/workflows-framework';
8
+ import { googleSheetsAuth } from '../common/common';
9
+ import {
10
+ areSheetIdsValid,
11
+ GoogleSheetsAuthValue,
12
+ googleSheetsCommon,
13
+ mapRowsToHeaderNames,
14
+ } from '../common/common';
15
+ import { isNil } from '@guayaba/workflows-shared';
16
+ import { HttpError } from '@guayaba/workflows-common';
17
+ import { z } from 'zod';
18
+ import { propsValidation } from '@guayaba/workflows-common';
19
+ import { getWorkSheetGridSize } from '../triggers/helpers';
20
+ import { commonProps } from '../common/props';
21
+
22
+ async function getRows(
23
+ store: Store,
24
+ auth: GoogleSheetsAuthValue,
25
+ spreadsheetId: string,
26
+ sheetId: number,
27
+ memKey: string,
28
+ groupSize: number,
29
+ startRow: number,
30
+ headerRow: number,
31
+ useHeaderNames: boolean,
32
+ testing: boolean
33
+ ) {
34
+ const sheetGridRange = await getWorkSheetGridSize(auth,spreadsheetId,sheetId);
35
+ const existingGridRowCount = sheetGridRange.rowCount ??0;
36
+ const memVal = await store.get(memKey, StoreScope.FLOW);
37
+
38
+ let startingRow;
39
+ if (isNil(memVal) || memVal === '') startingRow = startRow || 1;
40
+ else {
41
+ startingRow = parseInt(memVal as string);
42
+ if (isNaN(startingRow)) {
43
+ throw Error(
44
+ 'The value stored in memory key : ' +
45
+ memKey +
46
+ ' is ' +
47
+ memVal +
48
+ ' and it is not a number'
49
+ );
50
+ }
51
+ }
52
+
53
+ if (startingRow < 1)
54
+ throw Error('Starting row : ' + startingRow + ' is less than 1' + memVal);
55
+
56
+
57
+ if(startingRow > existingGridRowCount-1){
58
+ return [];
59
+ }
60
+
61
+ const endRow = Math.min(startingRow + groupSize,existingGridRowCount);
62
+
63
+ if (testing == false) await store.put(memKey, endRow, StoreScope.FLOW);
64
+
65
+ const row = await googleSheetsCommon.getGoogleSheetRows({
66
+ auth,
67
+ sheetId: sheetId,
68
+ spreadsheetId: spreadsheetId,
69
+ rowIndex_s: startingRow,
70
+ rowIndex_e: endRow - 1,
71
+ headerRow: headerRow,
72
+ });
73
+
74
+ if (row.length == 0) {
75
+ const allRows = await googleSheetsCommon.getGoogleSheetRows({
76
+ spreadsheetId: spreadsheetId,
77
+ auth,
78
+ sheetId: sheetId,
79
+ rowIndex_s: undefined,
80
+ rowIndex_e: undefined,
81
+ headerRow: headerRow,
82
+ });
83
+ const lastRow = allRows.length + 1;
84
+ if (testing == false) await store.put(memKey, lastRow, StoreScope.FLOW);
85
+ }
86
+
87
+ const finalRows = await mapRowsToHeaderNames(
88
+ row,
89
+ useHeaderNames,
90
+ spreadsheetId,
91
+ sheetId,
92
+ headerRow,
93
+ auth,
94
+ );
95
+
96
+ return finalRows;
97
+ }
98
+
99
+ const notes = `
100
+ **Notes:**
101
+
102
+ - Memory key is used to remember where last row was processed and will be used in the following runs.
103
+ - Republishing the flow **keeps** the memory key value, If you want to start over **change** the memory key.
104
+ `
105
+ export const getRowsAction = createAction({
106
+ auth: googleSheetsAuth,
107
+ name: 'get_next_rows',
108
+ description: 'Get next group of rows from a specifiec workheet',
109
+ displayName: 'Get next row(s)',
110
+ props: {
111
+ ...commonProps,
112
+ startRow: Property.Number({
113
+ displayName: 'Start Row',
114
+ description: 'Which row to start from?',
115
+ required: true,
116
+ defaultValue: 1,
117
+ }),
118
+ headerRow: Property.Number({
119
+ displayName: 'Header Row',
120
+ description: 'Which row contains the headers?',
121
+ required: true,
122
+ defaultValue: 1,
123
+ }),
124
+ useHeaderNames: Property.Checkbox({
125
+ displayName: 'Use header names for keys',
126
+ description: 'Map A/B/C… to the actual column headers (row specified above).',
127
+ required: false,
128
+ defaultValue: false,
129
+ }),
130
+ markdown: Property.MarkDown({
131
+ value: notes
132
+ }),
133
+ memKey: Property.ShortText({
134
+ displayName: 'Memory Key',
135
+ description: 'The key used to store the current row number in memory',
136
+ required: true,
137
+ defaultValue: 'row_number',
138
+ }),
139
+ groupSize: Property.Number({
140
+ displayName: 'Group Size',
141
+ description: 'The number of rows to get',
142
+ required: true,
143
+ defaultValue: 1,
144
+ }),
145
+ },
146
+ async run({ store, auth, propsValue }) {
147
+ const { startRow, groupSize, memKey, headerRow, spreadsheetId, sheetId, useHeaderNames} = propsValue;
148
+
149
+ if (!areSheetIdsValid(spreadsheetId, sheetId)) {
150
+ throw new Error('Please select a spreadsheet and sheet first.');
151
+ }
152
+
153
+ await propsValidation.validateZod(propsValue, {
154
+ startRow: z.number().min(1),
155
+ groupSize: z.number().min(1),
156
+ });
157
+
158
+ try {
159
+ return await getRows(
160
+ store,
161
+ auth,
162
+ spreadsheetId as string,
163
+ sheetId as number,
164
+ memKey,
165
+ groupSize,
166
+ startRow,
167
+ headerRow,
168
+ useHeaderNames as boolean,
169
+ false
170
+ );
171
+ } catch (error) {
172
+ if (error instanceof HttpError) {
173
+ const errorBody = error.response.body as any;
174
+ throw new Error(errorBody['error']['message']);
175
+ }
176
+ throw error;
177
+ }
178
+ },
179
+ async test({ store, auth, propsValue }) {
180
+ const { startRow, groupSize, memKey, headerRow, spreadsheetId, sheetId, useHeaderNames} = propsValue;
181
+
182
+ if (!areSheetIdsValid(spreadsheetId, sheetId)) {
183
+ throw new Error('Please select a spreadsheet and sheet first.');
184
+ }
185
+
186
+ try {
187
+ return await getRows(
188
+ store,
189
+ auth,
190
+ spreadsheetId as string,
191
+ sheetId as number,
192
+ memKey,
193
+ groupSize,
194
+ startRow,
195
+ headerRow,
196
+ useHeaderNames as boolean,
197
+ true
198
+ );
199
+ } catch (error) {
200
+ if (error instanceof HttpError) {
201
+ const errorBody = error.response.body as any;
202
+ throw new Error(errorBody['error']['message']);
203
+ }
204
+ throw error;
205
+ }
206
+ },
207
+ });