@lokalise/api-contracts 6.5.2 → 6.5.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/README.md +36 -49
- package/dist/sse/dualModeContracts.d.ts +6 -6
- package/dist/sse/sseContractBuilders.d.ts +12 -12
- package/dist/sse/sseContracts.d.ts +6 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,8 +12,8 @@ type-safe way).
|
|
|
12
12
|
|
|
13
13
|
Use `buildContract` as a single entry point for creating any type of API contract. It automatically delegates to the appropriate specialized builder based on the configuration:
|
|
14
14
|
|
|
15
|
-
| `
|
|
16
|
-
|
|
15
|
+
| `serverSentEventSchemas` | Contract Type |
|
|
16
|
+
|--------------------------|---------------|
|
|
17
17
|
| ❌ | REST contract (GET, POST, PUT, PATCH, DELETE) |
|
|
18
18
|
| ✅ | SSE or Dual-mode contract |
|
|
19
19
|
|
|
@@ -44,11 +44,9 @@ const deleteUser = buildContract({
|
|
|
44
44
|
|
|
45
45
|
// SSE-only streaming endpoint
|
|
46
46
|
const notifications = buildContract({
|
|
47
|
+
method: 'get',
|
|
47
48
|
pathResolver: () => '/api/notifications/stream',
|
|
48
|
-
|
|
49
|
-
query: z.object({}),
|
|
50
|
-
requestHeaders: z.object({}),
|
|
51
|
-
sseEvents: {
|
|
49
|
+
serverSentEventSchemas: {
|
|
52
50
|
notification: z.object({ id: z.string(), message: z.string() }),
|
|
53
51
|
},
|
|
54
52
|
})
|
|
@@ -57,12 +55,9 @@ const notifications = buildContract({
|
|
|
57
55
|
const chatCompletion = buildContract({
|
|
58
56
|
method: 'post',
|
|
59
57
|
pathResolver: () => '/api/chat/completions',
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
requestBody: z.object({ message: z.string() }),
|
|
64
|
-
syncResponseBody: z.object({ reply: z.string() }),
|
|
65
|
-
sseEvents: {
|
|
58
|
+
requestBodySchema: z.object({ message: z.string() }),
|
|
59
|
+
successResponseBodySchema: z.object({ reply: z.string() }),
|
|
60
|
+
serverSentEventSchemas: {
|
|
66
61
|
chunk: z.object({ delta: z.string() }),
|
|
67
62
|
done: z.object({ usage: z.object({ tokens: z.number() }) }),
|
|
68
63
|
},
|
|
@@ -302,12 +297,12 @@ import { buildSseContract } from '@lokalise/api-contracts'
|
|
|
302
297
|
import { z } from 'zod'
|
|
303
298
|
|
|
304
299
|
// GET SSE endpoint for live notifications
|
|
300
|
+
// requestPathParamsSchema, requestQuerySchema, requestHeaderSchema are optional
|
|
305
301
|
const notificationsStream = buildSseContract({
|
|
302
|
+
method: 'get',
|
|
306
303
|
pathResolver: () => '/api/notifications/stream',
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
requestHeaders: z.object({}),
|
|
310
|
-
sseEvents: {
|
|
304
|
+
requestQuerySchema: z.object({ userId: z.string().optional() }),
|
|
305
|
+
serverSentEventSchemas: {
|
|
311
306
|
notification: z.object({ id: z.string(), message: z.string() }),
|
|
312
307
|
},
|
|
313
308
|
})
|
|
@@ -317,11 +312,8 @@ const notificationsStream = buildSseContract({
|
|
|
317
312
|
const processStream = buildSseContract({
|
|
318
313
|
method: 'post',
|
|
319
314
|
pathResolver: () => '/api/process/stream',
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
requestHeaders: z.object({}),
|
|
323
|
-
requestBody: z.object({ fileId: z.string() }),
|
|
324
|
-
sseEvents: {
|
|
315
|
+
requestBodySchema: z.object({ fileId: z.string() }),
|
|
316
|
+
serverSentEventSchemas: {
|
|
325
317
|
progress: z.object({ percent: z.number() }),
|
|
326
318
|
done: z.object({ result: z.string() }),
|
|
327
319
|
},
|
|
@@ -330,15 +322,15 @@ const processStream = buildSseContract({
|
|
|
330
322
|
|
|
331
323
|
// SSE endpoint with error schemas (for errors before streaming starts)
|
|
332
324
|
const channelStream = buildSseContract({
|
|
325
|
+
method: 'get',
|
|
333
326
|
pathResolver: (params) => `/api/channels/${params.channelId}/stream`,
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
sseEvents: {
|
|
327
|
+
requestPathParamsSchema: z.object({ channelId: z.string() }),
|
|
328
|
+
requestHeaderSchema: z.object({ authorization: z.string() }),
|
|
329
|
+
serverSentEventSchemas: {
|
|
338
330
|
message: z.object({ text: z.string() }),
|
|
339
331
|
},
|
|
340
332
|
// Errors returned before streaming begins
|
|
341
|
-
|
|
333
|
+
responseBodySchemasByStatusCode: {
|
|
342
334
|
401: z.object({ error: z.literal('Unauthorized') }),
|
|
343
335
|
404: z.object({ error: z.literal('Channel not found') }),
|
|
344
336
|
},
|
|
@@ -363,16 +355,13 @@ import { z } from 'zod'
|
|
|
363
355
|
const chatCompletion = buildSseContract({
|
|
364
356
|
method: 'post',
|
|
365
357
|
pathResolver: () => '/api/chat/completions',
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
requestBody: z.object({ message: z.string() }),
|
|
370
|
-
// Adding syncResponseBody makes it dual-mode
|
|
371
|
-
syncResponseBody: z.object({
|
|
358
|
+
requestBodySchema: z.object({ message: z.string() }),
|
|
359
|
+
// Adding successResponseBodySchema makes it dual-mode
|
|
360
|
+
successResponseBodySchema: z.object({
|
|
372
361
|
reply: z.string(),
|
|
373
362
|
usage: z.object({ tokens: z.number() }),
|
|
374
363
|
}),
|
|
375
|
-
|
|
364
|
+
serverSentEventSchemas: {
|
|
376
365
|
chunk: z.object({ delta: z.string() }),
|
|
377
366
|
done: z.object({ usage: z.object({ totalTokens: z.number() }) }),
|
|
378
367
|
},
|
|
@@ -381,15 +370,15 @@ const chatCompletion = buildSseContract({
|
|
|
381
370
|
|
|
382
371
|
// GET dual-mode endpoint for job status (poll or stream)
|
|
383
372
|
const jobStatus = buildSseContract({
|
|
373
|
+
method: 'get',
|
|
384
374
|
pathResolver: (params) => `/api/jobs/${params.jobId}/status`,
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
syncResponseBody: z.object({
|
|
375
|
+
requestPathParamsSchema: z.object({ jobId: z.string().uuid() }),
|
|
376
|
+
requestQuerySchema: z.object({ verbose: z.string().optional() }),
|
|
377
|
+
successResponseBodySchema: z.object({
|
|
389
378
|
status: z.enum(['pending', 'running', 'completed', 'failed']),
|
|
390
379
|
progress: z.number(),
|
|
391
380
|
}),
|
|
392
|
-
|
|
381
|
+
serverSentEventSchemas: {
|
|
393
382
|
progress: z.object({ percent: z.number() }),
|
|
394
383
|
done: z.object({ result: z.string() }),
|
|
395
384
|
},
|
|
@@ -399,21 +388,19 @@ const jobStatus = buildSseContract({
|
|
|
399
388
|
|
|
400
389
|
### Response Schemas by Status Code
|
|
401
390
|
|
|
402
|
-
Both SSE-only and dual-mode contracts support `
|
|
391
|
+
Both SSE-only and dual-mode contracts support `responseBodySchemasByStatusCode` for defining different response shapes for errors that occur **before streaming starts** (e.g., authentication failures, validation errors, resource not found):
|
|
403
392
|
|
|
404
393
|
```ts
|
|
405
394
|
const chatCompletion = buildSseContract({
|
|
406
395
|
method: 'post',
|
|
407
396
|
pathResolver: () => '/api/chat/completions',
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
syncResponseBody: z.object({ reply: z.string() }),
|
|
413
|
-
sseEvents: {
|
|
397
|
+
requestHeaderSchema: z.object({ authorization: z.string() }),
|
|
398
|
+
requestBodySchema: z.object({ message: z.string() }),
|
|
399
|
+
successResponseBodySchema: z.object({ reply: z.string() }),
|
|
400
|
+
serverSentEventSchemas: {
|
|
414
401
|
chunk: z.object({ delta: z.string() }),
|
|
415
402
|
},
|
|
416
|
-
|
|
403
|
+
responseBodySchemasByStatusCode: {
|
|
417
404
|
400: z.object({ error: z.string(), details: z.array(z.string()) }),
|
|
418
405
|
401: z.object({ error: z.literal('Unauthorized') }),
|
|
419
406
|
429: z.object({ error: z.string(), retryAfter: z.number() }),
|
|
@@ -423,10 +410,10 @@ const chatCompletion = buildSseContract({
|
|
|
423
410
|
|
|
424
411
|
### Contract Type Detection
|
|
425
412
|
|
|
426
|
-
`buildSseContract` automatically determines the contract type based on the presence of `
|
|
413
|
+
`buildSseContract` automatically determines the contract type based on the presence of `successResponseBodySchema`:
|
|
427
414
|
|
|
428
|
-
| `
|
|
429
|
-
|
|
415
|
+
| `successResponseBodySchema` | `requestBodySchema` | Result |
|
|
416
|
+
|----------------------------|---------------------|--------|
|
|
430
417
|
| ❌ | ❌ | SSE-only GET |
|
|
431
418
|
| ❌ | ✅ | SSE-only POST/PUT/PATCH |
|
|
432
419
|
| ✅ | ❌ | Dual-mode GET |
|
|
@@ -20,9 +20,9 @@ import type { SSEEventSchemas } from './sseTypes.ts';
|
|
|
20
20
|
export type DualModeContractDefinition<Method extends SSEMethod = SSEMethod, Params extends z.ZodTypeAny = z.ZodTypeAny, Query extends z.ZodTypeAny = z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny = z.ZodTypeAny, Body extends z.ZodTypeAny | undefined = undefined, SyncResponse extends z.ZodTypeAny = z.ZodTypeAny, Events extends SSEEventSchemas = SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
21
21
|
method: Method;
|
|
22
22
|
pathResolver: RoutePathResolver<z.infer<Params>>;
|
|
23
|
-
requestPathParamsSchema
|
|
24
|
-
requestQuerySchema
|
|
25
|
-
requestHeaderSchema
|
|
23
|
+
requestPathParamsSchema?: Params;
|
|
24
|
+
requestQuerySchema?: Query;
|
|
25
|
+
requestHeaderSchema?: RequestHeaders;
|
|
26
26
|
requestBodySchema: Body;
|
|
27
27
|
/** Sync response schema - use with `sync` handler */
|
|
28
28
|
successResponseBodySchema: SyncResponse;
|
|
@@ -50,9 +50,9 @@ export type DualModeContractDefinition<Method extends SSEMethod = SSEMethod, Par
|
|
|
50
50
|
export type AnyDualModeContractDefinition = {
|
|
51
51
|
method: SSEMethod;
|
|
52
52
|
pathResolver: RoutePathResolver<any>;
|
|
53
|
-
requestPathParamsSchema
|
|
54
|
-
requestQuerySchema
|
|
55
|
-
requestHeaderSchema
|
|
53
|
+
requestPathParamsSchema?: z.ZodTypeAny;
|
|
54
|
+
requestQuerySchema?: z.ZodTypeAny;
|
|
55
|
+
requestHeaderSchema?: z.ZodTypeAny;
|
|
56
56
|
requestBodySchema: z.ZodTypeAny | undefined;
|
|
57
57
|
/** Sync response schema - use with `sync` handler */
|
|
58
58
|
successResponseBodySchema: z.ZodTypeAny;
|
|
@@ -11,9 +11,9 @@ import type { SSEEventSchemas } from './sseTypes.ts';
|
|
|
11
11
|
export type SSEGetContractConfig<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
12
12
|
method: 'get';
|
|
13
13
|
pathResolver: RoutePathResolver<z.infer<Params>>;
|
|
14
|
-
requestPathParamsSchema
|
|
15
|
-
requestQuerySchema
|
|
16
|
-
requestHeaderSchema
|
|
14
|
+
requestPathParamsSchema?: Params;
|
|
15
|
+
requestQuerySchema?: Query;
|
|
16
|
+
requestHeaderSchema?: RequestHeaders;
|
|
17
17
|
serverSentEventSchemas: Events;
|
|
18
18
|
/**
|
|
19
19
|
* Error response schemas by HTTP status code.
|
|
@@ -39,9 +39,9 @@ export type SSEGetContractConfig<Params extends z.ZodTypeAny, Query extends z.Zo
|
|
|
39
39
|
export type SSEPayloadContractConfig<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Body extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
40
40
|
method: 'post' | 'put' | 'patch';
|
|
41
41
|
pathResolver: RoutePathResolver<z.infer<Params>>;
|
|
42
|
-
requestPathParamsSchema
|
|
43
|
-
requestQuerySchema
|
|
44
|
-
requestHeaderSchema
|
|
42
|
+
requestPathParamsSchema?: Params;
|
|
43
|
+
requestQuerySchema?: Query;
|
|
44
|
+
requestHeaderSchema?: RequestHeaders;
|
|
45
45
|
requestBodySchema: Body;
|
|
46
46
|
serverSentEventSchemas: Events;
|
|
47
47
|
/**
|
|
@@ -67,9 +67,9 @@ export type SSEPayloadContractConfig<Params extends z.ZodTypeAny, Query extends
|
|
|
67
67
|
export type DualModeGetContractConfig<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, JsonResponse extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
68
68
|
method: 'get';
|
|
69
69
|
pathResolver: RoutePathResolver<z.infer<Params>>;
|
|
70
|
-
requestPathParamsSchema
|
|
71
|
-
requestQuerySchema
|
|
72
|
-
requestHeaderSchema
|
|
70
|
+
requestPathParamsSchema?: Params;
|
|
71
|
+
requestQuerySchema?: Query;
|
|
72
|
+
requestHeaderSchema?: RequestHeaders;
|
|
73
73
|
/** Single sync response schema */
|
|
74
74
|
successResponseBodySchema: JsonResponse;
|
|
75
75
|
/**
|
|
@@ -108,9 +108,9 @@ export type DualModeGetContractConfig<Params extends z.ZodTypeAny, Query extends
|
|
|
108
108
|
export type DualModePayloadContractConfig<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Body extends z.ZodTypeAny, JsonResponse extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
109
109
|
method: 'post' | 'put' | 'patch';
|
|
110
110
|
pathResolver: RoutePathResolver<z.infer<Params>>;
|
|
111
|
-
requestPathParamsSchema
|
|
112
|
-
requestQuerySchema
|
|
113
|
-
requestHeaderSchema
|
|
111
|
+
requestPathParamsSchema?: Params;
|
|
112
|
+
requestQuerySchema?: Query;
|
|
113
|
+
requestHeaderSchema?: RequestHeaders;
|
|
114
114
|
requestBodySchema: Body;
|
|
115
115
|
/** Single sync response schema */
|
|
116
116
|
successResponseBodySchema: JsonResponse;
|
|
@@ -26,9 +26,9 @@ export type SSEContractDefinition<Method extends SSEMethod = SSEMethod, Params e
|
|
|
26
26
|
* Receives typed params and returns the URL path string.
|
|
27
27
|
*/
|
|
28
28
|
pathResolver: RoutePathResolver<z.infer<Params>>;
|
|
29
|
-
requestPathParamsSchema
|
|
30
|
-
requestQuerySchema
|
|
31
|
-
requestHeaderSchema
|
|
29
|
+
requestPathParamsSchema?: Params;
|
|
30
|
+
requestQuerySchema?: Query;
|
|
31
|
+
requestHeaderSchema?: RequestHeaders;
|
|
32
32
|
requestBodySchema: Body;
|
|
33
33
|
serverSentEventSchemas: Events;
|
|
34
34
|
/**
|
|
@@ -54,9 +54,9 @@ export type SSEContractDefinition<Method extends SSEMethod = SSEMethod, Params e
|
|
|
54
54
|
export type AnySSEContractDefinition = {
|
|
55
55
|
method: SSEMethod;
|
|
56
56
|
pathResolver: RoutePathResolver<any>;
|
|
57
|
-
requestPathParamsSchema
|
|
58
|
-
requestQuerySchema
|
|
59
|
-
requestHeaderSchema
|
|
57
|
+
requestPathParamsSchema?: z.ZodTypeAny;
|
|
58
|
+
requestQuerySchema?: z.ZodTypeAny;
|
|
59
|
+
requestHeaderSchema?: z.ZodTypeAny;
|
|
60
60
|
requestBodySchema: z.ZodTypeAny | undefined;
|
|
61
61
|
serverSentEventSchemas: SSEEventSchemas;
|
|
62
62
|
responseBodySchemasByStatusCode?: Partial<Record<HttpStatusCode, z.ZodTypeAny>>;
|