@thinkingdifferently/core 1.0.3 → 1.2.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/README.md +321 -0
- package/dist/index.d.mts +38 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +219 -24
- package/dist/index.mjs +219 -24
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# `@thinkingdifferently/core`
|
|
2
|
+
|
|
3
|
+
Official TypeScript SDK for the Thinking Differently Backend-as-a-Service platform.
|
|
4
|
+
|
|
5
|
+
The SDK provides a simple interface for interacting with Thinking Differently collections without manually managing HTTP requests, authentication headers, request formatting, or query serialization.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- TypeScript-first SDK
|
|
10
|
+
- Collection querying with chained builders
|
|
11
|
+
- Automatic API key authentication via `x-api-key`
|
|
12
|
+
- Axios-based HTTP layer
|
|
13
|
+
- Built-in validation for query inputs
|
|
14
|
+
- `FormData` support for inserts
|
|
15
|
+
- Query inspection with `toJSON()`
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @thinkingdifferently/core
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { ThinkingDifferently } from "@thinkingdifferently/core";
|
|
27
|
+
|
|
28
|
+
const sdk = new ThinkingDifferently({
|
|
29
|
+
apiKey: "YOUR_API_KEY"
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const animals = await sdk
|
|
33
|
+
.collection("animals")
|
|
34
|
+
.where("age", ">", 10)
|
|
35
|
+
.limit(10)
|
|
36
|
+
.sort("createdAt", "desc")
|
|
37
|
+
.get();
|
|
38
|
+
|
|
39
|
+
console.log(animals);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## TypeScript Usage
|
|
43
|
+
|
|
44
|
+
The SDK is designed for TypeScript developers and supports generic response typing:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
type Animal = {
|
|
48
|
+
name: string;
|
|
49
|
+
age: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const animals = await sdk
|
|
53
|
+
.collection("animals")
|
|
54
|
+
.get<Animal>();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
You can also inspect the generated query before sending it:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
const query = sdk
|
|
61
|
+
.collection("animals")
|
|
62
|
+
.where("age", ">", 10);
|
|
63
|
+
|
|
64
|
+
console.log(query.toJSON());
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API Reference
|
|
68
|
+
|
|
69
|
+
### `new ThinkingDifferently(config)`
|
|
70
|
+
|
|
71
|
+
Creates an SDK instance.
|
|
72
|
+
|
|
73
|
+
#### Parameters
|
|
74
|
+
|
|
75
|
+
- `config.apiKey: string` — API key used for authenticated requests
|
|
76
|
+
|
|
77
|
+
#### Example
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const sdk = new ThinkingDifferently({
|
|
81
|
+
apiKey: "YOUR_API_KEY"
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `sdk.collection(name)`
|
|
86
|
+
|
|
87
|
+
Creates a query builder for a collection.
|
|
88
|
+
|
|
89
|
+
#### Parameters
|
|
90
|
+
|
|
91
|
+
- `name: string` — collection name
|
|
92
|
+
|
|
93
|
+
#### Returns
|
|
94
|
+
|
|
95
|
+
A `QueryBuilder` instance.
|
|
96
|
+
|
|
97
|
+
### `QueryBuilder.where(field, operator, value)`
|
|
98
|
+
|
|
99
|
+
Adds a filter to the query.
|
|
100
|
+
|
|
101
|
+
#### Supported operators
|
|
102
|
+
|
|
103
|
+
- `=`
|
|
104
|
+
- `!=`
|
|
105
|
+
- `>`
|
|
106
|
+
- `<`
|
|
107
|
+
- `>=`
|
|
108
|
+
- `<=`
|
|
109
|
+
- `in`
|
|
110
|
+
- `contains`
|
|
111
|
+
|
|
112
|
+
#### Notes
|
|
113
|
+
|
|
114
|
+
- Empty field names are rejected
|
|
115
|
+
- The `in` operator requires an array value
|
|
116
|
+
- Multiple `where()` calls append filters
|
|
117
|
+
|
|
118
|
+
#### Example
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
const query = sdk
|
|
122
|
+
.collection("animals")
|
|
123
|
+
.where("age", ">", 10)
|
|
124
|
+
.where("status", "=", "active");
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### `QueryBuilder.limit(count)`
|
|
128
|
+
|
|
129
|
+
Sets the maximum number of returned documents.
|
|
130
|
+
|
|
131
|
+
#### Validation
|
|
132
|
+
|
|
133
|
+
- Must be a positive integer
|
|
134
|
+
- Subsequent calls overwrite the previous limit
|
|
135
|
+
|
|
136
|
+
#### Example
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
const query = sdk.collection("animals").limit(20);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### `QueryBuilder.sort(field, direction)`
|
|
143
|
+
|
|
144
|
+
Adds a sort clause to the query.
|
|
145
|
+
|
|
146
|
+
#### Parameters
|
|
147
|
+
|
|
148
|
+
- `field: string` — field to sort by
|
|
149
|
+
- `direction: "asc" | "desc"` — sort direction
|
|
150
|
+
|
|
151
|
+
#### Notes
|
|
152
|
+
|
|
153
|
+
- Empty field names are rejected
|
|
154
|
+
- Subsequent calls overwrite the previous sort
|
|
155
|
+
|
|
156
|
+
#### Example
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
const query = sdk.collection("animals").sort("createdAt", "desc");
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### `QueryBuilder.get<T>()`
|
|
163
|
+
|
|
164
|
+
Executes the query and returns an array of typed results.
|
|
165
|
+
|
|
166
|
+
#### Signature
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
get<T = any>(): Promise<T[]>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Example
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
const animals = await sdk
|
|
176
|
+
.collection("animals")
|
|
177
|
+
.where("age", ">", 10)
|
|
178
|
+
.get<{ name: string; age: number }>();
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### `QueryBuilder.count()`
|
|
182
|
+
|
|
183
|
+
Returns the number of documents matching the current query.
|
|
184
|
+
|
|
185
|
+
#### Signature
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
count(): Promise<number>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### Example
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
const total = await sdk
|
|
195
|
+
.collection("animals")
|
|
196
|
+
.where("age", ">", 10)
|
|
197
|
+
.count();
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### `QueryBuilder.toJSON()`
|
|
201
|
+
|
|
202
|
+
Returns a deep copy of the generated query object.
|
|
203
|
+
|
|
204
|
+
#### Example
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
const query = sdk.collection("animals").where("age", ">", 10);
|
|
208
|
+
console.log(query.toJSON());
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### `types `
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
interface SDKConfig {
|
|
215
|
+
apiKey: string;
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## HTTP Details
|
|
220
|
+
|
|
221
|
+
- Base URL: `https://www.thinkingdifferently.dev/api/v1`
|
|
222
|
+
- Authentication header: `x-api-key: YOUR_API_KEY`
|
|
223
|
+
- HTTP client: Axios
|
|
224
|
+
- Supported methods: `GET`, `POST`, `PATCH`, `DELETE`
|
|
225
|
+
|
|
226
|
+
## Error Handling
|
|
227
|
+
|
|
228
|
+
The SDK throws JavaScript `Error` objects when requests fail or when query validation fails.
|
|
229
|
+
|
|
230
|
+
### Request errors
|
|
231
|
+
|
|
232
|
+
Backend errors are converted into `Error` messages.
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
try {
|
|
236
|
+
const animals = await sdk
|
|
237
|
+
.collection("animals")
|
|
238
|
+
.get();
|
|
239
|
+
|
|
240
|
+
console.log(animals);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.error(error);
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Validation errors
|
|
247
|
+
|
|
248
|
+
The SDK validates query input before sending requests:
|
|
249
|
+
|
|
250
|
+
- Empty field names are rejected
|
|
251
|
+
- Invalid limit values are rejected
|
|
252
|
+
- The `in` operator requires an array
|
|
253
|
+
- Query responses are validated before parsing
|
|
254
|
+
|
|
255
|
+
## Examples
|
|
256
|
+
|
|
257
|
+
### Filter, sort, and limit
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
const animals = await sdk
|
|
261
|
+
.collection("animals")
|
|
262
|
+
.where("age", ">", 10)
|
|
263
|
+
.where("price", "<", 50000)
|
|
264
|
+
.limit(10)
|
|
265
|
+
.sort("createdAt", "desc")
|
|
266
|
+
.get();
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Count matching documents
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
const total = await sdk
|
|
273
|
+
.collection("animals")
|
|
274
|
+
.where("age", ">", 10)
|
|
275
|
+
.count();
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Inspect the generated query
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
const query = sdk
|
|
282
|
+
.collection("animals")
|
|
283
|
+
.where("age", ">", 10);
|
|
284
|
+
|
|
285
|
+
console.log(JSON.stringify(query.toJSON(), null, 2));
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## FAQ
|
|
289
|
+
|
|
290
|
+
### How do I authenticate?
|
|
291
|
+
|
|
292
|
+
Pass your API key to `new ThinkingDifferently({ apiKey })`. The SDK automatically sends it using the `x-api-key` header.
|
|
293
|
+
|
|
294
|
+
### What does `collection()` return?
|
|
295
|
+
|
|
296
|
+
It returns a query builder that lets you chain `where()`, `limit()`, `sort()`, `get()`, `count()`, and `toJSON()`.
|
|
297
|
+
|
|
298
|
+
### Can I inspect a query before executing it?
|
|
299
|
+
|
|
300
|
+
Yes. Call `toJSON()` on the query builder to get a deep copy of the query object.
|
|
301
|
+
|
|
302
|
+
### Does the SDK validate input?
|
|
303
|
+
|
|
304
|
+
Yes. Empty field names, invalid limit values, and invalid `in` operator values are rejected.
|
|
305
|
+
|
|
306
|
+
### What transport does the SDK use?
|
|
307
|
+
|
|
308
|
+
The SDK uses Axios for network requests.
|
|
309
|
+
|
|
310
|
+
## Roadmap
|
|
311
|
+
|
|
312
|
+
The following items are listed in the current design notes as not yet implemented:
|
|
313
|
+
|
|
314
|
+
- `update()`
|
|
315
|
+
- `delete()`
|
|
316
|
+
- `first()`
|
|
317
|
+
- pagination helpers
|
|
318
|
+
- aggregation queries
|
|
319
|
+
- `OR` conditions
|
|
320
|
+
- joins
|
|
321
|
+
|
package/dist/index.d.mts
CHANGED
|
@@ -7,15 +7,52 @@ interface GetOptions {
|
|
|
7
7
|
|
|
8
8
|
declare class TDClient {
|
|
9
9
|
private api;
|
|
10
|
+
private apikey;
|
|
10
11
|
constructor(apiKey: string);
|
|
11
12
|
request(method: "POST" | "GET" | "PATCH" | "DELETE", body?: any): Promise<any>;
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
type Operator = "=" | "!=" | ">" | "<" | ">=" | "<=" | "in" | "contains";
|
|
16
|
+
type Operation = "find" | "count" | "insert" | "update" | "delete" | "updateMany" | "deleteMany";
|
|
17
|
+
type Filter = {
|
|
18
|
+
field: string;
|
|
19
|
+
operator: Operator;
|
|
20
|
+
value: unknown;
|
|
21
|
+
};
|
|
22
|
+
type Query = {
|
|
23
|
+
operation: Operation | null;
|
|
24
|
+
collection: string;
|
|
25
|
+
filters: Filter[];
|
|
26
|
+
limit: number | null;
|
|
27
|
+
sort: {
|
|
28
|
+
field: string;
|
|
29
|
+
direction: "asc" | "desc";
|
|
30
|
+
} | null;
|
|
31
|
+
id?: string;
|
|
32
|
+
data?: unknown;
|
|
33
|
+
};
|
|
34
|
+
declare class QueryBuilder {
|
|
35
|
+
private query;
|
|
36
|
+
private client;
|
|
37
|
+
constructor(collection: string, client: TDClient);
|
|
38
|
+
where(field: string, operator: Operator, value: unknown): this;
|
|
39
|
+
limit(count: number): this;
|
|
40
|
+
sort(field: string, direction: "asc" | "desc"): this;
|
|
41
|
+
count(): Promise<number>;
|
|
42
|
+
toJSON(): Query;
|
|
43
|
+
get<T = any>(): Promise<T[]>;
|
|
44
|
+
insert(data: unknown): Promise<any>;
|
|
45
|
+
UpdateById(id: string, data: Record<string, any>): Promise<any>;
|
|
46
|
+
updateMany(data: Record<string, any>): Promise<any>;
|
|
47
|
+
DeleteById(id: string): Promise<any>;
|
|
48
|
+
deleteMany(): Promise<any>;
|
|
49
|
+
}
|
|
50
|
+
|
|
14
51
|
declare class ThinkingDifferently {
|
|
15
52
|
private client;
|
|
16
53
|
constructor(config: SDKConfig);
|
|
54
|
+
collection(name: string): QueryBuilder;
|
|
17
55
|
insert(key: string, data: any): Promise<any>;
|
|
18
|
-
get(key: string, options?: GetOptions): Promise<any>;
|
|
19
56
|
update(key: string, id: string, data: Record<string, any>): Promise<any>;
|
|
20
57
|
delete(key: string, id: string): Promise<any>;
|
|
21
58
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,15 +7,52 @@ interface GetOptions {
|
|
|
7
7
|
|
|
8
8
|
declare class TDClient {
|
|
9
9
|
private api;
|
|
10
|
+
private apikey;
|
|
10
11
|
constructor(apiKey: string);
|
|
11
12
|
request(method: "POST" | "GET" | "PATCH" | "DELETE", body?: any): Promise<any>;
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
type Operator = "=" | "!=" | ">" | "<" | ">=" | "<=" | "in" | "contains";
|
|
16
|
+
type Operation = "find" | "count" | "insert" | "update" | "delete" | "updateMany" | "deleteMany";
|
|
17
|
+
type Filter = {
|
|
18
|
+
field: string;
|
|
19
|
+
operator: Operator;
|
|
20
|
+
value: unknown;
|
|
21
|
+
};
|
|
22
|
+
type Query = {
|
|
23
|
+
operation: Operation | null;
|
|
24
|
+
collection: string;
|
|
25
|
+
filters: Filter[];
|
|
26
|
+
limit: number | null;
|
|
27
|
+
sort: {
|
|
28
|
+
field: string;
|
|
29
|
+
direction: "asc" | "desc";
|
|
30
|
+
} | null;
|
|
31
|
+
id?: string;
|
|
32
|
+
data?: unknown;
|
|
33
|
+
};
|
|
34
|
+
declare class QueryBuilder {
|
|
35
|
+
private query;
|
|
36
|
+
private client;
|
|
37
|
+
constructor(collection: string, client: TDClient);
|
|
38
|
+
where(field: string, operator: Operator, value: unknown): this;
|
|
39
|
+
limit(count: number): this;
|
|
40
|
+
sort(field: string, direction: "asc" | "desc"): this;
|
|
41
|
+
count(): Promise<number>;
|
|
42
|
+
toJSON(): Query;
|
|
43
|
+
get<T = any>(): Promise<T[]>;
|
|
44
|
+
insert(data: unknown): Promise<any>;
|
|
45
|
+
UpdateById(id: string, data: Record<string, any>): Promise<any>;
|
|
46
|
+
updateMany(data: Record<string, any>): Promise<any>;
|
|
47
|
+
DeleteById(id: string): Promise<any>;
|
|
48
|
+
deleteMany(): Promise<any>;
|
|
49
|
+
}
|
|
50
|
+
|
|
14
51
|
declare class ThinkingDifferently {
|
|
15
52
|
private client;
|
|
16
53
|
constructor(config: SDKConfig);
|
|
54
|
+
collection(name: string): QueryBuilder;
|
|
17
55
|
insert(key: string, data: any): Promise<any>;
|
|
18
|
-
get(key: string, options?: GetOptions): Promise<any>;
|
|
19
56
|
update(key: string, id: string, data: Record<string, any>): Promise<any>;
|
|
20
57
|
delete(key: string, id: string): Promise<any>;
|
|
21
58
|
}
|
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
39
39
|
var import_axios = __toESM(require("axios"));
|
|
40
40
|
var TDClient = class {
|
|
41
41
|
constructor(apiKey) {
|
|
42
|
+
this.apikey = apiKey;
|
|
42
43
|
this.api = import_axios.default.create({
|
|
43
44
|
baseURL: "https://www.thinkingdifferently.dev/api/v1",
|
|
44
45
|
headers: {
|
|
@@ -50,6 +51,14 @@ var TDClient = class {
|
|
|
50
51
|
async request(method, body) {
|
|
51
52
|
try {
|
|
52
53
|
const isFormData = body instanceof FormData;
|
|
54
|
+
if (isFormData) {
|
|
55
|
+
body.append("key", this.apikey);
|
|
56
|
+
} else {
|
|
57
|
+
body = {
|
|
58
|
+
key: this.apikey,
|
|
59
|
+
query: body
|
|
60
|
+
};
|
|
61
|
+
}
|
|
53
62
|
const response = await this.api.request({
|
|
54
63
|
url: "/data",
|
|
55
64
|
method,
|
|
@@ -65,12 +74,222 @@ var TDClient = class {
|
|
|
65
74
|
}
|
|
66
75
|
};
|
|
67
76
|
|
|
77
|
+
// src/QueryBuilder.ts
|
|
78
|
+
var QueryBuilder = class {
|
|
79
|
+
constructor(collection, client) {
|
|
80
|
+
this.client = client;
|
|
81
|
+
this.query = {
|
|
82
|
+
operation: null,
|
|
83
|
+
collection,
|
|
84
|
+
filters: [],
|
|
85
|
+
limit: null,
|
|
86
|
+
sort: null
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
where(field, operator, value) {
|
|
90
|
+
if (operator === "in" && !Array.isArray(value)) {
|
|
91
|
+
throw new Error("Value must be an array for 'in' operator");
|
|
92
|
+
}
|
|
93
|
+
if (!field.trim()) {
|
|
94
|
+
throw new Error("Field name cannot be empty");
|
|
95
|
+
}
|
|
96
|
+
this.query.filters.push({ field, operator, value });
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
limit(count) {
|
|
100
|
+
if (!Number.isInteger(count) || count <= 0) {
|
|
101
|
+
throw new Error("Limit must be a positive integer");
|
|
102
|
+
}
|
|
103
|
+
this.query.limit = count;
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
sort(field, direction) {
|
|
107
|
+
if (!field.trim()) {
|
|
108
|
+
throw new Error("Field name cannot be empty");
|
|
109
|
+
}
|
|
110
|
+
this.query.sort = { field, direction };
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
// build() {
|
|
114
|
+
// return this.query;
|
|
115
|
+
// }
|
|
116
|
+
//to do writing the count method for the query builder
|
|
117
|
+
//the conditions are specified , so now the count method should return the number of documents that match the specified conditions in the query builder
|
|
118
|
+
//means count will first get the data based on the filters and then return the length of the data array as the count of matching documents
|
|
119
|
+
async count() {
|
|
120
|
+
this.query.operation = "count";
|
|
121
|
+
console.log("\n================ COUNT REQUEST ================");
|
|
122
|
+
console.log("[SDK] Final Query:", this.query);
|
|
123
|
+
try {
|
|
124
|
+
const response = await this.client.request(
|
|
125
|
+
"POST",
|
|
126
|
+
this.query
|
|
127
|
+
);
|
|
128
|
+
return response.count;
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error("[SDK] COUNT ERROR");
|
|
131
|
+
console.error(error);
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
toJSON() {
|
|
136
|
+
return structuredClone(this.query);
|
|
137
|
+
}
|
|
138
|
+
async get() {
|
|
139
|
+
this.query.operation = "find";
|
|
140
|
+
console.log("\n================ GET REQUEST ================");
|
|
141
|
+
console.log("[SDK] Final Query:", this.query);
|
|
142
|
+
try {
|
|
143
|
+
const response = await this.client.request(
|
|
144
|
+
"POST",
|
|
145
|
+
this.query
|
|
146
|
+
);
|
|
147
|
+
console.log("[SDK] Raw Response:", response);
|
|
148
|
+
if (!Array.isArray(response.data)) {
|
|
149
|
+
throw new Error("Invalid response format");
|
|
150
|
+
}
|
|
151
|
+
console.log("sdk response ", response);
|
|
152
|
+
console.log("[SDK] Data:", response.data);
|
|
153
|
+
return response.data;
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.error("[SDK] GET ERROR");
|
|
156
|
+
console.error(error);
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
async insert(data) {
|
|
161
|
+
this.query.operation = "insert";
|
|
162
|
+
console.log("\n================ INSERT REQUEST ================");
|
|
163
|
+
try {
|
|
164
|
+
if (data instanceof FormData) {
|
|
165
|
+
console.log("[SDK] FormData detected");
|
|
166
|
+
const payload = new FormData();
|
|
167
|
+
const extractedData = {};
|
|
168
|
+
for (const [key, value] of data.entries()) {
|
|
169
|
+
if (value instanceof File) {
|
|
170
|
+
payload.append(
|
|
171
|
+
key,
|
|
172
|
+
value
|
|
173
|
+
);
|
|
174
|
+
} else {
|
|
175
|
+
extractedData[key] = value;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
this.query.data = extractedData;
|
|
179
|
+
payload.append(
|
|
180
|
+
"query",
|
|
181
|
+
JSON.stringify(this.query)
|
|
182
|
+
);
|
|
183
|
+
console.log("[SDK] Query:", this.query);
|
|
184
|
+
return await this.client.request(
|
|
185
|
+
"POST",
|
|
186
|
+
payload
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
this.query.data = data;
|
|
190
|
+
console.log("[SDK] Final Query:", this.query);
|
|
191
|
+
return await this.client.request(
|
|
192
|
+
"POST",
|
|
193
|
+
this.query
|
|
194
|
+
);
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.error("[SDK] INSERT ERROR");
|
|
197
|
+
console.error(error);
|
|
198
|
+
throw error;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
async UpdateById(id, data) {
|
|
202
|
+
this.query.operation = "update";
|
|
203
|
+
this.query.id = id;
|
|
204
|
+
this.query.data = data;
|
|
205
|
+
console.log("\n================ UPDATE REQUEST ================");
|
|
206
|
+
console.log("[SDK] Final Query:", this.query);
|
|
207
|
+
try {
|
|
208
|
+
const response = await this.client.request(
|
|
209
|
+
"PATCH",
|
|
210
|
+
this.query
|
|
211
|
+
);
|
|
212
|
+
console.log("[SDK] Update Response:", response);
|
|
213
|
+
return response;
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error("[SDK] UPDATE ERROR");
|
|
216
|
+
console.error(error);
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
//updateMany
|
|
221
|
+
// its just like the get() it will call hte client
|
|
222
|
+
//example sdk.collection("animals").where("price", ">", 1000).updateMany({status : "expensive"}) it will update all the animals whose price is greater than 1000 and set their status to expensive
|
|
223
|
+
async updateMany(data) {
|
|
224
|
+
this.query.operation = "updateMany";
|
|
225
|
+
this.query.data = data;
|
|
226
|
+
console.log("\n================ UPDATE MANY REQUEST ================");
|
|
227
|
+
console.log("[SDK] Final Query:", this.query);
|
|
228
|
+
try {
|
|
229
|
+
const response = await this.client.request(
|
|
230
|
+
"PATCH",
|
|
231
|
+
this.query
|
|
232
|
+
);
|
|
233
|
+
console.log("[SDK] Update Many Response:", response);
|
|
234
|
+
return response;
|
|
235
|
+
} catch (error) {
|
|
236
|
+
console.error("[SDK] UPDATE MANY ERROR");
|
|
237
|
+
console.error(error);
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async DeleteById(id) {
|
|
242
|
+
this.query.operation = "delete";
|
|
243
|
+
this.query.id = id;
|
|
244
|
+
console.log("\n================ DELETE REQUEST ================");
|
|
245
|
+
console.log("[SDK] Final Query:", this.query);
|
|
246
|
+
try {
|
|
247
|
+
const response = await this.client.request(
|
|
248
|
+
"DELETE",
|
|
249
|
+
this.query
|
|
250
|
+
);
|
|
251
|
+
console.log("[SDK] Delete Response:", response);
|
|
252
|
+
return response;
|
|
253
|
+
} catch (error) {
|
|
254
|
+
console.error("[SDK] DELETE ERROR");
|
|
255
|
+
console.error(error);
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//deleteMany
|
|
260
|
+
// its just like the get() it will call hte client
|
|
261
|
+
//example sdk.collection("animals").where("price", ">", 1000).deleteMany() it will delete all the animals whose price is greater than 1000
|
|
262
|
+
async deleteMany() {
|
|
263
|
+
this.query.operation = "deleteMany";
|
|
264
|
+
console.log("\n================ DELETE MANY REQUEST ================");
|
|
265
|
+
console.log("[SDK] Final Query:", this.query);
|
|
266
|
+
try {
|
|
267
|
+
const response = await this.client.request(
|
|
268
|
+
"DELETE",
|
|
269
|
+
this.query
|
|
270
|
+
);
|
|
271
|
+
console.log("[SDK] Delete Many Response:", response);
|
|
272
|
+
return response;
|
|
273
|
+
} catch (error) {
|
|
274
|
+
console.error("[SDK] DELETE MANY ERROR");
|
|
275
|
+
console.error(error);
|
|
276
|
+
throw error;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
68
281
|
// src/index.ts
|
|
69
282
|
var ThinkingDifferently = class {
|
|
70
283
|
constructor(config) {
|
|
71
284
|
console.log("[ThinkingDifferently SDK] Initializing SDK");
|
|
72
285
|
this.client = new TDClient(config.apiKey);
|
|
73
286
|
}
|
|
287
|
+
collection(name) {
|
|
288
|
+
return new QueryBuilder(
|
|
289
|
+
name,
|
|
290
|
+
this.client
|
|
291
|
+
);
|
|
292
|
+
}
|
|
74
293
|
async insert(key, data) {
|
|
75
294
|
console.log("\n================ INSERT REQUEST ================");
|
|
76
295
|
console.log("[SDK] Collection Key:", key);
|
|
@@ -122,30 +341,6 @@ var ThinkingDifferently = class {
|
|
|
122
341
|
throw error;
|
|
123
342
|
}
|
|
124
343
|
}
|
|
125
|
-
async get(key, options) {
|
|
126
|
-
console.log("\n================ GET REQUEST ================");
|
|
127
|
-
console.log("[SDK] Collection Key:", key);
|
|
128
|
-
console.log("[SDK] Options:", options);
|
|
129
|
-
try {
|
|
130
|
-
const response = await this.client.request(
|
|
131
|
-
"GET",
|
|
132
|
-
{
|
|
133
|
-
key,
|
|
134
|
-
...options
|
|
135
|
-
}
|
|
136
|
-
);
|
|
137
|
-
console.log("[SDK] Raw Response:", response);
|
|
138
|
-
const parsed = response.data.map(
|
|
139
|
-
(item) => item.data
|
|
140
|
-
);
|
|
141
|
-
console.log("[SDK] Parsed Data:", parsed);
|
|
142
|
-
return parsed;
|
|
143
|
-
} catch (error) {
|
|
144
|
-
console.error("[SDK] GET ERROR");
|
|
145
|
-
console.error(error);
|
|
146
|
-
throw error;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
344
|
async update(key, id, data) {
|
|
150
345
|
console.log("\n================ UPDATE REQUEST ================");
|
|
151
346
|
console.log("[SDK] Collection Key:", key);
|
package/dist/index.mjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import axios from "axios";
|
|
3
3
|
var TDClient = class {
|
|
4
4
|
constructor(apiKey) {
|
|
5
|
+
this.apikey = apiKey;
|
|
5
6
|
this.api = axios.create({
|
|
6
7
|
baseURL: "https://www.thinkingdifferently.dev/api/v1",
|
|
7
8
|
headers: {
|
|
@@ -13,6 +14,14 @@ var TDClient = class {
|
|
|
13
14
|
async request(method, body) {
|
|
14
15
|
try {
|
|
15
16
|
const isFormData = body instanceof FormData;
|
|
17
|
+
if (isFormData) {
|
|
18
|
+
body.append("key", this.apikey);
|
|
19
|
+
} else {
|
|
20
|
+
body = {
|
|
21
|
+
key: this.apikey,
|
|
22
|
+
query: body
|
|
23
|
+
};
|
|
24
|
+
}
|
|
16
25
|
const response = await this.api.request({
|
|
17
26
|
url: "/data",
|
|
18
27
|
method,
|
|
@@ -28,12 +37,222 @@ var TDClient = class {
|
|
|
28
37
|
}
|
|
29
38
|
};
|
|
30
39
|
|
|
40
|
+
// src/QueryBuilder.ts
|
|
41
|
+
var QueryBuilder = class {
|
|
42
|
+
constructor(collection, client) {
|
|
43
|
+
this.client = client;
|
|
44
|
+
this.query = {
|
|
45
|
+
operation: null,
|
|
46
|
+
collection,
|
|
47
|
+
filters: [],
|
|
48
|
+
limit: null,
|
|
49
|
+
sort: null
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
where(field, operator, value) {
|
|
53
|
+
if (operator === "in" && !Array.isArray(value)) {
|
|
54
|
+
throw new Error("Value must be an array for 'in' operator");
|
|
55
|
+
}
|
|
56
|
+
if (!field.trim()) {
|
|
57
|
+
throw new Error("Field name cannot be empty");
|
|
58
|
+
}
|
|
59
|
+
this.query.filters.push({ field, operator, value });
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
limit(count) {
|
|
63
|
+
if (!Number.isInteger(count) || count <= 0) {
|
|
64
|
+
throw new Error("Limit must be a positive integer");
|
|
65
|
+
}
|
|
66
|
+
this.query.limit = count;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
sort(field, direction) {
|
|
70
|
+
if (!field.trim()) {
|
|
71
|
+
throw new Error("Field name cannot be empty");
|
|
72
|
+
}
|
|
73
|
+
this.query.sort = { field, direction };
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
// build() {
|
|
77
|
+
// return this.query;
|
|
78
|
+
// }
|
|
79
|
+
//to do writing the count method for the query builder
|
|
80
|
+
//the conditions are specified , so now the count method should return the number of documents that match the specified conditions in the query builder
|
|
81
|
+
//means count will first get the data based on the filters and then return the length of the data array as the count of matching documents
|
|
82
|
+
async count() {
|
|
83
|
+
this.query.operation = "count";
|
|
84
|
+
console.log("\n================ COUNT REQUEST ================");
|
|
85
|
+
console.log("[SDK] Final Query:", this.query);
|
|
86
|
+
try {
|
|
87
|
+
const response = await this.client.request(
|
|
88
|
+
"POST",
|
|
89
|
+
this.query
|
|
90
|
+
);
|
|
91
|
+
return response.count;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error("[SDK] COUNT ERROR");
|
|
94
|
+
console.error(error);
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
toJSON() {
|
|
99
|
+
return structuredClone(this.query);
|
|
100
|
+
}
|
|
101
|
+
async get() {
|
|
102
|
+
this.query.operation = "find";
|
|
103
|
+
console.log("\n================ GET REQUEST ================");
|
|
104
|
+
console.log("[SDK] Final Query:", this.query);
|
|
105
|
+
try {
|
|
106
|
+
const response = await this.client.request(
|
|
107
|
+
"POST",
|
|
108
|
+
this.query
|
|
109
|
+
);
|
|
110
|
+
console.log("[SDK] Raw Response:", response);
|
|
111
|
+
if (!Array.isArray(response.data)) {
|
|
112
|
+
throw new Error("Invalid response format");
|
|
113
|
+
}
|
|
114
|
+
console.log("sdk response ", response);
|
|
115
|
+
console.log("[SDK] Data:", response.data);
|
|
116
|
+
return response.data;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error("[SDK] GET ERROR");
|
|
119
|
+
console.error(error);
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async insert(data) {
|
|
124
|
+
this.query.operation = "insert";
|
|
125
|
+
console.log("\n================ INSERT REQUEST ================");
|
|
126
|
+
try {
|
|
127
|
+
if (data instanceof FormData) {
|
|
128
|
+
console.log("[SDK] FormData detected");
|
|
129
|
+
const payload = new FormData();
|
|
130
|
+
const extractedData = {};
|
|
131
|
+
for (const [key, value] of data.entries()) {
|
|
132
|
+
if (value instanceof File) {
|
|
133
|
+
payload.append(
|
|
134
|
+
key,
|
|
135
|
+
value
|
|
136
|
+
);
|
|
137
|
+
} else {
|
|
138
|
+
extractedData[key] = value;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
this.query.data = extractedData;
|
|
142
|
+
payload.append(
|
|
143
|
+
"query",
|
|
144
|
+
JSON.stringify(this.query)
|
|
145
|
+
);
|
|
146
|
+
console.log("[SDK] Query:", this.query);
|
|
147
|
+
return await this.client.request(
|
|
148
|
+
"POST",
|
|
149
|
+
payload
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
this.query.data = data;
|
|
153
|
+
console.log("[SDK] Final Query:", this.query);
|
|
154
|
+
return await this.client.request(
|
|
155
|
+
"POST",
|
|
156
|
+
this.query
|
|
157
|
+
);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
console.error("[SDK] INSERT ERROR");
|
|
160
|
+
console.error(error);
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async UpdateById(id, data) {
|
|
165
|
+
this.query.operation = "update";
|
|
166
|
+
this.query.id = id;
|
|
167
|
+
this.query.data = data;
|
|
168
|
+
console.log("\n================ UPDATE REQUEST ================");
|
|
169
|
+
console.log("[SDK] Final Query:", this.query);
|
|
170
|
+
try {
|
|
171
|
+
const response = await this.client.request(
|
|
172
|
+
"PATCH",
|
|
173
|
+
this.query
|
|
174
|
+
);
|
|
175
|
+
console.log("[SDK] Update Response:", response);
|
|
176
|
+
return response;
|
|
177
|
+
} catch (error) {
|
|
178
|
+
console.error("[SDK] UPDATE ERROR");
|
|
179
|
+
console.error(error);
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//updateMany
|
|
184
|
+
// its just like the get() it will call hte client
|
|
185
|
+
//example sdk.collection("animals").where("price", ">", 1000).updateMany({status : "expensive"}) it will update all the animals whose price is greater than 1000 and set their status to expensive
|
|
186
|
+
async updateMany(data) {
|
|
187
|
+
this.query.operation = "updateMany";
|
|
188
|
+
this.query.data = data;
|
|
189
|
+
console.log("\n================ UPDATE MANY REQUEST ================");
|
|
190
|
+
console.log("[SDK] Final Query:", this.query);
|
|
191
|
+
try {
|
|
192
|
+
const response = await this.client.request(
|
|
193
|
+
"PATCH",
|
|
194
|
+
this.query
|
|
195
|
+
);
|
|
196
|
+
console.log("[SDK] Update Many Response:", response);
|
|
197
|
+
return response;
|
|
198
|
+
} catch (error) {
|
|
199
|
+
console.error("[SDK] UPDATE MANY ERROR");
|
|
200
|
+
console.error(error);
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async DeleteById(id) {
|
|
205
|
+
this.query.operation = "delete";
|
|
206
|
+
this.query.id = id;
|
|
207
|
+
console.log("\n================ DELETE REQUEST ================");
|
|
208
|
+
console.log("[SDK] Final Query:", this.query);
|
|
209
|
+
try {
|
|
210
|
+
const response = await this.client.request(
|
|
211
|
+
"DELETE",
|
|
212
|
+
this.query
|
|
213
|
+
);
|
|
214
|
+
console.log("[SDK] Delete Response:", response);
|
|
215
|
+
return response;
|
|
216
|
+
} catch (error) {
|
|
217
|
+
console.error("[SDK] DELETE ERROR");
|
|
218
|
+
console.error(error);
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
//deleteMany
|
|
223
|
+
// its just like the get() it will call hte client
|
|
224
|
+
//example sdk.collection("animals").where("price", ">", 1000).deleteMany() it will delete all the animals whose price is greater than 1000
|
|
225
|
+
async deleteMany() {
|
|
226
|
+
this.query.operation = "deleteMany";
|
|
227
|
+
console.log("\n================ DELETE MANY REQUEST ================");
|
|
228
|
+
console.log("[SDK] Final Query:", this.query);
|
|
229
|
+
try {
|
|
230
|
+
const response = await this.client.request(
|
|
231
|
+
"DELETE",
|
|
232
|
+
this.query
|
|
233
|
+
);
|
|
234
|
+
console.log("[SDK] Delete Many Response:", response);
|
|
235
|
+
return response;
|
|
236
|
+
} catch (error) {
|
|
237
|
+
console.error("[SDK] DELETE MANY ERROR");
|
|
238
|
+
console.error(error);
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
31
244
|
// src/index.ts
|
|
32
245
|
var ThinkingDifferently = class {
|
|
33
246
|
constructor(config) {
|
|
34
247
|
console.log("[ThinkingDifferently SDK] Initializing SDK");
|
|
35
248
|
this.client = new TDClient(config.apiKey);
|
|
36
249
|
}
|
|
250
|
+
collection(name) {
|
|
251
|
+
return new QueryBuilder(
|
|
252
|
+
name,
|
|
253
|
+
this.client
|
|
254
|
+
);
|
|
255
|
+
}
|
|
37
256
|
async insert(key, data) {
|
|
38
257
|
console.log("\n================ INSERT REQUEST ================");
|
|
39
258
|
console.log("[SDK] Collection Key:", key);
|
|
@@ -85,30 +304,6 @@ var ThinkingDifferently = class {
|
|
|
85
304
|
throw error;
|
|
86
305
|
}
|
|
87
306
|
}
|
|
88
|
-
async get(key, options) {
|
|
89
|
-
console.log("\n================ GET REQUEST ================");
|
|
90
|
-
console.log("[SDK] Collection Key:", key);
|
|
91
|
-
console.log("[SDK] Options:", options);
|
|
92
|
-
try {
|
|
93
|
-
const response = await this.client.request(
|
|
94
|
-
"GET",
|
|
95
|
-
{
|
|
96
|
-
key,
|
|
97
|
-
...options
|
|
98
|
-
}
|
|
99
|
-
);
|
|
100
|
-
console.log("[SDK] Raw Response:", response);
|
|
101
|
-
const parsed = response.data.map(
|
|
102
|
-
(item) => item.data
|
|
103
|
-
);
|
|
104
|
-
console.log("[SDK] Parsed Data:", parsed);
|
|
105
|
-
return parsed;
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.error("[SDK] GET ERROR");
|
|
108
|
-
console.error(error);
|
|
109
|
-
throw error;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
307
|
async update(key, id, data) {
|
|
113
308
|
console.log("\n================ UPDATE REQUEST ================");
|
|
114
309
|
console.log("[SDK] Collection Key:", key);
|