@sheet2db/sdk 1.0.5 → 1.0.7

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 CHANGED
@@ -28,7 +28,7 @@ npm install @sheet2db/sdk
28
28
  ### Import and Initialize
29
29
 
30
30
  ```typescript
31
- import Sheet2DB, { Sheet2DBOptions } from 'sheet2db';
31
+ import { Sheet2DB,Sheet2DBOptions } from 'sheet2db';
32
32
 
33
33
  const options: Sheet2DBOptions = {
34
34
  mode: 'apikey',
package/dist/index.d.ts CHANGED
@@ -22,8 +22,12 @@ export type ReadOptions = {
22
22
  offset?: number;
23
23
  sheet?: string;
24
24
  format?: 'records' | 'dict' | 'series' | 'split' | 'index' | 'raw';
25
- cast_numbers?: string;
25
+ cast_numbers?: string[] | string;
26
26
  value_render?: "FORMATTED_VALUE" | "UNFORMATTED_VALUE" | "FORMULA";
27
+ columns?: string[] | string;
28
+ sort?: string;
29
+ sort_method?: 'date';
30
+ sort_date_format?: string;
27
31
  };
28
32
  export type GetKeysOptions = {
29
33
  sheet?: string;
@@ -112,7 +116,13 @@ export declare class Sheet2DB {
112
116
  DeleteWithQuery(options: DeleteWithQueryOptions): Promise<{
113
117
  deleted: number;
114
118
  }>;
115
- Clear(options: ClearSheetOptions): Promise<unknown>;
116
- CreateSheet(options: CreateSheetOptions): Promise<unknown>;
117
- DeleteSheet(options: DeleteSheetOptions): Promise<unknown>;
119
+ Clear(options: ClearSheetOptions): Promise<{
120
+ success: boolean;
121
+ }>;
122
+ CreateSheet(options: CreateSheetOptions): Promise<{
123
+ success: boolean;
124
+ }>;
125
+ DeleteSheet(options: DeleteSheetOptions): Promise<{
126
+ success: boolean;
127
+ }>;
118
128
  }
package/dist/index.js CHANGED
@@ -49,7 +49,7 @@ class Sheet2DB {
49
49
  }
50
50
  }
51
51
  }
52
- const response = await this.fetchFn(endpoint.toString(), {
52
+ const response = await this.fetchFn(endpoint.href, {
53
53
  headers,
54
54
  method,
55
55
  body: body ? JSON.stringify(body) : undefined
@@ -62,6 +62,12 @@ class Sheet2DB {
62
62
  }
63
63
  }
64
64
  ReadContent(options) {
65
+ if (options.columns && options.columns.constructor == Array) {
66
+ options.columns = options.columns.join(',');
67
+ }
68
+ if (options.cast_numbers && options.cast_numbers.constructor == Array) {
69
+ options.cast_numbers = options.cast_numbers.join(',');
70
+ }
65
71
  const query = new URLSearchParams(options);
66
72
  return this.fetch('', "GET", query);
67
73
  }
@@ -89,7 +95,7 @@ class Sheet2DB {
89
95
  Insert(options) {
90
96
  const { data, ...queryParams } = options;
91
97
  const query = new URLSearchParams(queryParams);
92
- return this.fetch('/', "POST", query, data);
98
+ return this.fetch('', "POST", query, data);
93
99
  }
94
100
  UpdateRow(options) {
95
101
  const { row, data, ...queryParams } = options;
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@sheet2db/sdk",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "test": "jest",
8
8
  "build":"tsc",
9
- "prepublish": "tsc"
9
+ "prepublish": "tsc && npm run test"
10
10
  },
11
11
  "exports":{
12
12
  ".":{
package/src/index.ts CHANGED
@@ -7,15 +7,15 @@ if (typeof window !== 'undefined' && typeof window.fetch !== 'undefined') {
7
7
  // We are in a Node.js environment
8
8
  fetchFunction = async (...args) => {
9
9
  const fetch = global.fetch;
10
- return fetch.apply(null,args)
10
+ return fetch.apply(null, args)
11
11
  };
12
12
  }
13
13
 
14
14
  export type Sheet2DBOptions = {
15
15
  mode: 'apikey';
16
- apiKey: string; // API to access public spreadsheets https://sheet2db.com/docs/public-spreadsheet
17
- spreadsheetId: string; // ID of the google spreadsheet
18
- version: "v1"; // Always v1
16
+ apiKey: string;
17
+ spreadsheetId: string;
18
+ version: "v1";
19
19
  fetchFn?: typeof fetch;
20
20
  } | {
21
21
  mode: 'connectionId';
@@ -27,7 +27,7 @@ export type Sheet2DBOptions = {
27
27
  jwtAuth?: {
28
28
  bearerToken: string;
29
29
  };
30
- version: "v1"; // Always v1
30
+ version: "v1";
31
31
  fetchFn?: typeof fetch;
32
32
  };
33
33
 
@@ -36,8 +36,12 @@ export type ReadOptions = {
36
36
  offset?: number;
37
37
  sheet?: string;
38
38
  format?: 'records' | 'dict' | 'series' | 'split' | 'index' | 'raw';
39
- cast_numbers?: string;
39
+ cast_numbers?: string[] | string;
40
40
  value_render?: "FORMATTED_VALUE" | "UNFORMATTED_VALUE" | "FORMULA";
41
+ columns?: string[] | string;
42
+ sort?: string;
43
+ sort_method?: 'date',
44
+ sort_date_format?: string;
41
45
  };
42
46
 
43
47
  export type GetKeysOptions = {
@@ -105,7 +109,6 @@ export type DeleteSheetOptions = {
105
109
  export class Sheet2DB {
106
110
 
107
111
  private apiEndpoint: string = "https://api.sheet2db.com";
108
- // private apiEndpoint: string = "http://localhost:8787";
109
112
  private fetchFn: typeof fetch;
110
113
 
111
114
  constructor(private readonly options: Sheet2DBOptions) {
@@ -136,12 +139,12 @@ export class Sheet2DB {
136
139
  });
137
140
  } else {
138
141
  endpoint.search = queryParams
139
- if(this.options.mode == 'apikey'){
142
+ if (this.options.mode == 'apikey') {
140
143
  endpoint.searchParams.set("__id", this.options.spreadsheetId);
141
144
  }
142
145
  }
143
146
  }
144
- const response = await this.fetchFn(endpoint.toString(), {
147
+ const response = await this.fetchFn(endpoint.href, {
145
148
  headers,
146
149
  method,
147
150
  body: body ? JSON.stringify(body) : undefined
@@ -153,7 +156,14 @@ export class Sheet2DB {
153
156
  }
154
157
  }
155
158
 
159
+
156
160
  ReadContent<T>(options?: ReadOptions) {
161
+ if (options.columns && options.columns.constructor == Array) {
162
+ options.columns = options.columns.join(',');
163
+ }
164
+ if (options.cast_numbers && options.cast_numbers.constructor == Array) {
165
+ options.cast_numbers = options.cast_numbers.join(',');
166
+ }
157
167
  const query = new URLSearchParams(options as Record<string, string>);
158
168
  return this.fetch<T>('', "GET", query);
159
169
  }
@@ -187,7 +197,7 @@ export class Sheet2DB {
187
197
  Insert(options: InsertOptions) {
188
198
  const { data, ...queryParams } = options;
189
199
  const query = new URLSearchParams(queryParams as Record<string, string>);
190
- return this.fetch<{ inserted: number }>('/', "POST", query, data);
200
+ return this.fetch<{ inserted: number }>('', "POST", query, data);
191
201
  }
192
202
 
193
203
  UpdateRow(options: UpdateRowOptions) {
@@ -231,16 +241,16 @@ export class Sheet2DB {
231
241
 
232
242
  Clear(options: ClearSheetOptions) {
233
243
  const path = `/clear/${options.sheet}`;
234
- return this.fetch(path, "DELETE");
244
+ return this.fetch<{success: boolean}>(path, "DELETE");
235
245
  }
236
246
 
237
247
  CreateSheet(options: CreateSheetOptions) {
238
248
  const query = new URLSearchParams(options as Record<string, string>);
239
- return this.fetch('/sheet', "POST", query);
249
+ return this.fetch<{success: boolean}>('/sheet', "POST", query);
240
250
  }
241
251
 
242
252
  DeleteSheet(options: DeleteSheetOptions) {
243
253
  const path = `/sheet/${options.sheet}`;
244
- return this.fetch(path, "DELETE");
254
+ return this.fetch<{success: boolean}>(path, "DELETE");
245
255
  }
246
256
  }
@@ -1,217 +1,334 @@
1
- import { describe, expect, test } from '@jest/globals';
2
- import {
3
- Sheet2DB,
4
- Sheet2DBOptions,
5
- ReadOptions,
6
- GetKeysOptions,
7
- GetCountOptions,
8
- GetRangeOptions,
9
- SearchOptions,
10
- InsertOptions,
11
- UpdateRowOptions,
12
- UpdateWithQueryOptions,
13
- BatchUpdateOptions,
14
- DeleteRowOptions,
15
- DeleteWithQueryOptions,
16
- ClearSheetOptions,
17
- CreateSheetOptions,
18
- DeleteSheetOptions,
19
- } from "../src";
20
-
21
- describe("Sheet2DB Class Tests", () => {
22
-
23
- describe("Tests with Connection ID", () => {
24
- const connectionIdOptions: Sheet2DBOptions = {
25
- connectionId: "608ae724-5285-42fd-a1d9-2e9fad3b22ee",
26
- // connectionId:"e90b9b28-64dd-4fcd-9be7-0c94edc9d897",
27
- version: "v1",
28
- mode: "connectionId"
29
- };
30
- const sheet2db = new Sheet2DB(connectionIdOptions);
31
-
32
- test("Read Content", async () => {
33
- let res = await sheet2db.ReadContent();
34
- expect(res).toBeDefined();
35
- // Add more specific checks based on known data structure
36
- });
37
-
38
- test("Get Keys", async () => {
39
- let res = await sheet2db.Keys();
40
- expect(res).toBeDefined();
41
- expect(res?.length).toBeGreaterThan(0);
42
- // Add more specific checks based on known data structure
43
- });
44
-
45
- test("Count", async () => {
46
- let res = await sheet2db.Count();
47
- expect(res).toBeDefined();
48
- expect(res?.count).toBeGreaterThanOrEqual(0);
49
- });
50
-
51
- test("Title", async () => {
52
- let res = await sheet2db.Title();
53
- expect(res).toBeDefined();
54
- expect(res?.spreadsheet_title).toBeTruthy();
55
- expect(res?.api_name).toBeTruthy();
56
- });
57
-
58
- test("Range", async () => {
59
- const rangeOptions: GetRangeOptions = {
60
- range: "A1:B2"
61
- };
62
- let res = await sheet2db.Range(rangeOptions);
63
- expect(res).toBeDefined();
64
- expect(res?.length).toBe(2);
65
- expect(res?.[0].length).toBe(2);
66
- });
67
-
68
- test("Search", async () => {
69
- const searchOptions: SearchOptions = {
70
- query: "Student Name=S*"
71
- };
72
- let res = await sheet2db.Search(searchOptions);
73
- expect(res.length).toBeGreaterThanOrEqual(1);
74
- // Add more specific checks based on known data structure
75
- });
76
-
77
- test("Insert", async () => {
78
- const insertOptions: InsertOptions = {
79
- data: { "Student Name": "Test" }
80
- };
81
- let res = await sheet2db.Insert(insertOptions);
82
- expect(res).toBeDefined();
83
- expect(res?.inserted).toBe(1);
84
- });
85
-
86
- test("UpdateRow", async () => {
87
- const updateRowOptions: UpdateRowOptions = {
88
- row: 31,
89
- data: { "Student Name": "Test0" }
90
- };
91
- let res = await sheet2db.UpdateRow(updateRowOptions);
92
- expect(res).toBeDefined();
93
- expect(res?.updated).toBe(1);
94
- });
95
-
96
- test("UpdateWithQuery", async () => {
97
- const updateWithQueryOptions: UpdateWithQueryOptions = {
98
- query: "Student Name=Test0",
99
- data: { "Age": 27 }
100
- };
101
- let res = await sheet2db.UpdateWithQuery(updateWithQueryOptions);
102
- expect(res).toBeDefined();
103
- expect(res?.updated).toBe(1);
104
- });
105
-
106
- test("BatchUpdate", async () => {
107
- const batchUpdateOptions: BatchUpdateOptions = {
108
- batches: [{ query: "Student Name=Test0", record: { Major: "updated value" } },{ query: "Student Name=Test0", record: { "Class Level": "3. Junior" } }]
109
- };
110
- let res = await sheet2db.BatchUpdate(batchUpdateOptions);
111
- expect(res).toBeDefined();
112
- expect(res?.updated).toBe(1);
113
- });
114
-
115
- test("DeleteRow", async () => {
116
- const deleteRowOptions: DeleteRowOptions = {
117
- row: 31
118
- };
119
- let res = await sheet2db.DeleteRow(deleteRowOptions);
120
- expect(res).toBeDefined();
121
- expect(res?.deleted).toBe(1);
122
- });
123
-
124
- test("DeleteWithQuery", async () => {
125
- const deleteWithQueryOptions: DeleteWithQueryOptions = {
126
- query: "Student Name=Test0"
127
- };
128
- let res = await sheet2db.DeleteWithQuery(deleteWithQueryOptions);
129
- expect(res).toBeDefined();
130
- expect(res?.deleted).toBe(0);
131
- });
132
-
133
- test("CreateSheet", async () => {
134
- const createSheetOptions: CreateSheetOptions = {
135
- title: "TestSheet"
136
- };
137
- let res = await sheet2db.CreateSheet(createSheetOptions);
138
- expect(res).toBeDefined();
139
- // Add specific assertions if return value is known
140
- });
141
-
142
- test("Clear", async () => {
143
- const clearOptions: ClearSheetOptions = {
144
- sheet: "TestSheet"
145
- };
146
- let res = await sheet2db.Clear(clearOptions);
147
- expect(res).toBeDefined();
148
- // Add specific assertions if return value is known
149
- });
150
-
151
- test("DeleteSheet", async () => {
152
- const deleteSheetOptions: DeleteSheetOptions = {
153
- sheet: "TestSheet"
154
- };
155
- let res = await sheet2db.DeleteSheet(deleteSheetOptions);
156
- expect(res).toBeDefined();
157
- // Add specific assertions if return value is known
158
- });
159
-
160
- });
161
-
162
- describe("Tests with API Key", () => {
163
- const apiKeyOptions: Sheet2DBOptions = {
164
- apiKey: "BmJrnOlf",
165
- spreadsheetId: "1H8t1vJkKTZzLkvVZwJZ5LlA0Fw6Hw2QY7kV1pLIJYo4",
166
- version: "v1",
167
- mode: "apikey"
168
- };
169
- const sheet2db = new Sheet2DB(apiKeyOptions);
170
-
171
- test("Read Content", async () => {
172
- let res = await sheet2db.ReadContent();
173
- expect(res).toBeDefined();
174
- // Add more specific checks based on known data structure
175
- });
176
-
177
- test("Get Keys", async () => {
178
- let res = await sheet2db.Keys();
179
- expect(res).toBeDefined();
180
- expect(res?.length).toBeGreaterThan(0);
181
- // Add more specific checks based on known data structure
182
- });
183
-
184
- test("Count", async () => {
185
- let res = await sheet2db.Count();
186
- expect(res).toBeDefined();
187
- expect(res?.count).toBeGreaterThanOrEqual(0);
188
- });
189
-
190
- test("Title", async () => {
191
- let res = await sheet2db.Title();
192
- expect(res).toBeDefined();
193
- expect(res?.spreadsheet_title).toBeTruthy();
194
- expect(res?.api_name).toBeTruthy();
195
- });
196
-
197
- test("Range", async () => {
198
- const rangeOptions: GetRangeOptions = {
199
- range: "A1:B2"
200
- };
201
- let res = await sheet2db.Range(rangeOptions);
202
- expect(res).toBeDefined();
203
- expect(res?.length).toBe(2);
204
- expect(res?.[0].length).toBe(2);
205
- });
206
-
207
- test("Search", async () => {
208
- const searchOptions: SearchOptions = {
209
- query: "search query"
210
- };
211
- let res = await sheet2db.Search(searchOptions);
212
- expect(res).toBeDefined();
213
- // Add more specific checks based on known data structure
214
- });
215
-
216
- })
217
- })
1
+ import { beforeEach, describe, expect, it, jest } from '@jest/globals';
2
+ import { Sheet2DB, Sheet2DBOptions, ReadOptions } from '../dist'; // Adjust the import path
3
+
4
+ const mockFetch = jest.fn(async () => {
5
+ return {
6
+ ok: true,
7
+ json: () => Promise.resolve({}),
8
+ text: () => Promise.resolve(''),
9
+ }
10
+ }) as jest.Mock<any>;
11
+
12
+ const apiKeyOptions: Sheet2DBOptions = {
13
+ mode: 'connectionId',
14
+ connectionId: 'test-spreadsheet-id',
15
+ version: 'v1',
16
+ //@ts-ignore
17
+ fetchFn: mockFetch
18
+ };
19
+
20
+ describe('Sheet2DB', () => {
21
+ let sheet2DB: Sheet2DB;
22
+
23
+ beforeEach(() => {
24
+ sheet2DB = new Sheet2DB(apiKeyOptions); // Create a new instance of Sheet2DB
25
+ jest.clearAllMocks(); // Reset mocks before each test
26
+ });
27
+
28
+ it('ReadContent', async () => {
29
+ // Arrange
30
+ const readOptions = {
31
+ limit: 10,
32
+ offset: 5,
33
+ sheet: 'Sheet1',
34
+ format: 'records' as const,
35
+ cast_numbers: ['col1'],
36
+ columns: ['col1', 'col2'],
37
+ value_render: 'FORMATTED_VALUE' as const,
38
+ }
39
+
40
+ // Act
41
+ await sheet2DB.ReadContent(readOptions);
42
+
43
+ // Assert
44
+ expect(mockFetch).toHaveBeenCalledTimes(1);
45
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
46
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
47
+ expect(calledUrl.pathname).toBe('/v1/test-spreadsheet-id');
48
+ expect(calledUrl.searchParams.get('limit')).toBe(readOptions.limit?.toString());
49
+ expect(calledUrl.searchParams.get('offset')).toBe(readOptions.offset?.toString());
50
+ expect(calledUrl.searchParams.get('sheet')).toBe(readOptions.sheet);
51
+ expect(calledUrl.searchParams.get('format')).toBe(readOptions.format);
52
+ expect(calledUrl.searchParams.get('columns')).toBe(readOptions.columns);
53
+ expect(calledUrl.searchParams.get('cast_numbers')).toBe(readOptions.cast_numbers);
54
+ expect(calledUrl.searchParams.get('value_render')).toBe(readOptions.value_render);
55
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
56
+ expect(options.method).toBe('GET');
57
+ });
58
+
59
+ it('Keys', async () => {
60
+ // Arrange
61
+ const keysOptions = {
62
+ sheet: 'Sheet1',
63
+ };
64
+
65
+ // Act
66
+ await sheet2DB.Keys(keysOptions);
67
+
68
+ // Assert
69
+ expect(mockFetch).toHaveBeenCalledTimes(1);
70
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
71
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
72
+ expect(calledUrl.pathname).toBe('/v1/test-spreadsheet-id/keys');
73
+ expect(calledUrl.searchParams.get('sheet')).toBe(keysOptions.sheet);
74
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
75
+ expect(options.method).toBe('GET');
76
+ })
77
+
78
+ it('Count', async () => {
79
+ // Arrange
80
+ const countOptions = {
81
+ sheet: 'Sheet1',
82
+ };
83
+
84
+ // Act
85
+ await sheet2DB.Count(countOptions);
86
+
87
+ // Assert
88
+ expect(mockFetch).toHaveBeenCalledTimes(1);
89
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
90
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
91
+ expect(calledUrl.pathname).toBe('/v1/test-spreadsheet-id/count');
92
+ expect(calledUrl.searchParams.get('sheet')).toBe(countOptions.sheet);
93
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
94
+ expect(options.method).toBe('GET');
95
+ })
96
+
97
+ it('Title', async () => {
98
+ // Act
99
+ await sheet2DB.Title();
100
+
101
+ // Assert
102
+ expect(mockFetch).toHaveBeenCalledTimes(1);
103
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
104
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
105
+ expect(calledUrl.pathname).toBe('/v1/test-spreadsheet-id/title');
106
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
107
+ expect(options.method).toBe('GET');
108
+ })
109
+
110
+ it('Range', async () => {
111
+ // Arrange
112
+ const rangeOptions = {
113
+ range: 'A1:B2',
114
+ }
115
+
116
+ // Act
117
+ await sheet2DB.Range(rangeOptions);
118
+
119
+ // Assert
120
+ expect(mockFetch).toHaveBeenCalledTimes(1);
121
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
122
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
123
+ expect(calledUrl.pathname).toBe(`/v1/test-spreadsheet-id/range/${rangeOptions.range}`);
124
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
125
+ expect(options.method).toBe('GET');
126
+ })
127
+
128
+ it('Search', async () => {
129
+ // Arrange
130
+ const searchOptions = {
131
+ sheet: 'Sheet1',
132
+ query: 'name=John',
133
+ or: true,
134
+ };
135
+
136
+ // Act
137
+ await sheet2DB.Search(searchOptions);
138
+
139
+ // Assert
140
+ expect(mockFetch).toHaveBeenCalledTimes(1);
141
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
142
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
143
+ expect(calledUrl.pathname).toBe(`/v1/test-spreadsheet-id/search_or/${searchOptions.sheet}`);
144
+ expect(decodeURIComponent(calledUrl.search)).toBe(`?${searchOptions.query}`);
145
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
146
+ expect(options.method).toBe('GET');
147
+ });
148
+
149
+ it('Insert', async () => {
150
+ // Arrange
151
+ const insertOptions = {
152
+ data: { name: 'John', age: 30 },
153
+ sheet: 'Sheet1',
154
+ };
155
+
156
+ // Act
157
+ await sheet2DB.Insert(insertOptions);
158
+
159
+ // Assert
160
+ expect(mockFetch).toHaveBeenCalledTimes(1);
161
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
162
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
163
+ expect(calledUrl.pathname).toBe('/v1/test-spreadsheet-id');
164
+ expect(calledUrl.searchParams.get('sheet')).toBe(insertOptions.sheet);
165
+ const otherOptions = mockFetch.mock.calls[0][1] as RequestInit;
166
+ expect(otherOptions.body).toBe(JSON.stringify(insertOptions.data))
167
+ expect(otherOptions.method).toBe('POST');
168
+ });
169
+
170
+ it('UpdateRow', async () => {
171
+ // Arrange
172
+ const updateRowOptions = {
173
+ data: { name: 'John', age: 30 },
174
+ row: 4,
175
+ sheet: 'Sheet1',
176
+ };
177
+
178
+ // Act
179
+ await sheet2DB.UpdateRow(updateRowOptions);
180
+
181
+ // Assert
182
+ expect(mockFetch).toHaveBeenCalledTimes(1);
183
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
184
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
185
+ expect(calledUrl.pathname).toBe(`/v1/test-spreadsheet-id/row/${updateRowOptions.row}`);
186
+ expect(calledUrl.searchParams.get('sheet')).toBe(updateRowOptions.sheet);
187
+ const otherOptions = mockFetch.mock.calls[0][1] as RequestInit;
188
+ expect(otherOptions.body).toBe(JSON.stringify(updateRowOptions.data))
189
+ expect(otherOptions.method).toBe('PATCH');
190
+ });
191
+
192
+ it('UpdateWithQuery', async () => {
193
+ // Arrange
194
+ const updateWithQueryOptions = {
195
+ sheet: 'Sheet1',
196
+ query: 'name=John',
197
+ data: { name: 'John Doe' },
198
+ };
199
+
200
+ // Act
201
+ await sheet2DB.UpdateWithQuery(updateWithQueryOptions);
202
+
203
+ // Assert
204
+ expect(mockFetch).toHaveBeenCalledTimes(1);
205
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
206
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
207
+ expect(calledUrl.pathname).toBe(`/v1/test-spreadsheet-id/${updateWithQueryOptions.sheet}`);
208
+ expect(decodeURIComponent(calledUrl.search)).toBe(`?${updateWithQueryOptions.query}`);
209
+ const otherOptions = mockFetch.mock.calls[0][1] as RequestInit;
210
+ expect(otherOptions.body).toBe(JSON.stringify(updateWithQueryOptions.data))
211
+ expect(otherOptions.method).toBe('PATCH');
212
+ });
213
+
214
+ it('BatchUpdate', async () => {
215
+ // Arrange
216
+ const batchUpdateOptions = {
217
+ sheet: 'Sheet1',
218
+ batches: [
219
+ { query: "name=John", record: { age: 21 } },
220
+ { query: "age>24", record: { name: "Jane Doe" } }
221
+ ],
222
+ };
223
+
224
+ // Act
225
+ await sheet2DB.BatchUpdate(batchUpdateOptions);
226
+
227
+ // Assert
228
+ expect(mockFetch).toHaveBeenCalledTimes(1);
229
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
230
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
231
+ expect(calledUrl.pathname).toBe(`/v1/test-spreadsheet-id/batch/${batchUpdateOptions.sheet}`);
232
+ const otherOptions = mockFetch.mock.calls[0][1] as RequestInit;
233
+ expect(otherOptions.body).toBe(JSON.stringify(batchUpdateOptions.batches))
234
+ expect(otherOptions.method).toBe('PATCH');
235
+ })
236
+
237
+ it('DeleteRow', async () => {
238
+ // Arrange
239
+ const deleteRowOptions = {
240
+ row: 4,
241
+ sheet: 'Sheet1',
242
+ };
243
+
244
+ // Act
245
+ await sheet2DB.DeleteRow(deleteRowOptions);
246
+
247
+ // Assert
248
+ expect(mockFetch).toHaveBeenCalledTimes(1);
249
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
250
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
251
+ expect(calledUrl.pathname).toBe('/v1/test-spreadsheet-id/row/4');
252
+ expect(calledUrl.searchParams.get('sheet')).toBe('Sheet1');
253
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
254
+ expect(options.method).toBe('DELETE');
255
+ });
256
+
257
+ it('DeleteWithQuery', async () => {
258
+ // Arrange
259
+ const deleteWithQueryOptions = {
260
+ query: "id=0",
261
+ sheet: 'Sheet1',
262
+ };
263
+
264
+ // Act
265
+ await sheet2DB.DeleteWithQuery(deleteWithQueryOptions);
266
+
267
+ // Assert
268
+ expect(mockFetch).toHaveBeenCalledTimes(1);
269
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
270
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
271
+ expect(calledUrl.pathname).toBe(`/v1/test-spreadsheet-id/${deleteWithQueryOptions.sheet}`);
272
+ expect(decodeURIComponent(calledUrl.search)).toBe(`?${deleteWithQueryOptions.query}`);
273
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
274
+ expect(options.method).toBe('DELETE');
275
+ })
276
+
277
+ it('Clear', async () => {
278
+ // Arrange
279
+ const clearOptions = {
280
+ sheet: 'Sheet1',
281
+ };
282
+
283
+ // Act
284
+ await sheet2DB.Clear(clearOptions);
285
+
286
+ // Assert
287
+ expect(mockFetch).toHaveBeenCalledTimes(1);
288
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
289
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
290
+ expect(calledUrl.pathname).toBe(`/v1/test-spreadsheet-id/clear/${clearOptions.sheet}`);
291
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
292
+ expect(options.method).toBe('DELETE');
293
+ })
294
+
295
+ it('Create Sheet', async () => {
296
+ // Arrange
297
+ const createSheetOptions = {
298
+ title: 'Sheet1',
299
+ };
300
+
301
+ // Act
302
+ await sheet2DB.CreateSheet(createSheetOptions);
303
+
304
+ // Assert
305
+ expect(mockFetch).toHaveBeenCalledTimes(1);
306
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
307
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
308
+ expect(calledUrl.pathname).toBe(`/v1/test-spreadsheet-id/sheet`);
309
+ expect(calledUrl.searchParams.get('title')).toBe(createSheetOptions.title);
310
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
311
+ expect(options.method).toBe('POST');
312
+ })
313
+
314
+ it('Delete Sheet', async ()=>{
315
+ // Arrange
316
+ const deleteSheetOptions = {
317
+ sheet: 'Sheet1',
318
+ };
319
+
320
+ // Act
321
+ await sheet2DB.DeleteSheet(deleteSheetOptions);
322
+
323
+ // Assert
324
+ expect(mockFetch).toHaveBeenCalledTimes(1);
325
+ const calledUrl = new URL(mockFetch.mock.calls[0][0] as string);
326
+ expect(calledUrl.origin).toBe('https://api.sheet2db.com');
327
+ expect(calledUrl.pathname).toBe(`/v1/test-spreadsheet-id/sheet/${deleteSheetOptions.sheet}`);
328
+ const options = mockFetch.mock.calls[0][1] as RequestInit;
329
+ expect(options.method).toBe('DELETE');
330
+ })
331
+
332
+
333
+ });
334
+