@object-ui/data-objectstack 0.3.1 → 2.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/README.md +317 -1
- package/dist/index.cjs +814 -39
- package/dist/index.d.cts +337 -8
- package/dist/index.d.ts +337 -8
- package/dist/index.js +804 -38
- package/package.json +5 -5
- package/src/cache/MetadataCache.test.ts +426 -0
- package/src/cache/MetadataCache.ts +229 -0
- package/src/connection.test.ts +141 -0
- package/src/errors.test.ts +426 -0
- package/src/errors.ts +275 -0
- package/src/index.ts +679 -48
- package/src/upload.test.ts +112 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ObjectStackClient } from '@objectstack/client';
|
|
2
|
-
import { DataSource, QueryParams, QueryResult } from '@object-ui/types';
|
|
2
|
+
import { DataSource, QueryParams, QueryResult, FileUploadResult } from '@object-ui/types';
|
|
3
|
+
export { FileUploadResult } from '@object-ui/types';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* ObjectUI
|
|
@@ -8,6 +9,186 @@ import { DataSource, QueryParams, QueryResult } from '@object-ui/types';
|
|
|
8
9
|
* This source code is licensed under the MIT license found in the
|
|
9
10
|
* LICENSE file in the root directory of this source tree.
|
|
10
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* Base error class for all ObjectStack adapter errors
|
|
14
|
+
*/
|
|
15
|
+
declare class ObjectStackError extends Error {
|
|
16
|
+
code: string;
|
|
17
|
+
statusCode?: number | undefined;
|
|
18
|
+
details?: Record<string, unknown> | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Create a new ObjectStackError
|
|
21
|
+
*
|
|
22
|
+
* @param message - Human-readable error message
|
|
23
|
+
* @param code - Unique error code for programmatic handling
|
|
24
|
+
* @param statusCode - Optional HTTP status code
|
|
25
|
+
* @param details - Optional additional error details for debugging
|
|
26
|
+
*/
|
|
27
|
+
constructor(message: string, code: string, statusCode?: number | undefined, details?: Record<string, unknown> | undefined);
|
|
28
|
+
/**
|
|
29
|
+
* Convert error to JSON for logging/debugging
|
|
30
|
+
*/
|
|
31
|
+
toJSON(): {
|
|
32
|
+
name: string;
|
|
33
|
+
message: string;
|
|
34
|
+
code: string;
|
|
35
|
+
statusCode: number | undefined;
|
|
36
|
+
details: Record<string, unknown> | undefined;
|
|
37
|
+
stack: string | undefined;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Error thrown when requested metadata/schema is not found
|
|
42
|
+
*/
|
|
43
|
+
declare class MetadataNotFoundError extends ObjectStackError {
|
|
44
|
+
constructor(objectName: string, details?: Record<string, unknown>);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Error thrown when a bulk operation fails
|
|
48
|
+
*/
|
|
49
|
+
declare class BulkOperationError extends ObjectStackError {
|
|
50
|
+
successCount: number;
|
|
51
|
+
failureCount: number;
|
|
52
|
+
errors: Array<{
|
|
53
|
+
index: number;
|
|
54
|
+
error: unknown;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Create a new BulkOperationError
|
|
58
|
+
*
|
|
59
|
+
* @param operation - The bulk operation that failed (create, update, delete)
|
|
60
|
+
* @param successCount - Number of successful operations
|
|
61
|
+
* @param failureCount - Number of failed operations
|
|
62
|
+
* @param errors - Array of individual errors
|
|
63
|
+
* @param details - Additional error details
|
|
64
|
+
*/
|
|
65
|
+
constructor(operation: 'create' | 'update' | 'delete', successCount: number, failureCount: number, errors: Array<{
|
|
66
|
+
index: number;
|
|
67
|
+
error: unknown;
|
|
68
|
+
}>, details?: Record<string, unknown>);
|
|
69
|
+
/**
|
|
70
|
+
* Get a summary of the bulk operation failure
|
|
71
|
+
*/
|
|
72
|
+
getSummary(): {
|
|
73
|
+
operation: string;
|
|
74
|
+
total: number;
|
|
75
|
+
successful: number;
|
|
76
|
+
failed: number;
|
|
77
|
+
failureRate: number;
|
|
78
|
+
errors: {
|
|
79
|
+
index: number;
|
|
80
|
+
error: unknown;
|
|
81
|
+
}[];
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Error thrown when connection to ObjectStack server fails
|
|
86
|
+
*/
|
|
87
|
+
declare class ConnectionError extends ObjectStackError {
|
|
88
|
+
url?: string | undefined;
|
|
89
|
+
constructor(message: string, url?: string | undefined, details?: Record<string, unknown>, statusCode?: number);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Error thrown when authentication fails
|
|
93
|
+
*/
|
|
94
|
+
declare class AuthenticationError extends ObjectStackError {
|
|
95
|
+
constructor(message?: string, details?: Record<string, unknown>, statusCode?: number);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Error thrown when data validation fails
|
|
99
|
+
*/
|
|
100
|
+
declare class ValidationError extends ObjectStackError {
|
|
101
|
+
field?: string | undefined;
|
|
102
|
+
validationErrors?: Array<{
|
|
103
|
+
field: string;
|
|
104
|
+
message: string;
|
|
105
|
+
}> | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* Create a new ValidationError
|
|
108
|
+
*
|
|
109
|
+
* @param message - Human-readable error message
|
|
110
|
+
* @param field - The field that failed validation (optional)
|
|
111
|
+
* @param validationErrors - Array of validation error details
|
|
112
|
+
* @param details - Additional error details
|
|
113
|
+
*/
|
|
114
|
+
constructor(message: string, field?: string | undefined, validationErrors?: Array<{
|
|
115
|
+
field: string;
|
|
116
|
+
message: string;
|
|
117
|
+
}> | undefined, details?: Record<string, unknown>);
|
|
118
|
+
/**
|
|
119
|
+
* Get all validation errors as a formatted list
|
|
120
|
+
*/
|
|
121
|
+
getValidationErrors(): {
|
|
122
|
+
field: string;
|
|
123
|
+
message: string;
|
|
124
|
+
}[];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Helper function to create an error from an HTTP response
|
|
128
|
+
*
|
|
129
|
+
* @param response - Response object or error from fetch/axios
|
|
130
|
+
* @param context - Additional context for debugging
|
|
131
|
+
* @returns Appropriate error instance
|
|
132
|
+
*/
|
|
133
|
+
declare function createErrorFromResponse(response: Record<string, unknown>, context?: string): ObjectStackError;
|
|
134
|
+
/**
|
|
135
|
+
* Type guard to check if an error is an ObjectStackError
|
|
136
|
+
*/
|
|
137
|
+
declare function isObjectStackError(error: unknown): error is ObjectStackError;
|
|
138
|
+
/**
|
|
139
|
+
* Type guard to check if an error is a specific ObjectStack error type
|
|
140
|
+
*/
|
|
141
|
+
declare function isErrorType<T extends ObjectStackError>(error: unknown, errorClass: new (...args: any[]) => T): error is T;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* ObjectUI
|
|
145
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
146
|
+
*
|
|
147
|
+
* This source code is licensed under the MIT license found in the
|
|
148
|
+
* LICENSE file in the root directory of this source tree.
|
|
149
|
+
*/
|
|
150
|
+
/**
|
|
151
|
+
* Cache statistics for monitoring
|
|
152
|
+
*/
|
|
153
|
+
interface CacheStats {
|
|
154
|
+
size: number;
|
|
155
|
+
maxSize: number;
|
|
156
|
+
hits: number;
|
|
157
|
+
misses: number;
|
|
158
|
+
evictions: number;
|
|
159
|
+
hitRate: number;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Connection state for monitoring
|
|
164
|
+
*/
|
|
165
|
+
type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error';
|
|
166
|
+
/**
|
|
167
|
+
* Connection state change event
|
|
168
|
+
*/
|
|
169
|
+
interface ConnectionStateEvent {
|
|
170
|
+
state: ConnectionState;
|
|
171
|
+
timestamp: number;
|
|
172
|
+
error?: Error;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Batch operation progress event
|
|
176
|
+
*/
|
|
177
|
+
interface BatchProgressEvent {
|
|
178
|
+
operation: 'create' | 'update' | 'delete';
|
|
179
|
+
total: number;
|
|
180
|
+
completed: number;
|
|
181
|
+
failed: number;
|
|
182
|
+
percentage: number;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Event listener type for connection state changes
|
|
186
|
+
*/
|
|
187
|
+
type ConnectionStateListener = (event: ConnectionStateEvent) => void;
|
|
188
|
+
/**
|
|
189
|
+
* Event listener type for batch operation progress
|
|
190
|
+
*/
|
|
191
|
+
type BatchProgressListener = (event: BatchProgressEvent) => void;
|
|
11
192
|
|
|
12
193
|
/**
|
|
13
194
|
* ObjectStack Data Source Adapter
|
|
@@ -22,7 +203,14 @@ import { DataSource, QueryParams, QueryResult } from '@object-ui/types';
|
|
|
22
203
|
*
|
|
23
204
|
* const dataSource = new ObjectStackAdapter({
|
|
24
205
|
* baseUrl: 'https://api.example.com',
|
|
25
|
-
* token: 'your-api-token'
|
|
206
|
+
* token: 'your-api-token',
|
|
207
|
+
* autoReconnect: true,
|
|
208
|
+
* maxReconnectAttempts: 5
|
|
209
|
+
* });
|
|
210
|
+
*
|
|
211
|
+
* // Monitor connection state
|
|
212
|
+
* dataSource.onConnectionStateChange((event) => {
|
|
213
|
+
* console.log('Connection state:', event.state);
|
|
26
214
|
* });
|
|
27
215
|
*
|
|
28
216
|
* const users = await dataSource.find('users', {
|
|
@@ -31,19 +219,64 @@ import { DataSource, QueryParams, QueryResult } from '@object-ui/types';
|
|
|
31
219
|
* });
|
|
32
220
|
* ```
|
|
33
221
|
*/
|
|
34
|
-
declare class ObjectStackAdapter<T =
|
|
222
|
+
declare class ObjectStackAdapter<T = unknown> implements DataSource<T> {
|
|
35
223
|
private client;
|
|
36
224
|
private connected;
|
|
225
|
+
private metadataCache;
|
|
226
|
+
private connectionState;
|
|
227
|
+
private connectionStateListeners;
|
|
228
|
+
private batchProgressListeners;
|
|
229
|
+
private autoReconnect;
|
|
230
|
+
private maxReconnectAttempts;
|
|
231
|
+
private reconnectDelay;
|
|
232
|
+
private reconnectAttempts;
|
|
233
|
+
private baseUrl;
|
|
234
|
+
private token?;
|
|
37
235
|
constructor(config: {
|
|
38
236
|
baseUrl: string;
|
|
39
237
|
token?: string;
|
|
40
238
|
fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
239
|
+
cache?: {
|
|
240
|
+
maxSize?: number;
|
|
241
|
+
ttl?: number;
|
|
242
|
+
};
|
|
243
|
+
autoReconnect?: boolean;
|
|
244
|
+
maxReconnectAttempts?: number;
|
|
245
|
+
reconnectDelay?: number;
|
|
41
246
|
});
|
|
42
247
|
/**
|
|
43
248
|
* Ensure the client is connected to the server.
|
|
44
249
|
* Call this before making requests or it will auto-connect on first request.
|
|
45
250
|
*/
|
|
46
251
|
connect(): Promise<void>;
|
|
252
|
+
/**
|
|
253
|
+
* Attempt to reconnect to the server with exponential backoff
|
|
254
|
+
*/
|
|
255
|
+
private attemptReconnect;
|
|
256
|
+
/**
|
|
257
|
+
* Get the current connection state
|
|
258
|
+
*/
|
|
259
|
+
getConnectionState(): ConnectionState;
|
|
260
|
+
/**
|
|
261
|
+
* Check if the adapter is currently connected
|
|
262
|
+
*/
|
|
263
|
+
isConnected(): boolean;
|
|
264
|
+
/**
|
|
265
|
+
* Register a listener for connection state changes
|
|
266
|
+
*/
|
|
267
|
+
onConnectionStateChange(listener: ConnectionStateListener): () => void;
|
|
268
|
+
/**
|
|
269
|
+
* Register a listener for batch operation progress
|
|
270
|
+
*/
|
|
271
|
+
onBatchProgress(listener: BatchProgressListener): () => void;
|
|
272
|
+
/**
|
|
273
|
+
* Set connection state and notify listeners
|
|
274
|
+
*/
|
|
275
|
+
private setConnectionState;
|
|
276
|
+
/**
|
|
277
|
+
* Emit batch progress event to listeners
|
|
278
|
+
*/
|
|
279
|
+
private emitBatchProgress;
|
|
47
280
|
/**
|
|
48
281
|
* Find multiple records with query parameters.
|
|
49
282
|
* Converts OData-style params to ObjectStack query options.
|
|
@@ -66,7 +299,13 @@ declare class ObjectStackAdapter<T = any> implements DataSource<T> {
|
|
|
66
299
|
*/
|
|
67
300
|
delete(resource: string, id: string | number): Promise<boolean>;
|
|
68
301
|
/**
|
|
69
|
-
* Bulk operations
|
|
302
|
+
* Bulk operations with optimized batch processing and error handling.
|
|
303
|
+
* Emits progress events for tracking operation status.
|
|
304
|
+
*
|
|
305
|
+
* @param resource - Resource name
|
|
306
|
+
* @param operation - Operation type (create, update, delete)
|
|
307
|
+
* @param data - Array of records to process
|
|
308
|
+
* @returns Promise resolving to array of results
|
|
70
309
|
*/
|
|
71
310
|
bulk(resource: string, operation: 'create' | 'update' | 'delete', data: Partial<T>[]): Promise<T[]>;
|
|
72
311
|
/**
|
|
@@ -76,15 +315,95 @@ declare class ObjectStackAdapter<T = any> implements DataSource<T> {
|
|
|
76
315
|
private convertQueryParams;
|
|
77
316
|
/**
|
|
78
317
|
* Get object schema/metadata from ObjectStack.
|
|
318
|
+
* Uses caching to improve performance for repeated requests.
|
|
79
319
|
*
|
|
80
320
|
* @param objectName - Object name
|
|
81
321
|
* @returns Promise resolving to the object schema
|
|
82
322
|
*/
|
|
83
|
-
getObjectSchema(objectName: string): Promise<
|
|
323
|
+
getObjectSchema(objectName: string): Promise<unknown>;
|
|
84
324
|
/**
|
|
85
325
|
* Get access to the underlying ObjectStack client for advanced operations.
|
|
86
326
|
*/
|
|
87
327
|
getClient(): ObjectStackClient;
|
|
328
|
+
/**
|
|
329
|
+
* Get the discovery information from the connected server.
|
|
330
|
+
* Returns the capabilities and service status of the ObjectStack server.
|
|
331
|
+
*
|
|
332
|
+
* Note: This accesses an internal property of the ObjectStackClient.
|
|
333
|
+
* The discovery data is populated during client.connect() and cached.
|
|
334
|
+
*
|
|
335
|
+
* @returns Promise resolving to discovery data, or null if not connected
|
|
336
|
+
*/
|
|
337
|
+
getDiscovery(): Promise<unknown | null>;
|
|
338
|
+
/**
|
|
339
|
+
* Get a view definition for an object.
|
|
340
|
+
* Attempts to fetch from the server metadata API.
|
|
341
|
+
* Falls back to null if the server doesn't provide view definitions,
|
|
342
|
+
* allowing the consumer to use static config.
|
|
343
|
+
*
|
|
344
|
+
* @param objectName - Object name
|
|
345
|
+
* @param viewId - View identifier
|
|
346
|
+
* @returns Promise resolving to the view definition or null
|
|
347
|
+
*/
|
|
348
|
+
getView(objectName: string, viewId: string): Promise<unknown | null>;
|
|
349
|
+
/**
|
|
350
|
+
* Get an application definition by name or ID.
|
|
351
|
+
* Attempts to fetch from the server metadata API.
|
|
352
|
+
* Falls back to null if the server doesn't provide app definitions,
|
|
353
|
+
* allowing the consumer to use static config.
|
|
354
|
+
*
|
|
355
|
+
* @param appId - Application identifier
|
|
356
|
+
* @returns Promise resolving to the app definition or null
|
|
357
|
+
*/
|
|
358
|
+
getApp(appId: string): Promise<unknown | null>;
|
|
359
|
+
/**
|
|
360
|
+
* Get cache statistics for monitoring performance.
|
|
361
|
+
*/
|
|
362
|
+
getCacheStats(): CacheStats;
|
|
363
|
+
/**
|
|
364
|
+
* Invalidate metadata cache entries.
|
|
365
|
+
*
|
|
366
|
+
* @param key - Optional key to invalidate. If omitted, invalidates all entries.
|
|
367
|
+
*/
|
|
368
|
+
invalidateCache(key?: string): void;
|
|
369
|
+
/**
|
|
370
|
+
* Clear all cache entries and statistics.
|
|
371
|
+
*/
|
|
372
|
+
clearCache(): void;
|
|
373
|
+
/**
|
|
374
|
+
* Upload a single file to a resource.
|
|
375
|
+
* Posts the file as multipart/form-data to the ObjectStack server.
|
|
376
|
+
*
|
|
377
|
+
* @param resource - The resource/object name to attach the file to
|
|
378
|
+
* @param file - File object or Blob to upload
|
|
379
|
+
* @param options - Additional upload options (recordId, fieldName, metadata)
|
|
380
|
+
* @returns Promise resolving to the upload result (file URL, metadata)
|
|
381
|
+
*/
|
|
382
|
+
uploadFile(resource: string, file: File | Blob, options?: {
|
|
383
|
+
recordId?: string;
|
|
384
|
+
fieldName?: string;
|
|
385
|
+
metadata?: Record<string, unknown>;
|
|
386
|
+
onProgress?: (percent: number) => void;
|
|
387
|
+
}): Promise<FileUploadResult>;
|
|
388
|
+
/**
|
|
389
|
+
* Upload multiple files to a resource.
|
|
390
|
+
* Posts all files as a single multipart/form-data request.
|
|
391
|
+
*
|
|
392
|
+
* @param resource - The resource/object name to attach the files to
|
|
393
|
+
* @param files - Array of File objects or Blobs to upload
|
|
394
|
+
* @param options - Additional upload options
|
|
395
|
+
* @returns Promise resolving to array of upload results
|
|
396
|
+
*/
|
|
397
|
+
uploadFiles(resource: string, files: (File | Blob)[], options?: {
|
|
398
|
+
recordId?: string;
|
|
399
|
+
fieldName?: string;
|
|
400
|
+
metadata?: Record<string, unknown>;
|
|
401
|
+
onProgress?: (percent: number) => void;
|
|
402
|
+
}): Promise<FileUploadResult[]>;
|
|
403
|
+
/**
|
|
404
|
+
* Get authorization headers from the adapter config.
|
|
405
|
+
*/
|
|
406
|
+
private getAuthHeaders;
|
|
88
407
|
}
|
|
89
408
|
/**
|
|
90
409
|
* Factory function to create an ObjectStack data source.
|
|
@@ -93,14 +412,24 @@ declare class ObjectStackAdapter<T = any> implements DataSource<T> {
|
|
|
93
412
|
* ```typescript
|
|
94
413
|
* const dataSource = createObjectStackAdapter({
|
|
95
414
|
* baseUrl: process.env.API_URL,
|
|
96
|
-
* token: process.env.API_TOKEN
|
|
415
|
+
* token: process.env.API_TOKEN,
|
|
416
|
+
* cache: { maxSize: 100, ttl: 300000 },
|
|
417
|
+
* autoReconnect: true,
|
|
418
|
+
* maxReconnectAttempts: 5
|
|
97
419
|
* });
|
|
98
420
|
* ```
|
|
99
421
|
*/
|
|
100
|
-
declare function createObjectStackAdapter<T =
|
|
422
|
+
declare function createObjectStackAdapter<T = unknown>(config: {
|
|
101
423
|
baseUrl: string;
|
|
102
424
|
token?: string;
|
|
103
425
|
fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
426
|
+
cache?: {
|
|
427
|
+
maxSize?: number;
|
|
428
|
+
ttl?: number;
|
|
429
|
+
};
|
|
430
|
+
autoReconnect?: boolean;
|
|
431
|
+
maxReconnectAttempts?: number;
|
|
432
|
+
reconnectDelay?: number;
|
|
104
433
|
}): DataSource<T>;
|
|
105
434
|
|
|
106
|
-
export { ObjectStackAdapter, createObjectStackAdapter };
|
|
435
|
+
export { AuthenticationError, type BatchProgressEvent, type BatchProgressListener, BulkOperationError, type CacheStats, ConnectionError, type ConnectionState, type ConnectionStateEvent, type ConnectionStateListener, MetadataNotFoundError, ObjectStackAdapter, ObjectStackError, ValidationError, createErrorFromResponse, createObjectStackAdapter, isErrorType, isObjectStackError };
|