google-spreadsheet 5.0.1 → 5.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "google-spreadsheet",
3
- "version": "5.0.1",
3
+ "version": "5.0.3",
4
4
  "description": "Google Sheets API -- simple interface to read/write data and manage sheets",
5
5
  "keywords": [
6
6
  "google spreadsheets",
@@ -39,26 +39,37 @@
39
39
  "src/index.ts",
40
40
  "src/lib"
41
41
  ],
42
- "dependencies": {},
42
+ "scripts": {
43
+ "build": "tsdown",
44
+ "dev": "tsdown --watch",
45
+ "docs:preview": "docsify serve docs",
46
+ "lint": "eslint ./ --ext .ts",
47
+ "lint:fix": "bun run lint --fix",
48
+ "nodev": "node -v",
49
+ "readme:copy": "echo \"<!-- DO NOT EDIT THIS FILE, EDIT MAIN README.md AND RUN \\`bun readme:copy\\` instead -->\n\n_Welcome to the docs site for_\n\" | cat - README.md > docs/README.md",
50
+ "test": "vitest",
51
+ "test:ci": "vitest run"
52
+ },
53
+ "dependencies": {
54
+ "es-toolkit": "^1.44.0",
55
+ "ky": "^1.14.3"
56
+ },
43
57
  "devDependencies": {
44
- "@changesets/cli": "^2.29.5",
45
- "@types/node": "^24.2.0",
58
+ "@changesets/cli": "^2.29.8",
59
+ "@types/node": "^25.2.3",
46
60
  "@typescript-eslint/eslint-plugin": "^5.59.7",
47
61
  "@typescript-eslint/parser": "^5.59.7",
48
- "auto-changelog": "^2.4.0",
49
62
  "docsify-cli": "^4.4.4",
50
- "es-toolkit": "^1.39.8",
51
63
  "eslint": "^8.41.0",
52
64
  "eslint-config-airbnb-base": "^15.0.0",
53
65
  "eslint-config-airbnb-typescript": "^17.0.0",
54
66
  "eslint-plugin-import": "^2.27.5",
55
67
  "eslint-plugin-no-floating-promise": "^1.0.2",
56
- "google-auth-library": "^10.2.1",
57
- "ky": "^1.8.2",
58
- "tsup": "^8.5.0",
59
- "typescript": "^5.5.4",
60
- "varlock": "^0.0.7",
61
- "vitest": "^3.2.4"
68
+ "google-auth-library": "^10.5.0",
69
+ "tsdown": "^0.20.3",
70
+ "typescript": "^5.9.3",
71
+ "varlock": "^0.2.2",
72
+ "vitest": "^4.0.18"
62
73
  },
63
74
  "peerDependencies": {
64
75
  "google-auth-library": ">=8.8.0"
@@ -67,19 +78,5 @@
67
78
  "google-auth-library": {
68
79
  "optional": true
69
80
  }
70
- },
71
- "volta": {
72
- "node": "20.17.0"
73
- },
74
- "scripts": {
75
- "build": "tsup",
76
- "dev": "tsup --watch",
77
- "docs:preview": "docsify serve docs",
78
- "lint": "eslint ./ --ext .ts",
79
- "lint:fix": "pnpm run lint --fix",
80
- "nodev": "node -v",
81
- "readme:copy": "echo \"<!-- DO NOT EDIT THIS FILE, EDIT MAIN README.md AND RUN \\`npm readme:copy\\` instead -->\n\n_Welcome to the docs site for_\n\" | cat - README.md > docs/README.md",
82
- "test": "vitest",
83
- "test:ci": "vitest run"
84
81
  }
85
82
  }
@@ -3,7 +3,8 @@ import * as _ from './toolkit';
3
3
  import { GoogleSpreadsheetWorksheet } from './GoogleSpreadsheetWorksheet';
4
4
  import { getFieldMask } from './utils';
5
5
  import {
6
- DataFilter, GridRange, NamedRangeId, SpreadsheetId, SpreadsheetProperties, WorksheetId, WorksheetProperties,
6
+ DataFilter, GridRange, NamedRangeId, ProtectedRange,
7
+ SpreadsheetId, SpreadsheetProperties, WorksheetId, WorksheetProperties,
7
8
  } from './types/sheets-types';
