UNPKG

@noloco/google-spreadsheet

Version:

Google Sheets API -- simple interface to read/write data and manage sheets

631 lines (549 loc) 22.1 kB
/* eslint-disable @typescript-eslint/no-unused-vars */ import { MakeOptional } from './util-types'; // some basic types which are just aliases, but they make the code a bit clearer export type Integer = number; export type SpreadsheetId = string; export type WorksheetId = number; export type DataSourceId = string; export type WorksheetIndex = number; export type RowOrColumnIndex = number; export type RowIndex = number; export type ColumnIndex = number; export type A1Address = string; export type ColumnAddress = string; export type A1Range = string; export type NamedRangeId = string; export type DeveloperMetadataId = number; export type DeveloperMetadataKey = string; export type DeveloperMetadataValue = string; /** * ISO language code * @example en * @example en_US * */ export type LocaleCode = string; /** * timezone code, if not recognized, may be a custom time zone such as `GMT-07:00` * @example America/New_York * */ export type Timezone = string; // ENUMS /////////////////////////////////////////////////////////////////////////////////////////////////// /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/sheets#SheetType */ export type WorksheetType = /** The sheet is a grid. */ 'GRID' | /** The sheet has no grid and instead has an object like a chart or image. */ 'OBJECT' | /** The sheet connects with an external DataSource and shows the preview of data. */ 'DATA_SOURCE'; export type WorksheetDimension = 'ROWS' | 'COLUMNS'; export type HyperlinkDisplayType = 'LINKED' | 'PLAIN_TEXT'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#numberformattype */ export type NumberFormatType = /** Text formatting, e.g 1000.12 */ 'TEXT' | /** Number formatting, e.g, 1,000.12 */ 'NUMBER' | /** Percent formatting, e.g 10.12% */ 'PERCENT' | /** Currency formatting, e.g $1,000.12 */ 'CURRENCY' | /** Date formatting, e.g 9/26/2008 */ 'DATE' | /** Time formatting, e.g 3:59:00 PM */ 'TIME' | /** Date+Time formatting, e.g 9/26/08 15:59:00 */ 'DATE_TIME' | /** Scientific number formatting, e.g 1.01E+03 */ 'SCIENTIFIC'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#errortype */ export type CellValueErrorType = /** Corresponds to the #ERROR! error */ 'ERROR' | /** Corresponds to the #NULL! error. */ 'NULL_VALUE' | /** Corresponds to the #DIV/0 error. */ 'DIVIDE_BY_ZERO' | /** Corresponds to the #VALUE! error. */ 'VALUE' | /** Corresponds to the #REF! error. */ 'REF' | /** Corresponds to the #NAME? error. */ 'NAME' | /** Corresponds to the #NUM! error. */ 'NUM' | /** Corresponds to the #N/A error. */ 'N_A' | /** Corresponds to the Loading... state. */ 'LOADING'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#horizontalalign */ export type HorizontalAlign = 'LEFT' | 'CENTER' | 'RIGHT'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#verticalalign */ export type VerticalAlign = 'TOP' | 'MIDDLE' | 'BOTTOM'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#textdirection */ export type TextDirection = 'LEFT_TO_RIGHT' | 'RIGHT_TO_LEFT'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#wrapstrategy */ export type WrapStrategy = 'OVERFLOW_CELL' | 'LEGACY_WRAP' | 'CLIP' | 'WRAP'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#themecolortype */ export type ThemeColorType = 'TEXT' | 'BACKGROUND' | 'ACCENT1' | 'ACCENT2' | 'ACCENT3' | 'ACCENT4' | 'ACCENT5' | 'ACCENT6' | 'LINK'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets#recalculationinterval */ export type RecalculationInterval = 'ON_CHANGE' | 'MINUTE' | 'HOUR'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.developerMetadata#developermetadatavisibility */ export type DeveloperMetadataVisibility = /** Document-visible metadata is accessible from any developer project with access to the document. */ | 'DOCUMENT' /** Project-visible metadata is only visible to and accessible by the developer project that created the metadata. */ | 'PROJECT'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.developerMetadata#developermetadatalocationtype */ export type DeveloperMetadataLocationType = 'ROW' | 'COLUMN' | 'SHEET' | 'SPREADSHEET'; export type DeveloperMetadataLookup = { locationType: DeveloperMetadataLocationType, metadataLocation: DeveloperMetadataLocation, locationMatchingStrategy: 'EXACT_LOCATION' | 'INTERSECTING_LOCATION' metadataId: DeveloperMetadataId, metadataKey: DeveloperMetadataKey, metadataValue: DeveloperMetadataValue, visibility: DeveloperMetadataVisibility }; // formatting types export type TextFormat = { foregroundColor?: Color; foregroundColorStyle?: ColorStyle; fontFamily?: string; fontSize?: number; bold?: boolean; italic?: boolean; strikethrough?: boolean; underline?: boolean; }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#Style */ export type CellBorderLineStyle = 'NONE' | 'DOTTED' | 'DASHED' | 'SOLID' | 'SOLID_MEDIUM' | 'SOLID_THICK' | 'DOUBLE'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#Border */ export type CellBorder = { style: CellBorderLineStyle; width: number; color: Color; colorStyle: ColorStyle; }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#Borders */ export type CellBorders = { top: CellBorder; bottom: CellBorder; left: CellBorder; right: CellBorder; }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#Padding */ export type CellPadding = { top: number; bottom: number; left: number; right: number; }; export type TextRotation = { angle: number; vertical: boolean; }; export type ThemeColorPair = { color: ColorStyle; colorType: ThemeColorType; }; export type SpreadsheetTheme = { primaryFontFamily: string; themeColors: ThemeColorPair[]; }; // --------------------------------- export type PaginationOptions = { limit: number; offset: number; }; /** * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets#iterativecalculationsettings */ export type IterativeCalculationSetting = { maxIterations: number; convergenceThreshold: number; }; export type DimensionRangeIndexes = { startIndex: RowOrColumnIndex; endIndex: RowOrColumnIndex; }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.developerMetadata#DeveloperMetadata.DeveloperMetadataLocation */ export interface DeveloperMetadataLocation { sheetId: number; spreadsheet: boolean; dimensionRange: DimensionRange; locationType: DeveloperMetadataLocationType; } /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.developerMetadata#DeveloperMetadata.DeveloperMetadataLocation */ export interface DeveloperMetadata { metadataId: number; metadataKey: string; metadataValue: string; location: DeveloperMetadataLocation; visibility: DeveloperMetadataVisibility; } export interface WorksheetDimensionProperties { pixelSize: number; hiddenByUser: boolean; hiddenByFilter: boolean; /** * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.developerMetadata#DeveloperMetadata */ developerMetadata: DeveloperMetadata[]; } /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#DataSourceColumnReference */ type DataSourceColumnReference = { name: string; }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#DataSourceColumn */ type DataSourceColumn = { reference: DataSourceColumnReference, formula: string }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#DataExecutionState */ type DataExecutionState = /** The data execution has not started. */ 'NOT_STARTED' | /** The data execution has started and is running. */ 'RUNNING' | /** The data execution has completed successfully. */ 'SUCCEEDED' | /** The data execution has completed with errors. */ 'FAILED'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#DataExecutionState */ type DataExecutionErrorCode = /** Default value, do not use. */ 'DATA_EXECUTION_ERROR_CODE_UNSPECIFIED' | /** The data execution timed out. */ 'TIMED_OUT' | /** The data execution returns more rows than the limit. */ 'TOO_MANY_ROWS' | /** The data execution returns more columns than the limit. */ 'TOO_MANY_COLUMNS' | /** The data execution returns more cells than the limit. */ 'TOO_MANY_CELLS' | /** Error is received from the backend data execution engine (e.g. BigQuery). Check errorMessage for details. */ 'ENGINE' | /** One or some of the provided data source parameters are invalid. */ 'PARAMETER_INVALID' | /** The data execution returns an unsupported data type. */ 'UNSUPPORTED_DATA_TYPE' | /** The data execution returns duplicate column names or aliases. */ 'DUPLICATE_COLUMN_NAMES' | /** The data execution is interrupted. Please refresh later. */ 'INTERRUPTED' | /** The data execution is currently in progress, can not be refreshed until it completes. */ 'CONCURRENT_QUERY' | /** Other errors. */ 'OTHER' | /** The data execution returns values that exceed the maximum characters allowed in a single cell. */ 'TOO_MANY_CHARS_PER_CELL' | /** The database referenced by the data source is not found. */ 'DATA_NOT_FOUND' | /** The user does not have access to the database referenced by the data source. */ 'PERMISSION_DENIED' | /** The data execution returns columns with missing aliases. */ 'MISSING_COLUMN_ALIAS' | /** The data source object does not exist. */ 'OBJECT_NOT_FOUND' | /** The data source object is currently in error state. To force refresh, set force in RefreshDataSourceRequest . */ 'OBJECT_IN_ERROR_STATE' | /** The data source object specification is invalid. */ 'OBJECT_SPEC_INVALID'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#DataExecutionStatus */ type DataExecutionStatus = { 'state': DataExecutionState, 'errorCode': DataExecutionErrorCode, 'errorMessage': string, 'lastRefreshTime': string }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/sheets#DataSourceSheetProperties */ export type DataSourceSheetProperties = { 'dataSourceId': DataSourceId 'columns': DataSourceColumn[], 'dataExecutionStatus': DataExecutionStatus, }; // Spreadsheet types ///////////////////// /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets#SpreadsheetProperties */ export type SpreadsheetProperties = { /** title of the spreadsheet */ title: string, /** locale of the spreadsheet (note - not all locales are supported) */ locale: LocaleCode, /** amount of time to wait before volatile functions are recalculated */ autoRecalc: RecalculationInterval, /** timezone of the sheet */ timeZone: Timezone; // TODO defaultFormat: any iterativeCalculationSettings: any, spreadsheetTheme: any }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/sheets#SheetProperties */ export type WorksheetProperties = { 'sheetId': WorksheetId, 'title': string, 'index': WorksheetIndex, 'sheetType': WorksheetType, 'gridProperties': WorksheetGridProperties, 'hidden': boolean, 'tabColor': Color, 'tabColorStyle': ColorStyle, 'rightToLeft': boolean, 'dataSourceSheetProperties': DataSourceSheetProperties }; export type WorksheetPropertiesPartial = { }; // Spreadsheet Cell types /////////////////// /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#CellFormat */ export type CellFormat = { /** format describing how number values should be represented to the user */ numberFormat: NumberFormat, /** @deprecated use backgroundColorStyle */ backgroundColor: Color, backgroundColorStyle: ColorStyle, borders: CellBorders, padding: CellPadding, horizontalAlignment: HorizontalAlign, verticalAlignment: VerticalAlign, wrapStrategy: WrapStrategy, textDirection: TextDirection, textFormat: TextFormat hyperlinkDisplayType: HyperlinkDisplayType, textRotation: TextRotation, }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#numberformat */ export type NumberFormat = { type: NumberFormatType; /** * pattern string used for formatting * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#numberformat * */ pattern: string; }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/sheets#GridProperties */ export type WorksheetGridProperties = { rowCount: number; columnCount: number; frozenRowCount?: number; frozenColumnCount?: number; hideGridlines?: boolean; rowGroupControlAfter?: boolean; columnGroupControlAfter?: boolean; }; // /** * * @see https://developers.google.com/sheets/api/reference/rest/v4/DimensionRange */ export type DimensionRange = { sheetId: WorksheetId, dimension: WorksheetDimension, startIndex?: Integer, endIndex?: Integer, }; export type DimensionRangeWithoutWorksheetId = Omit<DimensionRange, 'sheetId'>; /** * object describing a range in a sheet * see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#GridRange * */ export type GridRange = { /** The sheet this range is on */ sheetId: WorksheetId, /** The start row (inclusive) of the range, or not set if unbounded. */ startRowIndex?: Integer, /** The end row (exclusive) of the range, or not set if unbounded. */ endRowIndex?: Integer, /** The start column (inclusive) of the range, or not set if unbounded. */ startColumnIndex?: Integer, /** The end column (exclusive) of the range, or not set if unbounded. */ endColumnIndex?: Integer }; export type GridRangeWithoutWorksheetId = Omit<GridRange, 'sheetId'>; export type GridRangeWithOptionalWorksheetId = MakeOptional<GridRange, 'sheetId'>; export type DataFilter = A1Range | GridRange; export type DataFilterWithoutWorksheetId = A1Range | GridRangeWithoutWorksheetId; export type DeveloperMetadataDataFilter = { a1Range?: A1Range, gridRange?: GridRange, developerMetadataLookup?: DeveloperMetadataLookup, }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#colorstyle */ export type ColorStyle = { rgbColor: Color } | { themeColor: ThemeColorType }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#Color */ export type Color = { red: number, green: number, blue: number, /** docs say alpha is not generally supported? */ alpha?: number }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/ValueRenderOption */ type ValueRenderOption = /** Values will be calculated & formatted in the reply according to the cell's formatting. Formatting is based on the spreadsheet's locale, not the requesting user's locale. For example, if A1 is 1.23 and A2 is =A1 and formatted as currency, then A2 would return "$1.23". */ 'FORMATTED_VALUE' | /** Values will be calculated, but not formatted in the reply. For example, if A1 is 1.23 and A2 is =A1 and formatted as currency, then A2 would return the number 1.23. */ 'UNFORMATTED_VALUE' | /** Values will not be calculated. The reply will include the formulas. For example, if A1 is 1.23 and A2 is =A1 and formatted as currency, then A2 would return "=A1". */ 'FORMULA'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/DateTimeRenderOption */ type DateTimeRenderOption = /** Instructs date, time, datetime, and duration fields to be output as doubles in "serial number" format, as popularized by Lotus 1-2-3. The whole number portion of the value (left of the decimal) counts the days since December 30th 1899. The fractional portion (right of the decimal) counts the time as a fraction of the day. For example, January 1st 1900 at noon would be 2.5, 2 because it's 2 days after December 30th 1899, and .5 because noon is half a day. February 1st 1900 at 3pm would be 33.625. This correctly treats the year 1900 as not a leap year. */ 'SERIAL_NUMBER' | /** Instructs date, time, datetime, and duration fields to be output as strings in their given number format (which depends on the spreadsheet locale). */ 'FORMATTED_STRING'; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get#query-parameters */ export type GetValuesRequestOptions = { majorDimension?: WorksheetDimension, valueRenderOption?: ValueRenderOption }; /** * Info about an error in a cell * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#errortype */ export type ErrorValue = { type: CellValueErrorType, message: string }; /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ExtendedValue */ export type ExtendedValue = { numberValue: number } | { stringValue: string } | { boolValue: boolean } | { formulaValue: string } | { errorValue: ErrorValue }; export type CellValueType = 'boolValue' | 'stringValue' | 'numberValue' | 'errorValue'; //------------------------------------ /** @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells */ export type CellData = { /** The value the user entered in the cell. e.g., 1234, 'Hello', or =NOW() Note: Dates, Times and DateTimes are represented as doubles in serial number format. */ userEnteredValue: ExtendedValue, /** The effective value of the cell. For cells with formulas, this is the calculated value. For cells with literals, this is the same as the userEnteredValue. This field is read-only. */ effectiveValue: ExtendedValue, /** The formatted value of the cell. This is the value as it's shown to the user. This field is read-only. */ formattedValue: string, /** The format the user entered for the cell. */ userEnteredFormat: CellFormat, /** The effective format being used by the cell. This includes the results of applying any conditional formatting and, if the cell contains a formula, the computed number format. If the effective format is the default format, effective format will not be written. This field is read-only. */ effectiveFormat: CellFormat, /** The data validation rule applied to the cell. */ dataValidation: DataValidationRule, /** hyperlink in the cell if any */ hyperlink?: string, /** note on the cell */ note?: string, // textFormatRuns: [ // { // object (TextFormatRun) // } // ], // dataValidation: { // object (DataValidationRule) // }, // pivotTable: { // object (PivotTable) // }, // dataSourceTable: { // object (DataSourceTable) // }, // dataSourceFormula: { // object (DataSourceFormula) // } }; /** shape of the cell data sent back when fetching the sheet */ export type CellDataRange = { startRow?: RowIndex, startColumn?: ColumnIndex, // TODO: fix these types rowMetadata: any[], columnMetadata: any[], rowData: { values: any[] }[] }; export type AddRowOptions = { /** set to true to use raw mode rather than user entered */ raw?: boolean, /** set to true to insert new rows in the sheet while adding this data */ insert?: boolean, }; /** * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ConditionType */ export type ConditionType = | 'NUMBER_GREATER' | 'NUMBER_GREATER_THAN_EQ' | 'NUMBER_LESS' | 'NUMBER_LESS_THAN_EQ' | 'NUMBER_EQ' | 'NUMBER_NOT_EQ' | 'NUMBER_BETWEEN' | 'NUMBER_NOT_BETWEEN' | 'TEXT_CONTAINS' | 'TEXT_NOT_CONTAINS' | 'TEXT_STARTS_WITH' | 'TEXT_ENDS_WITH' | 'TEXT_EQ' | 'TEXT_IS_EMAIL' | 'TEXT_IS_URL' | 'DATE_EQ' | 'DATE_BEFORE' | 'DATE_AFTER' | 'DATE_ON_OR_BEFORE' | 'DATE_ON_OR_AFTER' | 'DATE_BETWEEN' | 'DATE_NOT_BETWEEN' | 'DATE_IS_VALID' | 'ONE_OF_RANGE' | 'ONE_OF_LIST' | 'BLANK' | 'NOT_BLANK' | 'CUSTOM_FORMULA' | 'BOOLEAN' | 'TEXT_NOT_EQ' | 'DATE_NOT_EQ' | 'FILTER_EXPRESSION'; /** * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#relativedate */ export type RelativeDate = | 'PAST_YEAR' | 'PAST_MONTH' | 'PAST_WEEK' | 'YESTERDAY' | 'TODAY' | 'TOMORROW'; /** * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ConditionValue */ export type ConditionValue = | { relativeDate: RelativeDate, userEnteredValue?: undefined } | { relativeDate?: undefined, userEnteredValue: string }; /** * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#BooleanCondition */ export type BooleanCondition = { /** The type of condition. */ type: ConditionType; /** * The values of the condition. * The number of supported values depends on the condition type. Some support zero values, others one or two values, and ConditionType.ONE_OF_LIST supports an arbitrary number of values. */ values: ConditionValue[]; }; /** * @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#DataValidationRule * * example: * - https://stackoverflow.com/a/43442775/3068233 */ export type DataValidationRule = { /** The condition that data in the cell must match. */ condition: BooleanCondition; /** A message to show the user when adding data to the cell. */ inputMessage?: string; /** True if invalid data should be rejected. */ strict: boolean; /** True if the UI should be customized based on the kind of condition. If true, "List" conditions will show a dropdown. */ showCustomUi: boolean; };