diff --git a/README.md b/README.md
index d905678..42bba3b 100644
--- a/README.md
+++ b/README.md
@@ -146,6 +146,35 @@ Cleared data will look like this:
A5 | B5 | C5 | D5 |
+#### Special Features
+When getting data you can set `firstRowAsHeader` as true to get data formatted as object with keys from first row. You can do it in constructor or in `get` method.
+
+Example normal response:
+```typescript
+[
+ ["A1", "B1", "C1", "D1"],
+ ["A2", "B2", "C2", "D2"],
+ ["A3", "B3", "C3", "D3"],
+]
+```
+Response with firstRowAsHeader set to true
+```typescript
+[
+ {
+ A1: "A2",
+ B1: "B2",
+ C1: "C2",
+ D1: "D2",
+ },
+ {
+ A1: "A3",
+ B1: "B3",
+ C1: "C3",
+ D1: "D3",
+ },
+]
+```
+
# Development setup
### Install dependencies
@@ -168,4 +197,4 @@ npm run test
Compiled JavaScript will be placed in `/build` folder.
-_Made by Michał Szajner_
\ No newline at end of file
+_Made by [Michał Szajner](https://github.com/M1chalS)_
\ No newline at end of file
diff --git a/package.json b/package.json
index a7e97fc..503793a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "sheets-simplified",
- "version": "1.0.0",
+ "version": "1.0.1",
"description": "TypeScript classes based package that eases and increases safety of working with Google Sheets API v4.",
"main": "./build/index.js",
"types": "./build/index.d.ts",
diff --git a/src/config/configurations.ts b/src/config/configurations.ts
index 45001c5..57f6ff9 100644
--- a/src/config/configurations.ts
+++ b/src/config/configurations.ts
@@ -6,6 +6,7 @@ export interface GetRequestConfiguration {
majorDimension?: Dimension;
valueRenderOption?: ValueRenderOption;
dateTimeRenderOption?: DateTimeRenderOption;
+ firstRowAsHeader?: boolean;
}
export interface AppendRequestConfiguration {
@@ -45,4 +46,5 @@ export interface Configuration {
includeValuesInResponse?: boolean;
responseDateTimeRenderOption?: DateTimeRenderOption;
responseValueRenderOption?: ValueRenderOption;
+ firstRowAsHeader?: boolean;
}
diff --git a/src/index.ts b/src/index.ts
index 396c090..2657088 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,2 +1,3 @@
export * from "./auth/google-sheets-auth";
-export * from "./sheets/sheets-connection";
\ No newline at end of file
+export * from "./sheets/sheets-connection"
+export * from "./types/types";
\ No newline at end of file
diff --git a/src/response-formatter/response-formatter.ts b/src/response-formatter/response-formatter.ts
new file mode 100644
index 0000000..4792936
--- /dev/null
+++ b/src/response-formatter/response-formatter.ts
@@ -0,0 +1,16 @@
+export const responseFormatter = (res: any) => {
+ const {data, ...rest } = res;
+
+ data.values = data.values.map((row: any[], index: number) => {
+ const newRow: any = {};
+ row.forEach((value: any, index: number) => {
+ newRow[data.values[0][index]] = value;
+ });
+ return newRow;
+ }).filter((val: any[], index: number) => index !== 0);
+
+ return {
+ data,
+ ...rest
+ }
+};
\ No newline at end of file
diff --git a/src/sheets/__tests__/sheets-connection.test.ts b/src/sheets/__tests__/sheets-connection.test.ts
index 3d83826..8652fbe 100644
--- a/src/sheets/__tests__/sheets-connection.test.ts
+++ b/src/sheets/__tests__/sheets-connection.test.ts
@@ -222,4 +222,111 @@ describe('Range logic checks', () => {
await expect(sheetsConnection.get({sheet: "Sheet2"})).rejects.toThrowError("Specify range or sheet in method or in constructor");
});
+});
+
+describe('Response formatter checks', () => {
+
+ test('Expect response to not be formatted', async () => {
+ const sheetsConnection = new SheetsConnection({
+ spreadsheetId: process.env.SHEET_ID!,
+ auth: googleAuthWrapper,
+ sheet: "Sheet1",
+ range: "A1:B"
+ });
+
+ await sheetsConnection.append([[
+ "test1",
+ "test2"
+ ], [
+ "test3",
+ "test4"
+ ]]);
+
+ const res = await sheetsConnection.get();
+
+ expect(res.data.values[0][0] === "test1").toBeTruthy();
+ expect(res.data.values[0][1] === "test2").toBeTruthy();
+ expect(res.data.values[1][0] === "test3").toBeTruthy();
+ expect(res.data.values[1][1] === "test4").toBeTruthy();
+
+ await sheetsConnection.clear();
+ });
+
+ test('Expect response to be formatted (set in constructor)', async () => {
+ const sheetsConnection = new SheetsConnection({
+ spreadsheetId: process.env.SHEET_ID!,
+ auth: googleAuthWrapper,
+ sheet: "Sheet1",
+ range: "A1:B",
+ firstRowAsHeader: true
+ });
+
+ await sheetsConnection.append([[
+ "test1",
+ "test2"
+ ], [
+ "test3",
+ "test4"
+ ]]);
+
+ const res = await sheetsConnection.get();
+
+ expect(res.data.values[0].test1 === "test3").toBeTruthy();
+ expect(res.data.values[0].test2 === "test4").toBeTruthy();
+
+ await sheetsConnection.clear();
+ });
+
+ test('Expect response to be formatted (set in method)', async () => {
+ const sheetsConnection = new SheetsConnection({
+ spreadsheetId: process.env.SHEET_ID!,
+ auth: googleAuthWrapper,
+ sheet: "Sheet1",
+ range: "A1:B",
+ });
+
+ await sheetsConnection.append([[
+ "test1",
+ "test2"
+ ], [
+ "test3",
+ "test4"
+ ]]);
+
+ const res = await sheetsConnection.get({
+ firstRowAsHeader: true
+ });
+
+ expect(res.data.values[0].test1 === "test3").toBeTruthy();
+ expect(res.data.values[0].test2 === "test4").toBeTruthy();
+
+ await sheetsConnection.clear();
+ });
+
+ test('Expect response to be formatted (set in both)', async () => {
+ const sheetsConnection = new SheetsConnection({
+ spreadsheetId: process.env.SHEET_ID!,
+ auth: googleAuthWrapper,
+ sheet: "Sheet1",
+ range: "A1:B",
+ firstRowAsHeader: true
+ });
+
+ await sheetsConnection.append([[
+ "test1",
+ "test2"
+ ], [
+ "test3",
+ "test4"
+ ]]);
+
+ const res = await sheetsConnection.get({
+ firstRowAsHeader: true
+ });
+
+ expect(res.data.values[0].test1 === "test3").toBeTruthy();
+ expect(res.data.values[0].test2 === "test4").toBeTruthy();
+
+ await sheetsConnection.clear();
+ });
});
\ No newline at end of file
diff --git a/src/sheets/sheets-connection.ts b/src/sheets/sheets-connection.ts
index 0b34d6f..07174b7 100644
--- a/src/sheets/sheets-connection.ts
+++ b/src/sheets/sheets-connection.ts
@@ -8,6 +8,7 @@ import {
GetRequestConfiguration,
UpdateRequestConfiguration
} from "../config/configurations";
+import {responseFormatter} from "../response-formatter/response-formatter";
export class SheetsConnection {
private sheets: sheets_v4.Sheets = google.sheets("v4");
@@ -24,6 +25,7 @@ export class SheetsConnection {
private readonly includeValuesInResponse: boolean;
private readonly responseDateTimeRenderOption: DateTimeRenderOption;
private readonly responseValueRenderOption: ValueRenderOption;
+ private readonly firstRowAsHeader: boolean;
public constructor(cfg: Configuration) {
this.spreadsheetId = cfg.spreadsheetId;
@@ -38,6 +40,7 @@ export class SheetsConnection {
this.includeValuesInResponse = cfg.includeValuesInResponse ?? false;
this.responseDateTimeRenderOption = cfg.responseDateTimeRenderOption ?? DateTimeRenderOption.FORMATTED_STRING;
this.responseValueRenderOption = cfg.responseValueRenderOption ?? ValueRenderOption.FORMATTED_VALUE;
+ this.firstRowAsHeader = cfg.firstRowAsHeader ?? false;
if (this.sheet && this.range) {
this.sheetRange = `${this.sheet}!${this.range}`;
@@ -47,7 +50,9 @@ export class SheetsConnection {
}
public get = async (cfg?: GetRequestConfiguration) => {
- return await this.sheets.spreadsheets.values.get(this.getRequestPayload(cfg));
+ const res = await this.sheets.spreadsheets.values.get(this.getRequestPayload(cfg));
+
+ return (this.firstRowAsHeader || cfg?.firstRowAsHeader) ? responseFormatter(res) : res;
};
public append = async (data: any[], cfg?: AppendRequestConfiguration) => {