google-sheets-automation 0.1.0 → 0.1.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 +109 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/providers/google.d.ts +2 -0
- package/dist/providers/google.js +2 -0
- package/dist/providers/googleProvider.d.ts +26 -0
- package/dist/providers/googleProvider.js +168 -0
- package/dist/providers/sheetClient.d.ts +21 -0
- package/dist/providers/sheetClient.js +29 -0
- package/dist/providers/types.d.ts +39 -0
- package/dist/providers/types.js +1 -0
- package/dist/utils/inputParser.d.ts +1 -0
- package/dist/utils/inputParser.js +9 -0
- package/package.json +19 -10
package/README.md
CHANGED
|
@@ -1,26 +1,38 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
<div align="center">
|
|
3
|
+
<img src="https://www.gstatic.com/images/icons/material/system/2x/sheets_googlegreen_48dp.png" width="64" alt="Google Sheets Logo" />
|
|
4
|
+
<h1>google-sheets-automation</h1>
|
|
5
|
+
<p>Automate Google Sheets from Node.js: add, update, and read rows with a simple API.</p>
|
|
6
|
+
</div>
|
|
3
7
|
|
|
4
|
-
|
|
8
|
+
---
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
- Add rows, update cells, batch updates
|
|
8
|
-
Automate populating and managing Google Sheets from Node.js. Usable in backend, CLI, or serverless environments.
|
|
9
|
-
- Accepts objects, arrays, or form data
|
|
10
|
-
- Simple, promise-based API
|
|
11
|
-
- Add rows, update cells, batch updates
|
|
12
|
-
- Google Sheets API support
|
|
13
|
-
- Accepts objects, arrays, or form data
|
|
14
|
-
- Simple, promise-based API
|
|
10
|
+
## Overview
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
`google-sheets-automation` is a Node.js package for programmatically managing Google Sheets. Easily add, update, and read rows using service account credentials. Designed for backend, CLI, and serverless environments.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
- Add rows with optional header mapping
|
|
16
|
+
- Update cells in bulk (A1 notation)
|
|
17
|
+
- Read sheet data as objects
|
|
18
|
+
- Batch operations
|
|
19
|
+
- Promise-based API
|
|
20
|
+
- Secure authentication via Google service accounts
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
18
25
|
npm install google-sheets-automation
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```js
|
|
19
31
|
import { GoogleSheetProvider } from 'google-sheets-automation';
|
|
20
32
|
|
|
21
33
|
const provider = new GoogleSheetProvider({
|
|
22
34
|
serviceAccount: {
|
|
23
|
-
|
|
35
|
+
client_email: 'your-service-account-email@project.iam.gserviceaccount.com',
|
|
24
36
|
private_key: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n',
|
|
25
37
|
},
|
|
26
38
|
sheetId: 'your-google-sheet-id',
|
|
@@ -37,9 +49,91 @@ const rows = [
|
|
|
37
49
|
{ name: 'Bob', email: 'bob@example.com', message: 'Hi!' },
|
|
38
50
|
];
|
|
39
51
|
|
|
40
|
-
await provider.addRows(
|
|
52
|
+
await provider.addRows({ spreadsheetId: 'your-google-sheet-id', sheetName: 'Sheet1', headerMap }, rows);
|
|
41
53
|
```
|
|
42
54
|
|
|
55
|
+
## Environment Setup
|
|
56
|
+
|
|
57
|
+
1. **Create a Google Cloud project** and enable the Google Sheets API.
|
|
58
|
+
2. **Create a service account** and download the JSON key.
|
|
59
|
+
3. **Share your target Google Sheet** with the service account email.
|
|
60
|
+
4. Store credentials in your `.env`:
|
|
61
|
+
```env
|
|
62
|
+
GOOGLE_SERVICE_ACCOUNT_EMAIL=your-service-account-email@project.iam.gserviceaccount.com
|
|
63
|
+
GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
|
|
64
|
+
GOOGLE_SHEET_ID=your-google-sheet-id
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API Reference
|
|
68
|
+
|
|
69
|
+
### GoogleSheetProvider
|
|
70
|
+
|
|
71
|
+
#### `addRows(options, rows)`
|
|
72
|
+
Add rows to a sheet. If `headerMap` is provided and the sheet is empty, headers are added automatically.
|
|
73
|
+
|
|
74
|
+
#### `updateCells(options)`
|
|
75
|
+
Update cells in a sheet using A1 notation and a 2D array of values.
|
|
76
|
+
|
|
77
|
+
#### `readData(options)`
|
|
78
|
+
Read all data from a sheet, returned as an array of objects (first row is used as keys).
|
|
79
|
+
|
|
80
|
+
#### `deleteRows(options)`
|
|
81
|
+
Delete rows by index (not yet implemented).
|
|
82
|
+
|
|
83
|
+
#### `createSheet(options)`
|
|
84
|
+
Create a new sheet (not yet implemented).
|
|
85
|
+
|
|
86
|
+
### Types
|
|
87
|
+
|
|
88
|
+
- `AddRowsOptions`: `{ spreadsheetId, sheetName, headerMap? }`
|
|
89
|
+
- `UpdateCellsOptions`: `{ spreadsheetId, sheetName, range?, values }`
|
|
90
|
+
- `ReadDataOptions`: `{ spreadsheetId, sheetName, range? }`
|
|
91
|
+
- `DeleteRowsOptions`: `{ spreadsheetId, sheetName, rowIndexes }`
|
|
92
|
+
- `CreateSheetOptions`: `{ spreadsheetId, sheetName }`
|
|
93
|
+
|
|
94
|
+
## Advanced Usage
|
|
95
|
+
|
|
96
|
+
### Update Cells Example
|
|
97
|
+
```js
|
|
98
|
+
await provider.updateCells({
|
|
99
|
+
spreadsheetId: 'your-google-sheet-id',
|
|
100
|
+
sheetName: 'Sheet1',
|
|
101
|
+
range: 'Sheet1!A2:B2',
|
|
102
|
+
values: [['Alice', 'alice@example.com']]
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Read Data Example
|
|
107
|
+
```js
|
|
108
|
+
const data = await provider.readData({
|
|
109
|
+
spreadsheetId: 'your-google-sheet-id',
|
|
110
|
+
sheetName: 'Sheet1'
|
|
111
|
+
});
|
|
112
|
+
console.log(data);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Testing
|
|
116
|
+
|
|
117
|
+
### Unit Tests
|
|
118
|
+
Run all unit tests (mocks Google API calls):
|
|
119
|
+
```bash
|
|
120
|
+
npm run test
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Integration Tests
|
|
124
|
+
Run integration tests against the real Google Sheets API (requires valid `.env` and sheet setup):
|
|
125
|
+
```bash
|
|
126
|
+
npm run test test/providers/googleProvider.integration.test.ts
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Contributing
|
|
130
|
+
|
|
131
|
+
Pull requests and issues are welcome! Please open an issue for feature requests or bugs.
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT
|
|
136
|
+
|
|
43
137
|
## Testing
|
|
44
138
|
Unit tests are written with Jest and mock all Google API calls, so no credentials are required:
|
|
45
139
|
```bash
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './providers/google';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './providers/google';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SheetRow, AddRowsOptions, UpdateCellsOptions, ReadDataOptions, DeleteRowsOptions, CreateSheetOptions } from './types';
|
|
2
|
+
export interface ISheetProvider {
|
|
3
|
+
addRows(options: AddRowsOptions, rows: SheetRow[]): Promise<void>;
|
|
4
|
+
updateCells(options: UpdateCellsOptions): Promise<void>;
|
|
5
|
+
readData(options: ReadDataOptions): Promise<SheetRow[]>;
|
|
6
|
+
deleteRows(options: DeleteRowsOptions): Promise<void>;
|
|
7
|
+
createSheet(options: CreateSheetOptions): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare class GoogleSheetProvider implements ISheetProvider {
|
|
10
|
+
private getBaseUrl;
|
|
11
|
+
private buildUrl;
|
|
12
|
+
private readonly credentials;
|
|
13
|
+
private _accessToken;
|
|
14
|
+
private _tokenExpiry;
|
|
15
|
+
constructor(credentials: any);
|
|
16
|
+
/**
|
|
17
|
+
* Get a valid access token, either from credentials or by generating from service account.
|
|
18
|
+
*/
|
|
19
|
+
private getAccessToken;
|
|
20
|
+
addRows(options: AddRowsOptions, rows: SheetRow[]): Promise<void>;
|
|
21
|
+
updateCells(options: UpdateCellsOptions): Promise<void>;
|
|
22
|
+
readData(options: ReadDataOptions): Promise<SheetRow[]>;
|
|
23
|
+
deleteRows(options: DeleteRowsOptions): Promise<void>;
|
|
24
|
+
createSheet(options: CreateSheetOptions): Promise<void>;
|
|
25
|
+
static mapHeaders(input: SheetRow, headerMap?: Record<string, string>): SheetRow;
|
|
26
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// Only import google-auth-library in Node.js
|
|
2
|
+
let GoogleAuth = undefined;
|
|
3
|
+
if (typeof process !== 'undefined' && process.versions?.node) {
|
|
4
|
+
try {
|
|
5
|
+
GoogleAuth = require('google-auth-library').GoogleAuth;
|
|
6
|
+
}
|
|
7
|
+
catch { }
|
|
8
|
+
}
|
|
9
|
+
export class GoogleSheetProvider {
|
|
10
|
+
getBaseUrl() {
|
|
11
|
+
return 'https://sheets.googleapis.com/v4/spreadsheets';
|
|
12
|
+
}
|
|
13
|
+
buildUrl(path, params) {
|
|
14
|
+
let url = `${this.getBaseUrl()}/${path}`;
|
|
15
|
+
if (params) {
|
|
16
|
+
const query = Object.entries(params)
|
|
17
|
+
.filter(([_, v]) => v !== undefined)
|
|
18
|
+
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
19
|
+
.join('&');
|
|
20
|
+
if (query)
|
|
21
|
+
url += `?${query}`;
|
|
22
|
+
}
|
|
23
|
+
return url;
|
|
24
|
+
}
|
|
25
|
+
constructor(credentials) {
|
|
26
|
+
this._accessToken = null;
|
|
27
|
+
this._tokenExpiry = null;
|
|
28
|
+
this.credentials = credentials;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get a valid access token, either from credentials or by generating from service account.
|
|
32
|
+
*/
|
|
33
|
+
async getAccessToken() {
|
|
34
|
+
if (this.credentials.accessToken) {
|
|
35
|
+
return this.credentials.accessToken;
|
|
36
|
+
}
|
|
37
|
+
// If service account credentials are provided (Node.js only)
|
|
38
|
+
if (GoogleAuth && this.credentials.private_key && this.credentials.client_email) {
|
|
39
|
+
if (this._accessToken && this._tokenExpiry && Date.now() < this._tokenExpiry - 60000) {
|
|
40
|
+
return this._accessToken;
|
|
41
|
+
}
|
|
42
|
+
const auth = new GoogleAuth({
|
|
43
|
+
credentials: this.credentials,
|
|
44
|
+
scopes: ['https://www.googleapis.com/auth/spreadsheets'],
|
|
45
|
+
});
|
|
46
|
+
const client = await auth.getClient();
|
|
47
|
+
const { token, res } = await client.getAccessToken();
|
|
48
|
+
let expiry = Date.now() + 50 * 60 * 1000;
|
|
49
|
+
if (res?.data?.expiry_date) {
|
|
50
|
+
expiry = res.data.expiry_date;
|
|
51
|
+
}
|
|
52
|
+
this._accessToken = token;
|
|
53
|
+
this._tokenExpiry = expiry;
|
|
54
|
+
return token;
|
|
55
|
+
}
|
|
56
|
+
throw new Error('No valid access token or service account credentials provided.');
|
|
57
|
+
}
|
|
58
|
+
async addRows(options, rows) {
|
|
59
|
+
const { spreadsheetId, sheetName, headerMap } = options;
|
|
60
|
+
const accessToken = await this.getAccessToken();
|
|
61
|
+
let values = [];
|
|
62
|
+
// If headerMap is passed and sheet is empty, add header row first
|
|
63
|
+
if (headerMap) {
|
|
64
|
+
// Check if sheet is empty by reading first row
|
|
65
|
+
const readUrl = this.buildUrl(`${spreadsheetId}/values/${encodeURIComponent(sheetName)}`, { majorDimension: 'ROWS', range: sheetName });
|
|
66
|
+
const readRes = await fetch(readUrl, {
|
|
67
|
+
method: 'GET',
|
|
68
|
+
headers: {
|
|
69
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
let sheetIsEmpty = true;
|
|
73
|
+
if (readRes.ok) {
|
|
74
|
+
const data = await readRes.json();
|
|
75
|
+
if (data.values && data.values.length > 0) {
|
|
76
|
+
sheetIsEmpty = false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (sheetIsEmpty) {
|
|
80
|
+
// Add header row
|
|
81
|
+
values.push(Object.values(headerMap));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Map headers if needed
|
|
85
|
+
const mappedRows = headerMap
|
|
86
|
+
? rows.map(row => GoogleSheetProvider.mapHeaders(row, headerMap))
|
|
87
|
+
: rows;
|
|
88
|
+
values = values.concat(mappedRows.map(row => Object.values(row)));
|
|
89
|
+
// Prepare API request
|
|
90
|
+
const url = this.buildUrl(`${spreadsheetId}/values/${encodeURIComponent(sheetName)}:append`, { valueInputOption: 'USER_ENTERED' });
|
|
91
|
+
const body = JSON.stringify({ values });
|
|
92
|
+
const res = await fetch(url, {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
headers: {
|
|
95
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
96
|
+
'Content-Type': 'application/json'
|
|
97
|
+
},
|
|
98
|
+
body
|
|
99
|
+
});
|
|
100
|
+
if (!res.ok) {
|
|
101
|
+
const err = await res.text();
|
|
102
|
+
throw new Error(`Google Sheets API error: ${res.status} ${err}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async updateCells(options) {
|
|
106
|
+
const { spreadsheetId, sheetName, range, values } = options;
|
|
107
|
+
const accessToken = await this.getAccessToken();
|
|
108
|
+
// values should be a 2D array matching the range
|
|
109
|
+
const url = this.buildUrl(`${spreadsheetId}/values/${encodeURIComponent(range || sheetName)}`, { valueInputOption: 'USER_ENTERED' });
|
|
110
|
+
const body = JSON.stringify({ values });
|
|
111
|
+
const res = await fetch(url, {
|
|
112
|
+
method: 'PUT',
|
|
113
|
+
headers: {
|
|
114
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
115
|
+
'Content-Type': 'application/json'
|
|
116
|
+
},
|
|
117
|
+
body
|
|
118
|
+
});
|
|
119
|
+
if (!res.ok) {
|
|
120
|
+
const err = await res.text();
|
|
121
|
+
throw new Error(`Google Sheets API error: ${res.status} ${err}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async readData(options) {
|
|
125
|
+
const { spreadsheetId, sheetName, range } = options;
|
|
126
|
+
const accessToken = await this.getAccessToken();
|
|
127
|
+
const url = this.buildUrl(`${spreadsheetId}/values/${encodeURIComponent(range || sheetName)}`, { majorDimension: 'ROWS' });
|
|
128
|
+
const res = await fetch(url, {
|
|
129
|
+
method: 'GET',
|
|
130
|
+
headers: {
|
|
131
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
if (!res.ok) {
|
|
135
|
+
const err = await res.text();
|
|
136
|
+
throw new Error(`Google Sheets API error: ${res.status} ${err}`);
|
|
137
|
+
}
|
|
138
|
+
const data = await res.json();
|
|
139
|
+
if (!data.values || data.values.length === 0)
|
|
140
|
+
return [];
|
|
141
|
+
// Assume first row is header
|
|
142
|
+
const headers = data.values[0];
|
|
143
|
+
const rows = [];
|
|
144
|
+
for (let i = 1; i < data.values.length; i++) {
|
|
145
|
+
const row = {};
|
|
146
|
+
for (let j = 0; j < headers.length; j++) {
|
|
147
|
+
row[headers[j]] = data.values[i][j];
|
|
148
|
+
}
|
|
149
|
+
rows.push(row);
|
|
150
|
+
}
|
|
151
|
+
return rows;
|
|
152
|
+
}
|
|
153
|
+
async deleteRows(options) {
|
|
154
|
+
// TODO: Implement row deletion logic
|
|
155
|
+
}
|
|
156
|
+
async createSheet(options) {
|
|
157
|
+
// TODO: Implement sheet creation logic
|
|
158
|
+
}
|
|
159
|
+
static mapHeaders(input, headerMap) {
|
|
160
|
+
if (!headerMap)
|
|
161
|
+
return input;
|
|
162
|
+
const mapped = {};
|
|
163
|
+
for (const key in input) {
|
|
164
|
+
mapped[headerMap[key] || key] = input[key];
|
|
165
|
+
}
|
|
166
|
+
return mapped;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SheetRow, AddRowsOptions, UpdateCellsOptions, ReadDataOptions, DeleteRowsOptions, CreateSheetOptions } from './types';
|
|
2
|
+
export interface ISheetClient {
|
|
3
|
+
addRows(options: AddRowsOptions, rows: SheetRow[]): Promise<void>;
|
|
4
|
+
updateCells(options: UpdateCellsOptions): Promise<void>;
|
|
5
|
+
readData(options: ReadDataOptions): Promise<SheetRow[]>;
|
|
6
|
+
deleteRows(options: DeleteRowsOptions): Promise<void>;
|
|
7
|
+
createSheet(options: CreateSheetOptions): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare class SheetClient implements ISheetClient {
|
|
10
|
+
private readonly provider;
|
|
11
|
+
constructor(config: {
|
|
12
|
+
provider: string;
|
|
13
|
+
credentials: any;
|
|
14
|
+
});
|
|
15
|
+
addRows(options: AddRowsOptions, rows: SheetRow[]): Promise<void>;
|
|
16
|
+
updateCells(options: UpdateCellsOptions): Promise<void>;
|
|
17
|
+
readData(options: ReadDataOptions): Promise<SheetRow[]>;
|
|
18
|
+
deleteRows(options: DeleteRowsOptions): Promise<void>;
|
|
19
|
+
createSheet(options: CreateSheetOptions): Promise<void>;
|
|
20
|
+
static mapHeaders(input: SheetRow, headerMap?: Record<string, string>): SheetRow;
|
|
21
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { GoogleSheetProvider } from './googleProvider';
|
|
2
|
+
export class SheetClient {
|
|
3
|
+
constructor(config) {
|
|
4
|
+
if (config.provider === 'google') {
|
|
5
|
+
this.provider = new GoogleSheetProvider(config.credentials);
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
throw new Error('Provider not supported');
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
addRows(options, rows) {
|
|
12
|
+
return this.provider.addRows(options, rows);
|
|
13
|
+
}
|
|
14
|
+
updateCells(options) {
|
|
15
|
+
return this.provider.updateCells(options);
|
|
16
|
+
}
|
|
17
|
+
readData(options) {
|
|
18
|
+
return this.provider.readData(options);
|
|
19
|
+
}
|
|
20
|
+
deleteRows(options) {
|
|
21
|
+
return this.provider.deleteRows(options);
|
|
22
|
+
}
|
|
23
|
+
createSheet(options) {
|
|
24
|
+
return this.provider.createSheet(options);
|
|
25
|
+
}
|
|
26
|
+
static mapHeaders(input, headerMap) {
|
|
27
|
+
return GoogleSheetProvider.mapHeaders(input, headerMap);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface SheetRow {
|
|
2
|
+
[key: string]: string | number | boolean | null;
|
|
3
|
+
}
|
|
4
|
+
export interface SheetRange {
|
|
5
|
+
startRow: number;
|
|
6
|
+
endRow: number;
|
|
7
|
+
startCol: number;
|
|
8
|
+
endCol: number;
|
|
9
|
+
}
|
|
10
|
+
export interface SheetOptions {
|
|
11
|
+
spreadsheetId: string;
|
|
12
|
+
sheetName: string;
|
|
13
|
+
}
|
|
14
|
+
export interface AddRowsOptions extends SheetOptions {
|
|
15
|
+
headerMap?: Record<string, string>;
|
|
16
|
+
}
|
|
17
|
+
export interface UpdateCellsOptions extends SheetOptions {
|
|
18
|
+
/**
|
|
19
|
+
* A1 notation range to update, e.g. "Sheet1!A2:B3". If omitted, uses sheetName.
|
|
20
|
+
*/
|
|
21
|
+
range?: string;
|
|
22
|
+
/**
|
|
23
|
+
* 2D array of values to write to the range.
|
|
24
|
+
*/
|
|
25
|
+
values: (string | number | boolean | null)[][];
|
|
26
|
+
}
|
|
27
|
+
export interface ReadDataOptions extends SheetOptions {
|
|
28
|
+
/**
|
|
29
|
+
* A1 notation range to read, e.g. "Sheet1!A2:B3". If omitted, uses sheetName.
|
|
30
|
+
*/
|
|
31
|
+
range?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface DeleteRowsOptions extends SheetOptions {
|
|
34
|
+
rowIndexes: number[];
|
|
35
|
+
}
|
|
36
|
+
export interface CreateSheetOptions {
|
|
37
|
+
spreadsheetId: string;
|
|
38
|
+
sheetName: string;
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseInput(input: any): any[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Utility to parse various input formats into rows for sheets
|
|
2
|
+
export function parseInput(input) {
|
|
3
|
+
if (Array.isArray(input))
|
|
4
|
+
return input;
|
|
5
|
+
if (typeof input === 'object')
|
|
6
|
+
return [input];
|
|
7
|
+
// Add more parsing logic as needed
|
|
8
|
+
throw new Error('Unsupported input format');
|
|
9
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "google-sheets-automation",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Automate Google Sheets from Node.js: add, update, and read rows with simple API. Supports service accounts, header mapping, and batch operations.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -16,18 +16,32 @@
|
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
18
|
"build": "tsc",
|
|
19
|
-
"test": "node --experimental-vm-modules node_modules/.bin/jest"
|
|
19
|
+
"test": "node --experimental-vm-modules node_modules/.bin/jest",
|
|
20
|
+
"test:unit": "npx jest --testPathIgnorePatterns=integration",
|
|
21
|
+
"test:integration": "npx jest --testPathPattern=integration"
|
|
20
22
|
},
|
|
21
23
|
"keywords": [
|
|
22
24
|
"google-sheets",
|
|
23
25
|
"spreadsheet",
|
|
24
26
|
"api",
|
|
25
27
|
"automation",
|
|
26
|
-
|
|
28
|
+
"nodejs",
|
|
27
29
|
"provider"
|
|
28
30
|
],
|
|
29
|
-
"author":
|
|
31
|
+
"author": {
|
|
32
|
+
"name": "Caesar Sage",
|
|
33
|
+
"email": "caesarsage@gmail.com",
|
|
34
|
+
"url": "https://github.com/CaesarSage"
|
|
35
|
+
},
|
|
30
36
|
"license": "MIT",
|
|
37
|
+
"homepage": "https://github.com/CaesarSage/google-sheets-automation#readme",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/CaesarSage/google-sheets-automation/issues"
|
|
40
|
+
},
|
|
41
|
+
"funding": {
|
|
42
|
+
"type": "github",
|
|
43
|
+
"url": "https://github.com/sponsors/CaesarSage"
|
|
44
|
+
},
|
|
31
45
|
"repository": {
|
|
32
46
|
"type": "git",
|
|
33
47
|
"url": "git+https://github.com/CaesarSage/google-sheets-automation.git"
|
|
@@ -35,17 +49,12 @@
|
|
|
35
49
|
"devDependencies": {
|
|
36
50
|
"@types/jest": "^30.0.0",
|
|
37
51
|
"@types/node": "^25.0.9",
|
|
38
|
-
"@types/react": "^19.2.9",
|
|
39
|
-
"@types/react-dom": "^19.2.3",
|
|
40
52
|
"dotenv": "^17.2.3",
|
|
41
53
|
"jest": "^30.2.0",
|
|
42
54
|
"ts-jest": "^29.4.6",
|
|
43
55
|
"typescript": "^5.0.0"
|
|
44
56
|
},
|
|
45
57
|
"dependencies": {
|
|
46
|
-
"google-auth-library": "^10.5.0"
|
|
47
|
-
"next": "^16.1.4",
|
|
48
|
-
"react": "^19.2.3",
|
|
49
|
-
"react-dom": "^19.2.3"
|
|
58
|
+
"google-auth-library": "^10.5.0"
|
|
50
59
|
}
|
|
51
60
|
}
|