google-spreadsheet 5.0.3 → 5.2.0
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/README.md +2 -0
- package/dist/index.cjs +596 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +654 -61
- package/dist/index.d.ts +654 -61
- package/dist/index.js +596 -58
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/lib/GoogleSpreadsheet.ts +47 -11
- package/src/lib/GoogleSpreadsheetCell.ts +26 -4
- package/src/lib/GoogleSpreadsheetRow.ts +20 -1
- package/src/lib/GoogleSpreadsheetWorksheet.ts +808 -128
- package/src/lib/types/sheets-types.ts +257 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "google-spreadsheet",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "Google Sheets API -- simple interface to read/write data and manage sheets",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"google spreadsheets",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"eslint-plugin-import": "^2.27.5",
|
|
67
67
|
"eslint-plugin-no-floating-promise": "^1.0.2",
|
|
68
68
|
"google-auth-library": "^10.5.0",
|
|
69
|
+
"nock": "^14.0.11",
|
|
69
70
|
"tsdown": "^0.20.3",
|
|
70
71
|
"typescript": "^5.9.3",
|
|
71
72
|
"varlock": "^0.2.2",
|
|
@@ -79,4 +80,4 @@
|
|
|
79
80
|
"optional": true
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
|
-
}
|
|
83
|
+
}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import ky, { HTTPError, KyInstance } from 'ky'; // eslint-disable-line import/no-extraneous-dependencies
|
|
1
|
+
import ky, { HTTPError, KyInstance, RetryOptions } from 'ky'; // eslint-disable-line import/no-extraneous-dependencies
|
|
2
2
|
import * as _ from './toolkit';
|
|
3
3
|
import { GoogleSpreadsheetWorksheet } from './GoogleSpreadsheetWorksheet';
|
|
4
4
|
import { getFieldMask } from './utils';
|
|
5
5
|
import {
|
|
6
|
-
DataFilter,
|
|
7
|
-
|
|
6
|
+
DataFilter,
|
|
7
|
+
DataFilterObject,
|
|
8
|
+
DeveloperMetadata,
|
|
9
|
+
GridRange,
|
|
10
|
+
NamedRangeId,
|
|
11
|
+
ProtectedRange,
|
|
12
|
+
SpreadsheetId,
|
|
13
|
+
SpreadsheetProperties,
|
|
14
|
+
WorksheetId,
|
|
15
|
+
WorksheetProperties,
|
|
8
16
|
} from './types/sheets-types';
|
|
9
17
|
import { PermissionRoles, PermissionsList, PublicPermissionRoles } from './types/drive-types';
|
|
10
18
|
import { RecursivePartial } from './types/util-types';
|
|
@@ -112,11 +120,20 @@ export class GoogleSpreadsheet {
|
|
|
112
120
|
* @category Initialization
|
|
113
121
|
* */
|
|
114
122
|
constructor(
|
|
115
|
-
/** id of
|
|
123
|
+
/** id of Google spreadsheet doc */
|
|
116
124
|
spreadsheetId: SpreadsheetId,
|
|
117
125
|
/** authentication to use with Google Sheets API */
|
|
118
|
-
auth: GoogleApiAuth
|
|
126
|
+
auth: GoogleApiAuth,
|
|
127
|
+
/** Additional options */
|
|
128
|
+
options?: {
|
|
129
|
+
/**
|
|
130
|
+
* customize retry behavior --
|
|
131
|
+
* see the [ky documentation](https://github.com/sindresorhus/ky#retry) for details of the available options and defaults.
|
|
132
|
+
* */
|
|
133
|
+
retryConfig?: RetryOptions | number
|
|
134
|
+
}
|
|
119
135
|
) {
|
|
136
|
+
const { retryConfig } = options || {};
|
|
120
137
|
this.spreadsheetId = spreadsheetId;
|
|
121
138
|
this.auth = auth;
|
|
122
139
|
|
|
@@ -131,6 +148,7 @@ export class GoogleSpreadsheet {
|
|
|
131
148
|
beforeRequest: [(r) => this._setAuthRequestHook(r)],
|
|
132
149
|
beforeError: [(e) => this._errorHook(e)],
|
|
133
150
|
},
|
|
151
|
+
retry: retryConfig,
|
|
134
152
|
});
|
|
135
153
|
this.driveApi = ky.create({
|
|
136
154
|
prefixUrl: `${DRIVE_API_BASE_URL}/${spreadsheetId}`,
|
|
@@ -138,6 +156,7 @@ export class GoogleSpreadsheet {
|
|
|
138
156
|
beforeRequest: [(r) => this._setAuthRequestHook(r)],
|
|
139
157
|
beforeError: [(e) => this._errorHook(e)],
|
|
140
158
|
},
|
|
159
|
+
retry: retryConfig,
|
|
141
160
|
});
|
|
142
161
|
}
|
|
143
162
|
|
|
@@ -395,15 +414,12 @@ export class GoogleSpreadsheet {
|
|
|
395
414
|
async loadCells(
|
|
396
415
|
/**
|
|
397
416
|
* single filter or array of filters
|
|
398
|
-
* strings are treated as A1 ranges, objects are treated as GridRange objects
|
|
417
|
+
* strings are treated as A1 ranges, objects are treated as GridRange objects,
|
|
418
|
+
* objects with a `developerMetadataLookup` key are treated as DeveloperMetadataLookup filters
|
|
399
419
|
* pass nothing to fetch all cells
|
|
400
420
|
* */
|
|
401
421
|
filters?: DataFilter | DataFilter[]
|
|
402
422
|
) {
|
|
403
|
-
// TODO: make it support DeveloperMetadataLookup objects
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
423
|
// TODO: switch to this mode if using a read-only auth token?
|
|
408
424
|
const readOnlyMode = this.authMode === AUTH_MODES.API_KEY;
|
|
409
425
|
|
|
@@ -416,7 +432,9 @@ export class GoogleSpreadsheet {
|
|
|
416
432
|
if (readOnlyMode) {
|
|
417
433
|
throw new Error('Only A1 ranges are supported when fetching cells with read-only access (using only an API key)');
|
|
418
434
|
}
|
|
419
|
-
|
|
435
|
+
if ('developerMetadataLookup' in filter) {
|
|
436
|
+
return { developerMetadataLookup: filter.developerMetadataLookup };
|
|
437
|
+
}
|
|
420
438
|
return { gridRange: filter };
|
|
421
439
|
}
|
|
422
440
|
throw new Error('Each filter must be an A1 range string or a gridrange object');
|
|
@@ -631,6 +649,24 @@ export class GoogleSpreadsheet {
|
|
|
631
649
|
await this.driveApi.delete(`permissions/${permissionId}`);
|
|
632
650
|
}
|
|
633
651
|
|
|
652
|
+
// DEVELOPER METADATA ///////////////////////////////////////////////////////////////////////////
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* search for developer metadata entries matching the given filters
|
|
656
|
+
* @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.developerMetadata/search
|
|
657
|
+
*/
|
|
658
|
+
async searchDeveloperMetadata(
|
|
659
|
+
/** array of DataFilter objects to match against */
|
|
660
|
+
filters: DataFilterObject[]
|
|
661
|
+
): Promise<DeveloperMetadata[]> {
|
|
662
|
+
const response = await this.sheetsApi.post('developerMetadata:search', {
|
|
663
|
+
json: { dataFilters: filters },
|
|
664
|
+
});
|
|
665
|
+
const data = await response.json<any>();
|
|
666
|
+
if (!data.matchedDeveloperMetadata) return [];
|
|
667
|
+
return data.matchedDeveloperMetadata.map((m: any) => m.developerMetadata);
|
|
668
|
+
}
|
|
669
|
+
|
|
634
670
|
//
|
|
635
671
|
// CREATE NEW DOC ////////////////////////////////////////////////////////////////////////////////
|
|
636
672
|
static async createNewSpreadsheetDocument(auth: GoogleApiAuth, properties?: Partial<SpreadsheetProperties>) {
|
|
@@ -15,6 +15,7 @@ export class GoogleSpreadsheetCell {
|
|
|
15
15
|
private _rawData?: CellData;
|
|
16
16
|
private _draftData: any = {};
|
|
17
17
|
private _error?: GoogleSpreadsheetCellErrorValue;
|
|
18
|
+
private _deleted = false;
|
|
18
19
|
|
|
19
20
|
constructor(
|
|
20
21
|
readonly _sheet: GoogleSpreadsheetWorksheet,
|
|
@@ -26,6 +27,8 @@ export class GoogleSpreadsheetCell {
|
|
|
26
27
|
this._rawData = rawCellData; // so TS does not complain
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
get deleted() { return this._deleted; }
|
|
31
|
+
|
|
29
32
|
// TODO: figure out how to deal with empty rawData
|
|
30
33
|
// newData can be undefined/null if the cell is totally empty and unformatted
|
|
31
34
|
/**
|
|
@@ -49,6 +52,25 @@ export class GoogleSpreadsheetCell {
|
|
|
49
52
|
get a1Row() { return this._rowIndex + 1; } // a1 row numbers start at 1 instead of 0
|
|
50
53
|
get a1Address() { return `${this.a1Column}${this.a1Row}`; }
|
|
51
54
|
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
* Used internally to update cell indices after deleting rows/columns.
|
|
58
|
+
* Should not be called directly.
|
|
59
|
+
*/
|
|
60
|
+
_updateIndices(rowIndex: RowIndex, columnIndex: ColumnIndex) {
|
|
61
|
+
this._rowIndex = rowIndex;
|
|
62
|
+
this._columnIndex = columnIndex;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @internal
|
|
67
|
+
* Used internally to mark cell as deleted.
|
|
68
|
+
* Should not be called directly.
|
|
69
|
+
*/
|
|
70
|
+
_markDeleted() {
|
|
71
|
+
this._deleted = true;
|
|
72
|
+
}
|
|
73
|
+
|
|
52
74
|
// CELL CONTENTS - VALUE/FORMULA/NOTES ///////////////////////////////////////////////////////////
|
|
53
75
|
get value(): number | boolean | string | null | GoogleSpreadsheetCellErrorValue {
|
|
54
76
|
// const typeKey = _.keys(this._rawData.effectiveValue)[0];
|
|
@@ -60,6 +82,8 @@ export class GoogleSpreadsheetCell {
|
|
|
60
82
|
|
|
61
83
|
|
|
62
84
|
set value(newValue: number | boolean | Date | string | null | undefined | GoogleSpreadsheetCellErrorValue) {
|
|
85
|
+
if (this._deleted) throw new Error('This cell has been deleted - reload cells before making updates.');
|
|
86
|
+
|
|
63
87
|
// had to include the GoogleSpreadsheetCellErrorValue in the type to make TS happy
|
|
64
88
|
if (newValue instanceof GoogleSpreadsheetCellErrorValue) {
|
|
65
89
|
throw new Error("You can't manually set a value to an error");
|
|
@@ -128,10 +152,8 @@ export class GoogleSpreadsheetCell {
|
|
|
128
152
|
return this.value as string;
|
|
129
153
|
}
|
|
130
154
|
set stringValue(val: string | undefined) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
this.value = val;
|
|
155
|
+
this._draftData.valueType = 'stringValue';
|
|
156
|
+
this._draftData.value = val || '';
|
|
135
157
|
}
|
|
136
158
|
|
|
137
159
|
/**
|
|
@@ -13,7 +13,15 @@ export class GoogleSpreadsheetRow<T extends Record<string, any> = Record<string,
|
|
|
13
13
|
/** raw underlying data for row */
|
|
14
14
|
private _rawData: any[]
|
|
15
15
|
) {
|
|
16
|
+
this._padRawData();
|
|
17
|
+
}
|
|
16
18
|
|
|
19
|
+
/** pad _rawData with empty strings so it always matches header length */
|
|
20
|
+
private _padRawData() {
|
|
21
|
+
const headerLength = this._worksheet.headerValues.length;
|
|
22
|
+
while (this._rawData.length < headerLength) {
|
|
23
|
+
this._rawData.push('');
|
|
24
|
+
}
|
|
17
25
|
}
|
|
18
26
|
|
|
19
27
|
private _deleted = false;
|
|
@@ -29,6 +37,16 @@ export class GoogleSpreadsheetRow<T extends Record<string, any> = Record<string,
|
|
|
29
37
|
_updateRowNumber(newRowNumber: number) {
|
|
30
38
|
this._rowNumber = newRowNumber;
|
|
31
39
|
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @internal
|
|
43
|
+
* Used internally to mark row as deleted.
|
|
44
|
+
* Should not be called directly.
|
|
45
|
+
*/
|
|
46
|
+
_markDeleted() {
|
|
47
|
+
this._deleted = true;
|
|
48
|
+
}
|
|
49
|
+
|
|
32
50
|
get a1Range() {
|
|
33
51
|
return [
|
|
34
52
|
this._worksheet.a1SheetName,
|
|
@@ -82,7 +100,8 @@ export class GoogleSpreadsheetRow<T extends Record<string, any> = Record<string,
|
|
|
82
100
|
},
|
|
83
101
|
});
|
|
84
102
|
const data = await response.json<any>();
|
|
85
|
-
this._rawData = data.updatedData.values[0];
|
|
103
|
+
this._rawData = data.updatedData.values?.[0] || [];
|
|
104
|
+
this._padRawData();
|
|
86
105
|
}
|
|
87
106
|
|
|
88
107
|
/** delete this row */
|