@sheet2db/sdk 1.0.0
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/dist/index.cjs.d.ts +2 -0
- package/dist/index.cjs.js +6 -0
- package/dist/index.d.ts +118 -0
- package/dist/index.js +182 -0
- package/jest.config.js +5 -0
- package/package.json +28 -0
- package/src/index.cjs.ts +2 -0
- package/src/index.ts +246 -0
- package/tests/index.test.ts +216 -0
- package/tsconfig.json +16 -0
package/dist/index.d.ts
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
export type Sheet2DBOptions = {
|
2
|
+
mode: 'apikey';
|
3
|
+
apiKey: string;
|
4
|
+
spreadsheetId: string;
|
5
|
+
version: "v1";
|
6
|
+
fetchFn?: typeof fetch;
|
7
|
+
} | {
|
8
|
+
mode: 'connectionId';
|
9
|
+
connectionId: string;
|
10
|
+
basicAuth?: {
|
11
|
+
username: string;
|
12
|
+
password: string;
|
13
|
+
};
|
14
|
+
jwtAuth?: {
|
15
|
+
bearerToken: string;
|
16
|
+
};
|
17
|
+
version: "v1";
|
18
|
+
fetchFn?: typeof fetch;
|
19
|
+
};
|
20
|
+
export type ReadOptions = {
|
21
|
+
limit?: number;
|
22
|
+
offset?: number;
|
23
|
+
sheet?: string;
|
24
|
+
format?: 'records' | 'dict' | 'series' | 'split' | 'index' | 'raw';
|
25
|
+
cast_numbers?: string;
|
26
|
+
value_render?: "FORMATTED_VALUE" | "UNFORMATTED_VALUE" | "FORMULA";
|
27
|
+
};
|
28
|
+
export type GetKeysOptions = {
|
29
|
+
sheet?: string;
|
30
|
+
};
|
31
|
+
export type GetCountOptions = {
|
32
|
+
sheet?: string;
|
33
|
+
};
|
34
|
+
export type GetRangeOptions = {
|
35
|
+
range: string;
|
36
|
+
};
|
37
|
+
export type SearchOptions = {
|
38
|
+
sheet?: string;
|
39
|
+
or?: boolean;
|
40
|
+
query: string;
|
41
|
+
};
|
42
|
+
export type InsertOptions = {
|
43
|
+
data: Record<string, any> | Record<string, any>[];
|
44
|
+
sheet?: string;
|
45
|
+
};
|
46
|
+
export type UpdateRowOptions = {
|
47
|
+
row: number;
|
48
|
+
sheet?: string;
|
49
|
+
data: Record<string, any>;
|
50
|
+
};
|
51
|
+
export type UpdateWithQueryOptions = {
|
52
|
+
sheet?: string;
|
53
|
+
query: string;
|
54
|
+
data: Record<string, any>;
|
55
|
+
};
|
56
|
+
export type BatchUpdateOptions = {
|
57
|
+
sheet?: string;
|
58
|
+
batches: {
|
59
|
+
query: string;
|
60
|
+
record: Record<string, any>;
|
61
|
+
}[];
|
62
|
+
};
|
63
|
+
export type DeleteRowOptions = {
|
64
|
+
sheet?: string;
|
65
|
+
row: number;
|
66
|
+
};
|
67
|
+
export type DeleteWithQueryOptions = {
|
68
|
+
sheet?: string;
|
69
|
+
query: string;
|
70
|
+
};
|
71
|
+
export type ClearSheetOptions = {
|
72
|
+
sheet: string;
|
73
|
+
};
|
74
|
+
export type CreateSheetOptions = {
|
75
|
+
title?: string;
|
76
|
+
};
|
77
|
+
export type DeleteSheetOptions = {
|
78
|
+
sheet: string;
|
79
|
+
};
|
80
|
+
export default class Sheet2DB {
|
81
|
+
private readonly options;
|
82
|
+
private apiEndpoint;
|
83
|
+
private fetchFn;
|
84
|
+
constructor(options: Sheet2DBOptions);
|
85
|
+
private fetch;
|
86
|
+
ReadContent<T>(options?: ReadOptions): Promise<T>;
|
87
|
+
Keys(options?: GetKeysOptions): Promise<string[]>;
|
88
|
+
Count(options?: GetCountOptions): Promise<{
|
89
|
+
count: number;
|
90
|
+
}>;
|
91
|
+
Title(): Promise<{
|
92
|
+
spreadsheet_title: string;
|
93
|
+
api_name: string;
|
94
|
+
}>;
|
95
|
+
Range(options: GetRangeOptions): Promise<string[][]>;
|
96
|
+
Search(options: SearchOptions): Promise<Record<string, any>>;
|
97
|
+
Insert(options: InsertOptions): Promise<{
|
98
|
+
inserted: number;
|
99
|
+
}>;
|
100
|
+
UpdateRow(options: UpdateRowOptions): Promise<{
|
101
|
+
updated: number;
|
102
|
+
}>;
|
103
|
+
UpdateWithQuery(options: UpdateWithQueryOptions): Promise<{
|
104
|
+
updated: number;
|
105
|
+
}>;
|
106
|
+
BatchUpdate(options: BatchUpdateOptions): Promise<{
|
107
|
+
updated: number;
|
108
|
+
}>;
|
109
|
+
DeleteRow(options: DeleteRowOptions): Promise<{
|
110
|
+
deleted: number;
|
111
|
+
}>;
|
112
|
+
DeleteWithQuery(options: DeleteWithQueryOptions): Promise<{
|
113
|
+
deleted: number;
|
114
|
+
}>;
|
115
|
+
Clear(options: ClearSheetOptions): Promise<unknown>;
|
116
|
+
CreateSheet(options: CreateSheetOptions): Promise<unknown>;
|
117
|
+
DeleteSheet(options: DeleteSheetOptions): Promise<unknown>;
|
118
|
+
}
|
package/dist/index.js
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
32
|
+
});
|
33
|
+
};
|
34
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
35
|
+
var t = {};
|
36
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
37
|
+
t[p] = s[p];
|
38
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
39
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
40
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
41
|
+
t[p[i]] = s[p[i]];
|
42
|
+
}
|
43
|
+
return t;
|
44
|
+
};
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
46
|
+
let fetchFunction;
|
47
|
+
if (typeof window !== 'undefined' && typeof window.fetch !== 'undefined') {
|
48
|
+
// We are in a browser environment
|
49
|
+
fetchFunction = window.fetch.bind(window);
|
50
|
+
}
|
51
|
+
else {
|
52
|
+
// We are in a Node.js environment
|
53
|
+
//@ts-ignore
|
54
|
+
fetchFunction = (...args) => __awaiter(void 0, void 0, void 0, function* () {
|
55
|
+
const fetch = yield Promise.resolve().then(() => __importStar(require('node-fetch')));
|
56
|
+
//@ts-ignore
|
57
|
+
return fetch.default(...args);
|
58
|
+
});
|
59
|
+
}
|
60
|
+
class Sheet2DB {
|
61
|
+
constructor(options) {
|
62
|
+
this.options = options;
|
63
|
+
this.apiEndpoint = "https://api.sheet2db.com";
|
64
|
+
this.fetchFn = options.fetchFn || fetchFunction;
|
65
|
+
}
|
66
|
+
fetch(path_1) {
|
67
|
+
return __awaiter(this, arguments, void 0, function* (path, method = "GET", queryParams, body) {
|
68
|
+
let endpoint = new URL(this.options.version, this.apiEndpoint);
|
69
|
+
let headers = { "Content-Type": "application/json" };
|
70
|
+
if (this.options.mode === 'connectionId') {
|
71
|
+
endpoint.pathname = `/${this.options.connectionId}${path}`;
|
72
|
+
if (this.options.basicAuth) {
|
73
|
+
let authorization = Buffer.from(`${this.options.basicAuth.username}:${this.options.basicAuth.password}`).toString('base64');
|
74
|
+
headers["Authorization"] = `Basic ${authorization}`;
|
75
|
+
}
|
76
|
+
else if (this.options.jwtAuth) {
|
77
|
+
headers["Authorization"] = `Bearer ${this.options.jwtAuth.bearerToken}`;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
else {
|
81
|
+
endpoint.pathname = `/${this.options.apiKey}${path}`;
|
82
|
+
endpoint.searchParams.set("__id", this.options.spreadsheetId);
|
83
|
+
}
|
84
|
+
if (queryParams) {
|
85
|
+
queryParams.forEach((value, key) => {
|
86
|
+
endpoint.searchParams.append(key, value);
|
87
|
+
});
|
88
|
+
}
|
89
|
+
const response = yield this.fetchFn(endpoint.toString(), {
|
90
|
+
headers,
|
91
|
+
method,
|
92
|
+
body: body ? JSON.stringify(body) : undefined
|
93
|
+
});
|
94
|
+
if (response.ok) {
|
95
|
+
return response.json();
|
96
|
+
}
|
97
|
+
else {
|
98
|
+
throw new Error(yield response.text());
|
99
|
+
}
|
100
|
+
});
|
101
|
+
}
|
102
|
+
ReadContent(options) {
|
103
|
+
const query = new URLSearchParams(options);
|
104
|
+
return this.fetch('', "GET", query);
|
105
|
+
}
|
106
|
+
Keys(options) {
|
107
|
+
const query = new URLSearchParams(options);
|
108
|
+
return this.fetch('/keys', "GET", query);
|
109
|
+
}
|
110
|
+
Count(options) {
|
111
|
+
const query = new URLSearchParams(options);
|
112
|
+
return this.fetch('/count', "GET", query);
|
113
|
+
}
|
114
|
+
Title() {
|
115
|
+
return this.fetch('/title', "GET");
|
116
|
+
}
|
117
|
+
Range(options) {
|
118
|
+
return this.fetch(`/range/${options.range}`, "GET");
|
119
|
+
}
|
120
|
+
Search(options) {
|
121
|
+
let path = options.or ? "/search_or" : "/search";
|
122
|
+
if (options.sheet) {
|
123
|
+
path = `${path}/${options.sheet}`;
|
124
|
+
}
|
125
|
+
const query = new URLSearchParams({ query: options.query });
|
126
|
+
return this.fetch(path, "GET", query);
|
127
|
+
}
|
128
|
+
Insert(options) {
|
129
|
+
const { data } = options, queryParams = __rest(options, ["data"]);
|
130
|
+
const query = new URLSearchParams(queryParams);
|
131
|
+
return this.fetch('/', "POST", query, data);
|
132
|
+
}
|
133
|
+
UpdateRow(options) {
|
134
|
+
const { row, data } = options, queryParams = __rest(options, ["row", "data"]);
|
135
|
+
const query = new URLSearchParams(queryParams);
|
136
|
+
return this.fetch(`/row/${row}`, "PATCH", query, data);
|
137
|
+
}
|
138
|
+
UpdateWithQuery(options) {
|
139
|
+
const { sheet, data, query: q } = options;
|
140
|
+
let path = '';
|
141
|
+
if (sheet) {
|
142
|
+
path = `/${sheet}`;
|
143
|
+
}
|
144
|
+
const query = new URLSearchParams({ query: q });
|
145
|
+
return this.fetch(path, "PATCH", query, data);
|
146
|
+
}
|
147
|
+
BatchUpdate(options) {
|
148
|
+
const { batches, sheet } = options;
|
149
|
+
let path = '';
|
150
|
+
if (sheet) {
|
151
|
+
path = `/${sheet}`;
|
152
|
+
}
|
153
|
+
return this.fetch(path, "PATCH", undefined, batches);
|
154
|
+
}
|
155
|
+
DeleteRow(options) {
|
156
|
+
const { row } = options, queryParams = __rest(options, ["row"]);
|
157
|
+
const query = new URLSearchParams(queryParams);
|
158
|
+
return this.fetch(`/${row}`, "DELETE", query);
|
159
|
+
}
|
160
|
+
DeleteWithQuery(options) {
|
161
|
+
const { query: search, sheet } = options;
|
162
|
+
const query = new URLSearchParams({ query: search });
|
163
|
+
let path = '';
|
164
|
+
if (sheet) {
|
165
|
+
path = `/${sheet}`;
|
166
|
+
}
|
167
|
+
return this.fetch(path, "DELETE", query);
|
168
|
+
}
|
169
|
+
Clear(options) {
|
170
|
+
const path = `/clear/${options.sheet}`;
|
171
|
+
return this.fetch(path, "DELETE");
|
172
|
+
}
|
173
|
+
CreateSheet(options) {
|
174
|
+
const query = new URLSearchParams(options);
|
175
|
+
return this.fetch('/sheet', "POST", query);
|
176
|
+
}
|
177
|
+
DeleteSheet(options) {
|
178
|
+
const path = `/sheet/${options.sheet}`;
|
179
|
+
return this.fetch(path, "DELETE");
|
180
|
+
}
|
181
|
+
}
|
182
|
+
exports.default = Sheet2DB;
|
package/jest.config.js
ADDED
package/package.json
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"name": "@sheet2db/sdk",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "",
|
5
|
+
"main": "dist/index.js",
|
6
|
+
"scripts": {
|
7
|
+
"test": "jest",
|
8
|
+
"build":"tsc"
|
9
|
+
},
|
10
|
+
"exports":{
|
11
|
+
".":{
|
12
|
+
"import":"./dist/index.js",
|
13
|
+
"require":"./dist/index.cjs"
|
14
|
+
}
|
15
|
+
},
|
16
|
+
"author": "",
|
17
|
+
"license": "ISC",
|
18
|
+
"devDependencies": {
|
19
|
+
"@jest/globals": "^29.7.0",
|
20
|
+
"jest": "^29.7.0",
|
21
|
+
"ts-jest": "^29.1.4",
|
22
|
+
"typescript": "^5.4.5"
|
23
|
+
},
|
24
|
+
"dependencies": {
|
25
|
+
"node-fetch": "^3.3.2"
|
26
|
+
},
|
27
|
+
"private":false
|
28
|
+
}
|
package/src/index.cjs.ts
ADDED
package/src/index.ts
ADDED
@@ -0,0 +1,246 @@
|
|
1
|
+
let fetchFunction: typeof fetch;
|
2
|
+
|
3
|
+
if (typeof window !== 'undefined' && typeof window.fetch !== 'undefined') {
|
4
|
+
// We are in a browser environment
|
5
|
+
fetchFunction = window.fetch.bind(window);
|
6
|
+
} else {
|
7
|
+
// We are in a Node.js environment
|
8
|
+
fetchFunction = async (...args) => {
|
9
|
+
const fetch = global.fetch;
|
10
|
+
return fetch(...args);
|
11
|
+
};
|
12
|
+
}
|
13
|
+
|
14
|
+
export type Sheet2DBOptions = {
|
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
|
19
|
+
fetchFn?: typeof fetch;
|
20
|
+
} | {
|
21
|
+
mode: 'connectionId';
|
22
|
+
connectionId: string;
|
23
|
+
basicAuth?: {
|
24
|
+
username: string;
|
25
|
+
password: string;
|
26
|
+
};
|
27
|
+
jwtAuth?: {
|
28
|
+
bearerToken: string;
|
29
|
+
};
|
30
|
+
version: "v1"; // Always v1
|
31
|
+
fetchFn?: typeof fetch;
|
32
|
+
};
|
33
|
+
|
34
|
+
export type ReadOptions = {
|
35
|
+
limit?: number;
|
36
|
+
offset?: number;
|
37
|
+
sheet?: string;
|
38
|
+
format?: 'records' | 'dict' | 'series' | 'split' | 'index' | 'raw';
|
39
|
+
cast_numbers?: string;
|
40
|
+
value_render?: "FORMATTED_VALUE" | "UNFORMATTED_VALUE" | "FORMULA";
|
41
|
+
};
|
42
|
+
|
43
|
+
export type GetKeysOptions = {
|
44
|
+
sheet?: string;
|
45
|
+
};
|
46
|
+
|
47
|
+
export type GetCountOptions = {
|
48
|
+
sheet?: string;
|
49
|
+
};
|
50
|
+
|
51
|
+
export type GetRangeOptions = {
|
52
|
+
range: string;
|
53
|
+
};
|
54
|
+
|
55
|
+
export type SearchOptions = {
|
56
|
+
sheet?: string;
|
57
|
+
or?: boolean;
|
58
|
+
query: string;
|
59
|
+
};
|
60
|
+
|
61
|
+
export type InsertOptions = {
|
62
|
+
data: Record<string, any> | Record<string, any>[];
|
63
|
+
sheet?: string;
|
64
|
+
};
|
65
|
+
|
66
|
+
export type UpdateRowOptions = {
|
67
|
+
row: number;
|
68
|
+
sheet?: string;
|
69
|
+
data: Record<string, any>;
|
70
|
+
};
|
71
|
+
|
72
|
+
export type UpdateWithQueryOptions = {
|
73
|
+
sheet?: string;
|
74
|
+
query: string;
|
75
|
+
data: Record<string, any>;
|
76
|
+
};
|
77
|
+
|
78
|
+
export type BatchUpdateOptions = {
|
79
|
+
sheet?: string;
|
80
|
+
batches: { query: string, record: Record<string, any> }[];
|
81
|
+
};
|
82
|
+
|
83
|
+
export type DeleteRowOptions = {
|
84
|
+
sheet?: string;
|
85
|
+
row: number;
|
86
|
+
};
|
87
|
+
|
88
|
+
export type DeleteWithQueryOptions = {
|
89
|
+
sheet?: string;
|
90
|
+
query: string;
|
91
|
+
};
|
92
|
+
|
93
|
+
export type ClearSheetOptions = {
|
94
|
+
sheet: string;
|
95
|
+
};
|
96
|
+
|
97
|
+
export type CreateSheetOptions = {
|
98
|
+
title?: string;
|
99
|
+
};
|
100
|
+
|
101
|
+
export type DeleteSheetOptions = {
|
102
|
+
sheet: string;
|
103
|
+
};
|
104
|
+
|
105
|
+
export default class Sheet2DB {
|
106
|
+
|
107
|
+
private apiEndpoint: string = "https://api.sheet2db.com";
|
108
|
+
// private apiEndpoint: string = "http://localhost:8787";
|
109
|
+
private fetchFn: typeof fetch;
|
110
|
+
|
111
|
+
constructor(private readonly options: Sheet2DBOptions) {
|
112
|
+
this.fetchFn = options.fetchFn || fetchFunction;
|
113
|
+
}
|
114
|
+
|
115
|
+
private async fetch<T>(path: string, method: "GET" | "POST" | "PATCH" | "DELETE" = "GET", queryParams?: URLSearchParams | string, body?: any): Promise<T> {
|
116
|
+
let endpoint = new URL(this.options.version, this.apiEndpoint);
|
117
|
+
let headers: Record<string, string> = { "Content-Type": "application/json" };
|
118
|
+
|
119
|
+
if (this.options.mode === 'connectionId') {
|
120
|
+
endpoint.pathname = `${endpoint.pathname}/${this.options.connectionId}${path}`;
|
121
|
+
if (this.options.basicAuth) {
|
122
|
+
let authorization = Buffer.from(`${this.options.basicAuth.username}:${this.options.basicAuth.password}`).toString('base64');
|
123
|
+
headers["Authorization"] = `Basic ${authorization}`;
|
124
|
+
} else if (this.options.jwtAuth) {
|
125
|
+
headers["Authorization"] = `Bearer ${this.options.jwtAuth.bearerToken}`;
|
126
|
+
}
|
127
|
+
} else {
|
128
|
+
endpoint.pathname = `${endpoint.pathname}/${this.options.apiKey}${path}`;
|
129
|
+
endpoint.searchParams.set("__id", this.options.spreadsheetId);
|
130
|
+
}
|
131
|
+
|
132
|
+
if (queryParams) {
|
133
|
+
if (typeof queryParams != 'string') {
|
134
|
+
queryParams.forEach((value, key) => {
|
135
|
+
endpoint.searchParams.append(key, value);
|
136
|
+
});
|
137
|
+
} else {
|
138
|
+
endpoint.search = queryParams
|
139
|
+
if(this.options.mode == 'apikey'){
|
140
|
+
endpoint.searchParams.set("__id", this.options.spreadsheetId);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
}
|
144
|
+
const response = await this.fetchFn(endpoint.toString(), {
|
145
|
+
headers,
|
146
|
+
method,
|
147
|
+
body: body ? JSON.stringify(body) : undefined
|
148
|
+
});
|
149
|
+
if (response.ok) {
|
150
|
+
return response.json() as Promise<T>;
|
151
|
+
} else {
|
152
|
+
throw new Error(await response.text());
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
ReadContent<T>(options?: ReadOptions) {
|
157
|
+
const query = new URLSearchParams(options as Record<string, string>);
|
158
|
+
return this.fetch<T>('', "GET", query);
|
159
|
+
}
|
160
|
+
|
161
|
+
Keys(options?: GetKeysOptions) {
|
162
|
+
const query = new URLSearchParams(options as Record<string, string>);
|
163
|
+
return this.fetch<string[]>('/keys', "GET", query);
|
164
|
+
}
|
165
|
+
|
166
|
+
Count(options?: GetCountOptions) {
|
167
|
+
const query = new URLSearchParams(options as Record<string, string>);
|
168
|
+
return this.fetch<{ count: number }>('/count', "GET", query);
|
169
|
+
}
|
170
|
+
|
171
|
+
Title() {
|
172
|
+
return this.fetch<{ spreadsheet_title: string, api_name: string }>('/title', "GET");
|
173
|
+
}
|
174
|
+
|
175
|
+
Range(options: GetRangeOptions) {
|
176
|
+
return this.fetch<string[][]>(`/range/${options.range}`, "GET");
|
177
|
+
}
|
178
|
+
|
179
|
+
Search(options: SearchOptions) {
|
180
|
+
let path = options.or ? "/search_or" : "/search";
|
181
|
+
if (options.sheet) {
|
182
|
+
path = `${path}/${options.sheet}`;
|
183
|
+
}
|
184
|
+
return this.fetch<Record<string, any>>(path, "GET", encodeURIComponent(options.query));
|
185
|
+
}
|
186
|
+
|
187
|
+
Insert(options: InsertOptions) {
|
188
|
+
const { data, ...queryParams } = options;
|
189
|
+
const query = new URLSearchParams(queryParams as Record<string, string>);
|
190
|
+
return this.fetch<{ inserted: number }>('/', "POST", query, data);
|
191
|
+
}
|
192
|
+
|
193
|
+
UpdateRow(options: UpdateRowOptions) {
|
194
|
+
const { row, data, ...queryParams } = options;
|
195
|
+
const query = new URLSearchParams(queryParams as Record<string, string>);
|
196
|
+
return this.fetch<{ updated: number }>(`/row/${row}`, "PATCH", query, data);
|
197
|
+
}
|
198
|
+
|
199
|
+
UpdateWithQuery(options: UpdateWithQueryOptions) {
|
200
|
+
const { sheet, data, query } = options;
|
201
|
+
let path = '';
|
202
|
+
if (sheet) {
|
203
|
+
path = `/${sheet}`;
|
204
|
+
}
|
205
|
+
return this.fetch<{ updated: number }>(path, "PATCH", encodeURIComponent(query), data);
|
206
|
+
}
|
207
|
+
|
208
|
+
BatchUpdate(options: BatchUpdateOptions) {
|
209
|
+
const { batches, sheet } = options;
|
210
|
+
let path = '/batch';
|
211
|
+
if (sheet) {
|
212
|
+
path = path + '/' + sheet;
|
213
|
+
}
|
214
|
+
return this.fetch<{ updated: number }>(path, "PATCH", undefined, batches);
|
215
|
+
}
|
216
|
+
|
217
|
+
DeleteRow(options: DeleteRowOptions) {
|
218
|
+
const { row, ...queryParams } = options;
|
219
|
+
const query = new URLSearchParams(queryParams as Record<string, string>);
|
220
|
+
return this.fetch<{ deleted: number }>(`/row/${row}`, "DELETE", query);
|
221
|
+
}
|
222
|
+
|
223
|
+
DeleteWithQuery(options: DeleteWithQueryOptions) {
|
224
|
+
const { query, sheet } = options;
|
225
|
+
let path = '';
|
226
|
+
if (sheet) {
|
227
|
+
path = `/${sheet}`;
|
228
|
+
}
|
229
|
+
return this.fetch<{ deleted: number }>(path, "DELETE", encodeURIComponent(query));
|
230
|
+
}
|
231
|
+
|
232
|
+
Clear(options: ClearSheetOptions) {
|
233
|
+
const path = `/clear/${options.sheet}`;
|
234
|
+
return this.fetch(path, "DELETE");
|
235
|
+
}
|
236
|
+
|
237
|
+
CreateSheet(options: CreateSheetOptions) {
|
238
|
+
const query = new URLSearchParams(options as Record<string, string>);
|
239
|
+
return this.fetch('/sheet', "POST", query);
|
240
|
+
}
|
241
|
+
|
242
|
+
DeleteSheet(options: DeleteSheetOptions) {
|
243
|
+
const path = `/sheet/${options.sheet}`;
|
244
|
+
return this.fetch(path, "DELETE");
|
245
|
+
}
|
246
|
+
}
|
@@ -0,0 +1,216 @@
|
|
1
|
+
import { describe, expect, test } from '@jest/globals';
|
2
|
+
import Sheet2DB, {
|
3
|
+
Sheet2DBOptions,
|
4
|
+
ReadOptions,
|
5
|
+
GetKeysOptions,
|
6
|
+
GetCountOptions,
|
7
|
+
GetRangeOptions,
|
8
|
+
SearchOptions,
|
9
|
+
InsertOptions,
|
10
|
+
UpdateRowOptions,
|
11
|
+
UpdateWithQueryOptions,
|
12
|
+
BatchUpdateOptions,
|
13
|
+
DeleteRowOptions,
|
14
|
+
DeleteWithQueryOptions,
|
15
|
+
ClearSheetOptions,
|
16
|
+
CreateSheetOptions,
|
17
|
+
DeleteSheetOptions,
|
18
|
+
} from "../src";
|
19
|
+
|
20
|
+
describe("Sheet2DB Class Tests", () => {
|
21
|
+
|
22
|
+
describe("Tests with Connection ID", () => {
|
23
|
+
const connectionIdOptions: Sheet2DBOptions = {
|
24
|
+
connectionId: "608ae724-5285-42fd-a1d9-2e9fad3b22ee",
|
25
|
+
// connectionId:"e90b9b28-64dd-4fcd-9be7-0c94edc9d897",
|
26
|
+
version: "v1",
|
27
|
+
mode: "connectionId"
|
28
|
+
};
|
29
|
+
const sheet2db = new Sheet2DB(connectionIdOptions);
|
30
|
+
|
31
|
+
test("Read Content", async () => {
|
32
|
+
let res = await sheet2db.ReadContent();
|
33
|
+
expect(res).toBeDefined();
|
34
|
+
// Add more specific checks based on known data structure
|
35
|
+
});
|
36
|
+
|
37
|
+
test("Get Keys", async () => {
|
38
|
+
let res = await sheet2db.Keys();
|
39
|
+
expect(res).toBeDefined();
|
40
|
+
expect(res?.length).toBeGreaterThan(0);
|
41
|
+
// Add more specific checks based on known data structure
|
42
|
+
});
|
43
|
+
|
44
|
+
test("Count", async () => {
|
45
|
+
let res = await sheet2db.Count();
|
46
|
+
expect(res).toBeDefined();
|
47
|
+
expect(res?.count).toBeGreaterThanOrEqual(0);
|
48
|
+
});
|
49
|
+
|
50
|
+
test("Title", async () => {
|
51
|
+
let res = await sheet2db.Title();
|
52
|
+
expect(res).toBeDefined();
|
53
|
+
expect(res?.spreadsheet_title).toBeTruthy();
|
54
|
+
expect(res?.api_name).toBeTruthy();
|
55
|
+
});
|
56
|
+
|
57
|
+
test("Range", async () => {
|
58
|
+
const rangeOptions: GetRangeOptions = {
|
59
|
+
range: "A1:B2"
|
60
|
+
};
|
61
|
+
let res = await sheet2db.Range(rangeOptions);
|
62
|
+
expect(res).toBeDefined();
|
63
|
+
expect(res?.length).toBe(2);
|
64
|
+
expect(res?.[0].length).toBe(2);
|
65
|
+
});
|
66
|
+
|
67
|
+
test("Search", async () => {
|
68
|
+
const searchOptions: SearchOptions = {
|
69
|
+
query: "Student Name=S*"
|
70
|
+
};
|
71
|
+
let res = await sheet2db.Search(searchOptions);
|
72
|
+
expect(res.length).toBeGreaterThanOrEqual(1);
|
73
|
+
// Add more specific checks based on known data structure
|
74
|
+
});
|
75
|
+
|
76
|
+
test("Insert", async () => {
|
77
|
+
const insertOptions: InsertOptions = {
|
78
|
+
data: { "Student Name": "Test" }
|
79
|
+
};
|
80
|
+
let res = await sheet2db.Insert(insertOptions);
|
81
|
+
expect(res).toBeDefined();
|
82
|
+
expect(res?.inserted).toBe(1);
|
83
|
+
});
|
84
|
+
|
85
|
+
test("UpdateRow", async () => {
|
86
|
+
const updateRowOptions: UpdateRowOptions = {
|
87
|
+
row: 31,
|
88
|
+
data: { "Student Name": "Test0" }
|
89
|
+
};
|
90
|
+
let res = await sheet2db.UpdateRow(updateRowOptions);
|
91
|
+
expect(res).toBeDefined();
|
92
|
+
expect(res?.updated).toBe(1);
|
93
|
+
});
|
94
|
+
|
95
|
+
test("UpdateWithQuery", async () => {
|
96
|
+
const updateWithQueryOptions: UpdateWithQueryOptions = {
|
97
|
+
query: "Student Name=Test0",
|
98
|
+
data: { "Age": 27 }
|
99
|
+
};
|
100
|
+
let res = await sheet2db.UpdateWithQuery(updateWithQueryOptions);
|
101
|
+
expect(res).toBeDefined();
|
102
|
+
expect(res?.updated).toBe(1);
|
103
|
+
});
|
104
|
+
|
105
|
+
test("BatchUpdate", async () => {
|
106
|
+
const batchUpdateOptions: BatchUpdateOptions = {
|
107
|
+
batches: [{ query: "Student Name=Test0", record: { Major: "updated value" } },{ query: "Student Name=Test0", record: { "Class Level": "3. Junior" } }]
|
108
|
+
};
|
109
|
+
let res = await sheet2db.BatchUpdate(batchUpdateOptions);
|
110
|
+
expect(res).toBeDefined();
|
111
|
+
expect(res?.updated).toBe(1);
|
112
|
+
});
|
113
|
+
|
114
|
+
test("DeleteRow", async () => {
|
115
|
+
const deleteRowOptions: DeleteRowOptions = {
|
116
|
+
row: 31
|
117
|
+
};
|
118
|
+
let res = await sheet2db.DeleteRow(deleteRowOptions);
|
119
|
+
expect(res).toBeDefined();
|
120
|
+
expect(res?.deleted).toBe(1);
|
121
|
+
});
|
122
|
+
|
123
|
+
test("DeleteWithQuery", async () => {
|
124
|
+
const deleteWithQueryOptions: DeleteWithQueryOptions = {
|
125
|
+
query: "Student Name=Test0"
|
126
|
+
};
|
127
|
+
let res = await sheet2db.DeleteWithQuery(deleteWithQueryOptions);
|
128
|
+
expect(res).toBeDefined();
|
129
|
+
expect(res?.deleted).toBe(0);
|
130
|
+
});
|
131
|
+
|
132
|
+
test("CreateSheet", async () => {
|
133
|
+
const createSheetOptions: CreateSheetOptions = {
|
134
|
+
title: "TestSheet"
|
135
|
+
};
|
136
|
+
let res = await sheet2db.CreateSheet(createSheetOptions);
|
137
|
+
expect(res).toBeDefined();
|
138
|
+
// Add specific assertions if return value is known
|
139
|
+
});
|
140
|
+
|
141
|
+
test("Clear", async () => {
|
142
|
+
const clearOptions: ClearSheetOptions = {
|
143
|
+
sheet: "TestSheet"
|
144
|
+
};
|
145
|
+
let res = await sheet2db.Clear(clearOptions);
|
146
|
+
expect(res).toBeDefined();
|
147
|
+
// Add specific assertions if return value is known
|
148
|
+
});
|
149
|
+
|
150
|
+
test("DeleteSheet", async () => {
|
151
|
+
const deleteSheetOptions: DeleteSheetOptions = {
|
152
|
+
sheet: "TestSheet"
|
153
|
+
};
|
154
|
+
let res = await sheet2db.DeleteSheet(deleteSheetOptions);
|
155
|
+
expect(res).toBeDefined();
|
156
|
+
// Add specific assertions if return value is known
|
157
|
+
});
|
158
|
+
|
159
|
+
});
|
160
|
+
|
161
|
+
describe("Tests with API Key", () => {
|
162
|
+
const apiKeyOptions: Sheet2DBOptions = {
|
163
|
+
apiKey: "BmJrnOlf",
|
164
|
+
spreadsheetId: "1H8t1vJkKTZzLkvVZwJZ5LlA0Fw6Hw2QY7kV1pLIJYo4",
|
165
|
+
version: "v1",
|
166
|
+
mode: "apikey"
|
167
|
+
};
|
168
|
+
const sheet2db = new Sheet2DB(apiKeyOptions);
|
169
|
+
|
170
|
+
test("Read Content", async () => {
|
171
|
+
let res = await sheet2db.ReadContent();
|
172
|
+
expect(res).toBeDefined();
|
173
|
+
// Add more specific checks based on known data structure
|
174
|
+
});
|
175
|
+
|
176
|
+
test("Get Keys", async () => {
|
177
|
+
let res = await sheet2db.Keys();
|
178
|
+
expect(res).toBeDefined();
|
179
|
+
expect(res?.length).toBeGreaterThan(0);
|
180
|
+
// Add more specific checks based on known data structure
|
181
|
+
});
|
182
|
+
|
183
|
+
test("Count", async () => {
|
184
|
+
let res = await sheet2db.Count();
|
185
|
+
expect(res).toBeDefined();
|
186
|
+
expect(res?.count).toBeGreaterThanOrEqual(0);
|
187
|
+
});
|
188
|
+
|
189
|
+
test("Title", async () => {
|
190
|
+
let res = await sheet2db.Title();
|
191
|
+
expect(res).toBeDefined();
|
192
|
+
expect(res?.spreadsheet_title).toBeTruthy();
|
193
|
+
expect(res?.api_name).toBeTruthy();
|
194
|
+
});
|
195
|
+
|
196
|
+
test("Range", async () => {
|
197
|
+
const rangeOptions: GetRangeOptions = {
|
198
|
+
range: "A1:B2"
|
199
|
+
};
|
200
|
+
let res = await sheet2db.Range(rangeOptions);
|
201
|
+
expect(res).toBeDefined();
|
202
|
+
expect(res?.length).toBe(2);
|
203
|
+
expect(res?.[0].length).toBe(2);
|
204
|
+
});
|
205
|
+
|
206
|
+
test("Search", async () => {
|
207
|
+
const searchOptions: SearchOptions = {
|
208
|
+
query: "search query"
|
209
|
+
};
|
210
|
+
let res = await sheet2db.Search(searchOptions);
|
211
|
+
expect(res).toBeDefined();
|
212
|
+
// Add more specific checks based on known data structure
|
213
|
+
});
|
214
|
+
|
215
|
+
})
|
216
|
+
})
|
package/tsconfig.json
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"target": "ES6",
|
4
|
+
"module": "CommonJS",
|
5
|
+
"moduleResolution": "node",
|
6
|
+
"outDir": "./dist",
|
7
|
+
"rootDir": "./src",
|
8
|
+
"strict": true,
|
9
|
+
"esModuleInterop": true,
|
10
|
+
"skipLibCheck": true,
|
11
|
+
"declaration": true
|
12
|
+
},
|
13
|
+
"include": ["src/**/*"],
|
14
|
+
"exclude": ["node_modules"]
|
15
|
+
}
|
16
|
+
|