UNPKG

@azteam/google-api

Version:

N/A

261 lines (230 loc) 8.43 kB
import _ from 'lodash'; import {genCharArray} from '@azteam/util'; import GoogleDriveAPI, {DRIVE_FILE_TYPE} from './GoogleDriveAPI'; import {DRIVE_SCOPE, SHEET_SCOPE} from './scope'; const SHEET_ENDPOINT = 'https://sheets.googleapis.com/v4'; class GoogleSheetAPI extends GoogleDriveAPI { constructor(accountType, credential, options = {}) { super( accountType, { ...credential, scope: SHEET_SCOPE, }, options ); } getAuthLink(redirectURI, state, arrayScope = [DRIVE_SCOPE, SHEET_SCOPE]) { return super.getAuthLink(redirectURI, state, arrayScope); } async hasScope(arrayScope = [DRIVE_SCOPE, SHEET_SCOPE]) { return super.hasScope(arrayScope); } static parseRange(range) { const matches = range.match(/(\w+?)(\d*):(\w+?)(\d*)/), colStart = matches[1] || null, rowStart = matches[2] ? Number(matches[2]) : null, colEnd = matches[3] || null, rowEnd = matches[4] ? Number(matches[4]) : null; if (colStart > colEnd || rowStart > rowEnd) { throw new Error('[range]: Syntax error'); } return { colStart, rowStart, colEnd, rowEnd, startRowIndex: rowStart - 1, endRowIndex: rowEnd, startColumnIndex: colStart.toUpperCase().charCodeAt(0) - 65, endColumnIndex: colEnd.toUpperCase().charCodeAt(0) - 65 + 1, }; } static parseValues(values, range) { const {colStart, colEnd, rowStart} = GoogleSheetAPI.parseRange(range), arrayColChar = genCharArray(colStart, colEnd), result = {}; for (let r = 0; r < values.length; r += 1) { const rowArray = values[r]; for (let c = 0; c < rowArray.length; c += 1) { const cell = rowArray[c], cellKey = arrayColChar[c] + (rowStart + r); result[cellKey] = cell; } } return result; } async getAllSpreadsheet(containsName = null, parentId = null) { let query = `mimeType='${DRIVE_FILE_TYPE.SHEET}' and trashed=false and '${parentId || 'root'}' in parents`; if (containsName) { query = `name contains '${containsName}' and ${query}`; } return this._getAllItem({ q: query, }); } async createSpreadsheet(title) { const client = await this._getAuthClient(), res = await client.post( `${SHEET_ENDPOINT}/spreadsheets`, { properties: { title, }, }, false ); if (res.error) { throw new Error(res.error.message); } if (res.spreadsheetId) { return { spreadsheetId: res.spreadsheetId, spreadsheetUrl: res.spreadsheetUrl, title: res.properties.title, }; } return null; } async getSpreadsheet(spreadsheetId) { const client = await this._getAuthClient(), res = await client.get(`${SHEET_ENDPOINT}/spreadsheets/${spreadsheetId}`); if (res.error) { throw new Error(res.error.message); } return { title: res.properties.title, sheets: res.sheets, link: res.spreadsheetUrl, }; } async createSheet(spreadsheetId, sheetName) { const client = await this._getAuthClient(), res = await client.post( `${SHEET_ENDPOINT}/spreadsheets/${spreadsheetId}:batchUpdate`, {requests: [{addSheet: {properties: {title: String(sheetName)}}}]}, false ); if (res.error) { throw new Error(res.error.message); } return res.replies[0].addSheet.properties; } async deleteSheet(spreadsheetId, sheetId) { const client = await this._getAuthClient(), res = await client.post( `${SHEET_ENDPOINT}/spreadsheets/${spreadsheetId}:batchUpdate`, { requests: [ { deleteSheet: { sheetId, }, }, ], }, false ); if (res.error) { throw new Error(res.error.message); } } async getSheetInfo(spreadsheetId, sheetName) { const {sheets} = await this.getSpreadsheet(spreadsheetId), data = sheets.find((obj) => obj.properties.title === sheetName); if (data) { return data.properties; } return {}; } async addRowsSheet(spreadsheetId, sheetId, numberRows) { const client = await this._getAuthClient(), res = await client.post( `${SHEET_ENDPOINT}/spreadsheets/${spreadsheetId}:batchUpdate`, { requests: [ { appendDimension: { sheetId, dimension: 'ROWS', length: numberRows, }, }, ], }, false ); if (res.error) { throw new Error(res.error.message); } return true; } async getValuesInSheet(spreadsheetId, sheetName, range, isParseValues = false) { const rangeQuery = `${sheetName}!${range}`, client = await this._getAuthClient(), res = await client.get(`${SHEET_ENDPOINT}/spreadsheets/${spreadsheetId}/values/${encodeURIComponent(rangeQuery)}`); if (res.error) { throw new Error(res.error.message); } const values = res.values || []; return isParseValues ? GoogleSheetAPI.parseValues(values, range) : values; } async validateSheet(spreadsheetId, sheetName, range, data = []) { const isParseValues = !Array.isArray(data), row = await this.getValuesInSheet(spreadsheetId, sheetName, range, isParseValues); if (!_.isEqual(row, data)) { return false; } return true; } async insertToSheet(spreadsheetId, sheetName, range, data = []) { const rangeQuery = `${sheetName}!${range}`, client = await this._getAuthClient(), res = await client.post( `${SHEET_ENDPOINT}/spreadsheets/${spreadsheetId}/values:batchUpdate`, { valueInputOption: 'RAW', data: [ { range: rangeQuery, values: data, }, ], }, false ); if (res.totalUpdatedRows && res.totalUpdatedRows === data.length) { return true; } console.error(res); throw new Error(`[insert]: Failed insert`); } async mergeCell(spreadsheetId, sheetId, range) { const {startColumnIndex, startRowIndex, endColumnIndex, endRowIndex} = GoogleSheetAPI.parseRange(range), client = await this._getAuthClient(), res = await client.post( `${SHEET_ENDPOINT}/spreadsheets/${spreadsheetId}:batchUpdate`, { requests: [ { mergeCells: { mergeType: 'MERGE_ALL', range: { sheetId, endRowIndex, endColumnIndex, startColumnIndex, startRowIndex, }, }, }, ], }, false ); if (res.error) { throw new Error(`${res.error.message}`); } } } export default GoogleSheetAPI;