@objectql/sdk 1.8.1 → 1.8.3
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/CHANGELOG.md +41 -1
- package/README.md +499 -0
- package/dist/index.d.ts +102 -1
- package/dist/index.js +215 -1
- package/dist/index.js.map +1 -1
- package/jest.config.js +3 -1
- package/package.json +33 -3
- package/src/index.ts +341 -1
- package/tsconfig.tsbuildinfo +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,49 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @objectql/sdk - Universal HTTP Client for ObjectQL
|
|
4
|
+
*
|
|
5
|
+
* This package provides type-safe HTTP clients for ObjectQL servers.
|
|
6
|
+
* It works seamlessly in browsers, Node.js, Deno, and edge runtimes.
|
|
7
|
+
*
|
|
8
|
+
* ## Browser Compatibility
|
|
9
|
+
*
|
|
10
|
+
* The SDK uses modern JavaScript APIs:
|
|
11
|
+
* - fetch API (universal)
|
|
12
|
+
* - AbortSignal.timeout() (Chrome 103+, Firefox 100+, Safari 16.4+)
|
|
13
|
+
*
|
|
14
|
+
* For older browsers, a polyfill is automatically applied if AbortSignal.timeout is not available.
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
2
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RemoteDriver = void 0;
|
|
19
|
+
exports.MetadataApiClient = exports.DataApiClient = exports.RemoteDriver = void 0;
|
|
20
|
+
const types_1 = require("@objectql/types");
|
|
21
|
+
/**
|
|
22
|
+
* Polyfill for AbortSignal.timeout if not available (for older browsers)
|
|
23
|
+
* This ensures the SDK works universally across all JavaScript environments.
|
|
24
|
+
*/
|
|
25
|
+
if (typeof AbortSignal !== 'undefined' && !AbortSignal.timeout) {
|
|
26
|
+
AbortSignal.timeout = function (ms) {
|
|
27
|
+
const controller = new AbortController();
|
|
28
|
+
setTimeout(() => controller.abort(), ms);
|
|
29
|
+
return controller.signal;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Helper function to create a timeout signal that works in all environments
|
|
34
|
+
*/
|
|
35
|
+
function createTimeoutSignal(ms) {
|
|
36
|
+
if (typeof AbortSignal !== 'undefined' && AbortSignal.timeout) {
|
|
37
|
+
return AbortSignal.timeout(ms);
|
|
38
|
+
}
|
|
39
|
+
// Fallback for environments without AbortSignal
|
|
40
|
+
const controller = new AbortController();
|
|
41
|
+
setTimeout(() => controller.abort(), ms);
|
|
42
|
+
return controller.signal;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Legacy Driver implementation that uses JSON-RPC style API
|
|
46
|
+
*/
|
|
4
47
|
class RemoteDriver {
|
|
5
48
|
constructor(baseUrl) {
|
|
6
49
|
this.baseUrl = baseUrl;
|
|
@@ -56,4 +99,175 @@ class RemoteDriver {
|
|
|
56
99
|
}
|
|
57
100
|
}
|
|
58
101
|
exports.RemoteDriver = RemoteDriver;
|
|
102
|
+
/**
|
|
103
|
+
* REST-based Data API Client
|
|
104
|
+
*
|
|
105
|
+
* Implements type-safe client for ObjectQL Data API endpoints.
|
|
106
|
+
* Uses the RESTful interface described in docs/api/rest.md
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const client = new DataApiClient({ baseUrl: 'http://localhost:3000' });
|
|
111
|
+
*
|
|
112
|
+
* // List users
|
|
113
|
+
* const response = await client.list('users', {
|
|
114
|
+
* filter: [['status', '=', 'active']],
|
|
115
|
+
* sort: [['created_at', 'desc']],
|
|
116
|
+
* limit: 20
|
|
117
|
+
* });
|
|
118
|
+
*
|
|
119
|
+
* // Get single user
|
|
120
|
+
* const user = await client.get('users', 'user_123');
|
|
121
|
+
*
|
|
122
|
+
* // Create user
|
|
123
|
+
* const newUser = await client.create('users', {
|
|
124
|
+
* name: 'Alice',
|
|
125
|
+
* email: 'alice@example.com'
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
class DataApiClient {
|
|
130
|
+
constructor(config) {
|
|
131
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
132
|
+
this.token = config.token;
|
|
133
|
+
this.headers = config.headers || {};
|
|
134
|
+
this.timeout = config.timeout || 30000;
|
|
135
|
+
}
|
|
136
|
+
async request(method, path, body, queryParams) {
|
|
137
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
138
|
+
// Add query parameters
|
|
139
|
+
if (queryParams) {
|
|
140
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
141
|
+
if (value !== undefined && value !== null) {
|
|
142
|
+
url.searchParams.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
const headers = {
|
|
147
|
+
'Content-Type': 'application/json',
|
|
148
|
+
...this.headers
|
|
149
|
+
};
|
|
150
|
+
if (this.token) {
|
|
151
|
+
headers['Authorization'] = `Bearer ${this.token}`;
|
|
152
|
+
}
|
|
153
|
+
const response = await fetch(url.toString(), {
|
|
154
|
+
method,
|
|
155
|
+
headers,
|
|
156
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
157
|
+
signal: createTimeoutSignal(this.timeout)
|
|
158
|
+
});
|
|
159
|
+
const json = await response.json();
|
|
160
|
+
if (json.error) {
|
|
161
|
+
throw new types_1.ObjectQLError({
|
|
162
|
+
code: json.error.code || types_1.ApiErrorCode.INTERNAL_ERROR,
|
|
163
|
+
message: json.error.message,
|
|
164
|
+
details: json.error.details
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return json;
|
|
168
|
+
}
|
|
169
|
+
async list(objectName, params) {
|
|
170
|
+
return this.request('GET', `/api/data/${objectName}`, undefined, params);
|
|
171
|
+
}
|
|
172
|
+
async get(objectName, id) {
|
|
173
|
+
return this.request('GET', `/api/data/${objectName}/${id}`);
|
|
174
|
+
}
|
|
175
|
+
async create(objectName, data) {
|
|
176
|
+
return this.request('POST', `/api/data/${objectName}`, data);
|
|
177
|
+
}
|
|
178
|
+
async createMany(objectName, data) {
|
|
179
|
+
return this.request('POST', `/api/data/${objectName}`, data);
|
|
180
|
+
}
|
|
181
|
+
async update(objectName, id, data) {
|
|
182
|
+
return this.request('PUT', `/api/data/${objectName}/${id}`, data);
|
|
183
|
+
}
|
|
184
|
+
async updateMany(objectName, request) {
|
|
185
|
+
return this.request('POST', `/api/data/${objectName}/bulk-update`, request);
|
|
186
|
+
}
|
|
187
|
+
async delete(objectName, id) {
|
|
188
|
+
return this.request('DELETE', `/api/data/${objectName}/${id}`);
|
|
189
|
+
}
|
|
190
|
+
async deleteMany(objectName, request) {
|
|
191
|
+
return this.request('POST', `/api/data/${objectName}/bulk-delete`, request);
|
|
192
|
+
}
|
|
193
|
+
async count(objectName, filters) {
|
|
194
|
+
return this.request('GET', `/api/data/${objectName}`, undefined, { filter: filters, limit: 0 });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.DataApiClient = DataApiClient;
|
|
198
|
+
/**
|
|
199
|
+
* REST-based Metadata API Client
|
|
200
|
+
*
|
|
201
|
+
* Implements type-safe client for ObjectQL Metadata API endpoints.
|
|
202
|
+
* Uses the interface described in docs/api/metadata.md
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* const client = new MetadataApiClient({ baseUrl: 'http://localhost:3000' });
|
|
207
|
+
*
|
|
208
|
+
* // List all objects
|
|
209
|
+
* const objects = await client.listObjects();
|
|
210
|
+
*
|
|
211
|
+
* // Get detailed object metadata
|
|
212
|
+
* const userSchema = await client.getObject('users');
|
|
213
|
+
* console.log(userSchema.fields);
|
|
214
|
+
*
|
|
215
|
+
* // Get field metadata
|
|
216
|
+
* const emailField = await client.getField('users', 'email');
|
|
217
|
+
*
|
|
218
|
+
* // List actions
|
|
219
|
+
* const actions = await client.listActions('users');
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
class MetadataApiClient {
|
|
223
|
+
constructor(config) {
|
|
224
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
225
|
+
this.token = config.token;
|
|
226
|
+
this.headers = config.headers || {};
|
|
227
|
+
this.timeout = config.timeout || 30000;
|
|
228
|
+
}
|
|
229
|
+
async request(method, path, body) {
|
|
230
|
+
const headers = {
|
|
231
|
+
'Content-Type': 'application/json',
|
|
232
|
+
...this.headers
|
|
233
|
+
};
|
|
234
|
+
if (this.token) {
|
|
235
|
+
headers['Authorization'] = `Bearer ${this.token}`;
|
|
236
|
+
}
|
|
237
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
238
|
+
method,
|
|
239
|
+
headers,
|
|
240
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
241
|
+
signal: createTimeoutSignal(this.timeout)
|
|
242
|
+
});
|
|
243
|
+
const json = await response.json();
|
|
244
|
+
if (json.error) {
|
|
245
|
+
throw new types_1.ObjectQLError({
|
|
246
|
+
code: json.error.code || types_1.ApiErrorCode.INTERNAL_ERROR,
|
|
247
|
+
message: json.error.message,
|
|
248
|
+
details: json.error.details
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
return json;
|
|
252
|
+
}
|
|
253
|
+
async listObjects() {
|
|
254
|
+
return this.request('GET', '/api/metadata/objects');
|
|
255
|
+
}
|
|
256
|
+
async getObject(objectName) {
|
|
257
|
+
return this.request('GET', `/api/metadata/object/${objectName}`);
|
|
258
|
+
}
|
|
259
|
+
async getField(objectName, fieldName) {
|
|
260
|
+
return this.request('GET', `/api/metadata/object/${objectName}/fields/${fieldName}`);
|
|
261
|
+
}
|
|
262
|
+
async listActions(objectName) {
|
|
263
|
+
return this.request('GET', `/api/metadata/object/${objectName}/actions`);
|
|
264
|
+
}
|
|
265
|
+
async listByType(metadataType) {
|
|
266
|
+
return this.request('GET', `/api/metadata/${metadataType}`);
|
|
267
|
+
}
|
|
268
|
+
async getMetadata(metadataType, id) {
|
|
269
|
+
return this.request('GET', `/api/metadata/${metadataType}/${id}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
exports.MetadataApiClient = MetadataApiClient;
|
|
59
273
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/jest.config.js
CHANGED
|
@@ -3,7 +3,9 @@ module.exports = {
|
|
|
3
3
|
testEnvironment: 'node',
|
|
4
4
|
testMatch: ['**/test/**/*.test.ts'],
|
|
5
5
|
moduleNameMapper: {
|
|
6
|
-
'^@objectql/
|
|
6
|
+
'^@objectql/types$': '<rootDir>/../../foundation/types/src',
|
|
7
|
+
'^@objectql/core$': '<rootDir>/../../foundation/core/src',
|
|
8
|
+
'^@objectql/platform-node$': '<rootDir>/../../foundation/platform-node/src',
|
|
7
9
|
},
|
|
8
10
|
transform: {
|
|
9
11
|
'^.+\\.ts$': ['ts-jest', {
|
package/package.json
CHANGED
|
@@ -1,16 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectql/sdk",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.3",
|
|
4
|
+
"description": "Remote HTTP driver for ObjectQL - Universal client for browser, Node.js, and edge runtimes",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"objectql",
|
|
7
|
+
"sdk",
|
|
8
|
+
"driver",
|
|
9
|
+
"remote",
|
|
10
|
+
"http",
|
|
11
|
+
"client",
|
|
12
|
+
"browser",
|
|
13
|
+
"frontend",
|
|
14
|
+
"universal",
|
|
15
|
+
"api",
|
|
16
|
+
"rest",
|
|
17
|
+
"fetch",
|
|
18
|
+
"typescript",
|
|
19
|
+
"esm",
|
|
20
|
+
"react",
|
|
21
|
+
"vue",
|
|
22
|
+
"angular"
|
|
23
|
+
],
|
|
4
24
|
"license": "MIT",
|
|
5
|
-
"description": "Remote/HTTP Driver for ObjectQL",
|
|
6
25
|
"main": "dist/index.js",
|
|
7
26
|
"types": "dist/index.d.ts",
|
|
27
|
+
"browser": "dist/index.js",
|
|
28
|
+
"sideEffects": false,
|
|
8
29
|
"dependencies": {
|
|
9
|
-
"@objectql/types": "1.8.
|
|
30
|
+
"@objectql/types": "1.8.3"
|
|
10
31
|
},
|
|
11
32
|
"devDependencies": {
|
|
12
33
|
"typescript": "^5.3.0"
|
|
13
34
|
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/objectstack-ai/objectql.git",
|
|
38
|
+
"directory": "packages/drivers/sdk"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/objectstack-ai/objectql/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://objectql.org",
|
|
14
44
|
"scripts": {
|
|
15
45
|
"build": "tsc",
|
|
16
46
|
"test": "jest"
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,76 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @objectql/sdk - Universal HTTP Client for ObjectQL
|
|
3
|
+
*
|
|
4
|
+
* This package provides type-safe HTTP clients for ObjectQL servers.
|
|
5
|
+
* It works seamlessly in browsers, Node.js, Deno, and edge runtimes.
|
|
6
|
+
*
|
|
7
|
+
* ## Browser Compatibility
|
|
8
|
+
*
|
|
9
|
+
* The SDK uses modern JavaScript APIs:
|
|
10
|
+
* - fetch API (universal)
|
|
11
|
+
* - AbortSignal.timeout() (Chrome 103+, Firefox 100+, Safari 16.4+)
|
|
12
|
+
*
|
|
13
|
+
* For older browsers, a polyfill is automatically applied if AbortSignal.timeout is not available.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
2
17
|
|
|
18
|
+
import {
|
|
19
|
+
Driver,
|
|
20
|
+
IDataApiClient,
|
|
21
|
+
IMetadataApiClient,
|
|
22
|
+
DataApiClientConfig,
|
|
23
|
+
MetadataApiClientConfig,
|
|
24
|
+
DataApiListParams,
|
|
25
|
+
DataApiListResponse,
|
|
26
|
+
DataApiItemResponse,
|
|
27
|
+
DataApiCreateRequest,
|
|
28
|
+
DataApiCreateManyRequest,
|
|
29
|
+
DataApiUpdateRequest,
|
|
30
|
+
DataApiBulkUpdateRequest,
|
|
31
|
+
DataApiBulkDeleteRequest,
|
|
32
|
+
DataApiCountResponse,
|
|
33
|
+
DataApiDeleteResponse,
|
|
34
|
+
DataApiResponse,
|
|
35
|
+
MetadataApiObjectListResponse,
|
|
36
|
+
MetadataApiObjectDetailResponse,
|
|
37
|
+
FieldMetadataResponse,
|
|
38
|
+
MetadataApiActionsResponse,
|
|
39
|
+
MetadataApiListResponse,
|
|
40
|
+
MetadataApiResponse,
|
|
41
|
+
ObjectQLError,
|
|
42
|
+
ApiErrorCode,
|
|
43
|
+
FilterExpression
|
|
44
|
+
} from '@objectql/types';
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Polyfill for AbortSignal.timeout if not available (for older browsers)
|
|
48
|
+
* This ensures the SDK works universally across all JavaScript environments.
|
|
49
|
+
*/
|
|
50
|
+
if (typeof AbortSignal !== 'undefined' && !AbortSignal.timeout) {
|
|
51
|
+
(AbortSignal as any).timeout = function(ms: number): AbortSignal {
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
setTimeout(() => controller.abort(), ms);
|
|
54
|
+
return controller.signal;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Helper function to create a timeout signal that works in all environments
|
|
60
|
+
*/
|
|
61
|
+
function createTimeoutSignal(ms: number): AbortSignal {
|
|
62
|
+
if (typeof AbortSignal !== 'undefined' && AbortSignal.timeout) {
|
|
63
|
+
return AbortSignal.timeout(ms);
|
|
64
|
+
}
|
|
65
|
+
// Fallback for environments without AbortSignal
|
|
66
|
+
const controller = new AbortController();
|
|
67
|
+
setTimeout(() => controller.abort(), ms);
|
|
68
|
+
return controller.signal;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Legacy Driver implementation that uses JSON-RPC style API
|
|
73
|
+
*/
|
|
3
74
|
export class RemoteDriver implements Driver {
|
|
4
75
|
constructor(private baseUrl: string) {}
|
|
5
76
|
|
|
@@ -66,3 +137,272 @@ export class RemoteDriver implements Driver {
|
|
|
66
137
|
return this.request('deleteMany', objectName, { filters });
|
|
67
138
|
}
|
|
68
139
|
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* REST-based Data API Client
|
|
143
|
+
*
|
|
144
|
+
* Implements type-safe client for ObjectQL Data API endpoints.
|
|
145
|
+
* Uses the RESTful interface described in docs/api/rest.md
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const client = new DataApiClient({ baseUrl: 'http://localhost:3000' });
|
|
150
|
+
*
|
|
151
|
+
* // List users
|
|
152
|
+
* const response = await client.list('users', {
|
|
153
|
+
* filter: [['status', '=', 'active']],
|
|
154
|
+
* sort: [['created_at', 'desc']],
|
|
155
|
+
* limit: 20
|
|
156
|
+
* });
|
|
157
|
+
*
|
|
158
|
+
* // Get single user
|
|
159
|
+
* const user = await client.get('users', 'user_123');
|
|
160
|
+
*
|
|
161
|
+
* // Create user
|
|
162
|
+
* const newUser = await client.create('users', {
|
|
163
|
+
* name: 'Alice',
|
|
164
|
+
* email: 'alice@example.com'
|
|
165
|
+
* });
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
export class DataApiClient implements IDataApiClient {
|
|
169
|
+
private baseUrl: string;
|
|
170
|
+
private token?: string;
|
|
171
|
+
private headers: Record<string, string>;
|
|
172
|
+
private timeout: number;
|
|
173
|
+
|
|
174
|
+
constructor(config: DataApiClientConfig) {
|
|
175
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
176
|
+
this.token = config.token;
|
|
177
|
+
this.headers = config.headers || {};
|
|
178
|
+
this.timeout = config.timeout || 30000;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private async request<T>(
|
|
182
|
+
method: string,
|
|
183
|
+
path: string,
|
|
184
|
+
body?: unknown,
|
|
185
|
+
queryParams?: Record<string, unknown>
|
|
186
|
+
): Promise<T> {
|
|
187
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
188
|
+
|
|
189
|
+
// Add query parameters
|
|
190
|
+
if (queryParams) {
|
|
191
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
192
|
+
if (value !== undefined && value !== null) {
|
|
193
|
+
url.searchParams.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value));
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const headers: Record<string, string> = {
|
|
199
|
+
'Content-Type': 'application/json',
|
|
200
|
+
...this.headers
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
if (this.token) {
|
|
204
|
+
headers['Authorization'] = `Bearer ${this.token}`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const response = await fetch(url.toString(), {
|
|
208
|
+
method,
|
|
209
|
+
headers,
|
|
210
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
211
|
+
signal: createTimeoutSignal(this.timeout)
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const json = await response.json();
|
|
215
|
+
|
|
216
|
+
if (json.error) {
|
|
217
|
+
throw new ObjectQLError({
|
|
218
|
+
code: json.error.code || ApiErrorCode.INTERNAL_ERROR,
|
|
219
|
+
message: json.error.message,
|
|
220
|
+
details: json.error.details
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return json as T;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async list<T = unknown>(objectName: string, params?: DataApiListParams): Promise<DataApiListResponse<T>> {
|
|
228
|
+
return this.request<DataApiListResponse<T>>(
|
|
229
|
+
'GET',
|
|
230
|
+
`/api/data/${objectName}`,
|
|
231
|
+
undefined,
|
|
232
|
+
params as Record<string, unknown>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async get<T = unknown>(objectName: string, id: string | number): Promise<DataApiItemResponse<T>> {
|
|
237
|
+
return this.request<DataApiItemResponse<T>>(
|
|
238
|
+
'GET',
|
|
239
|
+
`/api/data/${objectName}/${id}`
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async create<T = unknown>(objectName: string, data: DataApiCreateRequest): Promise<DataApiItemResponse<T>> {
|
|
244
|
+
return this.request<DataApiItemResponse<T>>(
|
|
245
|
+
'POST',
|
|
246
|
+
`/api/data/${objectName}`,
|
|
247
|
+
data
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async createMany<T = unknown>(objectName: string, data: DataApiCreateManyRequest): Promise<DataApiListResponse<T>> {
|
|
252
|
+
return this.request<DataApiListResponse<T>>(
|
|
253
|
+
'POST',
|
|
254
|
+
`/api/data/${objectName}`,
|
|
255
|
+
data
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async update<T = unknown>(objectName: string, id: string | number, data: DataApiUpdateRequest): Promise<DataApiItemResponse<T>> {
|
|
260
|
+
return this.request<DataApiItemResponse<T>>(
|
|
261
|
+
'PUT',
|
|
262
|
+
`/api/data/${objectName}/${id}`,
|
|
263
|
+
data
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async updateMany(objectName: string, request: DataApiBulkUpdateRequest): Promise<DataApiResponse> {
|
|
268
|
+
return this.request<DataApiResponse>(
|
|
269
|
+
'POST',
|
|
270
|
+
`/api/data/${objectName}/bulk-update`,
|
|
271
|
+
request
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async delete(objectName: string, id: string | number): Promise<DataApiDeleteResponse> {
|
|
276
|
+
return this.request<DataApiDeleteResponse>(
|
|
277
|
+
'DELETE',
|
|
278
|
+
`/api/data/${objectName}/${id}`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async deleteMany(objectName: string, request: DataApiBulkDeleteRequest): Promise<DataApiDeleteResponse> {
|
|
283
|
+
return this.request<DataApiDeleteResponse>(
|
|
284
|
+
'POST',
|
|
285
|
+
`/api/data/${objectName}/bulk-delete`,
|
|
286
|
+
request
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
async count(objectName: string, filters?: FilterExpression): Promise<DataApiCountResponse> {
|
|
291
|
+
return this.request<DataApiCountResponse>(
|
|
292
|
+
'GET',
|
|
293
|
+
`/api/data/${objectName}`,
|
|
294
|
+
undefined,
|
|
295
|
+
{ filter: filters, limit: 0 }
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* REST-based Metadata API Client
|
|
302
|
+
*
|
|
303
|
+
* Implements type-safe client for ObjectQL Metadata API endpoints.
|
|
304
|
+
* Uses the interface described in docs/api/metadata.md
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```typescript
|
|
308
|
+
* const client = new MetadataApiClient({ baseUrl: 'http://localhost:3000' });
|
|
309
|
+
*
|
|
310
|
+
* // List all objects
|
|
311
|
+
* const objects = await client.listObjects();
|
|
312
|
+
*
|
|
313
|
+
* // Get detailed object metadata
|
|
314
|
+
* const userSchema = await client.getObject('users');
|
|
315
|
+
* console.log(userSchema.fields);
|
|
316
|
+
*
|
|
317
|
+
* // Get field metadata
|
|
318
|
+
* const emailField = await client.getField('users', 'email');
|
|
319
|
+
*
|
|
320
|
+
* // List actions
|
|
321
|
+
* const actions = await client.listActions('users');
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
export class MetadataApiClient implements IMetadataApiClient {
|
|
325
|
+
private baseUrl: string;
|
|
326
|
+
private token?: string;
|
|
327
|
+
private headers: Record<string, string>;
|
|
328
|
+
private timeout: number;
|
|
329
|
+
|
|
330
|
+
constructor(config: MetadataApiClientConfig) {
|
|
331
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
332
|
+
this.token = config.token;
|
|
333
|
+
this.headers = config.headers || {};
|
|
334
|
+
this.timeout = config.timeout || 30000;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
private async request<T>(method: string, path: string, body?: unknown): Promise<T> {
|
|
338
|
+
const headers: Record<string, string> = {
|
|
339
|
+
'Content-Type': 'application/json',
|
|
340
|
+
...this.headers
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
if (this.token) {
|
|
344
|
+
headers['Authorization'] = `Bearer ${this.token}`;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
348
|
+
method,
|
|
349
|
+
headers,
|
|
350
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
351
|
+
signal: createTimeoutSignal(this.timeout)
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
const json = await response.json();
|
|
355
|
+
|
|
356
|
+
if (json.error) {
|
|
357
|
+
throw new ObjectQLError({
|
|
358
|
+
code: json.error.code || ApiErrorCode.INTERNAL_ERROR,
|
|
359
|
+
message: json.error.message,
|
|
360
|
+
details: json.error.details
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return json as T;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async listObjects(): Promise<MetadataApiObjectListResponse> {
|
|
368
|
+
return this.request<MetadataApiObjectListResponse>(
|
|
369
|
+
'GET',
|
|
370
|
+
'/api/metadata/objects'
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
async getObject(objectName: string): Promise<MetadataApiObjectDetailResponse> {
|
|
375
|
+
return this.request<MetadataApiObjectDetailResponse>(
|
|
376
|
+
'GET',
|
|
377
|
+
`/api/metadata/object/${objectName}`
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
async getField(objectName: string, fieldName: string): Promise<FieldMetadataResponse> {
|
|
382
|
+
return this.request<FieldMetadataResponse>(
|
|
383
|
+
'GET',
|
|
384
|
+
`/api/metadata/object/${objectName}/fields/${fieldName}`
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
async listActions(objectName: string): Promise<MetadataApiActionsResponse> {
|
|
389
|
+
return this.request<MetadataApiActionsResponse>(
|
|
390
|
+
'GET',
|
|
391
|
+
`/api/metadata/object/${objectName}/actions`
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
async listByType<T = unknown>(metadataType: string): Promise<MetadataApiListResponse<T>> {
|
|
396
|
+
return this.request<MetadataApiListResponse<T>>(
|
|
397
|
+
'GET',
|
|
398
|
+
`/api/metadata/${metadataType}`
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
async getMetadata<T = unknown>(metadataType: string, id: string): Promise<MetadataApiResponse<T>> {
|
|
403
|
+
return this.request<MetadataApiResponse<T>>(
|
|
404
|
+
'GET',
|
|
405
|
+
`/api/metadata/${metadataType}/${id}`
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
}
|