google-spreadsheet 4.1.5 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- import { ReadableStream } from 'node:stream/web';
2
- import * as _ from './lodash';
1
+ import { type ReadableStream } from 'stream/web';
2
+ import * as _ from './toolkit';
3
3
 
4
4
  import { GoogleSpreadsheetRow } from './GoogleSpreadsheetRow';
5
5
  import { GoogleSpreadsheetCell } from './GoogleSpreadsheetCell';
@@ -374,24 +374,26 @@ export class GoogleSpreadsheetWorksheet {
374
374
 
375
375
  if (headerRowIndex) this._headerRowIndex = headerRowIndex;
376
376
 
377
- const response = await this._spreadsheet.sheetsApi.request({
378
- method: 'put',
379
- url: `/values/${this.encodedA1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,
380
- params: {
381
- valueInputOption: 'USER_ENTERED', // other option is RAW
382
- includeValuesInResponse: true,
383
- },
384
- data: {
385
- range: `${this.a1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,
386
- majorDimension: 'ROWS',
387
- values: [[
388
- ...trimmedHeaderValues,
389
- // pad the rest of the row with empty values to clear them all out
390
- ..._.times(this.columnCount - trimmedHeaderValues.length, () => ''),
391
- ]],
392
- },
393
- });
394
- this._headerValues = response.data.updatedData.values[0];
377
+ const response = await this._spreadsheet.sheetsApi.put(
378
+ `values/${this.encodedA1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,
379
+ {
380
+ searchParams: {
381
+ valueInputOption: 'USER_ENTERED', // other option is RAW
382
+ includeValuesInResponse: true,
383
+ },
384
+ json: {
385
+ range: `${this.a1SheetName}!${this._headerRowIndex}:${this._headerRowIndex}`,
386
+ majorDimension: 'ROWS',
387
+ values: [[
388
+ ...trimmedHeaderValues,
389
+ // pad the rest of the row with empty values to clear them all out
390
+ ..._.times(this.columnCount - trimmedHeaderValues.length, () => ''),
391
+ ]],
392
+ },
393
+ }
394
+ );
395
+ const data = await response.json<any>();
396
+ this._headerValues = data.updatedData.values[0];
395
397
  }
396
398
 
397
399
  // TODO: look at these types
@@ -435,22 +437,24 @@ export class GoogleSpreadsheetWorksheet {
435
437
  rowsAsArrays.push(rowAsArray);
436
438
  });
437
439
 
438
- const response = await this._spreadsheet.sheetsApi.request({
439
- method: 'post',
440
- url: `/values/${this.encodedA1SheetName}!A${this._headerRowIndex}:append`,
441
- params: {
442
- valueInputOption: options.raw ? 'RAW' : 'USER_ENTERED',
443
- insertDataOption: options.insert ? 'INSERT_ROWS' : 'OVERWRITE',
444
- includeValuesInResponse: true,
445
- },
446
- data: {
447
- values: rowsAsArrays,
448
- },
449
- });
440
+ const response = await this._spreadsheet.sheetsApi.post(
441
+ `values/${this.encodedA1SheetName}!A${this._headerRowIndex}:append`,
442
+ {
443
+ searchParams: {
444
+ valueInputOption: options.raw ? 'RAW' : 'USER_ENTERED',
445
+ insertDataOption: options.insert ? 'INSERT_ROWS' : 'OVERWRITE',
446
+ includeValuesInResponse: true,
447
+ },
448
+ json: {
449
+ values: rowsAsArrays,
450
+ },
451
+ }
452
+ );
450
453
 
451
454
  // extract the new row number from the A1-notation data range in the response
452
455
  // ex: in "'Sheet8!A2:C2" -- we want the `2`
453
- const { updatedRange } = response.data.updates;
456
+ const data = await response.json<any>();
457
+ const { updatedRange } = data.updates;
454
458
  let rowNumber = updatedRange.match(/![A-Z]+([0-9]+):?/)[1];
455
459
  rowNumber = parseInt(rowNumber);
456
460
 
@@ -464,7 +468,7 @@ export class GoogleSpreadsheetWorksheet {
464
468
  this._rawProperties!.gridProperties.rowCount = rowNumber + rows.length - 1;
465
469
  }
466
470
 
467
- return _.map(response.data.updates.updatedData.values, (rowValues) => {
471
+ return _.map(data.updates.updatedData.values, (rowValues) => {
468
472
  const row = new GoogleSpreadsheetRow(this, rowNumber++, rowValues);
469
473
  return row;
470
474
  });
@@ -547,7 +551,7 @@ export class GoogleSpreadsheetWorksheet {
547
551
  // default to first row after header
548
552
  const startRowIndex = options?.start || this._headerRowIndex + 1;
549
553
  const endRowIndex = options?.end || this.rowCount;
550
- await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}!${startRowIndex}:${endRowIndex}:clear`);
554
+ await this._spreadsheet.sheetsApi.post(`values/${this.encodedA1SheetName}!${startRowIndex}:${endRowIndex}:clear`);
551
555
  this._rowCache.forEach((row) => {
552
556
  if (row.rowNumber >= startRowIndex && row.rowNumber <= endRowIndex) row._clearRowData();
553
557
  });
@@ -608,18 +612,20 @@ export class GoogleSpreadsheetWorksheet {
608
612
  // this uses the "values" getter and does not give all the info about the cell contents
609
613
  // it is used internally when loading header cells
610
614
  async getCellsInRange(a1Range: A1Range, options?: GetValuesRequestOptions) {
611
- const response = await this._spreadsheet.sheetsApi.get(`/values/${this.encodedA1SheetName}!${a1Range}`, {
612
- params: options,
615
+ const response = await this._spreadsheet.sheetsApi.get(`values/${this.encodedA1SheetName}!${a1Range}`, {
616
+ searchParams: options,
613
617
  });
614
- return response.data.values;
618
+ const data = await response.json<any>();
619
+ return data.values;
615
620
  }
616
621
 
617
622
  async batchGetCellsInRange(a1Ranges: A1Range[], options?: GetValuesRequestOptions) {
618
623
  const ranges = a1Ranges.map((r) => `ranges=${this.encodedA1SheetName}!${r}`).join('&');
619
- const response = await this._spreadsheet.sheetsApi.get(`/values:batchGet?${ranges}`, {
620
- params: options,
624
+ const response = await this._spreadsheet.sheetsApi.get(`values:batchGet?${ranges}`, {
625
+ searchParams: options,
621
626
  });
622
- return response.data.valueRanges.map((r: any) => r.values);
627
+ const data = await response.json<any>();
628
+ return data.valueRanges.map((r: any) => r.values);
623
629
  }
624
630
 
625
631
  async updateNamedRange() {
@@ -975,9 +981,13 @@ export class GoogleSpreadsheetWorksheet {
975
981
  * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.sheets/copyTo
976
982
  * */
977
983
  async copyToSpreadsheet(destinationSpreadsheetId: SpreadsheetId) {
978
- return this._spreadsheet.sheetsApi.post(`/sheets/${this.sheetId}:copyTo`, {
979
- destinationSpreadsheetId,
984
+ const req = this._spreadsheet.sheetsApi.post(`sheets/${this.sheetId}:copyTo`, {
985
+ json: {
986
+ destinationSpreadsheetId,
987
+ },
980
988
  });
989
+ const data = await req.json<any>();
990
+ return data;
981
991
  }
982
992
 
983
993
  /** clear data in the sheet - either the entire sheet or a specific range */
@@ -987,7 +997,7 @@ export class GoogleSpreadsheetWorksheet {
987
997
  ) {
988
998
  const range = a1Range ? `!${a1Range}` : '';
989
999
  // sheet name without ie 'sheet1' rather than 'sheet1'!A1:B5 is all cells
990
- await this._spreadsheet.sheetsApi.post(`/values/${this.encodedA1SheetName}${range}:clear`);
1000
+ await this._spreadsheet.sheetsApi.post(`values/${this.encodedA1SheetName}${range}:clear`);
991
1001
  this.resetLocalCache(true);
992
1002
  }
993
1003
 
@@ -0,0 +1,34 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+
3
+ // re-export just what we need from es-toolkit (prev lodash) these will be bundled into the final result
4
+ // but this lets us have a single import, which is nicer to use
5
+
6
+ export {
7
+ compact,
8
+ each,
9
+ filter,
10
+ find,
11
+ flatten,
12
+ get,
13
+ groupBy,
14
+ isArray,
15
+ isBoolean,
16
+ isEqual,
17
+ isFinite,
18
+ isInteger,
19
+ isNil,
20
+ isNumber,
21
+ isObject,
22
+ isString,
23
+ keyBy,
24
+ keys,
25
+ map,
26
+ omit,
27
+ pickBy,
28
+ set,
29
+ some,
30
+ sortBy,
31
+ times,
32
+ unset,
33
+ values,
34
+ } from 'es-toolkit/compat';
package/src/lib/utils.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as _ from './lodash';
1
+ import * as _ from './toolkit';
2
2
 
3
3
  export function getFieldMask(obj: Record<string, unknown>) {
4
4
  let fromGrid = '';
@@ -34,25 +34,6 @@ export function letterToColumn(letter: string) {
34
34
  return column;
35
35
  }
36
36
 
37
- // send arrays in params with duplicate keys - ie `?thing=1&thing=2` vs `?thing[]=1...`
38
- // solution taken from https://github.com/axios/axios/issues/604
39
- export function axiosParamsSerializer(params: Record<PropertyKey, any>) {
40
- let options = '';
41
- Object.keys(params).forEach((key) => {
42
- const isParamTypeObject = typeof params[key] === 'object';
43
- const isParamTypeArray = isParamTypeObject && (params[key].length >= 0);
44
- if (!isParamTypeObject) options += `${key}=${encodeURIComponent(params[key])}&`;
45
- if (isParamTypeObject && isParamTypeArray) {
46
- // eslint-disable-next-line no-restricted-syntax
47
- for (const val of params[key]) {
48
- options += `${key}=${encodeURIComponent(val)}&`;
49
- }
50
- }
51
- });
52
- return options ? options.slice(0, -1) : options;
53
- }
54
-
55
-
56
37
  export function checkForDuplicateHeaders(headers: string[]) {
57
38
  // check for duplicate headers
58
39
  const checkForDupes = _.groupBy(headers); // { c1: ['c1'], c2: ['c2', 'c2' ]}
package/dist/index.mjs DELETED
@@ -1 +0,0 @@
1
- import I from"axios";import w from"lodash/compact.js";import u from"lodash/each.js";import C from"lodash/filter.js";import O from"lodash/find.js";import A from"lodash/flatten.js";import p from"lodash/get.js";import L 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){let e="";const t=Object.keys(s).filter(r=>r!=="gridProperties").join(",");return s.gridProperties&&(e=Object.keys(s.gridProperties).map(r=>`gridProperties.${r}`).join(","),e.length&&t.length&&(e=`${e},`)),e+t}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=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 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 P=p(t,`rowData[${i}].values[${n}]`);this._cells[d][l]?this._cells[d][l]._updateRawData(P):this._cells[d][l]=new $(this,d,l,P)}}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:C(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=C(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 j(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 U(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 j(this.auth)}async _setAxiosRequestAuth(e){const t=await U(this.auth);if(t.headers){const r="entries"in t.headers?Object.fromEntries(t.headers.entries()):t.headers;Object.entries(r).forEach(([a,o])=>{e.headers.set(a,String(o))})}return 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!==void 0&&{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=O(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(j(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 U(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/src/lib/lodash.ts DELETED
@@ -1,34 +0,0 @@
1
- /* eslint-disable import/extensions */
2
-
3
- // re-export just what we need from lodash
4
- // we do this so we can use a single import, but hopefully
5
- // it helps keep bundle sizes down in front-end projects using this lib
6
-
7
- export { default as compact } from 'lodash/compact.js';
8
-
9
- export { default as each } from 'lodash/each.js';
10
- export { default as filter } from 'lodash/filter.js';
11
- export { default as find } from 'lodash/find.js';
12
- export { default as flatten } from 'lodash/flatten.js';
13
- export { default as get } from 'lodash/get.js';
14
- export { default as groupBy } from 'lodash/groupBy.js';
15
- export { default as isArray } from 'lodash/isArray.js';
16
- export { default as isBoolean } from 'lodash/isBoolean.js';
17
- export { default as isEqual } from 'lodash/isEqual.js';
18
- export { default as isFinite } from 'lodash/isFinite.js';
19
- export { default as isInteger } from 'lodash/isInteger.js';
20
- export { default as isNil } from 'lodash/isNil.js';
21
- export { default as isNumber } from 'lodash/isNumber.js';
22
- export { default as isObject } from 'lodash/isObject.js';
23
- export { default as isString } from 'lodash/isString.js';
24
- export { default as keyBy } from 'lodash/keyBy.js';
25
- export { default as keys } from 'lodash/keys.js';
26
- export { default as map } from 'lodash/map.js';
27
- export { default as omit } from 'lodash/omit.js';
28
- export { default as pickBy } from 'lodash/pickBy.js';
29
- export { default as set } from 'lodash/set.js';
30
- export { default as some } from 'lodash/some.js';
31
- export { default as sortBy } from 'lodash/sortBy.js';
32
- export { default as times } from 'lodash/times.js';
33
- export { default as unset } from 'lodash/unset.js';
34
- export { default as values } from 'lodash/values.js';