8
9
  import { PermissionRoles, PermissionsList, PublicPermissionRoles } from './types/drive-types';
9
10
  import { RecursivePartial } from './types/util-types';
@@ -125,6 +126,7 @@ export class GoogleSpreadsheet {
125
126
  // create a ky instance with sheet root URL and hooks to handle auth
126
127
  this.sheetsApi = ky.create({
127
128
  prefixUrl: `${SHEETS_API_BASE_URL}/${spreadsheetId}`,
129
+ timeout: 180_000,
128
130
  hooks: {
129
131
  beforeRequest: [(r) => this._setAuthRequestHook(r)],
130
132
  beforeError: [(e) => this._errorHook(e)],
@@ -143,7 +145,7 @@ export class GoogleSpreadsheet {
143
145
  // INTERNAL UTILITY FUNCTIONS ////////////////////////////////////////////////////////////////////
144
146
 
145
147
  /** @internal */
146
- async _setAuthRequestHook(req: Request) {
148
+ async _setAuthRequestHook(req: Request): Promise<Request> {
147
149
  const authConfig = await getRequestAuthConfig(this.auth);
148
150
  if (authConfig.headers) {
149
151
  Object.entries(authConfig.headers).forEach(([key, val]) => {
@@ -239,13 +241,13 @@ export class GoogleSpreadsheet {
239
241
  _updateRawProperties(newProperties: SpreadsheetProperties) { this._rawProperties = newProperties; }
240
242
 
241
243
  /** @internal */
242
- _updateOrCreateSheet(sheetInfo: { properties: WorksheetProperties, data: any }) {
243
- const { properties, data } = sheetInfo;
244
+ _updateOrCreateSheet(sheetInfo: { properties: WorksheetProperties, data: any, protectedRanges?: ProtectedRange[] }) {
245
+ const { properties, data, protectedRanges } = sheetInfo;
244
246
  const { sheetId } = properties;
245
247
  if (!this._rawSheets[sheetId]) {
246
- this._rawSheets[sheetId] = new GoogleSpreadsheetWorksheet(this, properties, data);
248
+ this._rawSheets[sheetId] = new GoogleSpreadsheetWorksheet(this, properties, data, protectedRanges);
247
249
  } else {
248
- this._rawSheets[sheetId].updateRawData(properties, data);
250
+ this._rawSheets[sheetId].updateRawData(properties, data, protectedRanges);
249
251
  }
250
252
  }
251
253
 
@@ -367,9 +369,11 @@ export class GoogleSpreadsheet {
367
369
  ) {
368
370
  // TODO: add named range to local cache
369
371
  return this._makeSingleUpdateRequest('addNamedRange', {
370
- name,
371
- namedRangeId,
372
- range,
372
+ namedRange: {
373
+ name,
374
+ namedRangeId,
375
+ range,
376
+ },
373
377
  });
374
378
  }
375
379
 
@@ -619,6 +623,14 @@ export class GoogleSpreadsheet {
619
623
  return shareReq.json();
620
624
  }
621
625
 
626
+ /**
627
+ * delete a permission by its ID
628
+ * @see https://developers.google.com/drive/api/v3/reference/permissions/delete
629
+ */
630
+ async deletePermission(permissionId: string) {
631
+ await this.driveApi.delete(`permissions/${permissionId}`);
632
+ }
633
+
622
634
  //
623
635
  // CREATE NEW DOC ////////////////////////////////////////////////////////////////////////////////
624
636
  static async createNewSpreadsheetDocument(auth: GoogleApiAuth, properties?: Partial<SpreadsheetProperties>) {
@@ -13,6 +13,7 @@ import {
13
13
  RowIndex, ColumnIndex, DataFilterWithoutWorksheetId, DataFilter, GetValuesRequestOptions, WorksheetGridProperties,
14
14
  WorksheetDimensionProperties, CellDataRange, AddRowOptions, GridRangeWithOptionalWorksheetId,
15
15
  DataValidationRule,
16
+ ProtectedRange, Integer,
16
17
  } from './types/sheets-types';
17
18
 
18
19
 
@@ -29,6 +30,7 @@ export class GoogleSpreadsheetWorksheet {
29
30
  private _cells: GoogleSpreadsheetCell[][] = [];
30
31
  private _rowMetadata: any[] = [];
31
32
  private _columnMetadata: any[] = [];
33
+ private _protectedRanges: ProtectedRange[] | null = null;
32
34
 
33
35
  private _headerValues: string[] | undefined;
34
36
  get headerValues() {
@@ -42,7 +44,8 @@ export class GoogleSpreadsheetWorksheet {
42
44
  /** parent GoogleSpreadsheet instance */
43
45
  readonly _spreadsheet: GoogleSpreadsheet,
44
46
  rawProperties: WorksheetProperties,
45
- rawCellData?: CellDataRange[]
47
+ rawCellData?: CellDataRange[],
48
+ protectedRanges?: ProtectedRange[]
46
49
  ) {
47
50
  this._headerRowIndex = 1;
48
51
 
@@ -53,15 +56,17 @@ export class GoogleSpreadsheetWorksheet {
53
56
 
54
57
  this._rowMetadata = []; // 1d sparse array
55
58
  this._columnMetadata = [];
59
+ if (protectedRanges) this._protectedRanges = protectedRanges;
56
60
 
57
61
  if (rawCellData) this._fillCellData(rawCellData);
58
62
  }
59
63
 
60
64
  // INTERNAL UTILITY FUNCTIONS ////////////////////////////////////////////////////////////////////
61
65
 
62
- updateRawData(properties: WorksheetProperties, rawCellData: CellDataRange[]) {
66
+ updateRawData(properties: WorksheetProperties, rawCellData: CellDataRange[], protectedRanges?: ProtectedRange[]) {
63
67
  this._rawProperties = properties;
64
68
  this._fillCellData(rawCellData);
69
+ if (protectedRanges) this._protectedRanges = protectedRanges;
65
70
  }
66
71
 
67
72
  async _makeSingleUpdateRequest(requestType: string, requestParams: any) {
@@ -166,6 +171,7 @@ export class GoogleSpreadsheetWorksheet {
166
171
  get hidden() { return this._getProp('hidden'); }
167
172
  get tabColor() { return this._getProp('tabColor'); }
168
173
  get rightToLeft() { return this._getProp('rightToLeft'); }
174
+ get protectedRanges() { return this._protectedRanges; }
169
175
  private get _headerRange() {
170
176
  return `A${this._headerRowIndex}:${this.lastColumnLetter}${this._headerRowIndex}`;
171
177
  }
@@ -788,9 +794,20 @@ export class GoogleSpreadsheetWorksheet {
788
794
  });
789
795
  }
790
796
 
791
- async insertRange() {
792
- // Request type = `insertRange`
793
- // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#InsertRangeRequest
797
+ /**
798
+ * insert empty cells in a range, shifting existing cells in the specified direction
799
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#InsertRangeRequest
800
+ */
801
+ async insertRange(
802
+ /** the range to insert new cells into */
803
+ range: GridRangeWithOptionalWorksheetId,
804
+ /** which direction to shift existing cells - ROWS (shift down) or COLUMNS (shift right) */
805
+ shiftDimension: WorksheetDimension
806
+ ) {
807
+ return this._makeSingleUpdateRequest('insertRange', {
808
+ range: this._addSheetIdToRange(range),
809
+ shiftDimension,
810
+ });
794
811
  }
795
812
 
796
813
  async moveDimension() {
@@ -871,24 +888,57 @@ export class GoogleSpreadsheetWorksheet {
871
888
  // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#SetBasicFilterRequest
872
889
  }
873
890
 
874
- async addProtectedRange() {
875
- // Request type = `addProtectedRange`
876
- // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#AddProtectedRangeRequest
891
+ /**
892
+ * add a new protected range to the sheet
893
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#AddProtectedRangeRequest
894
+ */
895
+ async addProtectedRange(protectedRange: ProtectedRange) {
896
+ if (!protectedRange.range && !protectedRange.namedRangeId) {
897
+ throw new Error('No range specified: either range or namedRangeId is required');
898
+ }
899
+ return this._makeSingleUpdateRequest('addProtectedRange', {
900
+ protectedRange,
901
+ });
877
902
  }
878
903
 
879
- async updateProtectedRange() {
880
- // Request type = `updateProtectedRange`
881
- // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#UpdateProtectedRangeRequest
904
+ /**
905
+ * update an existing protected range
906
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#UpdateProtectedRangeRequest
907
+ */
908
+ async updateProtectedRange(protectedRangeId: Integer, protectedRange: Partial<ProtectedRange>) {
909
+ return this._makeSingleUpdateRequest('updateProtectedRange', {
910
+ protectedRange: { protectedRangeId, ...protectedRange },
911
+ fields: getFieldMask(protectedRange as Record<string, unknown>),
912
+ });
882
913
  }
883
914
 
884
- async deleteProtectedRange() {
885
- // Request type = `deleteProtectedRange`
886
- // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#DeleteProtectedRangeRequest
915
+ /**
916
+ * delete a protected range by ID
917
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#DeleteProtectedRangeRequest
918
+ */
919
+ async deleteProtectedRange(protectedRangeId: Integer) {
920
+ return this._makeSingleUpdateRequest('deleteProtectedRange', {
921
+ protectedRangeId,
922
+ });
887
923
  }
888
924
 
889
- async autoResizeDimensions() {
890
- // Request type = `autoResizeDimensions`
891
- // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#AutoResizeDimensionsRequest
925
+ /**
926
+ * auto-resize rows or columns to fit their contents
927
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#AutoResizeDimensionsRequest
928
+ */
929
+ async autoResizeDimensions(
930
+ /** which dimension to auto-resize */
931
+ columnsOrRows: WorksheetDimension,
932
+ /** start and end indexes (optional, defaults to all) */
933
+ rangeIndexes?: DimensionRangeIndexes
934
+ ) {
935
+ return this._makeSingleUpdateRequest('autoResizeDimensions', {
936
+ dimensions: {
937
+ sheetId: this.sheetId,
938
+ dimension: columnsOrRows,
939
+ ...rangeIndexes,
940
+ },
941
+ });
892
942
  }
893
943
 
894
944
  async addChart() {
@@ -413,6 +413,41 @@ export type GridRangeWithOptionalWorksheetId = MakeOptional<GridRange, 'sheetId'
413
413
  export type DataFilter = A1Range | GridRange;
414
414
  export type DataFilterWithoutWorksheetId = A1Range | GridRangeWithoutWorksheetId;
415
415
 
416
+ /**
417
+ * object describing the editors of a protected range
418
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/sheets#Editors
419
+ * */
420
+ export type Editors = {
421
+ /** The email addresses of users with edit access to the protected range. */
422
+ users?: string[],
423
+ /** The email addresses of groups with edit access to the protected range. */
424
+ groups?: string[],
425
+ /** True if anyone in the document's domain has edit access to the protected range. */
426
+ domainUsersCanEdit?: boolean
427
+ };
428
+
429
+ /**
430
+ * object describing a protected range in a sheet
431
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/sheets#ProtectedRange
432
+ * */
433
+ export type ProtectedRange = {
434
+ /** The ID of the protected range - read-only, auto-assigned */
435
+ protectedRangeId?: Integer,
436
+ /** The range that is being protected - mutually exclusive with namedRangeId */
437
+ range?: GridRange,
438
+ /** The named range this protected range is backed by - mutually exclusive with range */
439
+ namedRangeId?: NamedRangeId,
440
+ /** The description of this protected range */
441
+ description?: string,
442
+ /** True if this protected range will show a warning when editing. When true, editors is ignored. */
443
+ warningOnly?: boolean,
444
+ /** True if the user who requested this protected range can edit the protected area - read-only */
445
+ requestingUserCanEdit?: boolean,
446
+ /** The list of unprotected ranges within a protected sheet. Only supported on protected sheets. */
447
+ unprotectedRanges?: GridRange[],
448
+ /** The users and groups with edit access to the protected range. Not supported with warningOnly. */
449
+ editors?: Editors
450
+ };
416
451
 
417
452
  /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#colorstyle */
418
453
  export type ColorStyle = { rgbColor: Color } | { themeColor: ThemeColorType };