google-spreadsheet 4.1.1 → 4.1.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/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # google-spreadsheet
2
+
2
3
  > The most popular [Google Sheets API](https://developers.google.com/sheets/api/guides/concepts) wrapper for javascript / typescript
3
4
 
4
5
  [![NPM version](https://img.shields.io/npm/v/google-spreadsheet)](https://www.npmjs.com/package/google-spreadsheet)
5
- [![CircleCI](https://circleci.com/gh/theoephraim/node-google-spreadsheet.svg?style=shield)](https://circleci.com/gh/theoephraim/node-google-spreadsheet)
6
+ [![CI status](https://github.com/theoephraim/node-google-spreadsheet/actions/workflows/ci.yml/badge.svg)](https://github.com/theoephraim/node-google-spreadsheet/actions/workflows/ci.yml)
6
7
  [![Known Vulnerabilities](https://snyk.io/test/github/theoephraim/node-google-spreadsheet/badge.svg?targetFile=package.json)](https://snyk.io/test/github/theoephraim/node-google-spreadsheet?targetFile=package.json)
7
8
  [![NPM](https://img.shields.io/npm/dw/google-spreadsheet)](https://www.npmtrends.com/google-spreadsheet)
8
9
 
@@ -16,37 +17,35 @@
16
17
  **Docs site -**
17
18
  Full docs available at [https://theoephraim.github.io/node-google-spreadsheet](https://theoephraim.github.io/node-google-spreadsheet)
18
19
 
19
- -------------
20
+ ---
20
21
 
21
22
  > 🌈 **Installation** - `pnpm i google-spreadsheet`<br/>(or `npm i google-spreadsheet --save` or `yarn add google-spreadsheet`)
22
23
 
23
24
  ## Examples
25
+
24
26
  _The following examples are meant to give you an idea of just some of the things you can do_
25
27
 
26
- > **IMPORTANT NOTE** - To keep the examples concise, I'm calling await [at the top level](https://v8.dev/features/top-level-await) which is not allowed by default in most versions of node. If you need to call await in a script at the root level, you must instead wrap it in an async function like so:
28
+ > **IMPORTANT NOTE** - To keep the examples concise, I'm calling await [at the top level](https://v8.dev/features/top-level-await) which is not allowed in some older versions of node. If you need to call await in a script at the root level and your environment does not support it, you must instead wrap it in an async function like so:
27
29
 
28
30
  ```javascript
29
- (async function() {
31
+ (async function () {
30
32
  await someAsyncFunction();
31
- }());
33
+ })();
32
34
  ```
33
35
 
34
-
35
36
  ### The Basics
37
+
36
38
  ```js
37
39
  import { GoogleSpreadsheet } from 'google-spreadsheet';
38
40
  import { JWT } from 'google-auth-library';
39
41
 
40
-
41
42
  // Initialize auth - see https://theoephraim.github.io/node-google-spreadsheet/#/guides/authentication
42
43
  const serviceAccountAuth = new JWT({
43
44
  // env var values here are copied from service account credentials generated by google
44
45
  // see "Authentication" section in docs for more info
45
46
  email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
46
47
  key: process.env.GOOGLE_PRIVATE_KEY,
47
- scopes: [
48
- 'https://www.googleapis.com/auth/spreadsheets',
49
- ],
48
+ scopes: ['https://www.googleapis.com/auth/spreadsheets'],
50
49
  });
51
50
 
52
51
  const doc = new GoogleSpreadsheet('<the sheet ID from the url>', serviceAccountAuth);
@@ -63,14 +62,15 @@ console.log(sheet.rowCount);
63
62
  const newSheet = await doc.addSheet({ title: 'another sheet' });
64
63
  await newSheet.delete();
65
64
  ```
65
+
66
66
  More info:
67
+
67
68
  - [GoogleSpreadsheet](https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet)
68
69
  - [GoogleSpreadsheetWorksheet](https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet-worksheet)
69
70
  - [Authentication](https://theoephraim.github.io/node-google-spreadsheet/#/guides/authentication)
70
71
 
71
-
72
-
73
72
  ### Working with rows
73
+
74
74
  ```js
75
75
  // if creating a new sheet, you can set the header row
76
76
  const sheet = await doc.addSheet({ headerValues: ['name', 'email'] });
@@ -87,7 +87,7 @@ const rows = await sheet.getRows(); // can pass in { limit, offset }
87
87
 
88
88
  // read/write row values
89
89
  console.log(rows[0].get('name')); // 'Larry Page'
90
- rows[1].set('email') = 'sergey@abc.xyz'; // update a value
90
+ rows[1].set('email', 'sergey@abc.xyz'); // update a value
91
91
  rows[2].assign({ name: 'Sundar Pichai', email: 'sundar@google.com' }); // set multiple values
92
92
  await rows[2].save(); // save updates on a row
93
93
  await rows[2].delete(); // delete a row
@@ -108,12 +108,12 @@ userRows[0].get('badColumn'); // <- will throw a type error
108
108
  ```
109
109
 
110
110
  More info:
111
+
111
112
  - [GoogleSpreadsheetWorksheet > Working With Rows](https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet-worksheet#working-with-rows)
112
113
  - [GoogleSpreadsheetRow](https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet-row)
113
114
 
114
-
115
-
116
115
  ### Working with cells
116
+
117
117
  ```js
118
118
  await sheet.loadCells('A1:E10'); // loads range of cells into local cache - DOES NOT RETURN THE CELLS
119
119
  console.log(sheet.cellStats); // total cells, loaded, how many non-empty
@@ -130,11 +130,12 @@ a1.textFormat = { bold: true };
130
130
  c6.note = 'This is a note!';
131
131
  await sheet.saveUpdatedCells(); // save all updates in one call
132
132
  ```
133
+
133
134
  More info:
135
+
134
136
  - [GoogleSpreadsheetWorksheet > Working With Cells](https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet-worksheet#working-with-cells)
135
137
  - [GoogleSpreadsheetCell](https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet-cell)
136
138
 
137
-
138
139
  ### Managing docs and sharing
139
140
 
140
141
  ```js
@@ -161,6 +162,7 @@ await newDoc.delete();
161
162
  ```
162
163
 
163
164
  ## Why?
165
+
164
166
  > **This module provides an intuitive wrapper around Google's API to simplify common interactions**
165
167
 
166
168
  While Google's v4 sheets API is much easier to use than v3 was, the official [googleapis npm module](https://www.npmjs.com/package/googleapis) is a giant autogenerated meta-tool that handles _every Google product_. The module and the API itself are awkward and the docs are pretty terrible, at least to get started.
@@ -169,7 +171,6 @@ While Google's v4 sheets API is much easier to use than v3 was, the official [go
169
171
  This module makes trade-offs for simplicity of the interface.
170
172
  Google's API provides a mechanism to make many requests in parallel, so if speed and efficiency are extremely important to your use case, you may want to use their API directly. There are also many lesser-used features of their API that are not implemented here yet.
171
173
 
172
-
173
174
  ## Support & Contributions
174
175
 
175
176
  This module was written and is actively maintained by [Theo Ephraim](https://theoephraim.com).
@@ -189,4 +190,5 @@ The docs site is generated using [docsify](https://docsify.js.org). To preview a
189
190
  The content lives in markdown files in the docs folder.
190
191
 
191
192
  ## License
193
+
192
194
  This is free and unencumbered public domain software. For more info, see https://unlicense.org.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";const p=require("axios"),compact_js=require("lodash/compact.js"),each_js=require("lodash/each.js"),filter_js=require("lodash/filter.js"),find_js=require("lodash/find.js"),flatten_js=require("lodash/flatten.js"),get_js=require("lodash/get.js"),groupBy_js=require("lodash/groupBy.js"),isArray_js=require("lodash/isArray.js"),isBoolean_js=require("lodash/isBoolean.js"),isEqual_js=require("lodash/isEqual.js"),isFinite_js=require("lodash/isFinite.js"),isInteger_js=require("lodash/isInteger.js"),isNil_js=require("lodash/isNil.js");require("lodash/isNumber.js");const isObject_js=require("lodash/isObject.js"),isString_js=require("lodash/isString.js"),keyBy_js=require("lodash/keyBy.js"),keys_js=require("lodash/keys.js"),map_js=require("lodash/map.js"),omit_js=require("lodash/omit.js"),pickBy_js=require("lodash/pickBy.js"),set_js=require("lodash/set.js"),some_js=require("lodash/some.js"),sortBy_js=require("lodash/sortBy.js"),times_js=require("lodash/times.js"),unset_js=require("lodash/unset.js"),values_js=require("lodash/values.js");function _interopDefaultCompat(r){return r&&typeof r=="object"&&"default"in r?r.default:r}const p__default=_interopDefaultCompat(p),compact_js__default=_interopDefaultCompat(compact_js),each_js__default=_interopDefaultCompat(each_js),filter_js__default=_interopDefaultCompat(filter_js),find_js__default=_interopDefaultCompat(find_js),flatten_js__default=_interopDefaultCompat(flatten_js),get_js__default=_interopDefaultCompat(get_js),groupBy_js__default=_interopDefaultCompat(groupBy_js),isArray_js__default=_interopDefaultCompat(isArray_js),isBoolean_js__default=_interopDefaultCompat(isBoolean_js),isEqual_js__default=_interopDefaultCompat(isEqual_js),isFinite_js__default=_interopDefaultCompat(isFinite_js),isInteger_js__default=_interopDefaultCompat(isInteger_js),isNil_js__default=_interopDefaultCompat(isNil_js),isObject_js__default=_interopDefaultCompat(isObject_js),isString_js__default=_interopDefaultCompat(isString_js),keyBy_js__default=_interopDefaultCompat(keyBy_js),keys_js__default=_interopDefaultCompat(keys_js),map_js__default=_interopDefaultCompat(map_js),omit_js__default=_interopDefaultCompat(omit_js),pickBy_js__default=_interopDefaultCompat(pickBy_js),set_js__default=_interopDefaultCompat(set_js),some_js__default=_interopDefaultCompat(some_js),sortBy_js__default=_interopDefaultCompat(sortBy_js),times_js__default=_interopDefaultCompat(times_js),unset_js__default=_interopDefaultCompat(unset_js),values_js__default=_interopDefaultCompat(values_js);function getFieldMask(r){return Object.keys(r).join(",")}function columnToLetter(r){let e,t="",s=r;for(;s>0;)e=(s-1)%26,t=String.fromCharCode(e+65)+t,s=(s-e-1)/26;return t}function letterToColumn(r){let e=0;const{length:t}=r;for(let s=0;s<t;s++)e+=(r.charCodeAt(s)-64)*26**(t-s-1);return e}function axiosParamsSerializer(r){let e="";return Object.keys(r).forEach(t=>{const s=typeof r[t]=="object",a=s&&r[t].length>=0;if(s||(e+=`${t}=${encodeURIComponent(r[t])}&`),s&&a)for(const o of r[t])e+=`${t}=${encodeURIComponent(o)}&`}),e&&e.slice(0,-1)}function checkForDuplicateHeaders(r){const e=groupBy_js__default(r);each_js__default(e,(t,s)=>{if(s&&t.length>1)throw new Error(`Duplicate header detected: "${s}". Please make sure all non-empty headers are unique`)})}class GoogleSpreadsheetRow{constructor(e,t,s){this._worksheet=e,this._rowNumber=t,this._rawData=s,this._deleted=!1}get deleted(){return this._deleted}get rowNumber(){return this._rowNumber}_updateRowNumber(e){this._rowNumber=e}get a1Range(){return[this._worksheet.a1SheetName,"!",`A${this._rowNumber}`,":",`${columnToLetter(this._worksheet.headerValues.length)}${this._rowNumber}`].join("")}get(e){const t=this._worksheet.headerValues.indexOf(e);return this._rawData[t]}set(e,t){const s=this._worksheet.headerValues.indexOf(e);this._rawData[s]=t}assign(e){for(const t in e)this.set(t,e[t])}toObject(){const e={};for(let t=0;t<this._worksheet.headerValues.length;t++){const s=this._worksheet.headerValues[t];s&&(e[s]=this._rawData[t])}return e}async save(e){if(this._deleted)throw new Error("This row has been deleted - call getRows again before making updates.");const t=await this._worksheet._spreadsheet.sheetsApi.request({method:"put",url:`/values/${encodeURIComponent(this.a1Range)}`,params:{valueInputOption:e?.raw?"RAW":"USER_ENTERED",includeValuesInResponse:!0},data:{range:this.a1Range,majorDimension:"ROWS",values:[this._rawData]}});this._rawData=t.data.updatedData.values[0]}async delete(){if(this._deleted)throw new Error("This row has been deleted - call getRows again before making updates.");const e=await this._worksheet._makeSingleUpdateRequest("deleteRange",{range:{sheetId:this._worksheet.sheetId,startRowIndex:this._rowNumber-1,endRowIndex:this._rowNumber},shiftDimension:"ROWS"});return this._deleted=!0,this._worksheet._shiftRowCache(this.rowNumber),e}_clearRowData(){for(let e=0;e<this._rawData.length;e++)this._rawData[e]=""}}class GoogleSpreadsheetCellErrorValue{constructor(e){this.type=e.type,this.message=e.message}}class GoogleSpreadsheetCell{constructor(e,t,s,a){this._sheet=e,this._rowIndex=t,this._columnIndex=s,this._draftData={},this._updateRawData(a),this._rawData=a}_updateRawData(e){this._rawData=e,this._draftData={},this._rawData?.effectiveValue&&"errorValue"in this._rawData.effectiveValue?this._error=new GoogleSpreadsheetCellErrorValue(this._rawData.effectiveValue.errorValue):this._error=void 0}get rowIndex(){return this._rowIndex}get columnIndex(){return this._columnIndex}get a1Column(){return columnToLetter(this._columnIndex+1)}get a1Row(){return this._rowIndex+1}get a1Address(){return`${this.a1Column}${this.a1Row}`}get value(){if(this._draftData.value!==void 0)throw new Error("Value has been changed");return this._error?this._error:this._rawData?.effectiveValue?values_js__default(this._rawData.effectiveValue)[0]:null}set value(e){if(e instanceof GoogleSpreadsheetCellErrorValue)throw new Error("You can't manually set a value to an error");if(isBoolean_js__default(e))this._draftData.valueType="boolValue";else if(isString_js__default(e))e.substring(0,1)==="="?this._draftData.valueType="formulaValue":this._draftData.valueType="stringValue";else if(isFinite_js__default(e))this._draftData.valueType="numberValue";else if(isNil_js__default(e))this._draftData.valueType="stringValue",e="";else throw new Error("Set value to boolean, string, or number");this._draftData.value=e}get valueType(){return this._error?"errorValue":this._rawData?.effectiveValue?keys_js__default(this._rawData.effectiveValue)[0]:null}get formattedValue(){return this._rawData?.formattedValue||null}get formula(){return get_js__default(this._rawData,"userEnteredValue.formulaValue",null)}set formula(e){if(!e)throw new Error("To clear a formula, set `cell.value = null`");if(e.substring(0,1)!=="=")throw new Error('formula must begin with "="');this.value=e}get formulaError(){return this._error}get errorValue(){return this._error}get numberValue(){if(this.valueType==="numberValue")return this.value}set numberValue(e){this.value=e}get boolValue(){if(this.valueType==="boolValue")return this.value}set boolValue(e){this.value=e}get stringValue(){if(this.valueType==="stringValue")return this.value}set stringValue(e){if(e?.startsWith("="))throw new Error("Use cell.formula to set formula values");this.value=e}get hyperlink(){if(this._draftData.value)throw new Error("Save cell to be able to read hyperlink");return this._rawData?.hyperlink}get note(){return this._draftData.note!==void 0?this._draftData.note:this._rawData?.note}set note(e){if((e==null||e===!1)&&(e=""),!isString_js__default(e))throw new Error("Note must be a string");e===this._rawData?.note?delete this._draftData.note:this._draftData.note=e}get userEnteredFormat(){return Object.freeze(this._rawData?.userEnteredFormat)}get effectiveFormat(){return Object.freeze(this._rawData?.effectiveFormat)}_getFormatParam(e){if(get_js__default(this._draftData,`userEnteredFormat.${e}`))throw new Error("User format is unsaved - save the cell to be able to read it again");return Object.freeze(this._rawData.userEnteredFormat[e])}_setFormatParam(e,t){isEqual_js__default(t,get_js__default(this._rawData,`userEnteredFormat.${e}`))?unset_js__default(this._draftData,`userEnteredFormat.${e}`):(set_js__default(this._draftData,`userEnteredFormat.${e}`,t),this._draftData.clearFormat=!1)}get numberFormat(){return this._getFormatParam("numberFormat")}get backgroundColor(){return this._getFormatParam("backgroundColor")}get backgroundColorStyle(){return this._getFormatParam("backgroundColorStyle")}get borders(){return this._getFormatParam("borders")}get padding(){return this._getFormatParam("padding")}get horizontalAlignment(){return this._getFormatParam("horizontalAlignment")}get verticalAlignment(){return this._getFormatParam("verticalAlignment")}get wrapStrategy(){return this._getFormatParam("wrapStrategy")}get textDirection(){return this._getFormatParam("textDirection")}get textFormat(){return this._getFormatParam("textFormat")}get hyperlinkDisplayType(){return this._getFormatParam("hyperlinkDisplayType")}get textRotation(){return this._getFormatParam("textRotation")}set numberFormat(e){this._setFormatParam("numberFormat",e)}set backgroundColor(e){this._setFormatParam("backgroundColor",e)}set backgroundColorStyle(e){this._setFormatParam("backgroundColorStyle",e)}set borders(e){this._setFormatParam("borders",e)}set padding(e){this._setFormatParam("padding",e)}set horizontalAlignment(e){this._setFormatParam("horizontalAlignment",e)}set verticalAlignment(e){this._setFormatParam("verticalAlignment",e)}set wrapStrategy(e){this._setFormatParam("wrapStrategy",e)}set textDirection(e){this._setFormatParam("textDirection",e)}set textFormat(e){this._setFormatParam("textFormat",e)}set hyperlinkDisplayType(e){this._setFormatParam("hyperlinkDisplayType",e)}set textRotation(e){this._setFormatParam("textRotation",e)}clearAllFormatting(){this._draftData.clearFormat=!0,delete this._draftData.userEnteredFormat}get _isDirty(){return!!(this._draftData.note!==void 0||keys_js__default(this._draftData.userEnteredFormat).length||this._draftData.clearFormat||this._draftData.value!==void 0)}discardUnsavedChanges(){this._draftData={}}async save(){await this._sheet.saveCells([this])}_getUpdateRequest(){const e=this._draftData.value!==void 0,t=this._draftData.note!==void 0,s=!!keys_js__default(this._draftData.userEnteredFormat||{}).length,a=this._draftData.clearFormat;if(!some_js__default([e,t,s,a]))return null;const o={...this._rawData?.userEnteredFormat,...this._draftData.userEnteredFormat};return get_js__default(this._draftData,"userEnteredFormat.backgroundColor")&&delete o.backgroundColorStyle,{updateCells:{rows:[{values:[{...e&&{userEnteredValue:{[this._draftData.valueType]:this._draftData.value}},...t&&{note:this._draftData.note},...s&&{userEnteredFormat:o},...a&&{userEnteredFormat:{}}}]}],fields:keys_js__default(pickBy_js__default({userEnteredValue:e,note:t,userEnteredFormat:s||a})).join(","),start:{sheetId:this._sheet.sheetId,rowIndex:this.rowIndex,columnIndex:this.columnIndex}}}}}class GoogleSpreadsheetWorksheet{constructor(e,t,s){this._spreadsheet=e,this._headerRowIndex=1,this._rawProperties=null,this._cells=[],this._rowMetadata=[],this._columnMetadata=[],this._rowCache=[],this._headerRowIndex=1,this._rawProperties=t,this._cells=[],this._rowMetadata=[],this._columnMetadata=[],s&&this._fillCellData(s)}get headerValues(){if(!this._headerValues)throw new Error("Header values are not yet loaded");return this._headerValues}updateRawData(e,t){this._rawProperties=e,this._fillCellData(t)}async _makeSingleUpdateRequest(e,t){return this._spreadsheet._makeSingleUpdateRequest(e,{...t})}_ensureInfoLoaded(){if(!this._rawProperties)throw new Error("You must call `doc.loadInfo()` again before accessing this property")}resetLocalCache(e){e||(this._rawProperties=null),this._headerValues=void 0,this._headerRowIndex=1,this._cells=[]}_fillCellData(e){each_js__default(e,t=>{const s=t.startRow||0,a=t.startColumn||0,o=t.rowMetadata.length,h=t.columnMetadata.length;for(let i=0;i<o;i++){const n=s+i;for(let d=0;d<h;d++){const l=a+d;this._cells[n]||(this._cells[n]=[]);const _=get_js__default(t,`rowData[${i}].values[${d}]`);this._cells[n][l]?this._cells[n][l]._updateRawData(_):this._cells[n][l]=new GoogleSpreadsheetCell(this,n,l,_)}}for(let i=0;i<t.rowMetadata.length;i++)this._rowMetadata[s+i]=t.rowMetadata[i];for(let i=0;i<t.columnMetadata.length;i++)this._columnMetadata[a+i]=t.columnMetadata[i]})}_addSheetIdToRange(e){if(e.sheetId&&e.sheetId!==this.sheetId)throw new Error("Leave sheet ID blank or set to matching ID of this sheet");return{...e,sheetId:this.sheetId}}_getProp(e){return this._ensureInfoLoaded(),this._rawProperties[e]}_setProp(e,t){throw new Error("Do not update directly - use `updateProperties()`")}get sheetId(){return this._getProp("sheetId")}get title(){return this._getProp("title")}get index(){return this._getProp("index")}get sheetType(){return this._getProp("sheetType")}get gridProperties(){return this._getProp("gridProperties")}get hidden(){return this._getProp("hidden")}get tabColor(){return this._getProp("tabColor")}get rightToLeft(){return this._getProp("rightToLeft")}set sheetId(e){this._setProp("sheetId",e)}set title(e){this._setProp("title",e)}set index(e){this._setProp("index",e)}set sheetType(e){this._setProp("sheetType",e)}set gridProperties(e){this._setProp("gridProperties",e)}set hidden(e){this._setProp("hidden",e)}set tabColor(e){this._setProp("tabColor",e)}set rightToLeft(e){this._setProp("rightToLeft",e)}get rowCount(){return this._ensureInfoLoaded(),this.gridProperties.rowCount}get columnCount(){return this._ensureInfoLoaded(),this.gridProperties.columnCount}get a1SheetName(){return`'${this.title.replace(/'/g,"''")}'`}get encodedA1SheetName(){return encodeURIComponent(this.a1SheetName)}get lastColumnLetter(){return this.columnCount?columnToLetter(this.columnCount):""}get cellStats(){let e=flatten_js__default(this._cells);return e=compact_js__default(e),{nonEmpty:filter_js__default(e,t=>t.value).length,loaded:e.length,total:this.rowCount*this.columnCount}}getCellByA1(e){const t=e.match(/([A-Z]+)([0-9]+)/);if(!t)throw new Error(`Cell address "${e}" not valid`);const s=letterToColumn(t[1]),a=parseInt(t[2]);return this.getCell(a-1,s-1)}getCell(e,t){if(e<0||t<0)throw new Error("Min coordinate is 0, 0");if(e>=this.rowCount||t>=this.columnCount)throw new Error(`Out of bounds, sheet is ${this.rowCount} by ${this.columnCount}`);if(!get_js__default(this._cells,`[${e}][${t}]`))throw new Error("This cell has not been loaded yet");return this._cells[e][t]}async loadCells(e){if(!e)return this._spreadsheet.loadCells(this.a1SheetName);const t=isArray_js__default(e)?e:[e],s=map_js__default(t,a=>{if(isString_js__default(a))return a.startsWith(this.a1SheetName)?a:`${this.a1SheetName}!${a}`;if(isObject_js__default(a)){const o=a;if(o.sheetId&&o.sheetId!==this.sheetId)throw new Error("Leave sheet ID blank or set to matching ID of this sheet");return{sheetId:this.sheetId,...a}}throw new Error("Each filter must be a A1 range string or gridrange object")});return this._spreadsheet.loadCells(s)}async saveUpdatedCells(){const e=filter_js__default(flatten_js__default(this._cells),{_isDirty:!0});e.length&&await this.saveCells(e)}async saveCells(e){const t=map_js__default(e,a=>a._getUpdateRequest()),s=map_js__default(e,a=>`${this.a1SheetName}!${a.a1Address}`);if(!compact_js__default(t).length)throw new Error("At least one cell must have something to update");await this._spreadsheet._makeBatchUpdateRequest(t,s)}async _ensureHeaderRowLoaded(){this._headerValues||await this.loadHeaderRow()}async loadHeaderRow(e){e!==void 0&&(this._headerRowIndex=e);const t=await this.getCellsInRange(`A${this._headerRowIndex}:${this.lastColumnLetter}${this._headerRowIndex}`);if(!t)throw new Error("No values in the header row - fill the first row with header values before trying to interact with rows");if(this._headerValues=map_js__default(t[0],s=>s?.trim()),!compact_js__default(this.headerValues).length)throw new Error("All your header cells are blank - fill the first row with header values before trying to interact with rows");checkForDuplicateHeaders(this.headerValues)}async setHeaderRow(e,t){if(!e)return;if(e.length>this.columnCount)throw new Error(`Sheet is not large enough to fit ${e.length} columns. Resize the sheet first.`);const s=map_js__default(e,o=>o?.trim());if(checkForDuplicateHeaders(s),!compact_js__default(s).length)throw new Error("All your header cells are blank -");t&&(this._headerRowIndex=t);const a=await this._spreadsheet.sheetsApi.request({method:"put",url:`/values/${this.encodedA1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,params:{valueInputOption:"USER_ENTERED",includeValuesInResponse:!0},data:{range:`${this.a1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,majorDimension:"ROWS",values:[[...s,...times_js__default(this.columnCount-s.length,()=>"")]]}});this._headerValues=a.data.updatedData.values[0]}async addRows(e,t={}){if(this.title.includes(":"))throw new Error('Please remove the ":" from your sheet title. There is a bug with the google API which breaks appending rows if any colons are in the sheet title.');if(!isArray_js__default(e))throw new Error("You must pass in an array of row values to append");await this._ensureHeaderRowLoaded();const s=[];each_js__default(e,i=>{let n;if(isArray_js__default(i))n=i;else if(isObject_js__default(i)){n=[];for(let d=0;d<this.headerValues.length;d++){const l=this.headerValues[d];n[d]=i[l]}}else throw new Error("Each row must be an object or an array");s.push(n)});const a=await this._spreadsheet.sheetsApi.request({method:"post",url:`/values/${this.encodedA1SheetName}!A${this._headerRowIndex}:append`,params:{valueInputOption:t.raw?"RAW":"USER_ENTERED",insertDataOption:t.insert?"INSERT_ROWS":"OVERWRITE",includeValuesInResponse:!0},data:{values:s}}),{updatedRange:o}=a.data.updates;let h=o.match(/![A-Z]+([0-9]+):?/)[1];return h=parseInt(h),this._ensureInfoLoaded(),t.insert?this._rawProperties.gridProperties.rowCount+=e.length:h+e.length>this.rowCount&&(this._rawProperties.gridProperties.rowCount=h+e.length-1),map_js__default(a.data.updates.updatedData.values,i=>new GoogleSpreadsheetRow(this,h++,i))}async addRow(e,t){return(await this.addRows([e],t))[0]}async getRows(e){const t=e?.offset||0,s=e?.limit||this.rowCount-1;await this._ensureHeaderRowLoaded();const a=1+this._headerRowIndex+t,o=a+s-1,h=columnToLetter(this.headerValues.length),i=await this.getCellsInRange(`A${a}:${h}${o}`);if(!i)return[];const n=[];let d=a;for(let l=0;l<i.length;l++){const _=new GoogleSpreadsheetRow(this,d++,i[l]);this._rowCache[_.rowNumber]=_,n.push(_)}return n}_shiftRowCache(e){delete this._rowCache[e],this._rowCache.forEach(t=>{t.rowNumber>e&&t._updateRowNumber(t.rowNumber-1)})}async clearRows(e){const t=e?.start||this._headerRowIndex+1,s=e?.end||this.rowCount;await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}!${t}:${s}:clear`),this._rowCache.forEach(a=>{a.rowNumber>=t&&a.rowNumber<=s&&a._clearRowData()})}async updateProperties(e){return this._makeSingleUpdateRequest("updateSheetProperties",{properties:{sheetId:this.sheetId,...e},fields:getFieldMask(e)})}async updateGridProperties(e){return this.updateProperties({gridProperties:e})}async resize(e){return this.updateGridProperties(e)}async updateDimensionProperties(e,t,s){return this._makeSingleUpdateRequest("updateDimensionProperties",{range:{sheetId:this.sheetId,dimension:e,...s},properties:t,fields:getFieldMask(t)})}async getCellsInRange(e,t){return(await this._spreadsheet.sheetsApi.get(`/values/${this.encodedA1SheetName}!${e}`,{params:t})).data.values}async updateNamedRange(){}async addNamedRange(){}async deleteNamedRange(){}async repeatCell(){}async autoFill(){}async cutPaste(){}async copyPaste(){}async mergeCells(e,t="MERGE_ALL"){await this._makeSingleUpdateRequest("mergeCells",{mergeType:t,range:this._addSheetIdToRange(e)})}async unmergeCells(e){await this._makeSingleUpdateRequest("unmergeCells",{range:this._addSheetIdToRange(e)})}async updateBorders(){}async addFilterView(){}async appendCells(){}async clearBasicFilter(){}async deleteDimension(){}async deleteEmbeddedObject(){}async deleteFilterView(){}async duplicateFilterView(){}async duplicate(e){const t=(await this._makeSingleUpdateRequest("duplicateSheet",{sourceSheetId:this.sheetId,...e?.index!==void 0&&{insertSheetIndex:e.index},...e?.id&&{newSheetId:e.id},...e?.title&&{newSheetName:e.title}})).properties.sheetId;return this._spreadsheet.sheetsById[t]}async findReplace(){}async insertDimension(e,t,s){if(!e)throw new Error("You need to specify a dimension. i.e. COLUMNS|ROWS");if(!isObject_js__default(t))throw new Error("`range` must be an object containing `startIndex` and `endIndex`");if(!isInteger_js__default(t.startIndex)||t.startIndex<0)throw new Error("range.startIndex must be an integer >=0");if(!isInteger_js__default(t.endIndex)||t.endIndex<0)throw new Error("range.endIndex must be an integer >=0");if(t.endIndex<=t.startIndex)throw new Error("range.endIndex must be greater than range.startIndex");if(s===void 0&&(s=t.startIndex>0),s&&t.startIndex===0)throw new Error("Cannot set inheritFromBefore to true if inserting in first row/column");return this._makeSingleUpdateRequest("insertDimension",{range:{sheetId:this.sheetId,dimension:e,startIndex:t.startIndex,endIndex:t.endIndex},inheritFromBefore:s})}async insertRange(){}async moveDimension(){}async updateEmbeddedObjectPosition(){}async pasteData(){}async textToColumns(){}async updateFilterView(){}async deleteRange(){}async appendDimension(){}async addConditionalFormatRule(){}async updateConditionalFormatRule(){}async deleteConditionalFormatRule(){}async sortRange(){}async setDataValidation(){}async setBasicFilter(){}async addProtectedRange(){}async updateProtectedRange(){}async deleteProtectedRange(){}async autoResizeDimensions(){}async addChart(){}async updateChartSpec(){}async updateBanding(){}async addBanding(){}async deleteBanding(){}async createDeveloperMetadata(){}async updateDeveloperMetadata(){}async deleteDeveloperMetadata(){}async randomizeRange(){}async addDimensionGroup(){}async deleteDimensionGroup(){}async updateDimensionGroup(){}async trimWhitespace(){}async deleteDuplicates(){}async addSlicer(){}async updateSlicerSpec(){}async delete(){return this._spreadsheet.deleteSheet(this.sheetId)}async copyToSpreadsheet(e){return this._spreadsheet.sheetsApi.post(`/sheets/${this.sheetId}:copyTo`,{destinationSpreadsheetId:e})}async clear(e){const t=e?`!${e}`:"";await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}${t}:clear`),this.resetLocalCache(!0)}async downloadAsCSV(e=!1){return this._spreadsheet._downloadAs("csv",this.sheetId,e)}async downloadAsTSV(e=!1){return this._spreadsheet._downloadAs("tsv",this.sheetId,e)}async downloadAsPDF(e=!1){return this._spreadsheet._downloadAs("pdf",this.sheetId,e)}}var AUTH_MODES=(r=>(r.GOOGLE_AUTH_CLIENT="google_auth",r.RAW_ACCESS_TOKEN="raw_access_token",r.API_KEY="api_key",r))(AUTH_MODES||{});const u="https://sheets.googleapis.com/v4/spreadsheets",w="https://www.googleapis.com/drive/v3/files",c={html:{},zip:{},xlsx:{},ods:{},csv:{singleWorksheet:!0},tsv:{singleWorksheet:!0},pdf:{singleWorksheet:!0}};function A(r){if("getRequestHeaders"in r)return AUTH_MODES.GOOGLE_AUTH_CLIENT;if("token"in r)return AUTH_MODES.RAW_ACCESS_TOKEN;if("apiKey"in r)return AUTH_MODES.API_KEY;throw new Error("Invalid auth")}async function m(r){if("getRequestHeaders"in r)return{headers:await r.getRequestHeaders()};if("apiKey"in r)return{params:{key:r.apiKey}};if("token"in r)return{headers:{Authorization:`Bearer ${r.token}`}};throw new Error("Invalid auth")}class GoogleSpreadsheet{constructor(e,t){this._rawProperties=null,this._spreadsheetUrl=null,this._deleted=!1,this.spreadsheetId=e,this.auth=t,this._rawSheets={},this._spreadsheetUrl=null,this.sheetsApi=p__default.create({baseURL:`${u}/${e}`,paramsSerializer:axiosParamsSerializer,maxContentLength:1/0,maxBodyLength:1/0}),this.driveApi=p__default.create({baseURL:`${w}/${e}`,paramsSerializer:axiosParamsSerializer}),this.sheetsApi.interceptors.request.use(this._setAxiosRequestAuth.bind(this)),this.sheetsApi.interceptors.response.use(this._handleAxiosResponse.bind(this),this._handleAxiosErrors.bind(this)),this.driveApi.interceptors.request.use(this._setAxiosRequestAuth.bind(this)),this.driveApi.interceptors.response.use(this._handleAxiosResponse.bind(this),this._handleAxiosErrors.bind(this))}get authMode(){return A(this.auth)}async _setAxiosRequestAuth(e){const t=await m(this.auth);return each_js__default(t.headers,(s,a)=>{e.headers.set(a,s)}),e.params={...e.params,...t.params},e}async _handleAxiosResponse(e){return e}async _handleAxiosErrors(e){const t=e.response?.data;if(t){if(!t.error)throw e;const{code:s,message:a}=t.error;throw e.message=`Google API error - [${s}] ${a}`,e}throw get_js__default(e,"response.status")===403&&"apiKey"in this.auth?new Error("Sheet is private. Use authentication or make public. (see https://github.com/theoephraim/node-google-spreadsheet#a-note-on-authentication for details)"):e}async _makeSingleUpdateRequest(e,t){const s=await this.sheetsApi.post(":batchUpdate",{requests:[{[e]:t}],includeSpreadsheetInResponse:!0});return this._updateRawProperties(s.data.updatedSpreadsheet.properties),each_js__default(s.data.updatedSpreadsheet.sheets,a=>this._updateOrCreateSheet(a)),s.data.replies[0][e]}async _makeBatchUpdateRequest(e,t){const s=await this.sheetsApi.post(":batchUpdate",{requests:e,includeSpreadsheetInResponse:!0,...t&&{responseIncludeGridData:!0,...t!=="*"&&{responseRanges:t}}});this._updateRawProperties(s.data.updatedSpreadsheet.properties),each_js__default(s.data.updatedSpreadsheet.sheets,a=>this._updateOrCreateSheet(a))}_ensureInfoLoaded(){if(!this._rawProperties)throw new Error("You must call `doc.loadInfo()` before accessing this property")}_updateRawProperties(e){this._rawProperties=e}_updateOrCreateSheet(e){const{properties:t,data:s}=e,{sheetId:a}=t;this._rawSheets[a]?this._rawSheets[a].updateRawData(t,s):this._rawSheets[a]=new GoogleSpreadsheetWorksheet(this,t,s)}_getProp(e){return this._ensureInfoLoaded(),this._rawProperties[e]}get title(){return this._getProp("title")}get locale(){return this._getProp("locale")}get timeZone(){return this._getProp("timeZone")}get autoRecalc(){return this._getProp("autoRecalc")}get defaultFormat(){return this._getProp("defaultFormat")}get spreadsheetTheme(){return this._getProp("spreadsheetTheme")}get iterativeCalculationSettings(){return this._getProp("iterativeCalculationSettings")}async updateProperties(e){await this._makeSingleUpdateRequest("updateSpreadsheetProperties",{properties:e,fields:getFieldMask(e)})}async loadInfo(e=!1){const t=await this.sheetsApi.get("/",{params:{...e&&{includeGridData:!0}}});this._spreadsheetUrl=t.data.spreadsheetUrl,this._rawProperties=t.data.properties,each_js__default(t.data.sheets,s=>this._updateOrCreateSheet(s))}resetLocalCache(){this._rawProperties=null,this._rawSheets={}}get sheetCount(){return this._ensureInfoLoaded(),values_js__default(this._rawSheets).length}get sheetsById(){return this._ensureInfoLoaded(),this._rawSheets}get sheetsByIndex(){return this._ensureInfoLoaded(),sortBy_js__default(this._rawSheets,"index")}get sheetsByTitle(){return this._ensureInfoLoaded(),keyBy_js__default(this._rawSheets,"title")}async addSheet(e={}){const t=(await this._makeSingleUpdateRequest("addSheet",{properties:omit_js__default(e,"headerValues","headerRowIndex")})).properties.sheetId,s=this.sheetsById[t];return e.headerValues&&await s.setHeaderRow(e.headerValues,e.headerRowIndex),s}async deleteSheet(e){await this._makeSingleUpdateRequest("deleteSheet",{sheetId:e}),delete this._rawSheets[e]}async addNamedRange(e,t,s){return this._makeSingleUpdateRequest("addNamedRange",{name:e,namedRangeId:s,range:t})}async deleteNamedRange(e){return this._makeSingleUpdateRequest("deleteNamedRange",{namedRangeId:e})}async loadCells(e){const t=this.authMode===AUTH_MODES.API_KEY,s=isArray_js__default(e)?e:[e],a=map_js__default(s,i=>{if(isString_js__default(i))return t?i:{a1Range:i};if(isObject_js__default(i)){if(t)throw new Error("Only A1 ranges are supported when fetching cells with read-only access (using only an API key)");return{gridRange:i}}throw new Error("Each filter must be an A1 range string or a gridrange object")});let o;this.authMode===AUTH_MODES.API_KEY?o=await this.sheetsApi.get("/",{params:{includeGridData:!0,ranges:a}}):o=await this.sheetsApi.post(":getByDataFilter",{includeGridData:!0,dataFilters:a});const{sheets:h}=o.data;each_js__default(h,i=>{this._updateOrCreateSheet(i)})}async _downloadAs(e,t,s){if(!c[e])throw new Error(`unsupported export fileType - ${e}`);if(c[e].singleWorksheet){if(t===void 0)throw new Error(`Must specify worksheetId when exporting as ${e}`)}else if(t)throw new Error(`Cannot specify worksheetId when exporting as ${e}`);if(e==="html"&&(e="zip"),!this._spreadsheetUrl)throw new Error("Cannot export sheet that is not fully loaded");const a=this._spreadsheetUrl.replace("/edit","/export");return(await this.sheetsApi.get(a,{baseURL:"",params:{id:this.spreadsheetId,format:e,...t&&{gid:t}},responseType:s?"stream":"arraybuffer"})).data}async downloadAsZippedHTML(e){return this._downloadAs("html",void 0,e)}async downloadAsHTML(e){return this._downloadAs("html",void 0,e)}async downloadAsXLSX(e=!1){return this._downloadAs("xlsx",void 0,e)}async downloadAsODS(e=!1){return this._downloadAs("ods",void 0,e)}async delete(){const e=await this.driveApi.delete("");return this._deleted=!0,e.data}async listPermissions(){return(await this.driveApi.request({method:"GET",url:"/permissions",params:{fields:"permissions(id,type,emailAddress,domain,role,displayName,photoLink,deleted)"}})).data.permissions}async setPublicAccessLevel(e){const t=await this.listPermissions(),s=find_js__default(t,a=>a.type==="anyone");if(e===!1){if(!s)return;await this.driveApi.request({method:"DELETE",url:`/permissions/${s.id}`})}else await this.driveApi.request({method:"POST",url:"/permissions",params:{},data:{role:e||"viewer",type:"anyone"}})}async share(e,t){let s,a;return e.includes("@")?s=e:a=e,(await this.driveApi.request({method:"POST",url:"/permissions",params:{...t?.emailMessage===!1&&{sendNotificationEmail:!1},...isString_js__default(t?.emailMessage)&&{emailMessage:t?.emailMessage},...t?.role==="owner"&&{transferOwnership:!0}},data:{role:t?.role||"writer",...s&&{type:t?.isGroup?"group":"user",emailAddress:s},...a&&{type:"domain",domain:a}}})).data}static async createNewSpreadsheetDocument(e,t){if("apiKey"in e)throw new Error("Cannot use api key only to create a new spreadsheet - it is only usable for read-only access of public docs");const s=await m(e),a=await p__default.request({method:"POST",url:u,paramsSerializer:axiosParamsSerializer,...s,data:{properties:t}}),o=new GoogleSpreadsheet(a.data.spreadsheetId,e);return o._spreadsheetUrl=a.data.spreadsheetUrl,o._rawProperties=a.data.properties,each_js__default(a.data.sheets,h=>o._updateOrCreateSheet(h)),o}}exports.GoogleSpreadsheet=GoogleSpreadsheet,exports.GoogleSpreadsheetCell=GoogleSpreadsheetCell,exports.GoogleSpreadsheetCellErrorValue=GoogleSpreadsheetCellErrorValue,exports.GoogleSpreadsheetRow=GoogleSpreadsheetRow,exports.GoogleSpreadsheetWorksheet=GoogleSpreadsheetWorksheet;
1
+ "use strict";const p=require("axios"),compact_js=require("lodash/compact.js"),each_js=require("lodash/each.js"),filter_js=require("lodash/filter.js"),find_js=require("lodash/find.js"),flatten_js=require("lodash/flatten.js"),get_js=require("lodash/get.js"),groupBy_js=require("lodash/groupBy.js"),isArray_js=require("lodash/isArray.js"),isBoolean_js=require("lodash/isBoolean.js"),isEqual_js=require("lodash/isEqual.js"),isFinite_js=require("lodash/isFinite.js"),isInteger_js=require("lodash/isInteger.js"),isNil_js=require("lodash/isNil.js");require("lodash/isNumber.js");const isObject_js=require("lodash/isObject.js"),isString_js=require("lodash/isString.js"),keyBy_js=require("lodash/keyBy.js"),keys_js=require("lodash/keys.js"),map_js=require("lodash/map.js"),omit_js=require("lodash/omit.js"),pickBy_js=require("lodash/pickBy.js"),set_js=require("lodash/set.js"),some_js=require("lodash/some.js"),sortBy_js=require("lodash/sortBy.js"),times_js=require("lodash/times.js"),unset_js=require("lodash/unset.js"),values_js=require("lodash/values.js");function _interopDefaultCompat(r){return r&&typeof r=="object"&&"default"in r?r.default:r}const p__default=_interopDefaultCompat(p),compact_js__default=_interopDefaultCompat(compact_js),each_js__default=_interopDefaultCompat(each_js),filter_js__default=_interopDefaultCompat(filter_js),find_js__default=_interopDefaultCompat(find_js),flatten_js__default=_interopDefaultCompat(flatten_js),get_js__default=_interopDefaultCompat(get_js),groupBy_js__default=_interopDefaultCompat(groupBy_js),isArray_js__default=_interopDefaultCompat(isArray_js),isBoolean_js__default=_interopDefaultCompat(isBoolean_js),isEqual_js__default=_interopDefaultCompat(isEqual_js),isFinite_js__default=_interopDefaultCompat(isFinite_js),isInteger_js__default=_interopDefaultCompat(isInteger_js),isNil_js__default=_interopDefaultCompat(isNil_js),isObject_js__default=_interopDefaultCompat(isObject_js),isString_js__default=_interopDefaultCompat(isString_js),keyBy_js__default=_interopDefaultCompat(keyBy_js),keys_js__default=_interopDefaultCompat(keys_js),map_js__default=_interopDefaultCompat(map_js),omit_js__default=_interopDefaultCompat(omit_js),pickBy_js__default=_interopDefaultCompat(pickBy_js),set_js__default=_interopDefaultCompat(set_js),some_js__default=_interopDefaultCompat(some_js),sortBy_js__default=_interopDefaultCompat(sortBy_js),times_js__default=_interopDefaultCompat(times_js),unset_js__default=_interopDefaultCompat(unset_js),values_js__default=_interopDefaultCompat(values_js);function getFieldMask(r){return Object.keys(r).join(",")}function columnToLetter(r){let e,t="",s=r;for(;s>0;)e=(s-1)%26,t=String.fromCharCode(e+65)+t,s=(s-e-1)/26;return t}function letterToColumn(r){let e=0;const{length:t}=r;for(let s=0;s<t;s++)e+=(r.charCodeAt(s)-64)*26**(t-s-1);return e}function axiosParamsSerializer(r){let e="";return Object.keys(r).forEach(t=>{const s=typeof r[t]=="object",a=s&&r[t].length>=0;if(s||(e+=`${t}=${encodeURIComponent(r[t])}&`),s&&a)for(const o of r[t])e+=`${t}=${encodeURIComponent(o)}&`}),e&&e.slice(0,-1)}function checkForDuplicateHeaders(r){const e=groupBy_js__default(r);each_js__default(e,(t,s)=>{if(s&&t.length>1)throw new Error(`Duplicate header detected: "${s}". Please make sure all non-empty headers are unique`)})}class GoogleSpreadsheetRow{constructor(e,t,s){this._worksheet=e,this._rowNumber=t,this._rawData=s,this._deleted=!1}get deleted(){return this._deleted}get rowNumber(){return this._rowNumber}_updateRowNumber(e){this._rowNumber=e}get a1Range(){return[this._worksheet.a1SheetName,"!",`A${this._rowNumber}`,":",`${columnToLetter(this._worksheet.headerValues.length)}${this._rowNumber}`].join("")}get(e){const t=this._worksheet.headerValues.indexOf(e);return this._rawData[t]}set(e,t){const s=this._worksheet.headerValues.indexOf(e);this._rawData[s]=t}assign(e){for(const t in e)this.set(t,e[t])}toObject(){const e={};for(let t=0;t<this._worksheet.headerValues.length;t++){const s=this._worksheet.headerValues[t];s&&(e[s]=this._rawData[t])}return e}async save(e){if(this._deleted)throw new Error("This row has been deleted - call getRows again before making updates.");const t=await this._worksheet._spreadsheet.sheetsApi.request({method:"put",url:`/values/${encodeURIComponent(this.a1Range)}`,params:{valueInputOption:e?.raw?"RAW":"USER_ENTERED",includeValuesInResponse:!0},data:{range:this.a1Range,majorDimension:"ROWS",values:[this._rawData]}});this._rawData=t.data.updatedData.values[0]}async delete(){if(this._deleted)throw new Error("This row has been deleted - call getRows again before making updates.");const e=await this._worksheet._makeSingleUpdateRequest("deleteRange",{range:{sheetId:this._worksheet.sheetId,startRowIndex:this._rowNumber-1,endRowIndex:this._rowNumber},shiftDimension:"ROWS"});return this._deleted=!0,this._worksheet._shiftRowCache(this.rowNumber),e}_clearRowData(){for(let e=0;e<this._rawData.length;e++)this._rawData[e]=""}}class GoogleSpreadsheetCellErrorValue{constructor(e){this.type=e.type,this.message=e.message}}class GoogleSpreadsheetCell{constructor(e,t,s,a){this._sheet=e,this._rowIndex=t,this._columnIndex=s,this._draftData={},this._updateRawData(a),this._rawData=a}_updateRawData(e){this._rawData=e,this._draftData={},this._rawData?.effectiveValue&&"errorValue"in this._rawData.effectiveValue?this._error=new GoogleSpreadsheetCellErrorValue(this._rawData.effectiveValue.errorValue):this._error=void 0}get rowIndex(){return this._rowIndex}get columnIndex(){return this._columnIndex}get a1Column(){return columnToLetter(this._columnIndex+1)}get a1Row(){return this._rowIndex+1}get a1Address(){return`${this.a1Column}${this.a1Row}`}get value(){if(this._draftData.value!==void 0)throw new Error("Value has been changed");return this._error?this._error:this._rawData?.effectiveValue?values_js__default(this._rawData.effectiveValue)[0]:null}set value(e){if(e instanceof GoogleSpreadsheetCellErrorValue)throw new Error("You can't manually set a value to an error");if(isBoolean_js__default(e))this._draftData.valueType="boolValue";else if(isString_js__default(e))e.substring(0,1)==="="?this._draftData.valueType="formulaValue":this._draftData.valueType="stringValue";else if(isFinite_js__default(e))this._draftData.valueType="numberValue";else if(isNil_js__default(e))this._draftData.valueType="stringValue",e="";else throw new Error("Set value to boolean, string, or number");this._draftData.value=e}get valueType(){return this._error?"errorValue":this._rawData?.effectiveValue?keys_js__default(this._rawData.effectiveValue)[0]:null}get formattedValue(){return this._rawData?.formattedValue||null}get formula(){return get_js__default(this._rawData,"userEnteredValue.formulaValue",null)}set formula(e){if(!e)throw new Error("To clear a formula, set `cell.value = null`");if(e.substring(0,1)!=="=")throw new Error('formula must begin with "="');this.value=e}get formulaError(){return this._error}get errorValue(){return this._error}get numberValue(){if(this.valueType==="numberValue")return this.value}set numberValue(e){this.value=e}get boolValue(){if(this.valueType==="boolValue")return this.value}set boolValue(e){this.value=e}get stringValue(){if(this.valueType==="stringValue")return this.value}set stringValue(e){if(e?.startsWith("="))throw new Error("Use cell.formula to set formula values");this.value=e}get hyperlink(){if(this._draftData.value)throw new Error("Save cell to be able to read hyperlink");return this._rawData?.hyperlink}get note(){return this._draftData.note!==void 0?this._draftData.note:this._rawData?.note}set note(e){if((e==null||e===!1)&&(e=""),!isString_js__default(e))throw new Error("Note must be a string");e===this._rawData?.note?delete this._draftData.note:this._draftData.note=e}get userEnteredFormat(){return Object.freeze(this._rawData?.userEnteredFormat)}get effectiveFormat(){return Object.freeze(this._rawData?.effectiveFormat)}_getFormatParam(e){if(get_js__default(this._draftData,`userEnteredFormat.${e}`))throw new Error("User format is unsaved - save the cell to be able to read it again");return Object.freeze(this._rawData.userEnteredFormat[e])}_setFormatParam(e,t){isEqual_js__default(t,get_js__default(this._rawData,`userEnteredFormat.${e}`))?unset_js__default(this._draftData,`userEnteredFormat.${e}`):(set_js__default(this._draftData,`userEnteredFormat.${e}`,t),this._draftData.clearFormat=!1)}get numberFormat(){return this._getFormatParam("numberFormat")}get backgroundColor(){return this._getFormatParam("backgroundColor")}get backgroundColorStyle(){return this._getFormatParam("backgroundColorStyle")}get borders(){return this._getFormatParam("borders")}get padding(){return this._getFormatParam("padding")}get horizontalAlignment(){return this._getFormatParam("horizontalAlignment")}get verticalAlignment(){return this._getFormatParam("verticalAlignment")}get wrapStrategy(){return this._getFormatParam("wrapStrategy")}get textDirection(){return this._getFormatParam("textDirection")}get textFormat(){return this._getFormatParam("textFormat")}get hyperlinkDisplayType(){return this._getFormatParam("hyperlinkDisplayType")}get textRotation(){return this._getFormatParam("textRotation")}set numberFormat(e){this._setFormatParam("numberFormat",e)}set backgroundColor(e){this._setFormatParam("backgroundColor",e)}set backgroundColorStyle(e){this._setFormatParam("backgroundColorStyle",e)}set borders(e){this._setFormatParam("borders",e)}set padding(e){this._setFormatParam("padding",e)}set horizontalAlignment(e){this._setFormatParam("horizontalAlignment",e)}set verticalAlignment(e){this._setFormatParam("verticalAlignment",e)}set wrapStrategy(e){this._setFormatParam("wrapStrategy",e)}set textDirection(e){this._setFormatParam("textDirection",e)}set textFormat(e){this._setFormatParam("textFormat",e)}set hyperlinkDisplayType(e){this._setFormatParam("hyperlinkDisplayType",e)}set textRotation(e){this._setFormatParam("textRotation",e)}clearAllFormatting(){this._draftData.clearFormat=!0,delete this._draftData.userEnteredFormat}get _isDirty(){return!!(this._draftData.note!==void 0||keys_js__default(this._draftData.userEnteredFormat).length||this._draftData.clearFormat||this._draftData.value!==void 0)}discardUnsavedChanges(){this._draftData={}}async save(){await this._sheet.saveCells([this])}_getUpdateRequest(){const e=this._draftData.value!==void 0,t=this._draftData.note!==void 0,s=!!keys_js__default(this._draftData.userEnteredFormat||{}).length,a=this._draftData.clearFormat;if(!some_js__default([e,t,s,a]))return null;const o={...this._rawData?.userEnteredFormat,...this._draftData.userEnteredFormat};return get_js__default(this._draftData,"userEnteredFormat.backgroundColor")&&delete o.backgroundColorStyle,{updateCells:{rows:[{values:[{...e&&{userEnteredValue:{[this._draftData.valueType]:this._draftData.value}},...t&&{note:this._draftData.note},...s&&{userEnteredFormat:o},...a&&{userEnteredFormat:{}}}]}],fields:keys_js__default(pickBy_js__default({userEnteredValue:e,note:t,userEnteredFormat:s||a})).join(","),start:{sheetId:this._sheet.sheetId,rowIndex:this.rowIndex,columnIndex:this.columnIndex}}}}}class GoogleSpreadsheetWorksheet{constructor(e,t,s){this._spreadsheet=e,this._headerRowIndex=1,this._rawProperties=null,this._cells=[],this._rowMetadata=[],this._columnMetadata=[],this._rowCache=[],this._headerRowIndex=1,this._rawProperties=t,this._cells=[],this._rowMetadata=[],this._columnMetadata=[],s&&this._fillCellData(s)}get headerValues(){if(!this._headerValues)throw new Error("Header values are not yet loaded");return this._headerValues}updateRawData(e,t){this._rawProperties=e,this._fillCellData(t)}async _makeSingleUpdateRequest(e,t){return this._spreadsheet._makeSingleUpdateRequest(e,{...t})}_ensureInfoLoaded(){if(!this._rawProperties)throw new Error("You must call `doc.loadInfo()` again before accessing this property")}resetLocalCache(e){e||(this._rawProperties=null),this._headerValues=void 0,this._headerRowIndex=1,this._cells=[]}_fillCellData(e){each_js__default(e,t=>{const s=t.startRow||0,a=t.startColumn||0,o=t.rowMetadata.length,h=t.columnMetadata.length;for(let i=0;i<o;i++){const d=s+i;for(let n=0;n<h;n++){const l=a+n;this._cells[d]||(this._cells[d]=[]);const _=get_js__default(t,`rowData[${i}].values[${n}]`);this._cells[d][l]?this._cells[d][l]._updateRawData(_):this._cells[d][l]=new GoogleSpreadsheetCell(this,d,l,_)}}for(let i=0;i<t.rowMetadata.length;i++)this._rowMetadata[s+i]=t.rowMetadata[i];for(let i=0;i<t.columnMetadata.length;i++)this._columnMetadata[a+i]=t.columnMetadata[i]})}_addSheetIdToRange(e){if(e.sheetId&&e.sheetId!==this.sheetId)throw new Error("Leave sheet ID blank or set to matching ID of this sheet");return{...e,sheetId:this.sheetId}}_getProp(e){return this._ensureInfoLoaded(),this._rawProperties[e]}_setProp(e,t){throw new Error("Do not update directly - use `updateProperties()`")}get sheetId(){return this._getProp("sheetId")}get title(){return this._getProp("title")}get index(){return this._getProp("index")}get sheetType(){return this._getProp("sheetType")}get gridProperties(){return this._getProp("gridProperties")}get hidden(){return this._getProp("hidden")}get tabColor(){return this._getProp("tabColor")}get rightToLeft(){return this._getProp("rightToLeft")}get _headerRange(){return`A${this._headerRowIndex}:${this.lastColumnLetter}${this._headerRowIndex}`}set sheetId(e){this._setProp("sheetId",e)}set title(e){this._setProp("title",e)}set index(e){this._setProp("index",e)}set sheetType(e){this._setProp("sheetType",e)}set gridProperties(e){this._setProp("gridProperties",e)}set hidden(e){this._setProp("hidden",e)}set tabColor(e){this._setProp("tabColor",e)}set rightToLeft(e){this._setProp("rightToLeft",e)}get rowCount(){return this._ensureInfoLoaded(),this.gridProperties.rowCount}get columnCount(){return this._ensureInfoLoaded(),this.gridProperties.columnCount}get a1SheetName(){return`'${this.title.replace(/'/g,"''")}'`}get encodedA1SheetName(){return encodeURIComponent(this.a1SheetName)}get lastColumnLetter(){return this.columnCount?columnToLetter(this.columnCount):""}get cellStats(){let e=flatten_js__default(this._cells);return e=compact_js__default(e),{nonEmpty:filter_js__default(e,t=>t.value).length,loaded:e.length,total:this.rowCount*this.columnCount}}getCellByA1(e){const t=e.match(/([A-Z]+)([0-9]+)/);if(!t)throw new Error(`Cell address "${e}" not valid`);const s=letterToColumn(t[1]),a=parseInt(t[2]);return this.getCell(a-1,s-1)}getCell(e,t){if(e<0||t<0)throw new Error("Min coordinate is 0, 0");if(e>=this.rowCount||t>=this.columnCount)throw new Error(`Out of bounds, sheet is ${this.rowCount} by ${this.columnCount}`);if(!get_js__default(this._cells,`[${e}][${t}]`))throw new Error("This cell has not been loaded yet");return this._cells[e][t]}async loadCells(e){if(!e)return this._spreadsheet.loadCells(this.a1SheetName);const t=isArray_js__default(e)?e:[e],s=map_js__default(t,a=>{if(isString_js__default(a))return a.startsWith(this.a1SheetName)?a:`${this.a1SheetName}!${a}`;if(isObject_js__default(a)){const o=a;if(o.sheetId&&o.sheetId!==this.sheetId)throw new Error("Leave sheet ID blank or set to matching ID of this sheet");return{sheetId:this.sheetId,...a}}throw new Error("Each filter must be a A1 range string or gridrange object")});return this._spreadsheet.loadCells(s)}async saveUpdatedCells(){const e=filter_js__default(flatten_js__default(this._cells),{_isDirty:!0});e.length&&await this.saveCells(e)}async saveCells(e){const t=map_js__default(e,a=>a._getUpdateRequest()),s=map_js__default(e,a=>`${this.a1SheetName}!${a.a1Address}`);if(!compact_js__default(t).length)throw new Error("At least one cell must have something to update");await this._spreadsheet._makeBatchUpdateRequest(t,s)}async _ensureHeaderRowLoaded(){this._headerValues||await this.loadHeaderRow()}async loadHeaderRow(e){e!==void 0&&(this._headerRowIndex=e);const t=await this.getCellsInRange(this._headerRange);this._processHeaderRow(t)}_processHeaderRow(e){if(!e)throw new Error("No values in the header row - fill the first row with header values before trying to interact with rows");if(this._headerValues=map_js__default(e[0],t=>t?.trim()),!compact_js__default(this.headerValues).length)throw new Error("All your header cells are blank - fill the first row with header values before trying to interact with rows");checkForDuplicateHeaders(this.headerValues)}async setHeaderRow(e,t){if(!e)return;if(e.length>this.columnCount)throw new Error(`Sheet is not large enough to fit ${e.length} columns. Resize the sheet first.`);const s=map_js__default(e,o=>o?.trim());if(checkForDuplicateHeaders(s),!compact_js__default(s).length)throw new Error("All your header cells are blank -");t&&(this._headerRowIndex=t);const a=await this._spreadsheet.sheetsApi.request({method:"put",url:`/values/${this.encodedA1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,params:{valueInputOption:"USER_ENTERED",includeValuesInResponse:!0},data:{range:`${this.a1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,majorDimension:"ROWS",values:[[...s,...times_js__default(this.columnCount-s.length,()=>"")]]}});this._headerValues=a.data.updatedData.values[0]}async addRows(e,t={}){if(this.title.includes(":"))throw new Error('Please remove the ":" from your sheet title. There is a bug with the google API which breaks appending rows if any colons are in the sheet title.');if(!isArray_js__default(e))throw new Error("You must pass in an array of row values to append");await this._ensureHeaderRowLoaded();const s=[];each_js__default(e,i=>{let d;if(isArray_js__default(i))d=i;else if(isObject_js__default(i)){d=[];for(let n=0;n<this.headerValues.length;n++){const l=this.headerValues[n];d[n]=i[l]}}else throw new Error("Each row must be an object or an array");s.push(d)});const a=await this._spreadsheet.sheetsApi.request({method:"post",url:`/values/${this.encodedA1SheetName}!A${this._headerRowIndex}:append`,params:{valueInputOption:t.raw?"RAW":"USER_ENTERED",insertDataOption:t.insert?"INSERT_ROWS":"OVERWRITE",includeValuesInResponse:!0},data:{values:s}}),{updatedRange:o}=a.data.updates;let h=o.match(/![A-Z]+([0-9]+):?/)[1];return h=parseInt(h),this._ensureInfoLoaded(),t.insert?this._rawProperties.gridProperties.rowCount+=e.length:h+e.length>this.rowCount&&(this._rawProperties.gridProperties.rowCount=h+e.length-1),map_js__default(a.data.updates.updatedData.values,i=>new GoogleSpreadsheetRow(this,h++,i))}async addRow(e,t){return(await this.addRows([e],t))[0]}async getRows(e){const t=e?.offset||0,s=e?.limit||this.rowCount-1,a=1+this._headerRowIndex+t,o=a+s-1;let h;if(this._headerValues){const n=columnToLetter(this.headerValues.length);h=await this.getCellsInRange(`A${a}:${n}${o}`)}else{const n=await this.batchGetCellsInRange([this._headerRange,`A${a}:${this.lastColumnLetter}${o}`]);this._processHeaderRow(n[0]),h=n[1]}if(!h)return[];const i=[];let d=a;for(let n=0;n<h.length;n++){const l=new GoogleSpreadsheetRow(this,d++,h[n]);this._rowCache[l.rowNumber]=l,i.push(l)}return i}_shiftRowCache(e){delete this._rowCache[e],this._rowCache.forEach(t=>{t.rowNumber>e&&t._updateRowNumber(t.rowNumber-1)})}async clearRows(e){const t=e?.start||this._headerRowIndex+1,s=e?.end||this.rowCount;await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}!${t}:${s}:clear`),this._rowCache.forEach(a=>{a.rowNumber>=t&&a.rowNumber<=s&&a._clearRowData()})}async updateProperties(e){return this._makeSingleUpdateRequest("updateSheetProperties",{properties:{sheetId:this.sheetId,...e},fields:getFieldMask(e)})}async updateGridProperties(e){return this.updateProperties({gridProperties:e})}async resize(e){return this.updateGridProperties(e)}async updateDimensionProperties(e,t,s){return this._makeSingleUpdateRequest("updateDimensionProperties",{range:{sheetId:this.sheetId,dimension:e,...s},properties:t,fields:getFieldMask(t)})}async getCellsInRange(e,t){return(await this._spreadsheet.sheetsApi.get(`/values/${this.encodedA1SheetName}!${e}`,{params:t})).data.values}async batchGetCellsInRange(e,t){const s=e.map(a=>`ranges=${this.encodedA1SheetName}!${a}`).join("&");return(await this._spreadsheet.sheetsApi.get(`/values:batchGet?${s}`,{params:t})).data.valueRanges.map(a=>a.values)}async updateNamedRange(){}async addNamedRange(){}async deleteNamedRange(){}async repeatCell(){}async autoFill(){}async cutPaste(){}async copyPaste(){}async mergeCells(e,t="MERGE_ALL"){await this._makeSingleUpdateRequest("mergeCells",{mergeType:t,range:this._addSheetIdToRange(e)})}async unmergeCells(e){await this._makeSingleUpdateRequest("unmergeCells",{range:this._addSheetIdToRange(e)})}async updateBorders(){}async addFilterView(){}async appendCells(){}async clearBasicFilter(){}async deleteDimension(){}async deleteEmbeddedObject(){}async deleteFilterView(){}async duplicateFilterView(){}async duplicate(e){const t=(await this._makeSingleUpdateRequest("duplicateSheet",{sourceSheetId:this.sheetId,...e?.index!==void 0&&{insertSheetIndex:e.index},...e?.id&&{newSheetId:e.id},...e?.title&&{newSheetName:e.title}})).properties.sheetId;return this._spreadsheet.sheetsById[t]}async findReplace(){}async insertDimension(e,t,s){if(!e)throw new Error("You need to specify a dimension. i.e. COLUMNS|ROWS");if(!isObject_js__default(t))throw new Error("`range` must be an object containing `startIndex` and `endIndex`");if(!isInteger_js__default(t.startIndex)||t.startIndex<0)throw new Error("range.startIndex must be an integer >=0");if(!isInteger_js__default(t.endIndex)||t.endIndex<0)throw new Error("range.endIndex must be an integer >=0");if(t.endIndex<=t.startIndex)throw new Error("range.endIndex must be greater than range.startIndex");if(s===void 0&&(s=t.startIndex>0),s&&t.startIndex===0)throw new Error("Cannot set inheritFromBefore to true if inserting in first row/column");return this._makeSingleUpdateRequest("insertDimension",{range:{sheetId:this.sheetId,dimension:e,startIndex:t.startIndex,endIndex:t.endIndex},inheritFromBefore:s})}async insertRange(){}async moveDimension(){}async updateEmbeddedObjectPosition(){}async pasteData(){}async textToColumns(){}async updateFilterView(){}async deleteRange(){}async appendDimension(){}async addConditionalFormatRule(){}async updateConditionalFormatRule(){}async deleteConditionalFormatRule(){}async sortRange(){}async setDataValidation(e,t){return this._makeSingleUpdateRequest("setDataValidation",{range:{sheetId:this.sheetId,...e},...t&&{rule:t}})}async setBasicFilter(){}async addProtectedRange(){}async updateProtectedRange(){}async deleteProtectedRange(){}async autoResizeDimensions(){}async addChart(){}async updateChartSpec(){}async updateBanding(){}async addBanding(){}async deleteBanding(){}async createDeveloperMetadata(){}async updateDeveloperMetadata(){}async deleteDeveloperMetadata(){}async randomizeRange(){}async addDimensionGroup(){}async deleteDimensionGroup(){}async updateDimensionGroup(){}async trimWhitespace(){}async deleteDuplicates(){}async addSlicer(){}async updateSlicerSpec(){}async delete(){return this._spreadsheet.deleteSheet(this.sheetId)}async copyToSpreadsheet(e){return this._spreadsheet.sheetsApi.post(`/sheets/${this.sheetId}:copyTo`,{destinationSpreadsheetId:e})}async clear(e){const t=e?`!${e}`:"";await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}${t}:clear`),this.resetLocalCache(!0)}async downloadAsCSV(e=!1){return this._spreadsheet._downloadAs("csv",this.sheetId,e)}async downloadAsTSV(e=!1){return this._spreadsheet._downloadAs("tsv",this.sheetId,e)}async downloadAsPDF(e=!1){return this._spreadsheet._downloadAs("pdf",this.sheetId,e)}}var AUTH_MODES=(r=>(r.GOOGLE_AUTH_CLIENT="google_auth",r.RAW_ACCESS_TOKEN="raw_access_token",r.API_KEY="api_key",r))(AUTH_MODES||{});const u="https://sheets.googleapis.com/v4/spreadsheets",A="https://www.googleapis.com/drive/v3/files",c={html:{},zip:{},xlsx:{},ods:{},csv:{singleWorksheet:!0},tsv:{singleWorksheet:!0},pdf:{singleWorksheet:!0}};function m(r){if("getRequestHeaders"in r)return AUTH_MODES.GOOGLE_AUTH_CLIENT;if("token"in r&&r.token)return AUTH_MODES.RAW_ACCESS_TOKEN;if("apiKey"in r&&r.apiKey)return AUTH_MODES.API_KEY;throw new Error("Invalid auth")}async function f(r){if("getRequestHeaders"in r)return{headers:await r.getRequestHeaders()};if("apiKey"in r&&r.apiKey)return{params:{key:r.apiKey}};if("token"in r&&r.token)return{headers:{Authorization:`Bearer ${r.token}`}};throw new Error("Invalid auth")}class GoogleSpreadsheet{constructor(e,t){this._rawProperties=null,this._spreadsheetUrl=null,this._deleted=!1,this.spreadsheetId=e,this.auth=t,this._rawSheets={},this._spreadsheetUrl=null,this.sheetsApi=p__default.create({baseURL:`${u}/${e}`,paramsSerializer:axiosParamsSerializer,maxContentLength:1/0,maxBodyLength:1/0}),this.driveApi=p__default.create({baseURL:`${A}/${e}`,paramsSerializer:axiosParamsSerializer}),this.sheetsApi.interceptors.request.use(this._setAxiosRequestAuth.bind(this)),this.sheetsApi.interceptors.response.use(this._handleAxiosResponse.bind(this),this._handleAxiosErrors.bind(this)),this.driveApi.interceptors.request.use(this._setAxiosRequestAuth.bind(this)),this.driveApi.interceptors.response.use(this._handleAxiosResponse.bind(this),this._handleAxiosErrors.bind(this))}get authMode(){return m(this.auth)}async _setAxiosRequestAuth(e){const t=await f(this.auth);return each_js__default(t.headers,(s,a)=>{e.headers.set(a,s)}),e.params={...e.params,...t.params},e}async _handleAxiosResponse(e){return e}async _handleAxiosErrors(e){const t=e.response?.data;if(t){if(!t.error)throw e;const{code:s,message:a}=t.error;throw e.message=`Google API error - [${s}] ${a}`,e}throw get_js__default(e,"response.status")===403&&"apiKey"in this.auth?new Error("Sheet is private. Use authentication or make public. (see https://github.com/theoephraim/node-google-spreadsheet#a-note-on-authentication for details)"):e}async _makeSingleUpdateRequest(e,t){const s=await this.sheetsApi.post(":batchUpdate",{requests:[{[e]:t}],includeSpreadsheetInResponse:!0});return this._updateRawProperties(s.data.updatedSpreadsheet.properties),each_js__default(s.data.updatedSpreadsheet.sheets,a=>this._updateOrCreateSheet(a)),s.data.replies[0][e]}async _makeBatchUpdateRequest(e,t){const s=await this.sheetsApi.post(":batchUpdate",{requests:e,includeSpreadsheetInResponse:!0,...t&&{responseIncludeGridData:!0,...t!=="*"&&{responseRanges:t}}});this._updateRawProperties(s.data.updatedSpreadsheet.properties),each_js__default(s.data.updatedSpreadsheet.sheets,a=>this._updateOrCreateSheet(a))}_ensureInfoLoaded(){if(!this._rawProperties)throw new Error("You must call `doc.loadInfo()` before accessing this property")}_updateRawProperties(e){this._rawProperties=e}_updateOrCreateSheet(e){const{properties:t,data:s}=e,{sheetId:a}=t;this._rawSheets[a]?this._rawSheets[a].updateRawData(t,s):this._rawSheets[a]=new GoogleSpreadsheetWorksheet(this,t,s)}_getProp(e){return this._ensureInfoLoaded(),this._rawProperties[e]}get title(){return this._getProp("title")}get locale(){return this._getProp("locale")}get timeZone(){return this._getProp("timeZone")}get autoRecalc(){return this._getProp("autoRecalc")}get defaultFormat(){return this._getProp("defaultFormat")}get spreadsheetTheme(){return this._getProp("spreadsheetTheme")}get iterativeCalculationSettings(){return this._getProp("iterativeCalculationSettings")}async updateProperties(e){await this._makeSingleUpdateRequest("updateSpreadsheetProperties",{properties:e,fields:getFieldMask(e)})}async loadInfo(e=!1){const t=await this.sheetsApi.get("/",{params:{...e&&{includeGridData:!0}}});this._spreadsheetUrl=t.data.spreadsheetUrl,this._rawProperties=t.data.properties,each_js__default(t.data.sheets,s=>this._updateOrCreateSheet(s))}resetLocalCache(){this._rawProperties=null,this._rawSheets={}}get sheetCount(){return this._ensureInfoLoaded(),values_js__default(this._rawSheets).length}get sheetsById(){return this._ensureInfoLoaded(),this._rawSheets}get sheetsByIndex(){return this._ensureInfoLoaded(),sortBy_js__default(this._rawSheets,"index")}get sheetsByTitle(){return this._ensureInfoLoaded(),keyBy_js__default(this._rawSheets,"title")}async addSheet(e={}){const t=(await this._makeSingleUpdateRequest("addSheet",{properties:omit_js__default(e,"headerValues","headerRowIndex")})).properties.sheetId,s=this.sheetsById[t];return e.headerValues&&await s.setHeaderRow(e.headerValues,e.headerRowIndex),s}async deleteSheet(e){await this._makeSingleUpdateRequest("deleteSheet",{sheetId:e}),delete this._rawSheets[e]}async addNamedRange(e,t,s){return this._makeSingleUpdateRequest("addNamedRange",{name:e,namedRangeId:s,range:t})}async deleteNamedRange(e){return this._makeSingleUpdateRequest("deleteNamedRange",{namedRangeId:e})}async loadCells(e){const t=this.authMode===AUTH_MODES.API_KEY,s=isArray_js__default(e)?e:[e],a=map_js__default(s,i=>{if(isString_js__default(i))return t?i:{a1Range:i};if(isObject_js__default(i)){if(t)throw new Error("Only A1 ranges are supported when fetching cells with read-only access (using only an API key)");return{gridRange:i}}throw new Error("Each filter must be an A1 range string or a gridrange object")});let o;this.authMode===AUTH_MODES.API_KEY?o=await this.sheetsApi.get("/",{params:{includeGridData:!0,ranges:a}}):o=await this.sheetsApi.post(":getByDataFilter",{includeGridData:!0,dataFilters:a});const{sheets:h}=o.data;each_js__default(h,i=>{this._updateOrCreateSheet(i)})}async _downloadAs(e,t,s){if(!c[e])throw new Error(`unsupported export fileType - ${e}`);if(c[e].singleWorksheet){if(t===void 0)throw new Error(`Must specify worksheetId when exporting as ${e}`)}else if(t)throw new Error(`Cannot specify worksheetId when exporting as ${e}`);if(e==="html"&&(e="zip"),!this._spreadsheetUrl)throw new Error("Cannot export sheet that is not fully loaded");const a=this._spreadsheetUrl.replace("/edit","/export");return(await this.sheetsApi.get(a,{baseURL:"",params:{id:this.spreadsheetId,format:e,...t&&{gid:t}},responseType:s?"stream":"arraybuffer"})).data}async downloadAsZippedHTML(e){return this._downloadAs("html",void 0,e)}async downloadAsHTML(e){return this._downloadAs("html",void 0,e)}async downloadAsXLSX(e=!1){return this._downloadAs("xlsx",void 0,e)}async downloadAsODS(e=!1){return this._downloadAs("ods",void 0,e)}async delete(){const e=await this.driveApi.delete("");return this._deleted=!0,e.data}async listPermissions(){return(await this.driveApi.request({method:"GET",url:"/permissions",params:{fields:"permissions(id,type,emailAddress,domain,role,displayName,photoLink,deleted)"}})).data.permissions}async setPublicAccessLevel(e){const t=await this.listPermissions(),s=find_js__default(t,a=>a.type==="anyone");if(e===!1){if(!s)return;await this.driveApi.request({method:"DELETE",url:`/permissions/${s.id}`})}else await this.driveApi.request({method:"POST",url:"/permissions",params:{},data:{role:e||"viewer",type:"anyone"}})}async share(e,t){let s,a;return e.includes("@")?s=e:a=e,(await this.driveApi.request({method:"POST",url:"/permissions",params:{...t?.emailMessage===!1&&{sendNotificationEmail:!1},...isString_js__default(t?.emailMessage)&&{emailMessage:t?.emailMessage},...t?.role==="owner"&&{transferOwnership:!0}},data:{role:t?.role||"writer",...s&&{type:t?.isGroup?"group":"user",emailAddress:s},...a&&{type:"domain",domain:a}}})).data}static async createNewSpreadsheetDocument(e,t){if(m(e)===AUTH_MODES.API_KEY)throw new Error("Cannot use api key only to create a new spreadsheet - it is only usable for read-only access of public docs");const s=await f(e),a=await p__default.request({method:"POST",url:u,paramsSerializer:axiosParamsSerializer,...s,data:{properties:t}}),o=new GoogleSpreadsheet(a.data.spreadsheetId,e);return o._spreadsheetUrl=a.data.spreadsheetUrl,o._rawProperties=a.data.properties,each_js__default(a.data.sheets,h=>o._updateOrCreateSheet(h)),o}}exports.GoogleSpreadsheet=GoogleSpreadsheet,exports.GoogleSpreadsheetCell=GoogleSpreadsheetCell,exports.GoogleSpreadsheetCellErrorValue=GoogleSpreadsheetCellErrorValue,exports.GoogleSpreadsheetRow=GoogleSpreadsheetRow,exports.GoogleSpreadsheetWorksheet=GoogleSpreadsheetWorksheet;
package/dist/index.d.ts CHANGED
@@ -457,6 +457,52 @@ type AddRowOptions = {
457
457
  /** set to true to insert new rows in the sheet while adding this data */
458
458
  insert?: boolean;
459
459
  };
460
+ /**
461
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ConditionType
462
+ */
463
+ type ConditionType = 'NUMBER_GREATER' | 'NUMBER_GREATER_THAN_EQ' | 'NUMBER_LESS' | 'NUMBER_LESS_THAN_EQ' | 'NUMBER_EQ' | 'NUMBER_NOT_EQ' | 'NUMBER_BETWEEN' | 'NUMBER_NOT_BETWEEN' | 'TEXT_CONTAINS' | 'TEXT_NOT_CONTAINS' | 'TEXT_STARTS_WITH' | 'TEXT_ENDS_WITH' | 'TEXT_EQ' | 'TEXT_IS_EMAIL' | 'TEXT_IS_URL' | 'DATE_EQ' | 'DATE_BEFORE' | 'DATE_AFTER' | 'DATE_ON_OR_BEFORE' | 'DATE_ON_OR_AFTER' | 'DATE_BETWEEN' | 'DATE_NOT_BETWEEN' | 'DATE_IS_VALID' | 'ONE_OF_RANGE' | 'ONE_OF_LIST' | 'BLANK' | 'NOT_BLANK' | 'CUSTOM_FORMULA' | 'BOOLEAN' | 'TEXT_NOT_EQ' | 'DATE_NOT_EQ' | 'FILTER_EXPRESSION';
464
+ /**
465
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#relativedate
466
+ */
467
+ type RelativeDate = 'PAST_YEAR' | 'PAST_MONTH' | 'PAST_WEEK' | 'YESTERDAY' | 'TODAY' | 'TOMORROW';
468
+ /**
469
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ConditionValue
470
+ */
471
+ type ConditionValue = {
472
+ relativeDate: RelativeDate;
473
+ userEnteredValue?: undefined;
474
+ } | {
475
+ relativeDate?: undefined;
476
+ userEnteredValue: string;
477
+ };
478
+ /**
479
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#BooleanCondition
480
+ */
481
+ type BooleanCondition = {
482
+ /** The type of condition. */
483
+ type: ConditionType;
484
+ /**
485
+ * The values of the condition.
486
+ * The number of supported values depends on the condition type. Some support zero values, others one or two values, and ConditionType.ONE_OF_LIST supports an arbitrary number of values.
487
+ */
488
+ values: ConditionValue[];
489
+ };
490
+ /**
491
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#DataValidationRule
492
+ *
493
+ * example:
494
+ * - https://stackoverflow.com/a/43442775/3068233
495
+ */
496
+ type DataValidationRule = {
497
+ /** The condition that data in the cell must match. */
498
+ condition: BooleanCondition;
499
+ /** A message to show the user when adding data to the cell. */
500
+ inputMessage?: string;
501
+ /** True if invalid data should be rejected. */
502
+ strict: boolean;
503
+ /** True if the UI should be customized based on the kind of condition. If true, "List" conditions will show a dropdown. */
504
+ showCustomUi: boolean;
505
+ };
460
506
 
461
507
  /**
462
508
  * Cell error
@@ -615,6 +661,7 @@ declare class GoogleSpreadsheetWorksheet {
615
661
  get hidden(): WorksheetProperties['hidden'];
616
662
  get tabColor(): WorksheetProperties['tabColor'];
617
663
  get rightToLeft(): WorksheetProperties['rightToLeft'];
664
+ private get _headerRange();
618
665
  set sheetId(newVal: WorksheetProperties['sheetId']);
619
666
  set title(newVal: WorksheetProperties['title']);
620
667
  set index(newVal: WorksheetProperties['index']);
@@ -640,6 +687,7 @@ declare class GoogleSpreadsheetWorksheet {
640
687
  saveCells(cellsToUpdate: GoogleSpreadsheetCell[]): Promise<void>;
641
688
  _ensureHeaderRowLoaded(): Promise<void>;
642
689
  loadHeaderRow(headerRowIndex?: number): Promise<void>;
690
+ private _processHeaderRow;
643
691
  setHeaderRow(headerValues: string[], headerRowIndex?: number): Promise<void>;
644
692
  addRows(rows: RawRowData[], options?: AddRowOptions): Promise<GoogleSpreadsheetRow<Record<string, any>>[]>;
645
693
  /** add a single row - see addRows for more info */
@@ -675,6 +723,7 @@ declare class GoogleSpreadsheetWorksheet {
675
723
  */
676
724
  updateDimensionProperties(columnsOrRows: WorksheetDimension, properties: WorksheetDimensionProperties, bounds: Partial<DimensionRangeIndexes>): Promise<any>;
677
725
  getCellsInRange(a1Range: A1Range, options?: GetValuesRequestOptions): Promise<any>;
726
+ batchGetCellsInRange(a1Ranges: A1Range[], options?: GetValuesRequestOptions): Promise<any>;
678
727
  updateNamedRange(): Promise<void>;
679
728
  addNamedRange(): Promise<void>;
680
729
  deleteNamedRange(): Promise<void>;
@@ -727,7 +776,13 @@ declare class GoogleSpreadsheetWorksheet {
727
776
  updateConditionalFormatRule(): Promise<void>;
728
777
  deleteConditionalFormatRule(): Promise<void>;
729
778
  sortRange(): Promise<void>;
730
- setDataValidation(): Promise<void>;
779
+ /**
780
+ * Sets (or unsets) a data validation rule to every cell in the range
781
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#SetDataValidationRequest
782
+ */
783
+ setDataValidation(range: GridRangeWithOptionalWorksheetId,
784
+ /** data validation rule object, or set to false to clear an existing rule */
785
+ rule: DataValidationRule | false): Promise<any>;
731
786
  setBasicFilter(): Promise<void>;
732
787
  addProtectedRange(): Promise<void>;
733
788
  updateProtectedRange(): Promise<void>;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import D from"axios";import g from"lodash/compact.js";import u from"lodash/each.js";import P from"lodash/filter.js";import j from"lodash/find.js";import A from"lodash/flatten.js";import p from"lodash/get.js";import L from"lodash/groupBy.js";import f from"lodash/isArray.js";import O from"lodash/isBoolean.js";import q from"lodash/isEqual.js";import M from"lodash/isFinite.js";import x from"lodash/isInteger.js";import B from"lodash/isNil.js";import"lodash/isNumber.js";import y from"lodash/isObject.js";import w from"lodash/isString.js";import G from"lodash/keyBy.js";import R from"lodash/keys.js";import c from"lodash/map.js";import z from"lodash/omit.js";import W from"lodash/pickBy.js";import H from"lodash/set.js";import K from"lodash/some.js";import Y from"lodash/sortBy.js";import Z from"lodash/times.js";import X from"lodash/unset.js";import k from"lodash/values.js";function v(s){return Object.keys(s).join(",")}function I(s){let e,t="",r=s;for(;r>0;)e=(r-1)%26,t=String.fromCharCode(e+65)+t,r=(r-e-1)/26;return t}function J(s){let e=0;const{length:t}=s;for(let r=0;r<t;r++)e+=(s.charCodeAt(r)-64)*26**(t-r-1);return e}function S(s){let e="";return Object.keys(s).forEach(t=>{const r=typeof s[t]=="object",a=r&&s[t].length>=0;if(r||(e+=`${t}=${encodeURIComponent(s[t])}&`),r&&a)for(const o of s[t])e+=`${t}=${encodeURIComponent(o)}&`}),e&&e.slice(0,-1)}function F(s){const e=L(s);u(e,(t,r)=>{if(r&&t.length>1)throw new Error(`Duplicate header detected: "${r}". Please make sure all non-empty headers are unique`)})}class E{constructor(e,t,r){this._worksheet=e,this._rowNumber=t,this._rawData=r,this._deleted=!1}get deleted(){return this._deleted}get rowNumber(){return this._rowNumber}_updateRowNumber(e){this._rowNumber=e}get a1Range(){return[this._worksheet.a1SheetName,"!",`A${this._rowNumber}`,":",`${I(this._worksheet.headerValues.length)}${this._rowNumber}`].join("")}get(e){const t=this._worksheet.headerValues.indexOf(e);return this._rawData[t]}set(e,t){const r=this._worksheet.headerValues.indexOf(e);this._rawData[r]=t}assign(e){for(const t in e)this.set(t,e[t])}toObject(){const e={};for(let t=0;t<this._worksheet.headerValues.length;t++){const r=this._worksheet.headerValues[t];r&&(e[r]=this._rawData[t])}return e}async save(e){if(this._deleted)throw new Error("This row has been deleted - call getRows again before making updates.");const t=await this._worksheet._spreadsheet.sheetsApi.request({method:"put",url:`/values/${encodeURIComponent(this.a1Range)}`,params:{valueInputOption:e?.raw?"RAW":"USER_ENTERED",includeValuesInResponse:!0},data:{range:this.a1Range,majorDimension:"ROWS",values:[this._rawData]}});this._rawData=t.data.updatedData.values[0]}async delete(){if(this._deleted)throw new Error("This row has been deleted - call getRows again before making updates.");const e=await this._worksheet._makeSingleUpdateRequest("deleteRange",{range:{sheetId:this._worksheet.sheetId,startRowIndex:this._rowNumber-1,endRowIndex:this._rowNumber},shiftDimension:"ROWS"});return this._deleted=!0,this._worksheet._shiftRowCache(this.rowNumber),e}_clearRowData(){for(let e=0;e<this._rawData.length;e++)this._rawData[e]=""}}class b{constructor(e){this.type=e.type,this.message=e.message}}class V{constructor(e,t,r,a){this._sheet=e,this._rowIndex=t,this._columnIndex=r,this._draftData={},this._updateRawData(a),this._rawData=a}_updateRawData(e){this._rawData=e,this._draftData={},this._rawData?.effectiveValue&&"errorValue"in this._rawData.effectiveValue?this._error=new b(this._rawData.effectiveValue.errorValue):this._error=void 0}get rowIndex(){return this._rowIndex}get columnIndex(){return this._columnIndex}get a1Column(){return I(this._columnIndex+1)}get a1Row(){return this._rowIndex+1}get a1Address(){return`${this.a1Column}${this.a1Row}`}get value(){if(this._draftData.value!==void 0)throw new Error("Value has been changed");return this._error?this._error:this._rawData?.effectiveValue?k(this._rawData.effectiveValue)[0]:null}set value(e){if(e instanceof b)throw new Error("You can't manually set a value to an error");if(O(e))this._draftData.valueType="boolValue";else if(w(e))e.substring(0,1)==="="?this._draftData.valueType="formulaValue":this._draftData.valueType="stringValue";else if(M(e))this._draftData.valueType="numberValue";else if(B(e))this._draftData.valueType="stringValue",e="";else throw new Error("Set value to boolean, string, or number");this._draftData.value=e}get valueType(){return this._error?"errorValue":this._rawData?.effectiveValue?R(this._rawData.effectiveValue)[0]:null}get formattedValue(){return this._rawData?.formattedValue||null}get formula(){return p(this._rawData,"userEnteredValue.formulaValue",null)}set formula(e){if(!e)throw new Error("To clear a formula, set `cell.value = null`");if(e.substring(0,1)!=="=")throw new Error('formula must begin with "="');this.value=e}get formulaError(){return this._error}get errorValue(){return this._error}get numberValue(){if(this.valueType==="numberValue")return this.value}set numberValue(e){this.value=e}get boolValue(){if(this.valueType==="boolValue")return this.value}set boolValue(e){this.value=e}get stringValue(){if(this.valueType==="stringValue")return this.value}set stringValue(e){if(e?.startsWith("="))throw new Error("Use cell.formula to set formula values");this.value=e}get hyperlink(){if(this._draftData.value)throw new Error("Save cell to be able to read hyperlink");return this._rawData?.hyperlink}get note(){return this._draftData.note!==void 0?this._draftData.note:this._rawData?.note}set note(e){if((e==null||e===!1)&&(e=""),!w(e))throw new Error("Note must be a string");e===this._rawData?.note?delete this._draftData.note:this._draftData.note=e}get userEnteredFormat(){return Object.freeze(this._rawData?.userEnteredFormat)}get effectiveFormat(){return Object.freeze(this._rawData?.effectiveFormat)}_getFormatParam(e){if(p(this._draftData,`userEnteredFormat.${e}`))throw new Error("User format is unsaved - save the cell to be able to read it again");return Object.freeze(this._rawData.userEnteredFormat[e])}_setFormatParam(e,t){q(t,p(this._rawData,`userEnteredFormat.${e}`))?X(this._draftData,`userEnteredFormat.${e}`):(H(this._draftData,`userEnteredFormat.${e}`,t),this._draftData.clearFormat=!1)}get numberFormat(){return this._getFormatParam("numberFormat")}get backgroundColor(){return this._getFormatParam("backgroundColor")}get backgroundColorStyle(){return this._getFormatParam("backgroundColorStyle")}get borders(){return this._getFormatParam("borders")}get padding(){return this._getFormatParam("padding")}get horizontalAlignment(){return this._getFormatParam("horizontalAlignment")}get verticalAlignment(){return this._getFormatParam("verticalAlignment")}get wrapStrategy(){return this._getFormatParam("wrapStrategy")}get textDirection(){return this._getFormatParam("textDirection")}get textFormat(){return this._getFormatParam("textFormat")}get hyperlinkDisplayType(){return this._getFormatParam("hyperlinkDisplayType")}get textRotation(){return this._getFormatParam("textRotation")}set numberFormat(e){this._setFormatParam("numberFormat",e)}set backgroundColor(e){this._setFormatParam("backgroundColor",e)}set backgroundColorStyle(e){this._setFormatParam("backgroundColorStyle",e)}set borders(e){this._setFormatParam("borders",e)}set padding(e){this._setFormatParam("padding",e)}set horizontalAlignment(e){this._setFormatParam("horizontalAlignment",e)}set verticalAlignment(e){this._setFormatParam("verticalAlignment",e)}set wrapStrategy(e){this._setFormatParam("wrapStrategy",e)}set textDirection(e){this._setFormatParam("textDirection",e)}set textFormat(e){this._setFormatParam("textFormat",e)}set hyperlinkDisplayType(e){this._setFormatParam("hyperlinkDisplayType",e)}set textRotation(e){this._setFormatParam("textRotation",e)}clearAllFormatting(){this._draftData.clearFormat=!0,delete this._draftData.userEnteredFormat}get _isDirty(){return!!(this._draftData.note!==void 0||R(this._draftData.userEnteredFormat).length||this._draftData.clearFormat||this._draftData.value!==void 0)}discardUnsavedChanges(){this._draftData={}}async save(){await this._sheet.saveCells([this])}_getUpdateRequest(){const e=this._draftData.value!==void 0,t=this._draftData.note!==void 0,r=!!R(this._draftData.userEnteredFormat||{}).length,a=this._draftData.clearFormat;if(!K([e,t,r,a]))return null;const o={...this._rawData?.userEnteredFormat,...this._draftData.userEnteredFormat};return p(this._draftData,"userEnteredFormat.backgroundColor")&&delete o.backgroundColorStyle,{updateCells:{rows:[{values:[{...e&&{userEnteredValue:{[this._draftData.valueType]:this._draftData.value}},...t&&{note:this._draftData.note},...r&&{userEnteredFormat:o},...a&&{userEnteredFormat:{}}}]}],fields:R(W({userEnteredValue:e,note:t,userEnteredFormat:r||a})).join(","),start:{sheetId:this._sheet.sheetId,rowIndex:this.rowIndex,columnIndex:this.columnIndex}}}}}class ${constructor(e,t,r){this._spreadsheet=e,this._headerRowIndex=1,this._rawProperties=null,this._cells=[],this._rowMetadata=[],this._columnMetadata=[],this._rowCache=[],this._headerRowIndex=1,this._rawProperties=t,this._cells=[],this._rowMetadata=[],this._columnMetadata=[],r&&this._fillCellData(r)}get headerValues(){if(!this._headerValues)throw new Error("Header values are not yet loaded");return this._headerValues}updateRawData(e,t){this._rawProperties=e,this._fillCellData(t)}async _makeSingleUpdateRequest(e,t){return this._spreadsheet._makeSingleUpdateRequest(e,{...t})}_ensureInfoLoaded(){if(!this._rawProperties)throw new Error("You must call `doc.loadInfo()` again before accessing this property")}resetLocalCache(e){e||(this._rawProperties=null),this._headerValues=void 0,this._headerRowIndex=1,this._cells=[]}_fillCellData(e){u(e,t=>{const r=t.startRow||0,a=t.startColumn||0,o=t.rowMetadata.length,h=t.columnMetadata.length;for(let i=0;i<o;i++){const n=r+i;for(let d=0;d<h;d++){const l=a+d;this._cells[n]||(this._cells[n]=[]);const m=p(t,`rowData[${i}].values[${d}]`);this._cells[n][l]?this._cells[n][l]._updateRawData(m):this._cells[n][l]=new V(this,n,l,m)}}for(let i=0;i<t.rowMetadata.length;i++)this._rowMetadata[r+i]=t.rowMetadata[i];for(let i=0;i<t.columnMetadata.length;i++)this._columnMetadata[a+i]=t.columnMetadata[i]})}_addSheetIdToRange(e){if(e.sheetId&&e.sheetId!==this.sheetId)throw new Error("Leave sheet ID blank or set to matching ID of this sheet");return{...e,sheetId:this.sheetId}}_getProp(e){return this._ensureInfoLoaded(),this._rawProperties[e]}_setProp(e,t){throw new Error("Do not update directly - use `updateProperties()`")}get sheetId(){return this._getProp("sheetId")}get title(){return this._getProp("title")}get index(){return this._getProp("index")}get sheetType(){return this._getProp("sheetType")}get gridProperties(){return this._getProp("gridProperties")}get hidden(){return this._getProp("hidden")}get tabColor(){return this._getProp("tabColor")}get rightToLeft(){return this._getProp("rightToLeft")}set sheetId(e){this._setProp("sheetId",e)}set title(e){this._setProp("title",e)}set index(e){this._setProp("index",e)}set sheetType(e){this._setProp("sheetType",e)}set gridProperties(e){this._setProp("gridProperties",e)}set hidden(e){this._setProp("hidden",e)}set tabColor(e){this._setProp("tabColor",e)}set rightToLeft(e){this._setProp("rightToLeft",e)}get rowCount(){return this._ensureInfoLoaded(),this.gridProperties.rowCount}get columnCount(){return this._ensureInfoLoaded(),this.gridProperties.columnCount}get a1SheetName(){return`'${this.title.replace(/'/g,"''")}'`}get encodedA1SheetName(){return encodeURIComponent(this.a1SheetName)}get lastColumnLetter(){return this.columnCount?I(this.columnCount):""}get cellStats(){let e=A(this._cells);return e=g(e),{nonEmpty:P(e,t=>t.value).length,loaded:e.length,total:this.rowCount*this.columnCount}}getCellByA1(e){const t=e.match(/([A-Z]+)([0-9]+)/);if(!t)throw new Error(`Cell address "${e}" not valid`);const r=J(t[1]),a=parseInt(t[2]);return this.getCell(a-1,r-1)}getCell(e,t){if(e<0||t<0)throw new Error("Min coordinate is 0, 0");if(e>=this.rowCount||t>=this.columnCount)throw new Error(`Out of bounds, sheet is ${this.rowCount} by ${this.columnCount}`);if(!p(this._cells,`[${e}][${t}]`))throw new Error("This cell has not been loaded yet");return this._cells[e][t]}async loadCells(e){if(!e)return this._spreadsheet.loadCells(this.a1SheetName);const t=f(e)?e:[e],r=c(t,a=>{if(w(a))return a.startsWith(this.a1SheetName)?a:`${this.a1SheetName}!${a}`;if(y(a)){const o=a;if(o.sheetId&&o.sheetId!==this.sheetId)throw new Error("Leave sheet ID blank or set to matching ID of this sheet");return{sheetId:this.sheetId,...a}}throw new Error("Each filter must be a A1 range string or gridrange object")});return this._spreadsheet.loadCells(r)}async saveUpdatedCells(){const e=P(A(this._cells),{_isDirty:!0});e.length&&await this.saveCells(e)}async saveCells(e){const t=c(e,a=>a._getUpdateRequest()),r=c(e,a=>`${this.a1SheetName}!${a.a1Address}`);if(!g(t).length)throw new Error("At least one cell must have something to update");await this._spreadsheet._makeBatchUpdateRequest(t,r)}async _ensureHeaderRowLoaded(){this._headerValues||await this.loadHeaderRow()}async loadHeaderRow(e){e!==void 0&&(this._headerRowIndex=e);const t=await this.getCellsInRange(`A${this._headerRowIndex}:${this.lastColumnLetter}${this._headerRowIndex}`);if(!t)throw new Error("No values in the header row - fill the first row with header values before trying to interact with rows");if(this._headerValues=c(t[0],r=>r?.trim()),!g(this.headerValues).length)throw new Error("All your header cells are blank - fill the first row with header values before trying to interact with rows");F(this.headerValues)}async setHeaderRow(e,t){if(!e)return;if(e.length>this.columnCount)throw new Error(`Sheet is not large enough to fit ${e.length} columns. Resize the sheet first.`);const r=c(e,o=>o?.trim());if(F(r),!g(r).length)throw new Error("All your header cells are blank -");t&&(this._headerRowIndex=t);const a=await this._spreadsheet.sheetsApi.request({method:"put",url:`/values/${this.encodedA1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,params:{valueInputOption:"USER_ENTERED",includeValuesInResponse:!0},data:{range:`${this.a1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,majorDimension:"ROWS",values:[[...r,...Z(this.columnCount-r.length,()=>"")]]}});this._headerValues=a.data.updatedData.values[0]}async addRows(e,t={}){if(this.title.includes(":"))throw new Error('Please remove the ":" from your sheet title. There is a bug with the google API which breaks appending rows if any colons are in the sheet title.');if(!f(e))throw new Error("You must pass in an array of row values to append");await this._ensureHeaderRowLoaded();const r=[];u(e,i=>{let n;if(f(i))n=i;else if(y(i)){n=[];for(let d=0;d<this.headerValues.length;d++){const l=this.headerValues[d];n[d]=i[l]}}else throw new Error("Each row must be an object or an array");r.push(n)});const a=await this._spreadsheet.sheetsApi.request({method:"post",url:`/values/${this.encodedA1SheetName}!A${this._headerRowIndex}:append`,params:{valueInputOption:t.raw?"RAW":"USER_ENTERED",insertDataOption:t.insert?"INSERT_ROWS":"OVERWRITE",includeValuesInResponse:!0},data:{values:r}}),{updatedRange:o}=a.data.updates;let h=o.match(/![A-Z]+([0-9]+):?/)[1];return h=parseInt(h),this._ensureInfoLoaded(),t.insert?this._rawProperties.gridProperties.rowCount+=e.length:h+e.length>this.rowCount&&(this._rawProperties.gridProperties.rowCount=h+e.length-1),c(a.data.updates.updatedData.values,i=>new E(this,h++,i))}async addRow(e,t){return(await this.addRows([e],t))[0]}async getRows(e){const t=e?.offset||0,r=e?.limit||this.rowCount-1;await this._ensureHeaderRowLoaded();const a=1+this._headerRowIndex+t,o=a+r-1,h=I(this.headerValues.length),i=await this.getCellsInRange(`A${a}:${h}${o}`);if(!i)return[];const n=[];let d=a;for(let l=0;l<i.length;l++){const m=new E(this,d++,i[l]);this._rowCache[m.rowNumber]=m,n.push(m)}return n}_shiftRowCache(e){delete this._rowCache[e],this._rowCache.forEach(t=>{t.rowNumber>e&&t._updateRowNumber(t.rowNumber-1)})}async clearRows(e){const t=e?.start||this._headerRowIndex+1,r=e?.end||this.rowCount;await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}!${t}:${r}:clear`),this._rowCache.forEach(a=>{a.rowNumber>=t&&a.rowNumber<=r&&a._clearRowData()})}async updateProperties(e){return this._makeSingleUpdateRequest("updateSheetProperties",{properties:{sheetId:this.sheetId,...e},fields:v(e)})}async updateGridProperties(e){return this.updateProperties({gridProperties:e})}async resize(e){return this.updateGridProperties(e)}async updateDimensionProperties(e,t,r){return this._makeSingleUpdateRequest("updateDimensionProperties",{range:{sheetId:this.sheetId,dimension:e,...r},properties:t,fields:v(t)})}async getCellsInRange(e,t){return(await this._spreadsheet.sheetsApi.get(`/values/${this.encodedA1SheetName}!${e}`,{params:t})).data.values}async updateNamedRange(){}async addNamedRange(){}async deleteNamedRange(){}async repeatCell(){}async autoFill(){}async cutPaste(){}async copyPaste(){}async mergeCells(e,t="MERGE_ALL"){await this._makeSingleUpdateRequest("mergeCells",{mergeType:t,range:this._addSheetIdToRange(e)})}async unmergeCells(e){await this._makeSingleUpdateRequest("unmergeCells",{range:this._addSheetIdToRange(e)})}async updateBorders(){}async addFilterView(){}async appendCells(){}async clearBasicFilter(){}async deleteDimension(){}async deleteEmbeddedObject(){}async deleteFilterView(){}async duplicateFilterView(){}async duplicate(e){const t=(await this._makeSingleUpdateRequest("duplicateSheet",{sourceSheetId:this.sheetId,...e?.index!==void 0&&{insertSheetIndex:e.index},...e?.id&&{newSheetId:e.id},...e?.title&&{newSheetName:e.title}})).properties.sheetId;return this._spreadsheet.sheetsById[t]}async findReplace(){}async insertDimension(e,t,r){if(!e)throw new Error("You need to specify a dimension. i.e. COLUMNS|ROWS");if(!y(t))throw new Error("`range` must be an object containing `startIndex` and `endIndex`");if(!x(t.startIndex)||t.startIndex<0)throw new Error("range.startIndex must be an integer >=0");if(!x(t.endIndex)||t.endIndex<0)throw new Error("range.endIndex must be an integer >=0");if(t.endIndex<=t.startIndex)throw new Error("range.endIndex must be greater than range.startIndex");if(r===void 0&&(r=t.startIndex>0),r&&t.startIndex===0)throw new Error("Cannot set inheritFromBefore to true if inserting in first row/column");return this._makeSingleUpdateRequest("insertDimension",{range:{sheetId:this.sheetId,dimension:e,startIndex:t.startIndex,endIndex:t.endIndex},inheritFromBefore:r})}async insertRange(){}async moveDimension(){}async updateEmbeddedObjectPosition(){}async pasteData(){}async textToColumns(){}async updateFilterView(){}async deleteRange(){}async appendDimension(){}async addConditionalFormatRule(){}async updateConditionalFormatRule(){}async deleteConditionalFormatRule(){}async sortRange(){}async setDataValidation(){}async setBasicFilter(){}async addProtectedRange(){}async updateProtectedRange(){}async deleteProtectedRange(){}async autoResizeDimensions(){}async addChart(){}async updateChartSpec(){}async updateBanding(){}async addBanding(){}async deleteBanding(){}async createDeveloperMetadata(){}async updateDeveloperMetadata(){}async deleteDeveloperMetadata(){}async randomizeRange(){}async addDimensionGroup(){}async deleteDimensionGroup(){}async updateDimensionGroup(){}async trimWhitespace(){}async deleteDuplicates(){}async addSlicer(){}async updateSlicerSpec(){}async delete(){return this._spreadsheet.deleteSheet(this.sheetId)}async copyToSpreadsheet(e){return this._spreadsheet.sheetsApi.post(`/sheets/${this.sheetId}:copyTo`,{destinationSpreadsheetId:e})}async clear(e){const t=e?`!${e}`:"";await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}${t}:clear`),this.resetLocalCache(!0)}async downloadAsCSV(e=!1){return this._spreadsheet._downloadAs("csv",this.sheetId,e)}async downloadAsTSV(e=!1){return this._spreadsheet._downloadAs("tsv",this.sheetId,e)}async downloadAsPDF(e=!1){return this._spreadsheet._downloadAs("pdf",this.sheetId,e)}}var _=(s=>(s.GOOGLE_AUTH_CLIENT="google_auth",s.RAW_ACCESS_TOKEN="raw_access_token",s.API_KEY="api_key",s))(_||{});const T="https://sheets.googleapis.com/v4/spreadsheets",Q="https://www.googleapis.com/drive/v3/files",N={html:{},zip:{},xlsx:{},ods:{},csv:{singleWorksheet:!0},tsv:{singleWorksheet:!0},pdf:{singleWorksheet:!0}};function ee(s){if("getRequestHeaders"in s)return _.GOOGLE_AUTH_CLIENT;if("token"in s)return _.RAW_ACCESS_TOKEN;if("apiKey"in s)return _.API_KEY;throw new Error("Invalid auth")}async function U(s){if("getRequestHeaders"in s)return{headers:await s.getRequestHeaders()};if("apiKey"in s)return{params:{key:s.apiKey}};if("token"in s)return{headers:{Authorization:`Bearer ${s.token}`}};throw new Error("Invalid auth")}class C{constructor(e,t){this._rawProperties=null,this._spreadsheetUrl=null,this._deleted=!1,this.spreadsheetId=e,this.auth=t,this._rawSheets={},this._spreadsheetUrl=null,this.sheetsApi=D.create({baseURL:`${T}/${e}`,paramsSerializer:S,maxContentLength:1/0,maxBodyLength:1/0}),this.driveApi=D.create({baseURL:`${Q}/${e}`,paramsSerializer:S}),this.sheetsApi.interceptors.request.use(this._setAxiosRequestAuth.bind(this)),this.sheetsApi.interceptors.response.use(this._handleAxiosResponse.bind(this),this._handleAxiosErrors.bind(this)),this.driveApi.interceptors.request.use(this._setAxiosRequestAuth.bind(this)),this.driveApi.interceptors.response.use(this._handleAxiosResponse.bind(this),this._handleAxiosErrors.bind(this))}get authMode(){return ee(this.auth)}async _setAxiosRequestAuth(e){const t=await U(this.auth);return u(t.headers,(r,a)=>{e.headers.set(a,r)}),e.params={...e.params,...t.params},e}async _handleAxiosResponse(e){return e}async _handleAxiosErrors(e){const t=e.response?.data;if(t){if(!t.error)throw e;const{code:r,message:a}=t.error;throw e.message=`Google API error - [${r}] ${a}`,e}throw p(e,"response.status")===403&&"apiKey"in this.auth?new Error("Sheet is private. Use authentication or make public. (see https://github.com/theoephraim/node-google-spreadsheet#a-note-on-authentication for details)"):e}async _makeSingleUpdateRequest(e,t){const r=await this.sheetsApi.post(":batchUpdate",{requests:[{[e]:t}],includeSpreadsheetInResponse:!0});return this._updateRawProperties(r.data.updatedSpreadsheet.properties),u(r.data.updatedSpreadsheet.sheets,a=>this._updateOrCreateSheet(a)),r.data.replies[0][e]}async _makeBatchUpdateRequest(e,t){const r=await this.sheetsApi.post(":batchUpdate",{requests:e,includeSpreadsheetInResponse:!0,...t&&{responseIncludeGridData:!0,...t!=="*"&&{responseRanges:t}}});this._updateRawProperties(r.data.updatedSpreadsheet.properties),u(r.data.updatedSpreadsheet.sheets,a=>this._updateOrCreateSheet(a))}_ensureInfoLoaded(){if(!this._rawProperties)throw new Error("You must call `doc.loadInfo()` before accessing this property")}_updateRawProperties(e){this._rawProperties=e}_updateOrCreateSheet(e){const{properties:t,data:r}=e,{sheetId:a}=t;this._rawSheets[a]?this._rawSheets[a].updateRawData(t,r):this._rawSheets[a]=new $(this,t,r)}_getProp(e){return this._ensureInfoLoaded(),this._rawProperties[e]}get title(){return this._getProp("title")}get locale(){return this._getProp("locale")}get timeZone(){return this._getProp("timeZone")}get autoRecalc(){return this._getProp("autoRecalc")}get defaultFormat(){return this._getProp("defaultFormat")}get spreadsheetTheme(){return this._getProp("spreadsheetTheme")}get iterativeCalculationSettings(){return this._getProp("iterativeCalculationSettings")}async updateProperties(e){await this._makeSingleUpdateRequest("updateSpreadsheetProperties",{properties:e,fields:v(e)})}async loadInfo(e=!1){const t=await this.sheetsApi.get("/",{params:{...e&&{includeGridData:!0}}});this._spreadsheetUrl=t.data.spreadsheetUrl,this._rawProperties=t.data.properties,u(t.data.sheets,r=>this._updateOrCreateSheet(r))}resetLocalCache(){this._rawProperties=null,this._rawSheets={}}get sheetCount(){return this._ensureInfoLoaded(),k(this._rawSheets).length}get sheetsById(){return this._ensureInfoLoaded(),this._rawSheets}get sheetsByIndex(){return this._ensureInfoLoaded(),Y(this._rawSheets,"index")}get sheetsByTitle(){return this._ensureInfoLoaded(),G(this._rawSheets,"title")}async addSheet(e={}){const t=(await this._makeSingleUpdateRequest("addSheet",{properties:z(e,"headerValues","headerRowIndex")})).properties.sheetId,r=this.sheetsById[t];return e.headerValues&&await r.setHeaderRow(e.headerValues,e.headerRowIndex),r}async deleteSheet(e){await this._makeSingleUpdateRequest("deleteSheet",{sheetId:e}),delete this._rawSheets[e]}async addNamedRange(e,t,r){return this._makeSingleUpdateRequest("addNamedRange",{name:e,namedRangeId:r,range:t})}async deleteNamedRange(e){return this._makeSingleUpdateRequest("deleteNamedRange",{namedRangeId:e})}async loadCells(e){const t=this.authMode===_.API_KEY,r=f(e)?e:[e],a=c(r,i=>{if(w(i))return t?i:{a1Range:i};if(y(i)){if(t)throw new Error("Only A1 ranges are supported when fetching cells with read-only access (using only an API key)");return{gridRange:i}}throw new Error("Each filter must be an A1 range string or a gridrange object")});let o;this.authMode===_.API_KEY?o=await this.sheetsApi.get("/",{params:{includeGridData:!0,ranges:a}}):o=await this.sheetsApi.post(":getByDataFilter",{includeGridData:!0,dataFilters:a});const{sheets:h}=o.data;u(h,i=>{this._updateOrCreateSheet(i)})}async _downloadAs(e,t,r){if(!N[e])throw new Error(`unsupported export fileType - ${e}`);if(N[e].singleWorksheet){if(t===void 0)throw new Error(`Must specify worksheetId when exporting as ${e}`)}else if(t)throw new Error(`Cannot specify worksheetId when exporting as ${e}`);if(e==="html"&&(e="zip"),!this._spreadsheetUrl)throw new Error("Cannot export sheet that is not fully loaded");const a=this._spreadsheetUrl.replace("/edit","/export");return(await this.sheetsApi.get(a,{baseURL:"",params:{id:this.spreadsheetId,format:e,...t&&{gid:t}},responseType:r?"stream":"arraybuffer"})).data}async downloadAsZippedHTML(e){return this._downloadAs("html",void 0,e)}async downloadAsHTML(e){return this._downloadAs("html",void 0,e)}async downloadAsXLSX(e=!1){return this._downloadAs("xlsx",void 0,e)}async downloadAsODS(e=!1){return this._downloadAs("ods",void 0,e)}async delete(){const e=await this.driveApi.delete("");return this._deleted=!0,e.data}async listPermissions(){return(await this.driveApi.request({method:"GET",url:"/permissions",params:{fields:"permissions(id,type,emailAddress,domain,role,displayName,photoLink,deleted)"}})).data.permissions}async setPublicAccessLevel(e){const t=await this.listPermissions(),r=j(t,a=>a.type==="anyone");if(e===!1){if(!r)return;await this.driveApi.request({method:"DELETE",url:`/permissions/${r.id}`})}else await this.driveApi.request({method:"POST",url:"/permissions",params:{},data:{role:e||"viewer",type:"anyone"}})}async share(e,t){let r,a;return e.includes("@")?r=e:a=e,(await this.driveApi.request({method:"POST",url:"/permissions",params:{...t?.emailMessage===!1&&{sendNotificationEmail:!1},...w(t?.emailMessage)&&{emailMessage:t?.emailMessage},...t?.role==="owner"&&{transferOwnership:!0}},data:{role:t?.role||"writer",...r&&{type:t?.isGroup?"group":"user",emailAddress:r},...a&&{type:"domain",domain:a}}})).data}static async createNewSpreadsheetDocument(e,t){if("apiKey"in e)throw new Error("Cannot use api key only to create a new spreadsheet - it is only usable for read-only access of public docs");const r=await U(e),a=await D.request({method:"POST",url:T,paramsSerializer:S,...r,data:{properties:t}}),o=new C(a.data.spreadsheetId,e);return o._spreadsheetUrl=a.data.spreadsheetUrl,o._rawProperties=a.data.properties,u(a.data.sheets,h=>o._updateOrCreateSheet(h)),o}}export{C as GoogleSpreadsheet,V as GoogleSpreadsheetCell,b as GoogleSpreadsheetCellErrorValue,E as GoogleSpreadsheetRow,$ as GoogleSpreadsheetWorksheet};
1
+ import I from"axios";import w from"lodash/compact.js";import u from"lodash/each.js";import P from"lodash/filter.js";import L from"lodash/find.js";import A from"lodash/flatten.js";import p from"lodash/get.js";import O from"lodash/groupBy.js";import g from"lodash/isArray.js";import q from"lodash/isBoolean.js";import M from"lodash/isEqual.js";import B from"lodash/isFinite.js";import x from"lodash/isInteger.js";import G from"lodash/isNil.js";import"lodash/isNumber.js";import f from"lodash/isObject.js";import _ from"lodash/isString.js";import H from"lodash/keyBy.js";import y from"lodash/keys.js";import c from"lodash/map.js";import z from"lodash/omit.js";import W from"lodash/pickBy.js";import K from"lodash/set.js";import Y from"lodash/some.js";import Z from"lodash/sortBy.js";import X from"lodash/times.js";import J from"lodash/unset.js";import k from"lodash/values.js";function v(s){return Object.keys(s).join(",")}function R(s){let e,t="",r=s;for(;r>0;)e=(r-1)%26,t=String.fromCharCode(e+65)+t,r=(r-e-1)/26;return t}function Q(s){let e=0;const{length:t}=s;for(let r=0;r<t;r++)e+=(s.charCodeAt(r)-64)*26**(t-r-1);return e}function D(s){let e="";return Object.keys(s).forEach(t=>{const r=typeof s[t]=="object",a=r&&s[t].length>=0;if(r||(e+=`${t}=${encodeURIComponent(s[t])}&`),r&&a)for(const o of s[t])e+=`${t}=${encodeURIComponent(o)}&`}),e&&e.slice(0,-1)}function F(s){const e=O(s);u(e,(t,r)=>{if(r&&t.length>1)throw new Error(`Duplicate header detected: "${r}". Please make sure all non-empty headers are unique`)})}class S{constructor(e,t,r){this._worksheet=e,this._rowNumber=t,this._rawData=r,this._deleted=!1}get deleted(){return this._deleted}get rowNumber(){return this._rowNumber}_updateRowNumber(e){this._rowNumber=e}get a1Range(){return[this._worksheet.a1SheetName,"!",`A${this._rowNumber}`,":",`${R(this._worksheet.headerValues.length)}${this._rowNumber}`].join("")}get(e){const t=this._worksheet.headerValues.indexOf(e);return this._rawData[t]}set(e,t){const r=this._worksheet.headerValues.indexOf(e);this._rawData[r]=t}assign(e){for(const t in e)this.set(t,e[t])}toObject(){const e={};for(let t=0;t<this._worksheet.headerValues.length;t++){const r=this._worksheet.headerValues[t];r&&(e[r]=this._rawData[t])}return e}async save(e){if(this._deleted)throw new Error("This row has been deleted - call getRows again before making updates.");const t=await this._worksheet._spreadsheet.sheetsApi.request({method:"put",url:`/values/${encodeURIComponent(this.a1Range)}`,params:{valueInputOption:e?.raw?"RAW":"USER_ENTERED",includeValuesInResponse:!0},data:{range:this.a1Range,majorDimension:"ROWS",values:[this._rawData]}});this._rawData=t.data.updatedData.values[0]}async delete(){if(this._deleted)throw new Error("This row has been deleted - call getRows again before making updates.");const e=await this._worksheet._makeSingleUpdateRequest("deleteRange",{range:{sheetId:this._worksheet.sheetId,startRowIndex:this._rowNumber-1,endRowIndex:this._rowNumber},shiftDimension:"ROWS"});return this._deleted=!0,this._worksheet._shiftRowCache(this.rowNumber),e}_clearRowData(){for(let e=0;e<this._rawData.length;e++)this._rawData[e]=""}}class b{constructor(e){this.type=e.type,this.message=e.message}}class ${constructor(e,t,r,a){this._sheet=e,this._rowIndex=t,this._columnIndex=r,this._draftData={},this._updateRawData(a),this._rawData=a}_updateRawData(e){this._rawData=e,this._draftData={},this._rawData?.effectiveValue&&"errorValue"in this._rawData.effectiveValue?this._error=new b(this._rawData.effectiveValue.errorValue):this._error=void 0}get rowIndex(){return this._rowIndex}get columnIndex(){return this._columnIndex}get a1Column(){return R(this._columnIndex+1)}get a1Row(){return this._rowIndex+1}get a1Address(){return`${this.a1Column}${this.a1Row}`}get value(){if(this._draftData.value!==void 0)throw new Error("Value has been changed");return this._error?this._error:this._rawData?.effectiveValue?k(this._rawData.effectiveValue)[0]:null}set value(e){if(e instanceof b)throw new Error("You can't manually set a value to an error");if(q(e))this._draftData.valueType="boolValue";else if(_(e))e.substring(0,1)==="="?this._draftData.valueType="formulaValue":this._draftData.valueType="stringValue";else if(B(e))this._draftData.valueType="numberValue";else if(G(e))this._draftData.valueType="stringValue",e="";else throw new Error("Set value to boolean, string, or number");this._draftData.value=e}get valueType(){return this._error?"errorValue":this._rawData?.effectiveValue?y(this._rawData.effectiveValue)[0]:null}get formattedValue(){return this._rawData?.formattedValue||null}get formula(){return p(this._rawData,"userEnteredValue.formulaValue",null)}set formula(e){if(!e)throw new Error("To clear a formula, set `cell.value = null`");if(e.substring(0,1)!=="=")throw new Error('formula must begin with "="');this.value=e}get formulaError(){return this._error}get errorValue(){return this._error}get numberValue(){if(this.valueType==="numberValue")return this.value}set numberValue(e){this.value=e}get boolValue(){if(this.valueType==="boolValue")return this.value}set boolValue(e){this.value=e}get stringValue(){if(this.valueType==="stringValue")return this.value}set stringValue(e){if(e?.startsWith("="))throw new Error("Use cell.formula to set formula values");this.value=e}get hyperlink(){if(this._draftData.value)throw new Error("Save cell to be able to read hyperlink");return this._rawData?.hyperlink}get note(){return this._draftData.note!==void 0?this._draftData.note:this._rawData?.note}set note(e){if((e==null||e===!1)&&(e=""),!_(e))throw new Error("Note must be a string");e===this._rawData?.note?delete this._draftData.note:this._draftData.note=e}get userEnteredFormat(){return Object.freeze(this._rawData?.userEnteredFormat)}get effectiveFormat(){return Object.freeze(this._rawData?.effectiveFormat)}_getFormatParam(e){if(p(this._draftData,`userEnteredFormat.${e}`))throw new Error("User format is unsaved - save the cell to be able to read it again");return Object.freeze(this._rawData.userEnteredFormat[e])}_setFormatParam(e,t){M(t,p(this._rawData,`userEnteredFormat.${e}`))?J(this._draftData,`userEnteredFormat.${e}`):(K(this._draftData,`userEnteredFormat.${e}`,t),this._draftData.clearFormat=!1)}get numberFormat(){return this._getFormatParam("numberFormat")}get backgroundColor(){return this._getFormatParam("backgroundColor")}get backgroundColorStyle(){return this._getFormatParam("backgroundColorStyle")}get borders(){return this._getFormatParam("borders")}get padding(){return this._getFormatParam("padding")}get horizontalAlignment(){return this._getFormatParam("horizontalAlignment")}get verticalAlignment(){return this._getFormatParam("verticalAlignment")}get wrapStrategy(){return this._getFormatParam("wrapStrategy")}get textDirection(){return this._getFormatParam("textDirection")}get textFormat(){return this._getFormatParam("textFormat")}get hyperlinkDisplayType(){return this._getFormatParam("hyperlinkDisplayType")}get textRotation(){return this._getFormatParam("textRotation")}set numberFormat(e){this._setFormatParam("numberFormat",e)}set backgroundColor(e){this._setFormatParam("backgroundColor",e)}set backgroundColorStyle(e){this._setFormatParam("backgroundColorStyle",e)}set borders(e){this._setFormatParam("borders",e)}set padding(e){this._setFormatParam("padding",e)}set horizontalAlignment(e){this._setFormatParam("horizontalAlignment",e)}set verticalAlignment(e){this._setFormatParam("verticalAlignment",e)}set wrapStrategy(e){this._setFormatParam("wrapStrategy",e)}set textDirection(e){this._setFormatParam("textDirection",e)}set textFormat(e){this._setFormatParam("textFormat",e)}set hyperlinkDisplayType(e){this._setFormatParam("hyperlinkDisplayType",e)}set textRotation(e){this._setFormatParam("textRotation",e)}clearAllFormatting(){this._draftData.clearFormat=!0,delete this._draftData.userEnteredFormat}get _isDirty(){return!!(this._draftData.note!==void 0||y(this._draftData.userEnteredFormat).length||this._draftData.clearFormat||this._draftData.value!==void 0)}discardUnsavedChanges(){this._draftData={}}async save(){await this._sheet.saveCells([this])}_getUpdateRequest(){const e=this._draftData.value!==void 0,t=this._draftData.note!==void 0,r=!!y(this._draftData.userEnteredFormat||{}).length,a=this._draftData.clearFormat;if(!Y([e,t,r,a]))return null;const o={...this._rawData?.userEnteredFormat,...this._draftData.userEnteredFormat};return p(this._draftData,"userEnteredFormat.backgroundColor")&&delete o.backgroundColorStyle,{updateCells:{rows:[{values:[{...e&&{userEnteredValue:{[this._draftData.valueType]:this._draftData.value}},...t&&{note:this._draftData.note},...r&&{userEnteredFormat:o},...a&&{userEnteredFormat:{}}}]}],fields:y(W({userEnteredValue:e,note:t,userEnteredFormat:r||a})).join(","),start:{sheetId:this._sheet.sheetId,rowIndex:this.rowIndex,columnIndex:this.columnIndex}}}}}class V{constructor(e,t,r){this._spreadsheet=e,this._headerRowIndex=1,this._rawProperties=null,this._cells=[],this._rowMetadata=[],this._columnMetadata=[],this._rowCache=[],this._headerRowIndex=1,this._rawProperties=t,this._cells=[],this._rowMetadata=[],this._columnMetadata=[],r&&this._fillCellData(r)}get headerValues(){if(!this._headerValues)throw new Error("Header values are not yet loaded");return this._headerValues}updateRawData(e,t){this._rawProperties=e,this._fillCellData(t)}async _makeSingleUpdateRequest(e,t){return this._spreadsheet._makeSingleUpdateRequest(e,{...t})}_ensureInfoLoaded(){if(!this._rawProperties)throw new Error("You must call `doc.loadInfo()` again before accessing this property")}resetLocalCache(e){e||(this._rawProperties=null),this._headerValues=void 0,this._headerRowIndex=1,this._cells=[]}_fillCellData(e){u(e,t=>{const r=t.startRow||0,a=t.startColumn||0,o=t.rowMetadata.length,h=t.columnMetadata.length;for(let i=0;i<o;i++){const d=r+i;for(let n=0;n<h;n++){const l=a+n;this._cells[d]||(this._cells[d]=[]);const C=p(t,`rowData[${i}].values[${n}]`);this._cells[d][l]?this._cells[d][l]._updateRawData(C):this._cells[d][l]=new $(this,d,l,C)}}for(let i=0;i<t.rowMetadata.length;i++)this._rowMetadata[r+i]=t.rowMetadata[i];for(let i=0;i<t.columnMetadata.length;i++)this._columnMetadata[a+i]=t.columnMetadata[i]})}_addSheetIdToRange(e){if(e.sheetId&&e.sheetId!==this.sheetId)throw new Error("Leave sheet ID blank or set to matching ID of this sheet");return{...e,sheetId:this.sheetId}}_getProp(e){return this._ensureInfoLoaded(),this._rawProperties[e]}_setProp(e,t){throw new Error("Do not update directly - use `updateProperties()`")}get sheetId(){return this._getProp("sheetId")}get title(){return this._getProp("title")}get index(){return this._getProp("index")}get sheetType(){return this._getProp("sheetType")}get gridProperties(){return this._getProp("gridProperties")}get hidden(){return this._getProp("hidden")}get tabColor(){return this._getProp("tabColor")}get rightToLeft(){return this._getProp("rightToLeft")}get _headerRange(){return`A${this._headerRowIndex}:${this.lastColumnLetter}${this._headerRowIndex}`}set sheetId(e){this._setProp("sheetId",e)}set title(e){this._setProp("title",e)}set index(e){this._setProp("index",e)}set sheetType(e){this._setProp("sheetType",e)}set gridProperties(e){this._setProp("gridProperties",e)}set hidden(e){this._setProp("hidden",e)}set tabColor(e){this._setProp("tabColor",e)}set rightToLeft(e){this._setProp("rightToLeft",e)}get rowCount(){return this._ensureInfoLoaded(),this.gridProperties.rowCount}get columnCount(){return this._ensureInfoLoaded(),this.gridProperties.columnCount}get a1SheetName(){return`'${this.title.replace(/'/g,"''")}'`}get encodedA1SheetName(){return encodeURIComponent(this.a1SheetName)}get lastColumnLetter(){return this.columnCount?R(this.columnCount):""}get cellStats(){let e=A(this._cells);return e=w(e),{nonEmpty:P(e,t=>t.value).length,loaded:e.length,total:this.rowCount*this.columnCount}}getCellByA1(e){const t=e.match(/([A-Z]+)([0-9]+)/);if(!t)throw new Error(`Cell address "${e}" not valid`);const r=Q(t[1]),a=parseInt(t[2]);return this.getCell(a-1,r-1)}getCell(e,t){if(e<0||t<0)throw new Error("Min coordinate is 0, 0");if(e>=this.rowCount||t>=this.columnCount)throw new Error(`Out of bounds, sheet is ${this.rowCount} by ${this.columnCount}`);if(!p(this._cells,`[${e}][${t}]`))throw new Error("This cell has not been loaded yet");return this._cells[e][t]}async loadCells(e){if(!e)return this._spreadsheet.loadCells(this.a1SheetName);const t=g(e)?e:[e],r=c(t,a=>{if(_(a))return a.startsWith(this.a1SheetName)?a:`${this.a1SheetName}!${a}`;if(f(a)){const o=a;if(o.sheetId&&o.sheetId!==this.sheetId)throw new Error("Leave sheet ID blank or set to matching ID of this sheet");return{sheetId:this.sheetId,...a}}throw new Error("Each filter must be a A1 range string or gridrange object")});return this._spreadsheet.loadCells(r)}async saveUpdatedCells(){const e=P(A(this._cells),{_isDirty:!0});e.length&&await this.saveCells(e)}async saveCells(e){const t=c(e,a=>a._getUpdateRequest()),r=c(e,a=>`${this.a1SheetName}!${a.a1Address}`);if(!w(t).length)throw new Error("At least one cell must have something to update");await this._spreadsheet._makeBatchUpdateRequest(t,r)}async _ensureHeaderRowLoaded(){this._headerValues||await this.loadHeaderRow()}async loadHeaderRow(e){e!==void 0&&(this._headerRowIndex=e);const t=await this.getCellsInRange(this._headerRange);this._processHeaderRow(t)}_processHeaderRow(e){if(!e)throw new Error("No values in the header row - fill the first row with header values before trying to interact with rows");if(this._headerValues=c(e[0],t=>t?.trim()),!w(this.headerValues).length)throw new Error("All your header cells are blank - fill the first row with header values before trying to interact with rows");F(this.headerValues)}async setHeaderRow(e,t){if(!e)return;if(e.length>this.columnCount)throw new Error(`Sheet is not large enough to fit ${e.length} columns. Resize the sheet first.`);const r=c(e,o=>o?.trim());if(F(r),!w(r).length)throw new Error("All your header cells are blank -");t&&(this._headerRowIndex=t);const a=await this._spreadsheet.sheetsApi.request({method:"put",url:`/values/${this.encodedA1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,params:{valueInputOption:"USER_ENTERED",includeValuesInResponse:!0},data:{range:`${this.a1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,majorDimension:"ROWS",values:[[...r,...X(this.columnCount-r.length,()=>"")]]}});this._headerValues=a.data.updatedData.values[0]}async addRows(e,t={}){if(this.title.includes(":"))throw new Error('Please remove the ":" from your sheet title. There is a bug with the google API which breaks appending rows if any colons are in the sheet title.');if(!g(e))throw new Error("You must pass in an array of row values to append");await this._ensureHeaderRowLoaded();const r=[];u(e,i=>{let d;if(g(i))d=i;else if(f(i)){d=[];for(let n=0;n<this.headerValues.length;n++){const l=this.headerValues[n];d[n]=i[l]}}else throw new Error("Each row must be an object or an array");r.push(d)});const a=await this._spreadsheet.sheetsApi.request({method:"post",url:`/values/${this.encodedA1SheetName}!A${this._headerRowIndex}:append`,params:{valueInputOption:t.raw?"RAW":"USER_ENTERED",insertDataOption:t.insert?"INSERT_ROWS":"OVERWRITE",includeValuesInResponse:!0},data:{values:r}}),{updatedRange:o}=a.data.updates;let h=o.match(/![A-Z]+([0-9]+):?/)[1];return h=parseInt(h),this._ensureInfoLoaded(),t.insert?this._rawProperties.gridProperties.rowCount+=e.length:h+e.length>this.rowCount&&(this._rawProperties.gridProperties.rowCount=h+e.length-1),c(a.data.updates.updatedData.values,i=>new S(this,h++,i))}async addRow(e,t){return(await this.addRows([e],t))[0]}async getRows(e){const t=e?.offset||0,r=e?.limit||this.rowCount-1,a=1+this._headerRowIndex+t,o=a+r-1;let h;if(this._headerValues){const n=R(this.headerValues.length);h=await this.getCellsInRange(`A${a}:${n}${o}`)}else{const n=await this.batchGetCellsInRange([this._headerRange,`A${a}:${this.lastColumnLetter}${o}`]);this._processHeaderRow(n[0]),h=n[1]}if(!h)return[];const i=[];let d=a;for(let n=0;n<h.length;n++){const l=new S(this,d++,h[n]);this._rowCache[l.rowNumber]=l,i.push(l)}return i}_shiftRowCache(e){delete this._rowCache[e],this._rowCache.forEach(t=>{t.rowNumber>e&&t._updateRowNumber(t.rowNumber-1)})}async clearRows(e){const t=e?.start||this._headerRowIndex+1,r=e?.end||this.rowCount;await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}!${t}:${r}:clear`),this._rowCache.forEach(a=>{a.rowNumber>=t&&a.rowNumber<=r&&a._clearRowData()})}async updateProperties(e){return this._makeSingleUpdateRequest("updateSheetProperties",{properties:{sheetId:this.sheetId,...e},fields:v(e)})}async updateGridProperties(e){return this.updateProperties({gridProperties:e})}async resize(e){return this.updateGridProperties(e)}async updateDimensionProperties(e,t,r){return this._makeSingleUpdateRequest("updateDimensionProperties",{range:{sheetId:this.sheetId,dimension:e,...r},properties:t,fields:v(t)})}async getCellsInRange(e,t){return(await this._spreadsheet.sheetsApi.get(`/values/${this.encodedA1SheetName}!${e}`,{params:t})).data.values}async batchGetCellsInRange(e,t){const r=e.map(a=>`ranges=${this.encodedA1SheetName}!${a}`).join("&");return(await this._spreadsheet.sheetsApi.get(`/values:batchGet?${r}`,{params:t})).data.valueRanges.map(a=>a.values)}async updateNamedRange(){}async addNamedRange(){}async deleteNamedRange(){}async repeatCell(){}async autoFill(){}async cutPaste(){}async copyPaste(){}async mergeCells(e,t="MERGE_ALL"){await this._makeSingleUpdateRequest("mergeCells",{mergeType:t,range:this._addSheetIdToRange(e)})}async unmergeCells(e){await this._makeSingleUpdateRequest("unmergeCells",{range:this._addSheetIdToRange(e)})}async updateBorders(){}async addFilterView(){}async appendCells(){}async clearBasicFilter(){}async deleteDimension(){}async deleteEmbeddedObject(){}async deleteFilterView(){}async duplicateFilterView(){}async duplicate(e){const t=(await this._makeSingleUpdateRequest("duplicateSheet",{sourceSheetId:this.sheetId,...e?.index!==void 0&&{insertSheetIndex:e.index},...e?.id&&{newSheetId:e.id},...e?.title&&{newSheetName:e.title}})).properties.sheetId;return this._spreadsheet.sheetsById[t]}async findReplace(){}async insertDimension(e,t,r){if(!e)throw new Error("You need to specify a dimension. i.e. COLUMNS|ROWS");if(!f(t))throw new Error("`range` must be an object containing `startIndex` and `endIndex`");if(!x(t.startIndex)||t.startIndex<0)throw new Error("range.startIndex must be an integer >=0");if(!x(t.endIndex)||t.endIndex<0)throw new Error("range.endIndex must be an integer >=0");if(t.endIndex<=t.startIndex)throw new Error("range.endIndex must be greater than range.startIndex");if(r===void 0&&(r=t.startIndex>0),r&&t.startIndex===0)throw new Error("Cannot set inheritFromBefore to true if inserting in first row/column");return this._makeSingleUpdateRequest("insertDimension",{range:{sheetId:this.sheetId,dimension:e,startIndex:t.startIndex,endIndex:t.endIndex},inheritFromBefore:r})}async insertRange(){}async moveDimension(){}async updateEmbeddedObjectPosition(){}async pasteData(){}async textToColumns(){}async updateFilterView(){}async deleteRange(){}async appendDimension(){}async addConditionalFormatRule(){}async updateConditionalFormatRule(){}async deleteConditionalFormatRule(){}async sortRange(){}async setDataValidation(e,t){return this._makeSingleUpdateRequest("setDataValidation",{range:{sheetId:this.sheetId,...e},...t&&{rule:t}})}async setBasicFilter(){}async addProtectedRange(){}async updateProtectedRange(){}async deleteProtectedRange(){}async autoResizeDimensions(){}async addChart(){}async updateChartSpec(){}async updateBanding(){}async addBanding(){}async deleteBanding(){}async createDeveloperMetadata(){}async updateDeveloperMetadata(){}async deleteDeveloperMetadata(){}async randomizeRange(){}async addDimensionGroup(){}async deleteDimensionGroup(){}async updateDimensionGroup(){}async trimWhitespace(){}async deleteDuplicates(){}async addSlicer(){}async updateSlicerSpec(){}async delete(){return this._spreadsheet.deleteSheet(this.sheetId)}async copyToSpreadsheet(e){return this._spreadsheet.sheetsApi.post(`/sheets/${this.sheetId}:copyTo`,{destinationSpreadsheetId:e})}async clear(e){const t=e?`!${e}`:"";await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}${t}:clear`),this.resetLocalCache(!0)}async downloadAsCSV(e=!1){return this._spreadsheet._downloadAs("csv",this.sheetId,e)}async downloadAsTSV(e=!1){return this._spreadsheet._downloadAs("tsv",this.sheetId,e)}async downloadAsPDF(e=!1){return this._spreadsheet._downloadAs("pdf",this.sheetId,e)}}var m=(s=>(s.GOOGLE_AUTH_CLIENT="google_auth",s.RAW_ACCESS_TOKEN="raw_access_token",s.API_KEY="api_key",s))(m||{});const T="https://sheets.googleapis.com/v4/spreadsheets",ee="https://www.googleapis.com/drive/v3/files",N={html:{},zip:{},xlsx:{},ods:{},csv:{singleWorksheet:!0},tsv:{singleWorksheet:!0},pdf:{singleWorksheet:!0}};function U(s){if("getRequestHeaders"in s)return m.GOOGLE_AUTH_CLIENT;if("token"in s&&s.token)return m.RAW_ACCESS_TOKEN;if("apiKey"in s&&s.apiKey)return m.API_KEY;throw new Error("Invalid auth")}async function j(s){if("getRequestHeaders"in s)return{headers:await s.getRequestHeaders()};if("apiKey"in s&&s.apiKey)return{params:{key:s.apiKey}};if("token"in s&&s.token)return{headers:{Authorization:`Bearer ${s.token}`}};throw new Error("Invalid auth")}class E{constructor(e,t){this._rawProperties=null,this._spreadsheetUrl=null,this._deleted=!1,this.spreadsheetId=e,this.auth=t,this._rawSheets={},this._spreadsheetUrl=null,this.sheetsApi=I.create({baseURL:`${T}/${e}`,paramsSerializer:D,maxContentLength:1/0,maxBodyLength:1/0}),this.driveApi=I.create({baseURL:`${ee}/${e}`,paramsSerializer:D}),this.sheetsApi.interceptors.request.use(this._setAxiosRequestAuth.bind(this)),this.sheetsApi.interceptors.response.use(this._handleAxiosResponse.bind(this),this._handleAxiosErrors.bind(this)),this.driveApi.interceptors.request.use(this._setAxiosRequestAuth.bind(this)),this.driveApi.interceptors.response.use(this._handleAxiosResponse.bind(this),this._handleAxiosErrors.bind(this))}get authMode(){return U(this.auth)}async _setAxiosRequestAuth(e){const t=await j(this.auth);return u(t.headers,(r,a)=>{e.headers.set(a,r)}),e.params={...e.params,...t.params},e}async _handleAxiosResponse(e){return e}async _handleAxiosErrors(e){const t=e.response?.data;if(t){if(!t.error)throw e;const{code:r,message:a}=t.error;throw e.message=`Google API error - [${r}] ${a}`,e}throw p(e,"response.status")===403&&"apiKey"in this.auth?new Error("Sheet is private. Use authentication or make public. (see https://github.com/theoephraim/node-google-spreadsheet#a-note-on-authentication for details)"):e}async _makeSingleUpdateRequest(e,t){const r=await this.sheetsApi.post(":batchUpdate",{requests:[{[e]:t}],includeSpreadsheetInResponse:!0});return this._updateRawProperties(r.data.updatedSpreadsheet.properties),u(r.data.updatedSpreadsheet.sheets,a=>this._updateOrCreateSheet(a)),r.data.replies[0][e]}async _makeBatchUpdateRequest(e,t){const r=await this.sheetsApi.post(":batchUpdate",{requests:e,includeSpreadsheetInResponse:!0,...t&&{responseIncludeGridData:!0,...t!=="*"&&{responseRanges:t}}});this._updateRawProperties(r.data.updatedSpreadsheet.properties),u(r.data.updatedSpreadsheet.sheets,a=>this._updateOrCreateSheet(a))}_ensureInfoLoaded(){if(!this._rawProperties)throw new Error("You must call `doc.loadInfo()` before accessing this property")}_updateRawProperties(e){this._rawProperties=e}_updateOrCreateSheet(e){const{properties:t,data:r}=e,{sheetId:a}=t;this._rawSheets[a]?this._rawSheets[a].updateRawData(t,r):this._rawSheets[a]=new V(this,t,r)}_getProp(e){return this._ensureInfoLoaded(),this._rawProperties[e]}get title(){return this._getProp("title")}get locale(){return this._getProp("locale")}get timeZone(){return this._getProp("timeZone")}get autoRecalc(){return this._getProp("autoRecalc")}get defaultFormat(){return this._getProp("defaultFormat")}get spreadsheetTheme(){return this._getProp("spreadsheetTheme")}get iterativeCalculationSettings(){return this._getProp("iterativeCalculationSettings")}async updateProperties(e){await this._makeSingleUpdateRequest("updateSpreadsheetProperties",{properties:e,fields:v(e)})}async loadInfo(e=!1){const t=await this.sheetsApi.get("/",{params:{...e&&{includeGridData:!0}}});this._spreadsheetUrl=t.data.spreadsheetUrl,this._rawProperties=t.data.properties,u(t.data.sheets,r=>this._updateOrCreateSheet(r))}resetLocalCache(){this._rawProperties=null,this._rawSheets={}}get sheetCount(){return this._ensureInfoLoaded(),k(this._rawSheets).length}get sheetsById(){return this._ensureInfoLoaded(),this._rawSheets}get sheetsByIndex(){return this._ensureInfoLoaded(),Z(this._rawSheets,"index")}get sheetsByTitle(){return this._ensureInfoLoaded(),H(this._rawSheets,"title")}async addSheet(e={}){const t=(await this._makeSingleUpdateRequest("addSheet",{properties:z(e,"headerValues","headerRowIndex")})).properties.sheetId,r=this.sheetsById[t];return e.headerValues&&await r.setHeaderRow(e.headerValues,e.headerRowIndex),r}async deleteSheet(e){await this._makeSingleUpdateRequest("deleteSheet",{sheetId:e}),delete this._rawSheets[e]}async addNamedRange(e,t,r){return this._makeSingleUpdateRequest("addNamedRange",{name:e,namedRangeId:r,range:t})}async deleteNamedRange(e){return this._makeSingleUpdateRequest("deleteNamedRange",{namedRangeId:e})}async loadCells(e){const t=this.authMode===m.API_KEY,r=g(e)?e:[e],a=c(r,i=>{if(_(i))return t?i:{a1Range:i};if(f(i)){if(t)throw new Error("Only A1 ranges are supported when fetching cells with read-only access (using only an API key)");return{gridRange:i}}throw new Error("Each filter must be an A1 range string or a gridrange object")});let o;this.authMode===m.API_KEY?o=await this.sheetsApi.get("/",{params:{includeGridData:!0,ranges:a}}):o=await this.sheetsApi.post(":getByDataFilter",{includeGridData:!0,dataFilters:a});const{sheets:h}=o.data;u(h,i=>{this._updateOrCreateSheet(i)})}async _downloadAs(e,t,r){if(!N[e])throw new Error(`unsupported export fileType - ${e}`);if(N[e].singleWorksheet){if(t===void 0)throw new Error(`Must specify worksheetId when exporting as ${e}`)}else if(t)throw new Error(`Cannot specify worksheetId when exporting as ${e}`);if(e==="html"&&(e="zip"),!this._spreadsheetUrl)throw new Error("Cannot export sheet that is not fully loaded");const a=this._spreadsheetUrl.replace("/edit","/export");return(await this.sheetsApi.get(a,{baseURL:"",params:{id:this.spreadsheetId,format:e,...t&&{gid:t}},responseType:r?"stream":"arraybuffer"})).data}async downloadAsZippedHTML(e){return this._downloadAs("html",void 0,e)}async downloadAsHTML(e){return this._downloadAs("html",void 0,e)}async downloadAsXLSX(e=!1){return this._downloadAs("xlsx",void 0,e)}async downloadAsODS(e=!1){return this._downloadAs("ods",void 0,e)}async delete(){const e=await this.driveApi.delete("");return this._deleted=!0,e.data}async listPermissions(){return(await this.driveApi.request({method:"GET",url:"/permissions",params:{fields:"permissions(id,type,emailAddress,domain,role,displayName,photoLink,deleted)"}})).data.permissions}async setPublicAccessLevel(e){const t=await this.listPermissions(),r=L(t,a=>a.type==="anyone");if(e===!1){if(!r)return;await this.driveApi.request({method:"DELETE",url:`/permissions/${r.id}`})}else await this.driveApi.request({method:"POST",url:"/permissions",params:{},data:{role:e||"viewer",type:"anyone"}})}async share(e,t){let r,a;return e.includes("@")?r=e:a=e,(await this.driveApi.request({method:"POST",url:"/permissions",params:{...t?.emailMessage===!1&&{sendNotificationEmail:!1},..._(t?.emailMessage)&&{emailMessage:t?.emailMessage},...t?.role==="owner"&&{transferOwnership:!0}},data:{role:t?.role||"writer",...r&&{type:t?.isGroup?"group":"user",emailAddress:r},...a&&{type:"domain",domain:a}}})).data}static async createNewSpreadsheetDocument(e,t){if(U(e)===m.API_KEY)throw new Error("Cannot use api key only to create a new spreadsheet - it is only usable for read-only access of public docs");const r=await j(e),a=await I.request({method:"POST",url:T,paramsSerializer:D,...r,data:{properties:t}}),o=new E(a.data.spreadsheetId,e);return o._spreadsheetUrl=a.data.spreadsheetUrl,o._rawProperties=a.data.properties,u(a.data.sheets,h=>o._updateOrCreateSheet(h)),o}}export{E as GoogleSpreadsheet,$ as GoogleSpreadsheetCell,b as GoogleSpreadsheetCellErrorValue,S as GoogleSpreadsheetRow,V as GoogleSpreadsheetWorksheet};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "google-spreadsheet",
3
- "version": "4.1.1",
3
+ "version": "4.1.3",
4
4
  "description": "Google Sheets API -- simple interface to read/write data and manage sheets",
5
5
  "keywords": [
6
6
  "google spreadsheets",
@@ -46,7 +46,7 @@
46
46
  "commit": "cz",
47
47
  "docs:preview": "docsify serve docs",
48
48
  "lint": "eslint ./ --ext .ts",
49
- "lint:fix": "npm run lint --fix",
49
+ "lint:fix": "pnpm run lint --fix",
50
50
  "nodev": "node -v",
51
51
  "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",
52
52
  "changelog": "auto-changelog --commit-limit false --unreleased-only --stdout",
@@ -60,7 +60,7 @@
60
60
  }
61
61
  },
62
62
  "dependencies": {
63
- "axios": "^1.4.0",
63
+ "axios": "^1.7.6",
64
64
  "lodash": "^4.17.21"
65
65
  },
66
66
  "devDependencies": {
@@ -82,7 +82,7 @@
82
82
  "eslint-plugin-import": "^2.27.5",
83
83
  "eslint-plugin-jest": "^27.2.1",
84
84
  "eslint-plugin-no-floating-promise": "^1.0.2",
85
- "google-auth-library": "^9.2.0",
85
+ "google-auth-library": "^9.14.0",
86
86
  "jest": "^29.5.0",
87
87
  "jest-junit": "^16.0.0",
88
88
  "release-it": "^15.11.0",
@@ -33,8 +33,9 @@ type ExportFileTypes = keyof typeof EXPORT_CONFIG;
33
33
 
34
34
  function getAuthMode(auth: GoogleApiAuth) {
35
35
  if ('getRequestHeaders' in auth) return AUTH_MODES.GOOGLE_AUTH_CLIENT;
36
- if ('token' in auth) return AUTH_MODES.RAW_ACCESS_TOKEN;
37
- if ('apiKey' in auth) return AUTH_MODES.API_KEY;
36
+ if ('token' in auth && auth.token) return AUTH_MODES.RAW_ACCESS_TOKEN;
37
+ // google-auth-library now has an empty `apiKey` property
38
+ if ('apiKey' in auth && auth.apiKey) return AUTH_MODES.API_KEY;
38
39
  throw new Error('Invalid auth');
39
40
  }
40
41
 
@@ -48,12 +49,12 @@ async function getRequestAuthConfig(auth: GoogleApiAuth) {
48
49
 
49
50
  // API key only access passes through the api key as a query param
50
51
  // (note this can only provide read-only access)
51
- if ('apiKey' in auth) {
52
+ if ('apiKey' in auth && auth.apiKey) {
52
53
  return { params: { key: auth.apiKey } };
53
54
  }
54
55
 
55
56
  // RAW ACCESS TOKEN
56
- if ('token' in auth) {
57
+ if ('token' in auth && auth.token) {
57
58
  return { headers: { Authorization: `Bearer ${auth.token}` } };
58
59
  }
59
60
 
@@ -606,7 +607,7 @@ export class GoogleSpreadsheet {
606
607
  static async createNewSpreadsheetDocument(auth: GoogleApiAuth, properties?: Partial<SpreadsheetProperties>) {
607
608
  // see updateProperties for more info about available properties
608
609
 
609
- if ('apiKey' in auth) {
610
+ if (getAuthMode(auth) === AUTH_MODES.API_KEY) {
610
611
  throw new Error('Cannot use api key only to create a new spreadsheet - it is only usable for read-only access of public docs');
611
612
  }
612
613
 
@@ -12,6 +12,7 @@ import {
12
12
  A1Range, SpreadsheetId, DimensionRangeIndexes, WorksheetDimension, WorksheetId, WorksheetProperties, A1Address,
13
13
  RowIndex, ColumnIndex, DataFilterWithoutWorksheetId, DataFilter, GetValuesRequestOptions, WorksheetGridProperties,
14
14
  WorksheetDimensionProperties, CellDataRange, AddRowOptions, GridRangeWithOptionalWorksheetId,
15
+ DataValidationRule,
15
16
  } from './types/sheets-types';
16
17
 
17
18
 
@@ -165,6 +166,9 @@ export class GoogleSpreadsheetWorksheet {
165
166
  get hidden() { return this._getProp('hidden'); }
166
167
  get tabColor() { return this._getProp('tabColor'); }
167
168
  get rightToLeft() { return this._getProp('rightToLeft'); }
169
+ private get _headerRange() {
170
+ return `A${this._headerRowIndex}:${this.lastColumnLetter}${this._headerRowIndex}`;
171
+ }
168
172
 
169
173
  set sheetId(newVal: WorksheetProperties['sheetId']) { this._setProp('sheetId', newVal); }
170
174
  set title(newVal: WorksheetProperties['title']) { this._setProp('title', newVal); }
@@ -341,7 +345,11 @@ export class GoogleSpreadsheetWorksheet {
341
345
 
342
346
  async loadHeaderRow(headerRowIndex?: number) {
343
347
  if (headerRowIndex !== undefined) this._headerRowIndex = headerRowIndex;
344
- const rows = await this.getCellsInRange(`A${this._headerRowIndex}:${this.lastColumnLetter}${this._headerRowIndex}`);
348
+ const rows = await this.getCellsInRange(this._headerRange);
349
+ this._processHeaderRow(rows);
350
+ }
351
+
352
+ private _processHeaderRow(rows: any[]) {
345
353
  if (!rows) {
346
354
  throw new Error('No values in the header row - fill the first row with header values before trying to interact with rows');
347
355
  }
@@ -488,14 +496,21 @@ export class GoogleSpreadsheetWorksheet {
488
496
  const offset = options?.offset || 0;
489
497
  const limit = options?.limit || this.rowCount - 1;
490
498
 
491
- await this._ensureHeaderRowLoaded();
492
-
493
499
  const firstRow = 1 + this._headerRowIndex + offset;
494
500
  const lastRow = firstRow + limit - 1; // inclusive so we subtract 1
495
- const lastColumn = columnToLetter(this.headerValues.length);
496
- const rawRows = await this.getCellsInRange(
497
- `A${firstRow}:${lastColumn}${lastRow}`
498
- );
501
+
502
+ let rawRows;
503
+ if (this._headerValues) {
504
+ const lastColumn = columnToLetter(this.headerValues.length);
505
+ rawRows = await this.getCellsInRange(
506
+ `A${firstRow}:${lastColumn}${lastRow}`
507
+ );
508
+ } else {
509
+ const result = await this.batchGetCellsInRange([this._headerRange,
510
+ `A${firstRow}:${this.lastColumnLetter}${lastRow}`]);
511
+ this._processHeaderRow(result[0]);
512
+ rawRows = result[1];
513
+ }
499
514
 
500
515
  if (!rawRows) return [];
501
516
 
@@ -599,6 +614,14 @@ export class GoogleSpreadsheetWorksheet {
599
614
  return response.data.values;
600
615
  }
601
616
 
617
+ async batchGetCellsInRange(a1Ranges: A1Range[], options?: GetValuesRequestOptions) {
618
+ const ranges = a1Ranges.map((r) => `ranges=${this.encodedA1SheetName}!${r}`).join('&');
619
+ const response = await this._spreadsheet.sheetsApi.get(`/values:batchGet?${ranges}`, {
620
+ params: options,
621
+ });
622
+ return response.data.valueRanges.map((r: any) => r.values);
623
+ }
624
+
602
625
  async updateNamedRange() {
603
626
  // Request type = `updateNamedRange`
604
627
  // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#UpdateNamedRangeRequest
@@ -819,9 +842,22 @@ export class GoogleSpreadsheetWorksheet {
819
842
  // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#SortRangeRequest
820
843
  }
821
844
 
822
- async setDataValidation() {
823
- // Request type = `setDataValidation`
824
- // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#SetDataValidationRequest
845
+ /**
846
+ * Sets (or unsets) a data validation rule to every cell in the range
847
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#SetDataValidationRequest
848
+ */
849
+ async setDataValidation(
850
+ range: GridRangeWithOptionalWorksheetId,
851
+ /** data validation rule object, or set to false to clear an existing rule */
852
+ rule: DataValidationRule | false
853
+ ) {
854
+ return this._makeSingleUpdateRequest('setDataValidation', {
855
+ range: {
856
+ sheetId: this.sheetId,
857
+ ...range,
858
+ },
859
+ ...rule && { rule },
860
+ });
825
861
  }
826
862
 
827
863
  async setBasicFilter() {
@@ -526,3 +526,88 @@ export type AddRowOptions = {
526
526
  /** set to true to insert new rows in the sheet while adding this data */
527
527
  insert?: boolean,
528
528
  };
529
+
530
+ /**
531
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ConditionType
532
+ */
533
+ export type ConditionType =
534
+ | 'NUMBER_GREATER'
535
+ | 'NUMBER_GREATER_THAN_EQ'
536
+ | 'NUMBER_LESS'
537
+ | 'NUMBER_LESS_THAN_EQ'
538
+ | 'NUMBER_EQ'
539
+ | 'NUMBER_NOT_EQ'
540
+ | 'NUMBER_BETWEEN'
541
+ | 'NUMBER_NOT_BETWEEN'
542
+ | 'TEXT_CONTAINS'
543
+ | 'TEXT_NOT_CONTAINS'
544
+ | 'TEXT_STARTS_WITH'
545
+ | 'TEXT_ENDS_WITH'
546
+ | 'TEXT_EQ'
547
+ | 'TEXT_IS_EMAIL'
548
+ | 'TEXT_IS_URL'
549
+ | 'DATE_EQ'
550
+ | 'DATE_BEFORE'
551
+ | 'DATE_AFTER'
552
+ | 'DATE_ON_OR_BEFORE'
553
+ | 'DATE_ON_OR_AFTER'
554
+ | 'DATE_BETWEEN'
555
+ | 'DATE_NOT_BETWEEN'
556
+ | 'DATE_IS_VALID'
557
+ | 'ONE_OF_RANGE'
558
+ | 'ONE_OF_LIST'
559
+ | 'BLANK'
560
+ | 'NOT_BLANK'
561
+ | 'CUSTOM_FORMULA'
562
+ | 'BOOLEAN'
563
+ | 'TEXT_NOT_EQ'
564
+ | 'DATE_NOT_EQ'
565
+ | 'FILTER_EXPRESSION';
566
+
567
+ /**
568
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#relativedate
569
+ */
570
+ export type RelativeDate =
571
+ | 'PAST_YEAR'
572
+ | 'PAST_MONTH'
573
+ | 'PAST_WEEK'
574
+ | 'YESTERDAY'
575
+ | 'TODAY'
576
+ | 'TOMORROW';
577
+
578
+ /**
579
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ConditionValue
580
+ */
581
+ export type ConditionValue =
582
+ | { relativeDate: RelativeDate, userEnteredValue?: undefined }
583
+ | { relativeDate?: undefined, userEnteredValue: string };
584
+
585
+ /**
586
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#BooleanCondition
587
+ */
588
+ export type BooleanCondition = {
589
+ /** The type of condition. */
590
+ type: ConditionType;
591
+ /**
592
+ * The values of the condition.
593
+ * The number of supported values depends on the condition type. Some support zero values, others one or two values, and ConditionType.ONE_OF_LIST supports an arbitrary number of values.
594
+ */
595
+ values: ConditionValue[];
596
+ };
597
+
598
+ /**
599
+ * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#DataValidationRule
600
+ *
601
+ * example:
602
+ * - https://stackoverflow.com/a/43442775/3068233
603
+ */
604
+ export type DataValidationRule = {
605
+ /** The condition that data in the cell must match. */
606
+ condition: BooleanCondition;
607
+ /** A message to show the user when adding data to the cell. */
608
+ inputMessage?: string;
609
+ /** True if invalid data should be rejected. */
610
+ strict: boolean;
611
+ /** True if the UI should be customized based on the kind of condition. If true, "List" conditions will show a dropdown. */
612
+ showCustomUi: boolean;
613
+ };