@deliverart/sdk-js-core 2.1.49 → 2.1.51

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.
Files changed (2) hide show
  1. package/README.md +429 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,429 @@
1
+ # @deliverart/sdk-js-core
2
+
3
+ Core package for the DeliverArt JavaScript SDK. Provides the API client, plugin system, and base request/response handling.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @deliverart/sdk-js-core
9
+ # or
10
+ pnpm add @deliverart/sdk-js-core
11
+ # or
12
+ yarn add @deliverart/sdk-js-core
13
+ ```
14
+
15
+ ## Exported Types
16
+
17
+ ### ApiClient
18
+ ```typescript
19
+ type ApiClient<Extensions extends ApiExtension = NonNullable<unknown>>
20
+ ```
21
+ The main API client interface that provides methods to make API calls and manage plugins.
22
+
23
+ **Methods:**
24
+ - `call<TInputSchema, TOutputSchema, Q, H>(request: AbstractApiRequest): Promise<output<TOutputSchema>>` - Execute an API request
25
+ - `addPlugin<T extends ApiExtension>(plugin: ApiClientPlugin<T>): ApiClient<T>` - Add a plugin to extend client functionality
26
+ - `addRequestMiddleware(middleware: RequestMiddleware): void` - Add middleware to intercept requests
27
+ - `addResponseMiddleware(middleware: ResponseMiddleware): void` - Add middleware to intercept responses
28
+
29
+ ### AbstractApiRequest
30
+ ```typescript
31
+ abstract class AbstractApiRequest<
32
+ TInputSchema extends ZodType<any, any, any>,
33
+ TOutputSchema extends ZodType<any, any, any>,
34
+ Query = unknown,
35
+ Headers = unknown
36
+ >
37
+ ```
38
+ Base class for all API requests. Extend this class to create custom API requests.
39
+
40
+ **Abstract Properties:**
41
+ - `method: 'GET' | 'POST' | 'PATCH' | 'DELETE'` - HTTP method (required)
42
+ - `contentType: 'application/json' | 'multipart/form-data' | 'application/merge-patch+json'` - Content-Type header (required)
43
+ - `accept: 'application/json'` - Accept header (required)
44
+ - `inputSchema: TInputSchema` - Zod schema for request validation (required)
45
+ - `outputSchema: TOutputSchema` - Zod schema for response validation (required)
46
+ - `querySchema?: ZodType<Query>` - Zod schema for query parameters (optional)
47
+ - `headersSchema?: ZodType<Headers>` - Zod schema for headers (optional)
48
+
49
+ **Abstract Methods:**
50
+ - `getPath(): string` - Returns the API endpoint path (required)
51
+
52
+ **Built-in Methods:**
53
+ - `validateInput(): output<TInputSchema>` - Validates the request input
54
+ - `validateQuery(): Query | undefined` - Validates query parameters
55
+ - `validateHeaders(): Headers | undefined` - Validates headers
56
+ - `validateOutput(data: unknown): output<TOutputSchema>` - Validates the response
57
+ - `parseResponse(data: unknown, rawResponse?: Response): output<TOutputSchema>` - Parses and validates the response (can be overridden)
58
+
59
+ ### ApiExtension
60
+ ```typescript
61
+ type ApiExtension = Record<string, unknown>
62
+ ```
63
+ Base type for plugin extensions that add new methods to the API client.
64
+
65
+ ### ApiClientPlugin
66
+ ```typescript
67
+ interface ApiClientPlugin<T extends ApiExtension = Record<string, unknown>> {
68
+ setup: (client: ApiClient<Record<string, unknown>>) => T
69
+ }
70
+ ```
71
+ Interface for creating plugins that extend the API client functionality.
72
+
73
+ ### Errors
74
+
75
+ #### InputValidationError
76
+ ```typescript
77
+ class InputValidationError extends Error {
78
+ constructor(public readonly issues: ZodIssue[])
79
+ }
80
+ ```
81
+ Thrown when request input validation fails.
82
+
83
+ **Properties:**
84
+ - `issues: ZodIssue[]` - Array of validation errors from Zod
85
+
86
+ #### OutputValidationError
87
+ ```typescript
88
+ class OutputValidationError extends Error {
89
+ constructor(public readonly issues: ZodIssue[])
90
+ }
91
+ ```
92
+ Thrown when response validation fails.
93
+
94
+ **Properties:**
95
+ - `issues: ZodIssue[]` - Array of validation errors from Zod
96
+
97
+ ## Usage
98
+
99
+ ### Creating the API Client
100
+
101
+ ```typescript
102
+ import { createApiClient } from '@deliverart/sdk-js-core';
103
+
104
+ const client = createApiClient({
105
+ baseUrl: 'https://api.deliverart.com'
106
+ });
107
+ ```
108
+
109
+ **Parameters:**
110
+ - `baseUrl: string` (required) - The base URL for all API requests
111
+
112
+ ### Creating a Custom Request
113
+
114
+ ```typescript
115
+ import { AbstractApiRequest } from '@deliverart/sdk-js-core';
116
+ import { z } from 'zod';
117
+
118
+ // Define input schema
119
+ const createUserInputSchema = z.object({
120
+ name: z.string().min(1),
121
+ email: z.string().email(),
122
+ age: z.number().min(18).optional()
123
+ });
124
+
125
+ // Define output schema
126
+ const userResponseSchema = z.object({
127
+ id: z.string(),
128
+ name: z.string(),
129
+ email: z.string(),
130
+ age: z.number().nullable(),
131
+ createdAt: z.string()
132
+ });
133
+
134
+ // Define query parameters schema (optional)
135
+ const getUsersQuerySchema = z.object({
136
+ page: z.number().optional(),
137
+ limit: z.number().optional(),
138
+ search: z.string().optional()
139
+ });
140
+
141
+ // Create the request class
142
+ class CreateUser extends AbstractApiRequest<
143
+ typeof createUserInputSchema,
144
+ typeof userResponseSchema
145
+ > {
146
+ readonly method = 'POST';
147
+ readonly contentType = 'application/json';
148
+ readonly accept = 'application/json';
149
+
150
+ readonly inputSchema = createUserInputSchema;
151
+ readonly outputSchema = userResponseSchema;
152
+ readonly querySchema = undefined;
153
+ readonly headersSchema = undefined;
154
+
155
+ constructor(input: z.input<typeof createUserInputSchema>) {
156
+ super(input);
157
+ }
158
+
159
+ getPath(): string {
160
+ return '/users';
161
+ }
162
+ }
163
+
164
+ // Request with path parameters
165
+ class GetUser extends AbstractApiRequest<
166
+ typeof z.undefined,
167
+ typeof userResponseSchema
168
+ > {
169
+ readonly method = 'GET';
170
+ readonly contentType = 'application/json';
171
+ readonly accept = 'application/json';
172
+
173
+ readonly inputSchema = z.undefined();
174
+ readonly outputSchema = userResponseSchema;
175
+ readonly querySchema = undefined;
176
+ readonly headersSchema = undefined;
177
+
178
+ private readonly userId: string;
179
+
180
+ constructor(userId: string) {
181
+ super(undefined);
182
+ this.userId = userId;
183
+ }
184
+
185
+ getPath(): string {
186
+ return `/users/${this.userId}`;
187
+ }
188
+ }
189
+
190
+ // Request with query parameters
191
+ class GetUsers extends AbstractApiRequest<
192
+ typeof z.undefined,
193
+ typeof z.array(userResponseSchema),
194
+ z.infer<typeof getUsersQuerySchema>
195
+ > {
196
+ readonly method = 'GET';
197
+ readonly contentType = 'application/json';
198
+ readonly accept = 'application/json';
199
+
200
+ readonly inputSchema = z.undefined();
201
+ readonly outputSchema = z.array(userResponseSchema);
202
+ readonly querySchema = getUsersQuerySchema;
203
+ readonly headersSchema = undefined;
204
+
205
+ constructor(options?: { query?: z.infer<typeof getUsersQuerySchema> }) {
206
+ super(undefined, options);
207
+ }
208
+
209
+ getPath(): string {
210
+ return '/users';
211
+ }
212
+ }
213
+ ```
214
+
215
+ ### Making API Calls
216
+
217
+ ```typescript
218
+ import { client } from './client';
219
+
220
+ // Create a user
221
+ const newUser = await client.call(new CreateUser({
222
+ name: 'John Doe',
223
+ email: 'john@example.com',
224
+ age: 25
225
+ }));
226
+
227
+ // Get a user
228
+ const user = await client.call(new GetUser('user-123'));
229
+
230
+ // Get users with filters
231
+ const users = await client.call(new GetUsers({
232
+ query: {
233
+ page: 1,
234
+ limit: 10,
235
+ search: 'john'
236
+ }
237
+ }));
238
+ ```
239
+
240
+ ### Adding Middleware
241
+
242
+ #### Request Middleware
243
+
244
+ ```typescript
245
+ client.addRequestMiddleware(async (ctx) => {
246
+ console.log('Making request to:', ctx.url.toString());
247
+
248
+ // Modify headers
249
+ return {
250
+ ...ctx,
251
+ init: {
252
+ ...ctx.init,
253
+ headers: {
254
+ ...ctx.init.headers,
255
+ 'X-Custom-Header': 'value'
256
+ }
257
+ }
258
+ };
259
+ });
260
+ ```
261
+
262
+ **Parameters:**
263
+ - `ctx.url: URL` - The request URL
264
+ - `ctx.init: RequestInit` - The fetch init options
265
+
266
+ **Return:** Modified `RequestContext` or the original context
267
+
268
+ #### Response Middleware
269
+
270
+ ```typescript
271
+ client.addResponseMiddleware(async (parsed, requestCtx) => {
272
+ console.log('Response status:', parsed.response.status);
273
+ console.log('Response body:', parsed.body);
274
+
275
+ return parsed;
276
+ });
277
+ ```
278
+
279
+ **Parameters:**
280
+ - `parsed.response: Response` - The fetch Response object
281
+ - `parsed.body: unknown` - The parsed response body
282
+ - `requestCtx: RequestContext` - The original request context
283
+
284
+ **Return:** Modified `ParsedResponse` or the original parsed response
285
+
286
+ ### Creating a Plugin
287
+
288
+ ```typescript
289
+ import { ApiClient, ApiClientPlugin, ApiExtension } from '@deliverart/sdk-js-core';
290
+
291
+ // Define the extension interface
292
+ interface LoggerExtension extends ApiExtension {
293
+ logger: {
294
+ enable: () => void;
295
+ disable: () => void;
296
+ };
297
+ }
298
+
299
+ // Create the plugin
300
+ class LoggerPlugin implements ApiClientPlugin<LoggerExtension> {
301
+ private enabled = true;
302
+
303
+ setup(client: ApiClient): LoggerExtension {
304
+ // Add request middleware
305
+ client.addRequestMiddleware(async (ctx) => {
306
+ if (this.enabled) {
307
+ console.log('[Request]', ctx.init.method, ctx.url.toString());
308
+ }
309
+ return ctx;
310
+ });
311
+
312
+ // Add response middleware
313
+ client.addResponseMiddleware(async (parsed, ctx) => {
314
+ if (this.enabled) {
315
+ console.log('[Response]', parsed.response.status);
316
+ }
317
+ return parsed;
318
+ });
319
+
320
+ // Return extension methods
321
+ return {
322
+ logger: {
323
+ enable: () => {
324
+ this.enabled = true;
325
+ },
326
+ disable: () => {
327
+ this.enabled = false;
328
+ }
329
+ }
330
+ };
331
+ }
332
+ }
333
+
334
+ // Use the plugin
335
+ const client = createApiClient({ baseUrl: 'https://api.example.com' })
336
+ .addPlugin(new LoggerPlugin());
337
+
338
+ // Now you can use the logger methods
339
+ client.logger.disable();
340
+ client.logger.enable();
341
+ ```
342
+
343
+ ### Error Handling
344
+
345
+ ```typescript
346
+ import { InputValidationError, OutputValidationError } from '@deliverart/sdk-js-core';
347
+
348
+ try {
349
+ await client.call(new CreateUser({
350
+ name: '', // Invalid: min length is 1
351
+ email: 'invalid-email', // Invalid email format
352
+ }));
353
+ } catch (error) {
354
+ if (error instanceof InputValidationError) {
355
+ console.error('Input validation failed:');
356
+ error.issues.forEach(issue => {
357
+ console.error(`- ${issue.path.join('.')}: ${issue.message}`);
358
+ });
359
+ } else if (error instanceof OutputValidationError) {
360
+ console.error('Response validation failed:');
361
+ error.issues.forEach(issue => {
362
+ console.error(`- ${issue.path.join('.')}: ${issue.message}`);
363
+ });
364
+ } else {
365
+ console.error('Other error:', error);
366
+ }
367
+ }
368
+ ```
369
+
370
+ ## Advanced Features
371
+
372
+ ### Custom Response Parsing
373
+
374
+ Override `parseResponse` to customize how responses are parsed:
375
+
376
+ ```typescript
377
+ import { Paginated, responseToPagination } from '@deliverart/sdk-js-global-types';
378
+
379
+ class GetUsers extends AbstractApiRequest</*...*/> {
380
+ // ... other properties ...
381
+
382
+ parseResponse(data: unknown, rawResponse: Response): Paginated<User> {
383
+ const users = z.array(userResponseSchema).parse(data);
384
+
385
+ return this.validateOutput({
386
+ data: users,
387
+ pagination: responseToPagination(rawResponse)
388
+ });
389
+ }
390
+ }
391
+ ```
392
+
393
+ ### FormData Requests
394
+
395
+ ```typescript
396
+ const uploadImageInputSchema = z.instanceof(FormData);
397
+
398
+ class UploadImage extends AbstractApiRequest<
399
+ typeof uploadImageInputSchema,
400
+ typeof imageResponseSchema
401
+ > {
402
+ readonly method = 'POST';
403
+ readonly contentType = 'multipart/form-data';
404
+ readonly accept = 'application/json';
405
+
406
+ readonly inputSchema = uploadImageInputSchema;
407
+ readonly outputSchema = imageResponseSchema;
408
+
409
+ constructor(formData: FormData) {
410
+ super(formData);
411
+ }
412
+
413
+ getPath(): string {
414
+ return '/images';
415
+ }
416
+ }
417
+
418
+ // Usage
419
+ const formData = new FormData();
420
+ formData.append('file', fileBlob);
421
+ formData.append('name', 'My Image');
422
+
423
+ const image = await client.call(new UploadImage(formData));
424
+ ```
425
+
426
+ ## License
427
+
428
+ MIT
429
+
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deliverart/sdk-js-core",
3
3
  "description": "Core SDK for DeliverArt, providing essential functionalities and utilities.",
4
- "version": "2.1.49",
4
+ "version": "2.1.51",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",