@voltom/contracts 1.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 +486 -0
- package/dist/index.d.mts +464 -0
- package/dist/index.d.ts +464 -0
- package/dist/index.js +246 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +206 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +50 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Universal primitive type builders for voltom contracts.
|
|
5
|
+
* Every field in every contract is built using these.
|
|
6
|
+
* They wrap Zod schemas with cleaner names and consistent validation.
|
|
7
|
+
*
|
|
8
|
+
* All validators are designed for production use:
|
|
9
|
+
* - Security (no injection vectors)
|
|
10
|
+
* - Performance (fast validation)
|
|
11
|
+
* - Clarity (error messages are useful)
|
|
12
|
+
*/
|
|
13
|
+
declare const t: {
|
|
14
|
+
/** UUID string (v4 or v5) */
|
|
15
|
+
readonly uuid: () => z.ZodString;
|
|
16
|
+
/** String with optional min/max length and pattern constraints */
|
|
17
|
+
readonly string: (opts?: {
|
|
18
|
+
min?: number;
|
|
19
|
+
max?: number;
|
|
20
|
+
pattern?: RegExp | string;
|
|
21
|
+
description?: string;
|
|
22
|
+
}) => z.ZodString;
|
|
23
|
+
/** Email address (RFC 5322 compliant) */
|
|
24
|
+
readonly email: () => z.ZodString;
|
|
25
|
+
/** Phone number (international format: +[country code][number], or 7+ digits) */
|
|
26
|
+
readonly phone: () => z.ZodString;
|
|
27
|
+
/** URL (HTTP, HTTPS, or custom protocol) */
|
|
28
|
+
readonly url: () => z.ZodString;
|
|
29
|
+
/** URL slug (lowercase alphanumeric, hyphens, underscores) */
|
|
30
|
+
readonly slug: (opts?: {
|
|
31
|
+
min?: number;
|
|
32
|
+
max?: number;
|
|
33
|
+
}) => z.ZodString;
|
|
34
|
+
/** Strong password (min 8 chars, mixed case, number, special char) */
|
|
35
|
+
readonly password: () => z.ZodString;
|
|
36
|
+
/** IPv4 or IPv6 address */
|
|
37
|
+
readonly ipAddress: () => z.ZodUnion<[z.ZodString, z.ZodString]>;
|
|
38
|
+
/** Hexadecimal string (colors, hashes) */
|
|
39
|
+
readonly hex: (opts?: {
|
|
40
|
+
length?: number;
|
|
41
|
+
}) => z.ZodString;
|
|
42
|
+
/** Alphanumeric identifier (no special chars) */
|
|
43
|
+
readonly id: () => z.ZodString;
|
|
44
|
+
/** Country code (ISO 3166-1 alpha-2) */
|
|
45
|
+
readonly countryCode: () => z.ZodString;
|
|
46
|
+
/** Currency code (ISO 4217) */
|
|
47
|
+
readonly currencyCode: () => z.ZodString;
|
|
48
|
+
/** Number with optional min/max bounds */
|
|
49
|
+
readonly number: (opts?: {
|
|
50
|
+
min?: number;
|
|
51
|
+
max?: number;
|
|
52
|
+
multipleOf?: number;
|
|
53
|
+
}) => z.ZodNumber;
|
|
54
|
+
/** Integer with optional min/max bounds */
|
|
55
|
+
readonly int: (opts?: {
|
|
56
|
+
min?: number;
|
|
57
|
+
max?: number;
|
|
58
|
+
positive?: boolean;
|
|
59
|
+
negative?: boolean;
|
|
60
|
+
}) => z.ZodNumber;
|
|
61
|
+
/** Percentage (0-100) */
|
|
62
|
+
readonly percent: () => z.ZodNumber;
|
|
63
|
+
/** Boolean */
|
|
64
|
+
readonly boolean: () => z.ZodBoolean;
|
|
65
|
+
/** ISO 8601 datetime (e.g., "2024-01-15T10:30:00Z") */
|
|
66
|
+
readonly datetime: () => z.ZodString;
|
|
67
|
+
/** ISO 8601 date (e.g., "2024-01-15") */
|
|
68
|
+
readonly date: () => z.ZodString;
|
|
69
|
+
/** ISO 8601 time (e.g., "14:30:00") */
|
|
70
|
+
readonly time: () => z.ZodString;
|
|
71
|
+
/** Unix timestamp (seconds since epoch) */
|
|
72
|
+
readonly timestamp: () => z.ZodNumber;
|
|
73
|
+
/** Enum with fixed string values */
|
|
74
|
+
readonly enum: <T extends readonly [string, ...string[]]>(values: T) => z.ZodEnum<z.Writeable<T>>;
|
|
75
|
+
/** Arbitrary JSON value (object, array, primitive) */
|
|
76
|
+
readonly json: () => z.ZodAny;
|
|
77
|
+
/** Make a schema optional (allows undefined) */
|
|
78
|
+
readonly optional: <S extends z.ZodTypeAny>(schema: S) => z.ZodOptional<S>;
|
|
79
|
+
/** Make a schema nullable (allows null) */
|
|
80
|
+
readonly nullable: <S extends z.ZodTypeAny>(schema: S) => z.ZodNullable<S>;
|
|
81
|
+
/** Array of a schema with optional length constraints */
|
|
82
|
+
readonly array: <S extends z.ZodTypeAny>(schema: S, opts?: {
|
|
83
|
+
min?: number;
|
|
84
|
+
max?: number;
|
|
85
|
+
nonempty?: boolean;
|
|
86
|
+
}) => any;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Canonical error codes for voltom APIs.
|
|
91
|
+
* These are the ONLY error codes that should be used across all products.
|
|
92
|
+
* Maps to HTTP status codes via ERROR_STATUS_MAP.
|
|
93
|
+
*
|
|
94
|
+
* Do NOT add product-specific codes. Keep these universal.
|
|
95
|
+
* If you need product logic, handle it in the backend with additional data.
|
|
96
|
+
*/
|
|
97
|
+
type ErrorCode = 'VALIDATION_ERROR' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'NOT_FOUND' | 'CONFLICT' | 'UNPROCESSABLE' | 'RATE_LIMITED' | 'INTERNAL_ERROR';
|
|
98
|
+
/**
|
|
99
|
+
* Map each ErrorCode to its HTTP status code.
|
|
100
|
+
* Use this in backend exception filters and middleware.
|
|
101
|
+
*/
|
|
102
|
+
declare const ERROR_STATUS_MAP: Record<ErrorCode, number>;
|
|
103
|
+
/**
|
|
104
|
+
* Default error messages for each code.
|
|
105
|
+
* Use these as fallback or customize with domain-specific context.
|
|
106
|
+
*/
|
|
107
|
+
declare const ERROR_MESSAGES: Record<ErrorCode, string>;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Pagination metadata included in PaginatedResponse.
|
|
111
|
+
*/
|
|
112
|
+
interface PaginationMeta {
|
|
113
|
+
/** Total number of items across all pages */
|
|
114
|
+
total: number;
|
|
115
|
+
/** Current page number (1-indexed) */
|
|
116
|
+
page: number;
|
|
117
|
+
/** Items per page */
|
|
118
|
+
per_page: number;
|
|
119
|
+
/** Whether more pages exist after this one */
|
|
120
|
+
has_more: boolean;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Cursor-based pagination (for very large datasets).
|
|
124
|
+
* Use when total count is unknown or for streaming data.
|
|
125
|
+
*/
|
|
126
|
+
interface CursorPaginationMeta {
|
|
127
|
+
/** Cursor to fetch next page (null if no more pages) */
|
|
128
|
+
next_cursor: string | null;
|
|
129
|
+
/** Whether more pages exist */
|
|
130
|
+
has_more: boolean;
|
|
131
|
+
/** Items returned on this page (for client-side counting) */
|
|
132
|
+
count: number;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Validation error details for a specific field.
|
|
136
|
+
*/
|
|
137
|
+
interface FieldError {
|
|
138
|
+
/** Field name (dot-notation for nested: "user.email") */
|
|
139
|
+
field: string;
|
|
140
|
+
/** Error code/type (e.g., "required", "min_length", "invalid_format") */
|
|
141
|
+
code: string;
|
|
142
|
+
/** Human-readable message */
|
|
143
|
+
message: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Response for a single item fetch (GET /:id, POST, PATCH, PUT).
|
|
147
|
+
* The only valid envelope for single-item responses.
|
|
148
|
+
*/
|
|
149
|
+
interface SingleResponse<T> {
|
|
150
|
+
/** The item */
|
|
151
|
+
data: T;
|
|
152
|
+
/** ISO 8601 timestamp */
|
|
153
|
+
timestamp: string;
|
|
154
|
+
/** Optional: unique request identifier for tracing */
|
|
155
|
+
request_id?: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Response for a paginated list (GET with pagination).
|
|
159
|
+
* The only valid envelope for list responses.
|
|
160
|
+
*/
|
|
161
|
+
interface PaginatedResponse<T> {
|
|
162
|
+
/** Array of items */
|
|
163
|
+
data: T[];
|
|
164
|
+
/** Pagination metadata */
|
|
165
|
+
meta: PaginationMeta;
|
|
166
|
+
/** ISO 8601 timestamp */
|
|
167
|
+
timestamp: string;
|
|
168
|
+
/** Optional: unique request identifier for tracing */
|
|
169
|
+
request_id?: string;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Response for cursor-based pagination (streaming, infinite scroll).
|
|
173
|
+
* Use for large datasets where total count is unavailable or expensive.
|
|
174
|
+
*/
|
|
175
|
+
interface CursorPaginatedResponse<T> {
|
|
176
|
+
/** Array of items */
|
|
177
|
+
data: T[];
|
|
178
|
+
/** Cursor pagination metadata */
|
|
179
|
+
meta: CursorPaginationMeta;
|
|
180
|
+
/** ISO 8601 timestamp */
|
|
181
|
+
timestamp: string;
|
|
182
|
+
/** Optional: unique request identifier for tracing */
|
|
183
|
+
request_id?: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Response for a resource deletion (DELETE /:id).
|
|
187
|
+
* The only valid envelope for delete responses.
|
|
188
|
+
*/
|
|
189
|
+
interface DeletedResponse {
|
|
190
|
+
/** Always true, confirms deletion */
|
|
191
|
+
deleted: true;
|
|
192
|
+
/** ID of the deleted resource */
|
|
193
|
+
id: string;
|
|
194
|
+
/** ISO 8601 timestamp */
|
|
195
|
+
timestamp: string;
|
|
196
|
+
/** Optional: unique request identifier for tracing */
|
|
197
|
+
request_id?: string;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Response for bulk/batch operations (POST /batch, DELETE /batch).
|
|
201
|
+
* Allows partial success with per-item error tracking.
|
|
202
|
+
*/
|
|
203
|
+
interface BulkResponse<T> {
|
|
204
|
+
/** Successfully created/updated items */
|
|
205
|
+
data: T[];
|
|
206
|
+
/** Items that failed with per-item error details */
|
|
207
|
+
errors: Array<{
|
|
208
|
+
/** Original request index or item ID */
|
|
209
|
+
key: string | number;
|
|
210
|
+
/** The error */
|
|
211
|
+
error: {
|
|
212
|
+
code: ErrorCode;
|
|
213
|
+
message: string;
|
|
214
|
+
details?: unknown;
|
|
215
|
+
};
|
|
216
|
+
}>;
|
|
217
|
+
/** Summary statistics */
|
|
218
|
+
meta: {
|
|
219
|
+
/** Total items processed */
|
|
220
|
+
total: number;
|
|
221
|
+
/** Successfully processed */
|
|
222
|
+
succeeded: number;
|
|
223
|
+
/** Failed items */
|
|
224
|
+
failed: number;
|
|
225
|
+
};
|
|
226
|
+
/** ISO 8601 timestamp */
|
|
227
|
+
timestamp: string;
|
|
228
|
+
/** Optional: unique request identifier for tracing */
|
|
229
|
+
request_id?: string;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Error response (any HTTP error status).
|
|
233
|
+
* The only valid envelope for errors.
|
|
234
|
+
*/
|
|
235
|
+
interface ApiError {
|
|
236
|
+
error: {
|
|
237
|
+
/** Canonical error code from @voltom/contracts */
|
|
238
|
+
code: ErrorCode;
|
|
239
|
+
/** Human-readable error message (safe for client display) */
|
|
240
|
+
message: string;
|
|
241
|
+
/** Optional: field name if error maps to a specific field */
|
|
242
|
+
field?: string;
|
|
243
|
+
/** Optional: validation details (only for VALIDATION_ERROR) */
|
|
244
|
+
validation_errors?: FieldError[];
|
|
245
|
+
/** Optional: safe, non-sensitive extra context */
|
|
246
|
+
details?: unknown;
|
|
247
|
+
/** Optional: hint for client-side retry/recovery */
|
|
248
|
+
hint?: string;
|
|
249
|
+
};
|
|
250
|
+
/** ISO 8601 timestamp */
|
|
251
|
+
timestamp: string;
|
|
252
|
+
/** Optional: unique request identifier for tracing */
|
|
253
|
+
request_id?: string;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Defines a single API endpoint within a contract.
|
|
258
|
+
*/
|
|
259
|
+
interface EndpointDef {
|
|
260
|
+
/** HTTP method */
|
|
261
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
262
|
+
/** URL path (e.g., "/" or "/:id") */
|
|
263
|
+
path: string;
|
|
264
|
+
/** Response shape type */
|
|
265
|
+
response?: 'single' | 'paginated' | 'deleted' | 'file';
|
|
266
|
+
/** Key into bodies map for request body */
|
|
267
|
+
body?: string;
|
|
268
|
+
/** Query parameters (Zod schema) */
|
|
269
|
+
query?: Record<string, z.ZodTypeAny>;
|
|
270
|
+
/** Possible error codes */
|
|
271
|
+
errors?: ErrorCode[];
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Defines an action — a special endpoint that requires a body.
|
|
275
|
+
* Actions are like custom endpoints that extend the standard CRUD.
|
|
276
|
+
* Body is required and can be either a string (reference to bodies map) or inline Zod schema.
|
|
277
|
+
*/
|
|
278
|
+
type ActionDef = Omit<EndpointDef, 'body'> & {
|
|
279
|
+
body: Record<string, z.ZodTypeAny> | string;
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* Complete contract definition for a resource.
|
|
283
|
+
* This is the source of truth for a resource's API shape.
|
|
284
|
+
*/
|
|
285
|
+
interface ContractConfig {
|
|
286
|
+
/** Resource name (e.g., "users", "teams") */
|
|
287
|
+
resource: string;
|
|
288
|
+
/** Base API path (e.g., "/api/v1/users") */
|
|
289
|
+
basePath: string;
|
|
290
|
+
/** The main entity shape (Zod schema fields) */
|
|
291
|
+
entity: Record<string, z.ZodTypeAny>;
|
|
292
|
+
/** CRUD and standard endpoints */
|
|
293
|
+
endpoints?: Record<string, EndpointDef>;
|
|
294
|
+
/** Request body definitions */
|
|
295
|
+
bodies?: Record<string, Record<string, z.ZodTypeAny>>;
|
|
296
|
+
/** Query filter definitions */
|
|
297
|
+
filters?: Record<string, z.ZodTypeAny>;
|
|
298
|
+
/** Custom action endpoints */
|
|
299
|
+
actions?: Record<string, ActionDef>;
|
|
300
|
+
/** Permission hints for access control */
|
|
301
|
+
permissions?: Record<string, string>;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* The Contract type after defineContract() validation.
|
|
305
|
+
* In practice, this is identical to ContractConfig, but the function
|
|
306
|
+
* ensures type correctness and enables inference.
|
|
307
|
+
*/
|
|
308
|
+
type Contract = ContractConfig;
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Define a contract for a resource in your product.
|
|
312
|
+
*
|
|
313
|
+
* This function validates the contract shape and returns it for use throughout
|
|
314
|
+
* your product (backend, frontend, codegen). The real power is in TypeScript's
|
|
315
|
+
* type inference — once you call defineContract(), every property is typed
|
|
316
|
+
* and all downstream consumers know exactly what to expect.
|
|
317
|
+
*
|
|
318
|
+
* @param config The contract configuration
|
|
319
|
+
* @returns The same contract config (validated)
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```typescript
|
|
323
|
+
* const usersContract = defineContract({
|
|
324
|
+
* resource: 'users',
|
|
325
|
+
* basePath: '/api/v1/users',
|
|
326
|
+
* entity: {
|
|
327
|
+
* id: t.uuid(),
|
|
328
|
+
* email: t.email(),
|
|
329
|
+
* name: t.string({ min: 1, max: 255 }),
|
|
330
|
+
* },
|
|
331
|
+
* endpoints: {
|
|
332
|
+
* list: { method: 'GET', path: '/', response: 'paginated' },
|
|
333
|
+
* show: { method: 'GET', path: '/:id', response: 'single' },
|
|
334
|
+
* create: { method: 'POST', path: '/', body: 'CreateUser' },
|
|
335
|
+
* },
|
|
336
|
+
* bodies: {
|
|
337
|
+
* CreateUser: {
|
|
338
|
+
* email: t.email(),
|
|
339
|
+
* name: t.string({ min: 1, max: 255 }),
|
|
340
|
+
* },
|
|
341
|
+
* },
|
|
342
|
+
* })
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
declare function defineContract<T extends ContractConfig>(config: T): T & Contract;
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Standard fields that most entities should have.
|
|
349
|
+
* Use these to ensure consistency across products.
|
|
350
|
+
*/
|
|
351
|
+
/**
|
|
352
|
+
* Audit trail fields (who, when)
|
|
353
|
+
* Include on entities that track ownership or modification history.
|
|
354
|
+
*/
|
|
355
|
+
declare const auditFields: {
|
|
356
|
+
readonly created_at: z.ZodString;
|
|
357
|
+
readonly created_by: z.ZodString;
|
|
358
|
+
readonly updated_at: z.ZodString;
|
|
359
|
+
readonly updated_by: z.ZodString;
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Soft delete fields (mark as deleted without removing data)
|
|
363
|
+
* Use when you need to preserve data for compliance or recovery.
|
|
364
|
+
*/
|
|
365
|
+
declare const softDeleteFields: {
|
|
366
|
+
readonly is_active: z.ZodBoolean;
|
|
367
|
+
readonly deleted_at: z.ZodNullable<z.ZodString>;
|
|
368
|
+
readonly deleted_by: z.ZodNullable<z.ZodString>;
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* Timestamp fields only (no user tracking)
|
|
372
|
+
* Minimum audit trail for systems that don't track users.
|
|
373
|
+
*/
|
|
374
|
+
declare const timestampFields: {
|
|
375
|
+
readonly created_at: z.ZodString;
|
|
376
|
+
readonly updated_at: z.ZodString;
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Standard metadata for multi-tenant systems
|
|
380
|
+
* Use when entities belong to organizations or accounts.
|
|
381
|
+
*/
|
|
382
|
+
declare const tenantFields: {
|
|
383
|
+
readonly tenant_id: z.ZodString;
|
|
384
|
+
readonly organization_id: z.ZodString;
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* Status enum commonly used across products
|
|
388
|
+
* Extend in product-specific contracts if needed.
|
|
389
|
+
*/
|
|
390
|
+
declare const StandardStatus: {
|
|
391
|
+
readonly DRAFT: "draft";
|
|
392
|
+
readonly ACTIVE: "active";
|
|
393
|
+
readonly INACTIVE: "inactive";
|
|
394
|
+
readonly ARCHIVED: "archived";
|
|
395
|
+
readonly DELETED: "deleted";
|
|
396
|
+
};
|
|
397
|
+
type StandardStatus = (typeof StandardStatus)[keyof typeof StandardStatus];
|
|
398
|
+
/**
|
|
399
|
+
* Sort direction for list queries
|
|
400
|
+
*/
|
|
401
|
+
type SortDirection = 'asc' | 'desc';
|
|
402
|
+
/**
|
|
403
|
+
* Standard query filters for list endpoints
|
|
404
|
+
* Use when your contract needs search/filter capabilities.
|
|
405
|
+
*/
|
|
406
|
+
declare const listQueryFilters: {
|
|
407
|
+
readonly search: z.ZodOptional<z.ZodString>;
|
|
408
|
+
readonly status: z.ZodOptional<z.ZodString>;
|
|
409
|
+
readonly sort_by: z.ZodOptional<z.ZodString>;
|
|
410
|
+
readonly sort_direction: z.ZodOptional<z.ZodEnum<["asc", "desc"]>>;
|
|
411
|
+
readonly limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
412
|
+
readonly offset: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
413
|
+
};
|
|
414
|
+
/**
|
|
415
|
+
* Standard pagination query parameters
|
|
416
|
+
*/
|
|
417
|
+
declare const paginationQuery: {
|
|
418
|
+
readonly page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
419
|
+
readonly per_page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
420
|
+
};
|
|
421
|
+
/**
|
|
422
|
+
* Create a consistent 'create' body type from an entity
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```typescript
|
|
426
|
+
* const userEntity = { id: t.uuid(), email: t.email(), name: t.string() }
|
|
427
|
+
* type CreateUserBody = OmitFields<typeof userEntity, 'id'> // email, name
|
|
428
|
+
* ```
|
|
429
|
+
*
|
|
430
|
+
* Note: In your contract, you can also just define bodies explicitly:
|
|
431
|
+
* bodies: { CreateUser: { email: t.email(), name: t.string() } }
|
|
432
|
+
*/
|
|
433
|
+
/**
|
|
434
|
+
* Create a consistent 'update' body type from an entity
|
|
435
|
+
* (all fields optional except id)
|
|
436
|
+
*/
|
|
437
|
+
declare const makeUpdateFields: <T extends Record<string, z.ZodTypeAny>>(entity: T, excludeFields?: (keyof T)[]) => Record<string, z.ZodTypeAny>;
|
|
438
|
+
/**
|
|
439
|
+
* Standard HTTP header hints for backend/frontend coordination
|
|
440
|
+
* Not part of contract, but useful metadata for documentation
|
|
441
|
+
*/
|
|
442
|
+
declare const ResponseHeaders: {
|
|
443
|
+
/** Cache-Control header value */
|
|
444
|
+
readonly CACHE: {
|
|
445
|
+
readonly NO_CACHE: "no-cache, no-store, must-revalidate";
|
|
446
|
+
readonly SHORT: "public, max-age=300";
|
|
447
|
+
readonly MEDIUM: "public, max-age=3600";
|
|
448
|
+
readonly LONG: "public, max-age=86400";
|
|
449
|
+
readonly NEVER: "no-store";
|
|
450
|
+
};
|
|
451
|
+
};
|
|
452
|
+
/**
|
|
453
|
+
* Security hints for contract fields
|
|
454
|
+
* Mark sensitive fields so frontend/backend handle them carefully
|
|
455
|
+
*/
|
|
456
|
+
declare const FieldSensitivity: {
|
|
457
|
+
readonly PUBLIC: "public";
|
|
458
|
+
readonly INTERNAL: "internal";
|
|
459
|
+
readonly CONFIDENTIAL: "confidential";
|
|
460
|
+
readonly SECRET: "secret";
|
|
461
|
+
};
|
|
462
|
+
type FieldSensitivity = (typeof FieldSensitivity)[keyof typeof FieldSensitivity];
|
|
463
|
+
|
|
464
|
+
export { type ActionDef, type ApiError, type BulkResponse, type Contract, type ContractConfig, type CursorPaginatedResponse, type CursorPaginationMeta, type DeletedResponse, ERROR_MESSAGES, ERROR_STATUS_MAP, type EndpointDef, type ErrorCode, type FieldError, FieldSensitivity, type PaginatedResponse, type PaginationMeta, ResponseHeaders, type SingleResponse, type SortDirection, StandardStatus, auditFields, defineContract, listQueryFilters, makeUpdateFields, paginationQuery, softDeleteFields, t, tenantFields, timestampFields };
|