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.
- package/README.md +9 -0
- package/dist/index.cjs +4048 -1
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1653 -0
- package/dist/index.d.ts +634 -23
- package/dist/index.js +4042 -0
- package/dist/index.js.map +1 -0
- package/package.json +24 -41
- package/src/lib/GoogleSpreadsheet.ts +121 -118
- package/src/lib/GoogleSpreadsheetCell.ts +1 -1
- package/src/lib/GoogleSpreadsheetRow.ts +5 -6
- package/src/lib/GoogleSpreadsheetWorksheet.ts +54 -44
- package/src/lib/toolkit.ts +34 -0
- package/src/lib/utils.ts +1 -20
- package/dist/index.mjs +0 -1
- package/src/lib/lodash.ts +0 -34
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ReadableStream } from '
|
|
2
|
-
import * as _ from './
|
|
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.
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
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.
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
612
|
-
|
|
615
|
+
const response = await this._spreadsheet.sheetsApi.get(`values/${this.encodedA1SheetName}!${a1Range}`, {
|
|
616
|
+
searchParams: options,
|
|
613
617
|
});
|
|
614
|
-
|
|
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(
|
|
620
|
-
|
|
624
|
+
const response = await this._spreadsheet.sheetsApi.get(`values:batchGet?${ranges}`, {
|
|
625
|
+
searchParams: options,
|
|
621
626
|
});
|
|
622
|
-
|
|
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
|
-
|
|
979
|
-
|
|
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(
|
|
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 './
|
|
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';
|