@trivious/sheets 1.0.0 → 1.0.1

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 ADDED
@@ -0,0 +1,41 @@
1
+ # Trivious Sheets
2
+
3
+ Google Sheets API wrapper module for Trivious framework
4
+
5
+ ---
6
+
7
+ ### Installation
8
+
9
+ ```bash
10
+ npm install @trivious/sheets
11
+ pnpm add @trivious/sheets
12
+ yarn add @trivious/sheets
13
+ ```
14
+ > Requires Node.js 18+
15
+
16
+ ---
17
+
18
+ ### Quick Start
19
+ This module is intended to be used with a Google Service Account, refer to [Google Cloud Documentation](https://docs.cloud.google.com/iam/docs/service-accounts-create) on how to create one.
20
+
21
+ ![Google Sheets URL Guide](https://github.com/user-attachments/assets/02f86b57-b8de-4710-9dd5-13974e982853)
22
+
23
+ ```ts
24
+ import { SheetsClient } from "@trivious/sheets";
25
+
26
+ const sheets = new SheetsClient({
27
+ spreadsheetId: "1ABCefG",
28
+ // Key credentials can be loaded in however you like as long as the client email and private key are passed
29
+ // To get these credentials, create a new key on the service account and download the JSON file
30
+ key: {
31
+ client_email: "account@project.iam.gserviceaccount.com",
32
+ private_key: "-----BEGIN PRIVATE KEY-----\nABC123"
33
+ }
34
+ });
35
+
36
+ await sheets.appendRow({
37
+ sheetName: "Sheet 1",
38
+ columns: { from: "A", to: "C" },
39
+ values: [["Hello", "World"]]
40
+ });
41
+ ```
package/dist/index.cjs CHANGED
@@ -42,11 +42,15 @@ var SheetsClient = class {
42
42
  * Creates an instance of SheetsClient.
43
43
  *
44
44
  * @constructor
45
- * @param {{ spreadsheetId: string; key: {} }} options
45
+ * @param {{ spreadsheetId: string; key: JWTOptions }} options
46
46
  */
47
47
  constructor(options) {
48
- const client = new googleAuthLibrary.JWT({});
49
- this._client = googleapis.google.sheets({ version: "v4", auth: client });
48
+ const auth = new googleAuthLibrary.JWT({
49
+ scopes: ["https://www.googleapis.com/auth/spreadsheets"],
50
+ email: options.key.client_email,
51
+ key: options.key.private_key
52
+ });
53
+ this._client = googleapis.google.sheets({ version: "v4", auth });
50
54
  this._spreadsheetId = options.spreadsheetId;
51
55
  }
52
56
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utility/errors.ts","../src/utility/functions.ts","../src/client.ts"],"names":["JWT","google"],"mappings":"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","file":"index.cjs","sourcesContent":["export class SheetsError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\n\t\tthis.name = \"SheetsError\";\n\t\tObject.setPrototypeOf(this, SheetsError.prototype);\n\t}\n}\n","import { ColumnRange, RowRange } from \"./types.js\";\n\n/**\n * Construct an A1 notation string for a column range\n *\n * @export\n * @param {{ range: ColumnRange; sheetName?: string }} options\n * @returns {string}\n */\nexport function constructColumnRangeString(options: { range: ColumnRange; sheetName?: string }) {\n\tconst { range, sheetName } = options;\n\tconst rangeString = `!${range.from}:${range.to}`;\n\n\treturn sheetName ? sheetName + rangeString : rangeString;\n}\n\n/**\n * Construct an A1 notation string for a full column & row range\n *\n * @export\n * @param {{ range: RowRange; sheetName?: string }} options\n * @returns {string}\n */\nexport function constructRowRangeString(options: { range: RowRange; sheetName?: string }) {\n\tconst { range, sheetName } = options;\n\tconst rangeString = `!${range.from[0]}${range.from[1]}:${range.to[0]}${range.to[1]}`;\n\n\treturn sheetName ? sheetName + rangeString : rangeString;\n}\n\n/**\n * @link https://stackoverflow.com/a/41427259\n */\nexport function alphabetPosition(text: string) {\n\tlet result = \"\";\n\tfor (let i = 0; i < text.length; i++) {\n\t\tlet code = text.toUpperCase().charCodeAt(i);\n\t\tif (code > 64 && code < 91) result += code - 64 + \" \";\n\t}\n\n\treturn Number(result.slice(0, result.length - 1));\n}\n","import { JWT } from \"google-auth-library\";\nimport { google, sheets_v4 } from \"googleapis\";\n\nimport { ColumnRange } from \"./utility/types.js\";\nimport { SheetsError } from \"./utility/errors.js\";\nimport {\n\talphabetPosition,\n\tconstructColumnRangeString,\n\tconstructRowRangeString,\n} from \"./utility/functions.js\";\n\n/**\n * Google Sheets client\n *\n * @export\n * @class SheetsClient\n * @typedef {SheetsClient}\n */\nexport default class SheetsClient {\n\tprivate _client: sheets_v4.Sheets;\n\tprivate _spreadsheetId: string;\n\n\t/**\n\t * Creates an instance of SheetsClient.\n\t *\n\t * @constructor\n\t * @param {{ spreadsheetId: string; key: {} }} options\n\t */\n\tconstructor(options: { spreadsheetId: string; key: {} }) {\n\t\tconst client = new JWT({});\n\n\t\tthis._client = google.sheets({ version: \"v4\", auth: client });\n\t\tthis._spreadsheetId = options.spreadsheetId;\n\t}\n\n\t/**\n\t * Get the current set spreadsheet ID\n\t *\n\t * @type {string}\n\t */\n\tget spreadsheetId() {\n\t\treturn this._spreadsheetId;\n\t}\n\n\t/**\n\t * Set the spreadsheet ID to use\n\t *\n\t * @type {string}\n\t */\n\tset spreadsheetId(spreadsheetId: string) {\n\t\tthis._spreadsheetId = spreadsheetId;\n\t}\n\n\t/**\n\t * Get the sheets client object\n\t *\n\t * @readonly\n\t * @type {sheets_v4.Sheets}\n\t */\n\tget client() {\n\t\treturn this._client;\n\t}\n\n\t/**\n\t * Get a row number from looking up a key\n\t *\n\t * @protected\n\t * @async\n\t * @param {{ sheetName: string, searchColumns: ColumnRange, key: string }} options\n\t * @returns {unknown}\n\t */\n\tprotected async getRowNumberByKey(options: {\n\t\tsheetName: string;\n\t\tsearchColumns: ColumnRange;\n\t\tkey: string;\n\t}) {\n\t\tconst { key, searchColumns, sheetName } = options;\n\n\t\tconst searchRange = constructColumnRangeString({ sheetName, range: searchColumns });\n\t\tconst sheetValues = await this.getSheetValues(searchRange);\n\n\t\tconst rows = sheetValues || [];\n\t\tconst rowIndex = rows.findIndex(row => row[0] === key);\n\n\t\tif (rowIndex === -1) {\n\t\t\tthrow new SheetsError(`No matching value found for key ${key}`);\n\t\t}\n\n\t\tconst rowNumber = rowIndex + 1;\n\t\treturn rowNumber;\n\t}\n\n\t/**\n\t * Get values from a range\n\t *\n\t * @async\n\t * @param {string} range\n\t * @returns {unknown}\n\t */\n\tasync getSheetValues(range: string) {\n\t\ttry {\n\t\t\tconst response = await this.client.spreadsheets.values.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange,\n\t\t\t});\n\n\t\t\treturn response.data.values;\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Append a new row in whitespace, respecting existing data\n\t *\n\t * @async\n\t * @param {{ sheetName: string; columns: ColumnRange; values: any[][] }} options\n\t * @returns {*}\n\t */\n\tasync appendRow(options: { sheetName: string; columns: ColumnRange; values: any[][] }) {\n\t\ttry {\n\t\t\tconst { columns, sheetName, values } = options;\n\t\t\tconst rangeToCheck = constructColumnRangeString({ range: columns, sheetName });\n\t\t\tconst sheetValues = await this.getSheetValues(rangeToCheck);\n\n\t\t\tconst existingRows = sheetValues?.length || 0;\n\t\t\tconst targetRow = existingRows + 1;\n\t\t\tconst fullRange = constructColumnRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: columns.from,\n\t\t\t\t\tto: targetRow.toString(),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait this.client.spreadsheets.values.append({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: fullRange,\n\t\t\t\tvalueInputOption: \"USER_ENTERED\",\n\t\t\t\tinsertDataOption: \"INSERT_ROWS\",\n\t\t\t\trequestBody: { values },\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Update a row by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tkey: string,\n\t * \t\tsearchColumns: ColumnRange,\n\t * \t\tupdateColumns: ColumnRange,\n\t * \t\tvalues: string[]\n\t * \t}} options\n\t * @returns {*}\n\t */\n\tasync updateRowByKey(options: {\n\t\tsheetName: string;\n\t\tkey: string;\n\t\tsearchColumns: ColumnRange;\n\t\tupdateColumns: ColumnRange;\n\t\tvalues: string[];\n\t}) {\n\t\ttry {\n\t\t\tconst { key, searchColumns, sheetName, updateColumns, values } = options;\n\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\t\t\tconst updateRange = constructRowRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: [updateColumns.from, rowNumber],\n\t\t\t\t\tto: [updateColumns.to, rowNumber],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait this.client.spreadsheets.values.update({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: updateRange,\n\t\t\t\tvalueInputOption: \"USER_ENTERED\",\n\t\t\t\trequestBody: { values: [values] },\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Get values from a range by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tkey: string,\n\t * \t\tsearchColumns: ColumnRange,\n\t * \t\tdataColumns: ColumnRange\n\t * \t}} options\n\t * @returns {unknown}\n\t */\n\tasync getValuesByKey(options: {\n\t\tsheetName: string;\n\t\tkey: string;\n\t\tsearchColumns: ColumnRange;\n\t\tdataColumns: ColumnRange;\n\t}) {\n\t\ttry {\n\t\t\tconst { dataColumns, key, searchColumns, sheetName } = options;\n\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\t\t\tconst dataRange = constructRowRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: [dataColumns.from, rowNumber],\n\t\t\t\t\tto: [dataColumns.to, rowNumber],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst response = await this.client.spreadsheets.values.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: dataRange,\n\t\t\t});\n\n\t\t\treturn response.data.values?.[0] || [];\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Add a note to a cell by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tsheetId: number,\n\t * \t\tkey: string,\n\t * \t\tnote: string,\n\t * \t\tsearchColumns: ColumnRange\n\t * \t\tnoteColumn: string\n\t * \t}} options\n\t * @returns {*}\n\t */\n\tasync addNoteToCellByKey(options: {\n\t\tsheetName: string;\n\t\tsheetId: number;\n\t\tkey: string;\n\t\tnote: string;\n\t\tsearchColumns: ColumnRange;\n\t\tnoteColumn: string;\n\t}) {\n\t\ttry {\n\t\t\tconst { key, note, searchColumns, sheetName, noteColumn, sheetId } = options;\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\n\t\t\tconst existingNote = await this.client.spreadsheets.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\tranges: [`${sheetName}!${noteColumn}${rowNumber}`],\n\t\t\t\tincludeGridData: true,\n\t\t\t});\n\n\t\t\tconst currentNote =\n\t\t\t\texistingNote.data.sheets?.[0].data?.[0].rowData?.[0].values?.[0].note || \"\";\n\t\t\tconst updatedNote = currentNote === \"\" ? note : `${currentNote}\\n\\n${note}`;\n\n\t\t\tawait this.client.spreadsheets.batchUpdate({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trequestBody: {\n\t\t\t\t\trequests: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tupdateCells: {\n\t\t\t\t\t\t\t\trows: [{ values: [{ note: updatedNote }] }],\n\t\t\t\t\t\t\t\tfields: \"note\",\n\t\t\t\t\t\t\t\tstart: { rowIndex: rowNumber, columnIndex: alphabetPosition(noteColumn), sheetId },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/utility/errors.ts","../src/utility/functions.ts","../src/client.ts"],"names":["JWT","google"],"mappings":"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","file":"index.cjs","sourcesContent":["export class SheetsError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\n\t\tthis.name = \"SheetsError\";\n\t\tObject.setPrototypeOf(this, SheetsError.prototype);\n\t}\n}\n","import { ColumnRange, RowRange } from \"./types.js\";\n\n/**\n * Construct an A1 notation string for a column range\n *\n * @export\n * @param {{ range: ColumnRange; sheetName?: string }} options\n * @returns {string}\n */\nexport function constructColumnRangeString(options: { range: ColumnRange; sheetName?: string }) {\n\tconst { range, sheetName } = options;\n\tconst rangeString = `!${range.from}:${range.to}`;\n\n\treturn sheetName ? sheetName + rangeString : rangeString;\n}\n\n/**\n * Construct an A1 notation string for a full column & row range\n *\n * @export\n * @param {{ range: RowRange; sheetName?: string }} options\n * @returns {string}\n */\nexport function constructRowRangeString(options: { range: RowRange; sheetName?: string }) {\n\tconst { range, sheetName } = options;\n\tconst rangeString = `!${range.from[0]}${range.from[1]}:${range.to[0]}${range.to[1]}`;\n\n\treturn sheetName ? sheetName + rangeString : rangeString;\n}\n\n/**\n * @link https://stackoverflow.com/a/41427259\n */\nexport function alphabetPosition(text: string) {\n\tlet result = \"\";\n\tfor (let i = 0; i < text.length; i++) {\n\t\tlet code = text.toUpperCase().charCodeAt(i);\n\t\tif (code > 64 && code < 91) result += code - 64 + \" \";\n\t}\n\n\treturn Number(result.slice(0, result.length - 1));\n}\n","import { JWT } from \"google-auth-library\";\nimport { google, sheets_v4 } from \"googleapis\";\n\nimport { ColumnRange } from \"./utility/types.js\";\nimport { SheetsError } from \"./utility/errors.js\";\nimport {\n\talphabetPosition,\n\tconstructColumnRangeString,\n\tconstructRowRangeString,\n} from \"./utility/functions.js\";\n\n/**\n * Google Sheets client\n *\n * @export\n * @class SheetsClient\n * @typedef {SheetsClient}\n */\nexport default class SheetsClient {\n\tprivate _client: sheets_v4.Sheets;\n\tprivate _spreadsheetId: string;\n\n\t/**\n\t * Creates an instance of SheetsClient.\n\t *\n\t * @constructor\n\t * @param {{ spreadsheetId: string; key: JWTOptions }} options\n\t */\n\tconstructor(options: { spreadsheetId: string; key: { client_email: string, private_key: string } }) {\n\t\tconst auth = new JWT({\n\t\t\tscopes: [\"https://www.googleapis.com/auth/spreadsheets\"],\n\t\t\temail: options.key.client_email,\n\t\t\tkey: options.key.private_key\n\t\t});\n\n\t\tthis._client = google.sheets({ version: \"v4\", auth });\n\t\tthis._spreadsheetId = options.spreadsheetId;\n\t}\n\n\t/**\n\t * Get the current set spreadsheet ID\n\t *\n\t * @type {string}\n\t */\n\tget spreadsheetId() {\n\t\treturn this._spreadsheetId;\n\t}\n\n\t/**\n\t * Set the spreadsheet ID to use\n\t *\n\t * @type {string}\n\t */\n\tset spreadsheetId(spreadsheetId: string) {\n\t\tthis._spreadsheetId = spreadsheetId;\n\t}\n\n\t/**\n\t * Get the sheets client object\n\t *\n\t * @readonly\n\t * @type {sheets_v4.Sheets}\n\t */\n\tget client() {\n\t\treturn this._client;\n\t}\n\n\t/**\n\t * Get a row number from looking up a key\n\t *\n\t * @protected\n\t * @async\n\t * @param {{ sheetName: string, searchColumns: ColumnRange, key: string }} options\n\t * @returns {unknown}\n\t */\n\tprotected async getRowNumberByKey(options: {\n\t\tsheetName: string;\n\t\tsearchColumns: ColumnRange;\n\t\tkey: string;\n\t}) {\n\t\tconst { key, searchColumns, sheetName } = options;\n\n\t\tconst searchRange = constructColumnRangeString({ sheetName, range: searchColumns });\n\t\tconst sheetValues = await this.getSheetValues(searchRange);\n\n\t\tconst rows = sheetValues || [];\n\t\tconst rowIndex = rows.findIndex(row => row[0] === key);\n\n\t\tif (rowIndex === -1) {\n\t\t\tthrow new SheetsError(`No matching value found for key ${key}`);\n\t\t}\n\n\t\tconst rowNumber = rowIndex + 1;\n\t\treturn rowNumber;\n\t}\n\n\t/**\n\t * Get values from a range\n\t *\n\t * @async\n\t * @param {string} range\n\t * @returns {unknown}\n\t */\n\tasync getSheetValues(range: string) {\n\t\ttry {\n\t\t\tconst response = await this.client.spreadsheets.values.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange,\n\t\t\t});\n\n\t\t\treturn response.data.values;\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Append a new row in whitespace, respecting existing data\n\t *\n\t * @async\n\t * @param {{ sheetName: string; columns: ColumnRange; values: any[][] }} options\n\t * @returns {*}\n\t */\n\tasync appendRow(options: { sheetName: string; columns: ColumnRange; values: any[][] }) {\n\t\ttry {\n\t\t\tconst { columns, sheetName, values } = options;\n\t\t\tconst rangeToCheck = constructColumnRangeString({ range: columns, sheetName });\n\t\t\tconst sheetValues = await this.getSheetValues(rangeToCheck);\n\n\t\t\tconst existingRows = sheetValues?.length || 0;\n\t\t\tconst targetRow = existingRows + 1;\n\t\t\tconst fullRange = constructColumnRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: columns.from,\n\t\t\t\t\tto: targetRow.toString(),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait this.client.spreadsheets.values.append({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: fullRange,\n\t\t\t\tvalueInputOption: \"USER_ENTERED\",\n\t\t\t\tinsertDataOption: \"INSERT_ROWS\",\n\t\t\t\trequestBody: { values },\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Update a row by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tkey: string,\n\t * \t\tsearchColumns: ColumnRange,\n\t * \t\tupdateColumns: ColumnRange,\n\t * \t\tvalues: string[]\n\t * \t}} options\n\t * @returns {*}\n\t */\n\tasync updateRowByKey(options: {\n\t\tsheetName: string;\n\t\tkey: string;\n\t\tsearchColumns: ColumnRange;\n\t\tupdateColumns: ColumnRange;\n\t\tvalues: string[];\n\t}) {\n\t\ttry {\n\t\t\tconst { key, searchColumns, sheetName, updateColumns, values } = options;\n\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\t\t\tconst updateRange = constructRowRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: [updateColumns.from, rowNumber],\n\t\t\t\t\tto: [updateColumns.to, rowNumber],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait this.client.spreadsheets.values.update({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: updateRange,\n\t\t\t\tvalueInputOption: \"USER_ENTERED\",\n\t\t\t\trequestBody: { values: [values] },\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Get values from a range by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tkey: string,\n\t * \t\tsearchColumns: ColumnRange,\n\t * \t\tdataColumns: ColumnRange\n\t * \t}} options\n\t * @returns {unknown}\n\t */\n\tasync getValuesByKey(options: {\n\t\tsheetName: string;\n\t\tkey: string;\n\t\tsearchColumns: ColumnRange;\n\t\tdataColumns: ColumnRange;\n\t}) {\n\t\ttry {\n\t\t\tconst { dataColumns, key, searchColumns, sheetName } = options;\n\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\t\t\tconst dataRange = constructRowRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: [dataColumns.from, rowNumber],\n\t\t\t\t\tto: [dataColumns.to, rowNumber],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst response = await this.client.spreadsheets.values.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: dataRange,\n\t\t\t});\n\n\t\t\treturn response.data.values?.[0] || [];\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Add a note to a cell by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tsheetId: number,\n\t * \t\tkey: string,\n\t * \t\tnote: string,\n\t * \t\tsearchColumns: ColumnRange\n\t * \t\tnoteColumn: string\n\t * \t}} options\n\t * @returns {*}\n\t */\n\tasync addNoteToCellByKey(options: {\n\t\tsheetName: string;\n\t\tsheetId: number;\n\t\tkey: string;\n\t\tnote: string;\n\t\tsearchColumns: ColumnRange;\n\t\tnoteColumn: string;\n\t}) {\n\t\ttry {\n\t\t\tconst { key, note, searchColumns, sheetName, noteColumn, sheetId } = options;\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\n\t\t\tconst existingNote = await this.client.spreadsheets.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\tranges: [`${sheetName}!${noteColumn}${rowNumber}`],\n\t\t\t\tincludeGridData: true,\n\t\t\t});\n\n\t\t\tconst currentNote =\n\t\t\t\texistingNote.data.sheets?.[0].data?.[0].rowData?.[0].values?.[0].note || \"\";\n\t\t\tconst updatedNote = currentNote === \"\" ? note : `${currentNote}\\n\\n${note}`;\n\n\t\t\tawait this.client.spreadsheets.batchUpdate({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trequestBody: {\n\t\t\t\t\trequests: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tupdateCells: {\n\t\t\t\t\t\t\t\trows: [{ values: [{ note: updatedNote }] }],\n\t\t\t\t\t\t\t\tfields: \"note\",\n\t\t\t\t\t\t\t\tstart: { rowIndex: rowNumber, columnIndex: alphabetPosition(noteColumn), sheetId },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -23,11 +23,14 @@ declare class SheetsClient {
23
23
  * Creates an instance of SheetsClient.
24
24
  *
25
25
  * @constructor
26
- * @param {{ spreadsheetId: string; key: {} }} options
26
+ * @param {{ spreadsheetId: string; key: JWTOptions }} options
27
27
  */
28
28
  constructor(options: {
29
29
  spreadsheetId: string;
30
- key: {};
30
+ key: {
31
+ client_email: string;
32
+ private_key: string;
33
+ };
31
34
  });
32
35
  /**
33
36
  * Get the current set spreadsheet ID
package/dist/index.d.ts CHANGED
@@ -23,11 +23,14 @@ declare class SheetsClient {
23
23
  * Creates an instance of SheetsClient.
24
24
  *
25
25
  * @constructor
26
- * @param {{ spreadsheetId: string; key: {} }} options
26
+ * @param {{ spreadsheetId: string; key: JWTOptions }} options
27
27
  */
28
28
  constructor(options: {
29
29
  spreadsheetId: string;
30
- key: {};
30
+ key: {
31
+ client_email: string;
32
+ private_key: string;
33
+ };
31
34
  });
32
35
  /**
33
36
  * Get the current set spreadsheet ID
package/dist/index.js CHANGED
@@ -40,11 +40,15 @@ var SheetsClient = class {
40
40
  * Creates an instance of SheetsClient.
41
41
  *
42
42
  * @constructor
43
- * @param {{ spreadsheetId: string; key: {} }} options
43
+ * @param {{ spreadsheetId: string; key: JWTOptions }} options
44
44
  */
45
45
  constructor(options) {
46
- const client = new JWT({});
47
- this._client = google.sheets({ version: "v4", auth: client });
46
+ const auth = new JWT({
47
+ scopes: ["https://www.googleapis.com/auth/spreadsheets"],
48
+ email: options.key.client_email,
49
+ key: options.key.private_key
50
+ });
51
+ this._client = google.sheets({ version: "v4", auth });
48
52
  this._spreadsheetId = options.spreadsheetId;
49
53
  }
50
54
  /**
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utility/errors.ts","../src/utility/functions.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export class SheetsError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\n\t\tthis.name = \"SheetsError\";\n\t\tObject.setPrototypeOf(this, SheetsError.prototype);\n\t}\n}\n","import { ColumnRange, RowRange } from \"./types.js\";\n\n/**\n * Construct an A1 notation string for a column range\n *\n * @export\n * @param {{ range: ColumnRange; sheetName?: string }} options\n * @returns {string}\n */\nexport function constructColumnRangeString(options: { range: ColumnRange; sheetName?: string }) {\n\tconst { range, sheetName } = options;\n\tconst rangeString = `!${range.from}:${range.to}`;\n\n\treturn sheetName ? sheetName + rangeString : rangeString;\n}\n\n/**\n * Construct an A1 notation string for a full column & row range\n *\n * @export\n * @param {{ range: RowRange; sheetName?: string }} options\n * @returns {string}\n */\nexport function constructRowRangeString(options: { range: RowRange; sheetName?: string }) {\n\tconst { range, sheetName } = options;\n\tconst rangeString = `!${range.from[0]}${range.from[1]}:${range.to[0]}${range.to[1]}`;\n\n\treturn sheetName ? sheetName + rangeString : rangeString;\n}\n\n/**\n * @link https://stackoverflow.com/a/41427259\n */\nexport function alphabetPosition(text: string) {\n\tlet result = \"\";\n\tfor (let i = 0; i < text.length; i++) {\n\t\tlet code = text.toUpperCase().charCodeAt(i);\n\t\tif (code > 64 && code < 91) result += code - 64 + \" \";\n\t}\n\n\treturn Number(result.slice(0, result.length - 1));\n}\n","import { JWT } from \"google-auth-library\";\nimport { google, sheets_v4 } from \"googleapis\";\n\nimport { ColumnRange } from \"./utility/types.js\";\nimport { SheetsError } from \"./utility/errors.js\";\nimport {\n\talphabetPosition,\n\tconstructColumnRangeString,\n\tconstructRowRangeString,\n} from \"./utility/functions.js\";\n\n/**\n * Google Sheets client\n *\n * @export\n * @class SheetsClient\n * @typedef {SheetsClient}\n */\nexport default class SheetsClient {\n\tprivate _client: sheets_v4.Sheets;\n\tprivate _spreadsheetId: string;\n\n\t/**\n\t * Creates an instance of SheetsClient.\n\t *\n\t * @constructor\n\t * @param {{ spreadsheetId: string; key: {} }} options\n\t */\n\tconstructor(options: { spreadsheetId: string; key: {} }) {\n\t\tconst client = new JWT({});\n\n\t\tthis._client = google.sheets({ version: \"v4\", auth: client });\n\t\tthis._spreadsheetId = options.spreadsheetId;\n\t}\n\n\t/**\n\t * Get the current set spreadsheet ID\n\t *\n\t * @type {string}\n\t */\n\tget spreadsheetId() {\n\t\treturn this._spreadsheetId;\n\t}\n\n\t/**\n\t * Set the spreadsheet ID to use\n\t *\n\t * @type {string}\n\t */\n\tset spreadsheetId(spreadsheetId: string) {\n\t\tthis._spreadsheetId = spreadsheetId;\n\t}\n\n\t/**\n\t * Get the sheets client object\n\t *\n\t * @readonly\n\t * @type {sheets_v4.Sheets}\n\t */\n\tget client() {\n\t\treturn this._client;\n\t}\n\n\t/**\n\t * Get a row number from looking up a key\n\t *\n\t * @protected\n\t * @async\n\t * @param {{ sheetName: string, searchColumns: ColumnRange, key: string }} options\n\t * @returns {unknown}\n\t */\n\tprotected async getRowNumberByKey(options: {\n\t\tsheetName: string;\n\t\tsearchColumns: ColumnRange;\n\t\tkey: string;\n\t}) {\n\t\tconst { key, searchColumns, sheetName } = options;\n\n\t\tconst searchRange = constructColumnRangeString({ sheetName, range: searchColumns });\n\t\tconst sheetValues = await this.getSheetValues(searchRange);\n\n\t\tconst rows = sheetValues || [];\n\t\tconst rowIndex = rows.findIndex(row => row[0] === key);\n\n\t\tif (rowIndex === -1) {\n\t\t\tthrow new SheetsError(`No matching value found for key ${key}`);\n\t\t}\n\n\t\tconst rowNumber = rowIndex + 1;\n\t\treturn rowNumber;\n\t}\n\n\t/**\n\t * Get values from a range\n\t *\n\t * @async\n\t * @param {string} range\n\t * @returns {unknown}\n\t */\n\tasync getSheetValues(range: string) {\n\t\ttry {\n\t\t\tconst response = await this.client.spreadsheets.values.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange,\n\t\t\t});\n\n\t\t\treturn response.data.values;\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Append a new row in whitespace, respecting existing data\n\t *\n\t * @async\n\t * @param {{ sheetName: string; columns: ColumnRange; values: any[][] }} options\n\t * @returns {*}\n\t */\n\tasync appendRow(options: { sheetName: string; columns: ColumnRange; values: any[][] }) {\n\t\ttry {\n\t\t\tconst { columns, sheetName, values } = options;\n\t\t\tconst rangeToCheck = constructColumnRangeString({ range: columns, sheetName });\n\t\t\tconst sheetValues = await this.getSheetValues(rangeToCheck);\n\n\t\t\tconst existingRows = sheetValues?.length || 0;\n\t\t\tconst targetRow = existingRows + 1;\n\t\t\tconst fullRange = constructColumnRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: columns.from,\n\t\t\t\t\tto: targetRow.toString(),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait this.client.spreadsheets.values.append({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: fullRange,\n\t\t\t\tvalueInputOption: \"USER_ENTERED\",\n\t\t\t\tinsertDataOption: \"INSERT_ROWS\",\n\t\t\t\trequestBody: { values },\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Update a row by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tkey: string,\n\t * \t\tsearchColumns: ColumnRange,\n\t * \t\tupdateColumns: ColumnRange,\n\t * \t\tvalues: string[]\n\t * \t}} options\n\t * @returns {*}\n\t */\n\tasync updateRowByKey(options: {\n\t\tsheetName: string;\n\t\tkey: string;\n\t\tsearchColumns: ColumnRange;\n\t\tupdateColumns: ColumnRange;\n\t\tvalues: string[];\n\t}) {\n\t\ttry {\n\t\t\tconst { key, searchColumns, sheetName, updateColumns, values } = options;\n\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\t\t\tconst updateRange = constructRowRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: [updateColumns.from, rowNumber],\n\t\t\t\t\tto: [updateColumns.to, rowNumber],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait this.client.spreadsheets.values.update({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: updateRange,\n\t\t\t\tvalueInputOption: \"USER_ENTERED\",\n\t\t\t\trequestBody: { values: [values] },\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Get values from a range by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tkey: string,\n\t * \t\tsearchColumns: ColumnRange,\n\t * \t\tdataColumns: ColumnRange\n\t * \t}} options\n\t * @returns {unknown}\n\t */\n\tasync getValuesByKey(options: {\n\t\tsheetName: string;\n\t\tkey: string;\n\t\tsearchColumns: ColumnRange;\n\t\tdataColumns: ColumnRange;\n\t}) {\n\t\ttry {\n\t\t\tconst { dataColumns, key, searchColumns, sheetName } = options;\n\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\t\t\tconst dataRange = constructRowRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: [dataColumns.from, rowNumber],\n\t\t\t\t\tto: [dataColumns.to, rowNumber],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst response = await this.client.spreadsheets.values.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: dataRange,\n\t\t\t});\n\n\t\t\treturn response.data.values?.[0] || [];\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Add a note to a cell by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tsheetId: number,\n\t * \t\tkey: string,\n\t * \t\tnote: string,\n\t * \t\tsearchColumns: ColumnRange\n\t * \t\tnoteColumn: string\n\t * \t}} options\n\t * @returns {*}\n\t */\n\tasync addNoteToCellByKey(options: {\n\t\tsheetName: string;\n\t\tsheetId: number;\n\t\tkey: string;\n\t\tnote: string;\n\t\tsearchColumns: ColumnRange;\n\t\tnoteColumn: string;\n\t}) {\n\t\ttry {\n\t\t\tconst { key, note, searchColumns, sheetName, noteColumn, sheetId } = options;\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\n\t\t\tconst existingNote = await this.client.spreadsheets.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\tranges: [`${sheetName}!${noteColumn}${rowNumber}`],\n\t\t\t\tincludeGridData: true,\n\t\t\t});\n\n\t\t\tconst currentNote =\n\t\t\t\texistingNote.data.sheets?.[0].data?.[0].rowData?.[0].values?.[0].note || \"\";\n\t\t\tconst updatedNote = currentNote === \"\" ? note : `${currentNote}\\n\\n${note}`;\n\n\t\t\tawait this.client.spreadsheets.batchUpdate({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trequestBody: {\n\t\t\t\t\trequests: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tupdateCells: {\n\t\t\t\t\t\t\t\trows: [{ values: [{ note: updatedNote }] }],\n\t\t\t\t\t\t\t\tfields: \"note\",\n\t\t\t\t\t\t\t\tstart: { rowIndex: rowNumber, columnIndex: alphabetPosition(noteColumn), sheetId },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/utility/errors.ts","../src/utility/functions.ts","../src/client.ts"],"names":[],"mappings":";;;;;;AAAO,IAAM,WAAA,GAAN,MAAM,YAAA,SAAoB,KAAA,CAAM;AAAA,EACtC,YAAY,OAAA,EAAiB;AAC5B,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,YAAA,CAAY,SAAS,CAAA;AAAA,EAClD;AACD,CAAA;;;ACEO,SAAS,2BAA2B,OAAA,EAAqD;AAC/F,EAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,OAAA;AAC7B,EAAA,MAAM,cAAc,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,MAAM,EAAE,CAAA,CAAA;AAE9C,EAAA,OAAO,SAAA,GAAY,YAAY,WAAA,GAAc,WAAA;AAC9C;AASO,SAAS,wBAAwB,OAAA,EAAkD;AACzF,EAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,OAAA;AAC7B,EAAA,MAAM,WAAA,GAAc,IAAI,KAAA,CAAM,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,MAAM,IAAA,CAAK,CAAC,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,GAAG,CAAC,CAAC,GAAG,KAAA,CAAM,EAAA,CAAG,CAAC,CAAC,CAAA,CAAA;AAElF,EAAA,OAAO,SAAA,GAAY,YAAY,WAAA,GAAc,WAAA;AAC9C;AAKO,SAAS,iBAAiB,IAAA,EAAc;AAC9C,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,IAAI,IAAA,GAAO,IAAA,CAAK,WAAA,EAAY,CAAE,WAAW,CAAC,CAAA;AAC1C,IAAA,IAAI,OAAO,EAAA,IAAM,IAAA,GAAO,EAAA,EAAI,MAAA,IAAU,OAAO,EAAA,GAAK,GAAA;AAAA,EACnD;AAEA,EAAA,OAAO,OAAO,MAAA,CAAO,KAAA,CAAM,GAAG,MAAA,CAAO,MAAA,GAAS,CAAC,CAAC,CAAA;AACjD;;;ACvBA,IAAqB,eAArB,MAAkC;AAAA,EACzB,OAAA;AAAA,EACA,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQR,YAAY,OAAA,EAAwF;AACnG,IAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI;AAAA,MACpB,MAAA,EAAQ,CAAC,8CAA8C,CAAA;AAAA,MACvD,KAAA,EAAO,QAAQ,GAAA,CAAI,YAAA;AAAA,MACnB,GAAA,EAAK,QAAQ,GAAA,CAAI;AAAA,KACjB,CAAA;AAED,IAAA,IAAA,CAAK,UAAU,MAAA,CAAO,MAAA,CAAO,EAAE,OAAA,EAAS,IAAA,EAAM,MAAM,CAAA;AACpD,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,aAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,aAAA,GAAgB;AACnB,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,cAAc,aAAA,EAAuB;AACxC,IAAA,IAAA,CAAK,cAAA,GAAiB,aAAA;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,MAAA,GAAS;AACZ,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAgB,kBAAkB,OAAA,EAI/B;AACF,IAAA,MAAM,EAAE,GAAA,EAAK,aAAA,EAAe,SAAA,EAAU,GAAI,OAAA;AAE1C,IAAA,MAAM,cAAc,0BAAA,CAA2B,EAAE,SAAA,EAAW,KAAA,EAAO,eAAe,CAAA;AAClF,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,cAAA,CAAe,WAAW,CAAA;AAEzD,IAAA,MAAM,IAAA,GAAO,eAAe,EAAC;AAC7B,IAAA,MAAM,WAAW,IAAA,CAAK,SAAA,CAAU,SAAO,GAAA,CAAI,CAAC,MAAM,GAAG,CAAA;AAErD,IAAA,IAAI,aAAa,EAAA,EAAI;AACpB,MAAA,MAAM,IAAI,WAAA,CAAY,CAAA,gCAAA,EAAmC,GAAG,CAAA,CAAE,CAAA;AAAA,IAC/D;AAEA,IAAA,MAAM,YAAY,QAAA,GAAW,CAAA;AAC7B,IAAA,OAAO,SAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAe,KAAA,EAAe;AACnC,IAAA,IAAI;AACH,MAAA,MAAM,WAAW,MAAM,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,OAAO,GAAA,CAAI;AAAA,QAC1D,eAAe,IAAA,CAAK,aAAA;AAAA,QACpB;AAAA,OACA,CAAA;AAED,MAAA,OAAO,SAAS,IAAA,CAAK,MAAA;AAAA,IACtB,SAAS,KAAA,EAAY;AACpB,MAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,IACpB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAU,OAAA,EAAuE;AACtF,IAAA,IAAI;AACH,MAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAW,MAAA,EAAO,GAAI,OAAA;AACvC,MAAA,MAAM,eAAe,0BAAA,CAA2B,EAAE,KAAA,EAAO,OAAA,EAAS,WAAW,CAAA;AAC7E,MAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,cAAA,CAAe,YAAY,CAAA;AAE1D,MAAA,MAAM,YAAA,GAAe,aAAa,MAAA,IAAU,CAAA;AAC5C,MAAA,MAAM,YAAY,YAAA,GAAe,CAAA;AACjC,MAAA,MAAM,YAAY,0BAAA,CAA2B;AAAA,QAC5C,SAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACN,MAAM,OAAA,CAAQ,IAAA;AAAA,UACd,EAAA,EAAI,UAAU,QAAA;AAAS;AACxB,OACA,CAAA;AAED,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,MAAA,CAAO,MAAA,CAAO;AAAA,QAC5C,eAAe,IAAA,CAAK,aAAA;AAAA,QACpB,KAAA,EAAO,SAAA;AAAA,QACP,gBAAA,EAAkB,cAAA;AAAA,QAClB,gBAAA,EAAkB,aAAA;AAAA,QAClB,WAAA,EAAa,EAAE,MAAA;AAAO,OACtB,CAAA;AAAA,IACF,SAAS,KAAA,EAAY;AACpB,MAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,IACpB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,eAAe,OAAA,EAMlB;AACF,IAAA,IAAI;AACH,MAAA,MAAM,EAAE,GAAA,EAAK,aAAA,EAAe,SAAA,EAAW,aAAA,EAAe,QAAO,GAAI,OAAA;AAEjE,MAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,iBAAA,CAAkB,EAAE,SAAA,EAAW,aAAA,EAAe,KAAK,CAAA;AAChF,MAAA,MAAM,cAAc,uBAAA,CAAwB;AAAA,QAC3C,SAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACN,IAAA,EAAM,CAAC,aAAA,CAAc,IAAA,EAAM,SAAS,CAAA;AAAA,UACpC,EAAA,EAAI,CAAC,aAAA,CAAc,EAAA,EAAI,SAAS;AAAA;AACjC,OACA,CAAA;AAED,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,MAAA,CAAO,MAAA,CAAO;AAAA,QAC5C,eAAe,IAAA,CAAK,aAAA;AAAA,QACpB,KAAA,EAAO,WAAA;AAAA,QACP,gBAAA,EAAkB,cAAA;AAAA,QAClB,WAAA,EAAa,EAAE,MAAA,EAAQ,CAAC,MAAM,CAAA;AAAE,OAChC,CAAA;AAAA,IACF,SAAS,KAAA,EAAY;AACpB,MAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,IACpB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,eAAe,OAAA,EAKlB;AACF,IAAA,IAAI;AACH,MAAA,MAAM,EAAE,WAAA,EAAa,GAAA,EAAK,aAAA,EAAe,WAAU,GAAI,OAAA;AAEvD,MAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,iBAAA,CAAkB,EAAE,SAAA,EAAW,aAAA,EAAe,KAAK,CAAA;AAChF,MAAA,MAAM,YAAY,uBAAA,CAAwB;AAAA,QACzC,SAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACN,IAAA,EAAM,CAAC,WAAA,CAAY,IAAA,EAAM,SAAS,CAAA;AAAA,UAClC,EAAA,EAAI,CAAC,WAAA,CAAY,EAAA,EAAI,SAAS;AAAA;AAC/B,OACA,CAAA;AAED,MAAA,MAAM,WAAW,MAAM,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,OAAO,GAAA,CAAI;AAAA,QAC1D,eAAe,IAAA,CAAK,aAAA;AAAA,QACpB,KAAA,EAAO;AAAA,OACP,CAAA;AAED,MAAA,OAAO,QAAA,CAAS,IAAA,CAAK,MAAA,GAAS,CAAC,KAAK,EAAC;AAAA,IACtC,SAAS,KAAA,EAAY;AACpB,MAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,IACpB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,mBAAmB,OAAA,EAOtB;AACF,IAAA,IAAI;AACH,MAAA,MAAM,EAAE,GAAA,EAAK,IAAA,EAAM,eAAe,SAAA,EAAW,UAAA,EAAY,SAAQ,GAAI,OAAA;AACrE,MAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,iBAAA,CAAkB,EAAE,SAAA,EAAW,aAAA,EAAe,KAAK,CAAA;AAEhF,MAAA,MAAM,YAAA,GAAe,MAAM,IAAA,CAAK,MAAA,CAAO,aAAa,GAAA,CAAI;AAAA,QACvD,eAAe,IAAA,CAAK,aAAA;AAAA,QACpB,MAAA,EAAQ,CAAC,CAAA,EAAG,SAAS,IAAI,UAAU,CAAA,EAAG,SAAS,CAAA,CAAE,CAAA;AAAA,QACjD,eAAA,EAAiB;AAAA,OACjB,CAAA;AAED,MAAA,MAAM,WAAA,GACL,YAAA,CAAa,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA,CAAE,IAAA,GAAO,CAAC,CAAA,CAAE,UAAU,CAAC,CAAA,CAAE,MAAA,GAAS,CAAC,EAAE,IAAA,IAAQ,EAAA;AAC1E,MAAA,MAAM,WAAA,GAAc,WAAA,KAAgB,EAAA,GAAK,IAAA,GAAO,GAAG,WAAW;;AAAA,EAAO,IAAI,CAAA,CAAA;AAEzE,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,WAAA,CAAY;AAAA,QAC1C,eAAe,IAAA,CAAK,aAAA;AAAA,QACpB,WAAA,EAAa;AAAA,UACZ,QAAA,EAAU;AAAA,YACT;AAAA,cACC,WAAA,EAAa;AAAA,gBACZ,IAAA,EAAM,CAAC,EAAE,MAAA,EAAQ,CAAC,EAAE,IAAA,EAAM,WAAA,EAAa,CAAA,EAAG,CAAA;AAAA,gBAC1C,MAAA,EAAQ,MAAA;AAAA,gBACR,KAAA,EAAO,EAAE,QAAA,EAAU,SAAA,EAAW,aAAa,gBAAA,CAAiB,UAAU,GAAG,OAAA;AAAQ;AAClF;AACD;AACD;AACD,OACA,CAAA;AAAA,IACF,SAAS,KAAA,EAAY;AACpB,MAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,IACpB;AAAA,EACD;AACD","file":"index.js","sourcesContent":["export class SheetsError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\n\t\tthis.name = \"SheetsError\";\n\t\tObject.setPrototypeOf(this, SheetsError.prototype);\n\t}\n}\n","import { ColumnRange, RowRange } from \"./types.js\";\n\n/**\n * Construct an A1 notation string for a column range\n *\n * @export\n * @param {{ range: ColumnRange; sheetName?: string }} options\n * @returns {string}\n */\nexport function constructColumnRangeString(options: { range: ColumnRange; sheetName?: string }) {\n\tconst { range, sheetName } = options;\n\tconst rangeString = `!${range.from}:${range.to}`;\n\n\treturn sheetName ? sheetName + rangeString : rangeString;\n}\n\n/**\n * Construct an A1 notation string for a full column & row range\n *\n * @export\n * @param {{ range: RowRange; sheetName?: string }} options\n * @returns {string}\n */\nexport function constructRowRangeString(options: { range: RowRange; sheetName?: string }) {\n\tconst { range, sheetName } = options;\n\tconst rangeString = `!${range.from[0]}${range.from[1]}:${range.to[0]}${range.to[1]}`;\n\n\treturn sheetName ? sheetName + rangeString : rangeString;\n}\n\n/**\n * @link https://stackoverflow.com/a/41427259\n */\nexport function alphabetPosition(text: string) {\n\tlet result = \"\";\n\tfor (let i = 0; i < text.length; i++) {\n\t\tlet code = text.toUpperCase().charCodeAt(i);\n\t\tif (code > 64 && code < 91) result += code - 64 + \" \";\n\t}\n\n\treturn Number(result.slice(0, result.length - 1));\n}\n","import { JWT } from \"google-auth-library\";\nimport { google, sheets_v4 } from \"googleapis\";\n\nimport { ColumnRange } from \"./utility/types.js\";\nimport { SheetsError } from \"./utility/errors.js\";\nimport {\n\talphabetPosition,\n\tconstructColumnRangeString,\n\tconstructRowRangeString,\n} from \"./utility/functions.js\";\n\n/**\n * Google Sheets client\n *\n * @export\n * @class SheetsClient\n * @typedef {SheetsClient}\n */\nexport default class SheetsClient {\n\tprivate _client: sheets_v4.Sheets;\n\tprivate _spreadsheetId: string;\n\n\t/**\n\t * Creates an instance of SheetsClient.\n\t *\n\t * @constructor\n\t * @param {{ spreadsheetId: string; key: JWTOptions }} options\n\t */\n\tconstructor(options: { spreadsheetId: string; key: { client_email: string, private_key: string } }) {\n\t\tconst auth = new JWT({\n\t\t\tscopes: [\"https://www.googleapis.com/auth/spreadsheets\"],\n\t\t\temail: options.key.client_email,\n\t\t\tkey: options.key.private_key\n\t\t});\n\n\t\tthis._client = google.sheets({ version: \"v4\", auth });\n\t\tthis._spreadsheetId = options.spreadsheetId;\n\t}\n\n\t/**\n\t * Get the current set spreadsheet ID\n\t *\n\t * @type {string}\n\t */\n\tget spreadsheetId() {\n\t\treturn this._spreadsheetId;\n\t}\n\n\t/**\n\t * Set the spreadsheet ID to use\n\t *\n\t * @type {string}\n\t */\n\tset spreadsheetId(spreadsheetId: string) {\n\t\tthis._spreadsheetId = spreadsheetId;\n\t}\n\n\t/**\n\t * Get the sheets client object\n\t *\n\t * @readonly\n\t * @type {sheets_v4.Sheets}\n\t */\n\tget client() {\n\t\treturn this._client;\n\t}\n\n\t/**\n\t * Get a row number from looking up a key\n\t *\n\t * @protected\n\t * @async\n\t * @param {{ sheetName: string, searchColumns: ColumnRange, key: string }} options\n\t * @returns {unknown}\n\t */\n\tprotected async getRowNumberByKey(options: {\n\t\tsheetName: string;\n\t\tsearchColumns: ColumnRange;\n\t\tkey: string;\n\t}) {\n\t\tconst { key, searchColumns, sheetName } = options;\n\n\t\tconst searchRange = constructColumnRangeString({ sheetName, range: searchColumns });\n\t\tconst sheetValues = await this.getSheetValues(searchRange);\n\n\t\tconst rows = sheetValues || [];\n\t\tconst rowIndex = rows.findIndex(row => row[0] === key);\n\n\t\tif (rowIndex === -1) {\n\t\t\tthrow new SheetsError(`No matching value found for key ${key}`);\n\t\t}\n\n\t\tconst rowNumber = rowIndex + 1;\n\t\treturn rowNumber;\n\t}\n\n\t/**\n\t * Get values from a range\n\t *\n\t * @async\n\t * @param {string} range\n\t * @returns {unknown}\n\t */\n\tasync getSheetValues(range: string) {\n\t\ttry {\n\t\t\tconst response = await this.client.spreadsheets.values.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange,\n\t\t\t});\n\n\t\t\treturn response.data.values;\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Append a new row in whitespace, respecting existing data\n\t *\n\t * @async\n\t * @param {{ sheetName: string; columns: ColumnRange; values: any[][] }} options\n\t * @returns {*}\n\t */\n\tasync appendRow(options: { sheetName: string; columns: ColumnRange; values: any[][] }) {\n\t\ttry {\n\t\t\tconst { columns, sheetName, values } = options;\n\t\t\tconst rangeToCheck = constructColumnRangeString({ range: columns, sheetName });\n\t\t\tconst sheetValues = await this.getSheetValues(rangeToCheck);\n\n\t\t\tconst existingRows = sheetValues?.length || 0;\n\t\t\tconst targetRow = existingRows + 1;\n\t\t\tconst fullRange = constructColumnRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: columns.from,\n\t\t\t\t\tto: targetRow.toString(),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait this.client.spreadsheets.values.append({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: fullRange,\n\t\t\t\tvalueInputOption: \"USER_ENTERED\",\n\t\t\t\tinsertDataOption: \"INSERT_ROWS\",\n\t\t\t\trequestBody: { values },\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Update a row by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tkey: string,\n\t * \t\tsearchColumns: ColumnRange,\n\t * \t\tupdateColumns: ColumnRange,\n\t * \t\tvalues: string[]\n\t * \t}} options\n\t * @returns {*}\n\t */\n\tasync updateRowByKey(options: {\n\t\tsheetName: string;\n\t\tkey: string;\n\t\tsearchColumns: ColumnRange;\n\t\tupdateColumns: ColumnRange;\n\t\tvalues: string[];\n\t}) {\n\t\ttry {\n\t\t\tconst { key, searchColumns, sheetName, updateColumns, values } = options;\n\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\t\t\tconst updateRange = constructRowRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: [updateColumns.from, rowNumber],\n\t\t\t\t\tto: [updateColumns.to, rowNumber],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait this.client.spreadsheets.values.update({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: updateRange,\n\t\t\t\tvalueInputOption: \"USER_ENTERED\",\n\t\t\t\trequestBody: { values: [values] },\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Get values from a range by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tkey: string,\n\t * \t\tsearchColumns: ColumnRange,\n\t * \t\tdataColumns: ColumnRange\n\t * \t}} options\n\t * @returns {unknown}\n\t */\n\tasync getValuesByKey(options: {\n\t\tsheetName: string;\n\t\tkey: string;\n\t\tsearchColumns: ColumnRange;\n\t\tdataColumns: ColumnRange;\n\t}) {\n\t\ttry {\n\t\t\tconst { dataColumns, key, searchColumns, sheetName } = options;\n\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\t\t\tconst dataRange = constructRowRangeString({\n\t\t\t\tsheetName,\n\t\t\t\trange: {\n\t\t\t\t\tfrom: [dataColumns.from, rowNumber],\n\t\t\t\t\tto: [dataColumns.to, rowNumber],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst response = await this.client.spreadsheets.values.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trange: dataRange,\n\t\t\t});\n\n\t\t\treturn response.data.values?.[0] || [];\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\n\t/**\n\t * Add a note to a cell by a key\n\t *\n\t * @async\n\t * @param {{\n\t * \t\tsheetName: string,\n\t * \t\tsheetId: number,\n\t * \t\tkey: string,\n\t * \t\tnote: string,\n\t * \t\tsearchColumns: ColumnRange\n\t * \t\tnoteColumn: string\n\t * \t}} options\n\t * @returns {*}\n\t */\n\tasync addNoteToCellByKey(options: {\n\t\tsheetName: string;\n\t\tsheetId: number;\n\t\tkey: string;\n\t\tnote: string;\n\t\tsearchColumns: ColumnRange;\n\t\tnoteColumn: string;\n\t}) {\n\t\ttry {\n\t\t\tconst { key, note, searchColumns, sheetName, noteColumn, sheetId } = options;\n\t\t\tconst rowNumber = await this.getRowNumberByKey({ sheetName, searchColumns, key });\n\n\t\t\tconst existingNote = await this.client.spreadsheets.get({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\tranges: [`${sheetName}!${noteColumn}${rowNumber}`],\n\t\t\t\tincludeGridData: true,\n\t\t\t});\n\n\t\t\tconst currentNote =\n\t\t\t\texistingNote.data.sheets?.[0].data?.[0].rowData?.[0].values?.[0].note || \"\";\n\t\t\tconst updatedNote = currentNote === \"\" ? note : `${currentNote}\\n\\n${note}`;\n\n\t\t\tawait this.client.spreadsheets.batchUpdate({\n\t\t\t\tspreadsheetId: this.spreadsheetId,\n\t\t\t\trequestBody: {\n\t\t\t\t\trequests: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tupdateCells: {\n\t\t\t\t\t\t\t\trows: [{ values: [{ note: updatedNote }] }],\n\t\t\t\t\t\t\t\tfields: \"note\",\n\t\t\t\t\t\t\t\tstart: { rowIndex: rowNumber, columnIndex: alphabetPosition(noteColumn), sheetId },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error: any) {\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trivious/sheets",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "description": "Google Sheets API wrapper module for Trivious framework",
6
6
  "main": "./dist/index.cjs",