@rexeus/typeweaver-core 0.0.1
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 +162 -0
- package/dist/index.d.ts +326 -0
- package/dist/index.js +298 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# @rexeus/typeweaver-core
|
|
2
|
+
|
|
3
|
+
A TypeScript library for defining type-safe HTTP APIs with runtime validation and code generation
|
|
4
|
+
support.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- **Type-Safe API Definitions** - Define HTTP operations with complete TypeScript type inference
|
|
9
|
+
- **Runtime Validation** - Zod schema integration for request/response validation
|
|
10
|
+
- **Framework Adapters** - Support for AWS Lambda, Hono, and other execution contexts
|
|
11
|
+
- **Client Generation Ready** - Abstract base classes designed for code generation
|
|
12
|
+
- **Route Matching** - Optimized route resolution with parameter support
|
|
13
|
+
- **Error Handling** - Structured validation errors with detailed issue reporting
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @rexeus/typeweaver-core
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Peer Dependencies:**
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install zod@^3.25.0 axios@^1.9.0 hono@^4.8.0
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
> **Important:** This library requires Zod v4 features and imports from `"zod/v4"`. Make sure you
|
|
28
|
+
> have a compatible Zod version installed.
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### Define API Operations
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { z } from "zod/v4";
|
|
36
|
+
import { HttpOperationDefinition, HttpStatusCode, HttpMethod } from "@rexeus/typeweaver-core";
|
|
37
|
+
import { accountSchema } from "./accountSchema";
|
|
38
|
+
import { sharedResponses } from "../shared/sharedResponses";
|
|
39
|
+
import { defaultResponseHeader } from "../shared/defaultResponseHeader";
|
|
40
|
+
import { defaultRequestHeadersWithPayload } from "../shared/defaultRequestHeader";
|
|
41
|
+
|
|
42
|
+
export default new HttpOperationDefinition({
|
|
43
|
+
operationId: "RegisterAccount",
|
|
44
|
+
path: "/accounts",
|
|
45
|
+
summary: "Register new account",
|
|
46
|
+
method: HttpMethod.POST,
|
|
47
|
+
request: {
|
|
48
|
+
body: z.object({
|
|
49
|
+
email: z.email().max(256),
|
|
50
|
+
password: z.string().max(256),
|
|
51
|
+
}),
|
|
52
|
+
header: defaultRequestHeadersWithPayload.omit({
|
|
53
|
+
Authorization: true,
|
|
54
|
+
}),
|
|
55
|
+
},
|
|
56
|
+
responses: [
|
|
57
|
+
{
|
|
58
|
+
statusCode: HttpStatusCode.OK,
|
|
59
|
+
description: "Account created successfully",
|
|
60
|
+
body: accountSchema,
|
|
61
|
+
name: "RegisterAccountSuccess",
|
|
62
|
+
header: defaultResponseHeader,
|
|
63
|
+
},
|
|
64
|
+
...sharedResponses,
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Framework Integration
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// AWS Lambda
|
|
73
|
+
import { AwsLambdaHandler, AwsLambdaRoute } from "@rexeus/typeweaver-core";
|
|
74
|
+
|
|
75
|
+
// Hono
|
|
76
|
+
import { HonoHttpRequestHandler, HonoHttpRoute } from "@rexeus/typeweaver-core";
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Architecture
|
|
80
|
+
|
|
81
|
+
This library provides a foundation for building type-safe APIs with:
|
|
82
|
+
|
|
83
|
+
- **Definition Layer** - OpenAPI-style operation definitions with Zod schemas
|
|
84
|
+
- **Validation Layer** - Request/response validation with detailed error reporting
|
|
85
|
+
- **Router Layer** - Efficient route matching with framework adapters
|
|
86
|
+
- **Client Layer** - Abstract base for generating type-safe API clients
|
|
87
|
+
|
|
88
|
+
## Key Benefits
|
|
89
|
+
|
|
90
|
+
### Type Safety
|
|
91
|
+
|
|
92
|
+
Complete end-to-end type safety from API definition to runtime execution.
|
|
93
|
+
|
|
94
|
+
### Runtime Validation
|
|
95
|
+
|
|
96
|
+
Zod schemas provide both TypeScript types and runtime validation.
|
|
97
|
+
|
|
98
|
+
### Code Generation Ready
|
|
99
|
+
|
|
100
|
+
Abstract patterns designed for generating API clients and servers.
|
|
101
|
+
|
|
102
|
+
### Performance Optimized
|
|
103
|
+
|
|
104
|
+
Route matching uses preprocessing and caching for O(n) performance.
|
|
105
|
+
|
|
106
|
+
### Framework Agnostic
|
|
107
|
+
|
|
108
|
+
Core definitions work with any execution context via adapter pattern.
|
|
109
|
+
|
|
110
|
+
## Framework Adapters
|
|
111
|
+
|
|
112
|
+
TypeWeaver Core includes adapters for various runtime environments:
|
|
113
|
+
|
|
114
|
+
### AWS Lambda Adapters
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import {
|
|
118
|
+
createAwsLambdaHandler,
|
|
119
|
+
createAwsApiGatewayV1Handler,
|
|
120
|
+
createAwsApiGatewayV2Handler,
|
|
121
|
+
createAwsLambdaFunctionUrlHandler,
|
|
122
|
+
createAwsAlbHandler
|
|
123
|
+
} from "@rexeus/typeweaver-core";
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Hono Integration
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import {
|
|
130
|
+
createHonoHttpApiHandler,
|
|
131
|
+
HonoHttpRouter
|
|
132
|
+
} from "@rexeus/typeweaver-core";
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Generic HTTP Adapters
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import {
|
|
139
|
+
HttpAdapter,
|
|
140
|
+
FetchApiAdapter
|
|
141
|
+
} from "@rexeus/typeweaver-core";
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Validation System
|
|
145
|
+
|
|
146
|
+
Comprehensive request and response validation with structured error handling:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import {
|
|
150
|
+
RequestValidator,
|
|
151
|
+
ResponseValidator,
|
|
152
|
+
RequestValidationError,
|
|
153
|
+
ResponseValidationError
|
|
154
|
+
} from "@rexeus/typeweaver-core";
|
|
155
|
+
|
|
156
|
+
const validator = new RequestValidator(operationDefinition);
|
|
157
|
+
const result = validator.safeValidate(request);
|
|
158
|
+
|
|
159
|
+
if (!result.isValid) {
|
|
160
|
+
console.error(result.error.issues);
|
|
161
|
+
}
|
|
162
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { ZodObject, ZodString, ZodStringFormat, ZodLiteral, ZodEnum, ZodOptional, ZodArray, ZodType, z } from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
type IHttpHeader = Record<string, string | string[]> | undefined;
|
|
4
|
+
type HttpHeaderValue = ZodString | ZodStringFormat | ZodLiteral<string> | ZodEnum<Record<string, string>>;
|
|
5
|
+
type HttpHeaderSchema = ZodObject<Record<string, HttpHeaderValue | ZodOptional<HttpHeaderValue> | ZodArray<HttpHeaderValue> | ZodOptional<ZodArray<HttpHeaderValue>>>>;
|
|
6
|
+
|
|
7
|
+
type IHttpParam = Record<string, string> | undefined;
|
|
8
|
+
type HttpParamValue = ZodString | ZodStringFormat | ZodLiteral<string> | ZodEnum<Record<string, string>>;
|
|
9
|
+
type HttpParamSchema = ZodObject<Record<string, HttpParamValue | ZodOptional<HttpParamValue>>>;
|
|
10
|
+
|
|
11
|
+
type IHttpBody = any | undefined;
|
|
12
|
+
type HttpBodySchema = ZodType;
|
|
13
|
+
|
|
14
|
+
type IHttpQuery = Record<string, string | string[]> | undefined;
|
|
15
|
+
type HttpQueryValue = ZodString | ZodStringFormat | ZodLiteral<string> | ZodEnum<Record<string, string>>;
|
|
16
|
+
type HttpQuerySchema = ZodObject<Record<string, HttpQueryValue | ZodOptional<HttpQueryValue> | ZodArray<HttpQueryValue> | ZodOptional<ZodArray<HttpQueryValue>>>>;
|
|
17
|
+
|
|
18
|
+
declare enum HttpMethod {
|
|
19
|
+
GET = "GET",
|
|
20
|
+
POST = "POST",
|
|
21
|
+
PUT = "PUT",
|
|
22
|
+
DELETE = "DELETE",
|
|
23
|
+
PATCH = "PATCH",
|
|
24
|
+
OPTIONS = "OPTIONS",
|
|
25
|
+
HEAD = "HEAD",
|
|
26
|
+
TRACE = "TRACE",
|
|
27
|
+
CONNECT = "CONNECT"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type IHttpRequest<Header extends IHttpHeader = IHttpHeader, Param extends IHttpParam = IHttpParam, Query extends IHttpQuery = IHttpQuery, Body extends IHttpBody = IHttpBody> = {
|
|
31
|
+
body?: Body;
|
|
32
|
+
query?: Query;
|
|
33
|
+
param?: Param;
|
|
34
|
+
header?: Header;
|
|
35
|
+
path: string;
|
|
36
|
+
method: HttpMethod;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
declare enum HttpStatusCode {
|
|
40
|
+
OK = 200,
|
|
41
|
+
CREATED = 201,
|
|
42
|
+
ACCEPTED = 202,
|
|
43
|
+
NO_CONTENT = 204,
|
|
44
|
+
RESET_CONTENT = 205,
|
|
45
|
+
PARTIAL_CONTENT = 206,
|
|
46
|
+
MULTI_STATUS = 207,
|
|
47
|
+
ALREADY_REPORTED = 208,
|
|
48
|
+
IM_USED = 226,
|
|
49
|
+
BAD_REQUEST = 400,
|
|
50
|
+
UNAUTHORIZED = 401,
|
|
51
|
+
PAYMENT_REQUIRED = 402,
|
|
52
|
+
FORBIDDEN = 403,
|
|
53
|
+
NOT_FOUND = 404,
|
|
54
|
+
METHOD_NOT_ALLOWED = 405,
|
|
55
|
+
NOT_ACCEPTABLE = 406,
|
|
56
|
+
PROXY_AUTHENTICATION_REQUIRED = 407,
|
|
57
|
+
REQUEST_TIMEOUT = 408,
|
|
58
|
+
CONFLICT = 409,
|
|
59
|
+
GONE = 410,
|
|
60
|
+
LENGTH_REQUIRED = 411,
|
|
61
|
+
PRECONDITION_FAILED = 412,
|
|
62
|
+
PAYLOAD_TOO_LARGE = 413,
|
|
63
|
+
URI_TOO_LONG = 414,
|
|
64
|
+
UNSUPPORTED_MEDIA_TYPE = 415,
|
|
65
|
+
RANGE_NOT_SATISFIABLE = 416,
|
|
66
|
+
EXPECTATION_FAILED = 417,
|
|
67
|
+
IM_A_TEAPOT = 418,
|
|
68
|
+
MISDIRECTED_REQUEST = 421,
|
|
69
|
+
UNPROCESSABLE_ENTITY = 422,
|
|
70
|
+
LOCKED = 423,
|
|
71
|
+
FAILED_DEPENDENCY = 424,
|
|
72
|
+
UPGRADE_REQUIRED = 426,
|
|
73
|
+
PRECONDITION_REQUIRED = 428,
|
|
74
|
+
TOO_MANY_REQUESTS = 429,
|
|
75
|
+
REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
|
|
76
|
+
UNAVAILABLE_FOR_LEGAL_REASONS = 451,
|
|
77
|
+
INTERNAL_SERVER_ERROR = 500,
|
|
78
|
+
NOT_IMPLEMENTED = 501,
|
|
79
|
+
BAD_GATEWAY = 502,
|
|
80
|
+
SERVICE_UNAVAILABLE = 503,
|
|
81
|
+
GATEWAY_TIMEOUT = 504,
|
|
82
|
+
HTTP_VERSION_NOT_SUPPORTED = 505,
|
|
83
|
+
VARIANT_ALSO_NEGOTIATES = 506,
|
|
84
|
+
INSUFFICIENT_STORAGE = 507,
|
|
85
|
+
LOOP_DETECTED = 508,
|
|
86
|
+
NOT_EXTENDED = 510,
|
|
87
|
+
NETWORK_AUTHENTICATION_REQUIRED = 511
|
|
88
|
+
}
|
|
89
|
+
type HttpStatusCodeNameMapKey = (typeof HttpStatusCode)[keyof typeof HttpStatusCode];
|
|
90
|
+
declare const HttpStatusCodeNameMap: Record<HttpStatusCodeNameMapKey, string>;
|
|
91
|
+
|
|
92
|
+
type IHttpResponse<Header extends IHttpHeader = IHttpHeader, Body extends IHttpBody = IHttpBody> = {
|
|
93
|
+
statusCode: HttpStatusCode;
|
|
94
|
+
header?: Header;
|
|
95
|
+
body?: Body;
|
|
96
|
+
};
|
|
97
|
+
declare class HttpResponse<Header extends IHttpHeader = IHttpHeader, Body extends IHttpBody = IHttpBody> implements IHttpResponse<Header, Body> {
|
|
98
|
+
readonly statusCode: HttpStatusCode;
|
|
99
|
+
readonly header: Header;
|
|
100
|
+
readonly body: Body;
|
|
101
|
+
constructor(statusCode: HttpStatusCode, header: Header, body: Body);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
type IHttpRequestDefinition<THeader extends HttpHeaderSchema | undefined = HttpHeaderSchema | undefined, TParam extends HttpParamSchema | undefined = HttpParamSchema | undefined, TQuery extends HttpQuerySchema | undefined = HttpQuerySchema | undefined, TBody extends HttpBodySchema | undefined = HttpBodySchema | undefined> = {
|
|
105
|
+
header?: THeader;
|
|
106
|
+
param?: TParam;
|
|
107
|
+
query?: TQuery;
|
|
108
|
+
body?: TBody;
|
|
109
|
+
};
|
|
110
|
+
declare class HttpRequestDefinition<THeader extends HttpHeaderSchema | undefined, TParam extends HttpParamSchema | undefined, TQuery extends HttpQuerySchema | undefined, TBody extends HttpBodySchema | undefined> implements IHttpRequestDefinition<THeader, TParam, TQuery, TBody> {
|
|
111
|
+
readonly header?: THeader;
|
|
112
|
+
readonly param?: TParam;
|
|
113
|
+
readonly query?: TQuery;
|
|
114
|
+
readonly body?: TBody;
|
|
115
|
+
constructor(definition: IHttpRequestDefinition<THeader, TParam, TQuery, TBody>);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
type IHttpResponseDefinition<TName extends string = string, TStatusCode extends HttpStatusCode = HttpStatusCode, TDescription extends string = string, THeader extends HttpHeaderSchema | undefined = HttpHeaderSchema | undefined, TBody extends HttpBodySchema | undefined = HttpBodySchema | undefined, TIsShared extends boolean = boolean> = {
|
|
119
|
+
name: TName;
|
|
120
|
+
statusCode: TStatusCode;
|
|
121
|
+
description: TDescription;
|
|
122
|
+
header?: THeader;
|
|
123
|
+
body?: TBody;
|
|
124
|
+
isShared?: TIsShared;
|
|
125
|
+
};
|
|
126
|
+
type IExtendHttpResponseDefinition<TName extends string, TStatusCode extends HttpStatusCode, TDescription extends string, THeader extends HttpHeaderSchema | undefined, TBody extends HttpBodySchema | undefined, TIsShared extends boolean> = Partial<IHttpResponseDefinition<TName, TStatusCode, TDescription, THeader, TBody, TIsShared>> & Pick<IHttpResponseDefinition<TName, TStatusCode, TDescription, THeader, TBody, TIsShared>, "name">;
|
|
127
|
+
declare class HttpResponseDefinition<TName extends string, TStatusCode extends HttpStatusCode, TDescription extends string, THeader extends HttpHeaderSchema | undefined, TBody extends HttpBodySchema | undefined, TIsShared extends boolean> {
|
|
128
|
+
private definition;
|
|
129
|
+
name: TName;
|
|
130
|
+
statusCode: TStatusCode;
|
|
131
|
+
description: TDescription;
|
|
132
|
+
header?: THeader;
|
|
133
|
+
body?: TBody;
|
|
134
|
+
isShared?: TIsShared;
|
|
135
|
+
constructor(definition: IHttpResponseDefinition<TName, TStatusCode, TDescription, THeader, TBody, TIsShared>);
|
|
136
|
+
extend<EName extends string, EStatusCode extends HttpStatusCode = TStatusCode, EDescription extends string = TDescription, EHeader extends HttpHeaderSchema | undefined = THeader, EBody extends HttpBodySchema | undefined = TBody, EIsShared extends boolean = TIsShared>(definition: IExtendHttpResponseDefinition<EName, EStatusCode, EDescription, EHeader, EBody, EIsShared>): HttpResponseDefinition<EName, EStatusCode, EDescription, THeader extends undefined ? EHeader : EHeader extends undefined ? THeader : THeader & EHeader, TBody extends undefined ? EBody : EBody extends undefined ? TBody : TBody & EBody, EIsShared>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Interface for HTTP operation definitions.
|
|
141
|
+
*
|
|
142
|
+
* Represents a complete HTTP API operation with:
|
|
143
|
+
* - Unique operation identifier
|
|
144
|
+
* - HTTP method and path
|
|
145
|
+
* - Request definition (headers, params, query, body)
|
|
146
|
+
* - Response definitions for different status codes
|
|
147
|
+
*
|
|
148
|
+
* @template TOperationId - The operation identifier literal type
|
|
149
|
+
* @template TPath - The URL path literal type
|
|
150
|
+
* @template TMethod - The HTTP method type
|
|
151
|
+
* @template TSummary - The operation summary literal type
|
|
152
|
+
* @template THeader - The header schema type
|
|
153
|
+
* @template TParam - The path parameter schema type
|
|
154
|
+
* @template TQuery - The query parameter schema type
|
|
155
|
+
* @template TBody - The request body schema type
|
|
156
|
+
* @template TRequest - The complete request definition type
|
|
157
|
+
* @template TResponses - The array of response definitions
|
|
158
|
+
*/
|
|
159
|
+
type IHttpOperationDefinition<TOperationId extends string = string, TPath extends string = string, TMethod extends HttpMethod = HttpMethod, TSummary extends string = string, THeader extends HttpHeaderSchema | undefined = HttpHeaderSchema | undefined, TParam extends HttpParamSchema | undefined = HttpParamSchema | undefined, TQuery extends HttpQuerySchema | undefined = HttpQuerySchema | undefined, TBody extends HttpBodySchema | undefined = HttpBodySchema | undefined, TRequest extends IHttpRequestDefinition<THeader, TParam, TQuery, TBody> = IHttpRequestDefinition<THeader, TParam, TQuery, TBody>, TResponses extends IHttpResponseDefinition[] = IHttpResponseDefinition[]> = {
|
|
160
|
+
operationId: TOperationId;
|
|
161
|
+
path: TPath;
|
|
162
|
+
method: TMethod;
|
|
163
|
+
summary: TSummary;
|
|
164
|
+
request: TRequest;
|
|
165
|
+
responses: TResponses;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Concrete implementation of HTTP operation definition.
|
|
169
|
+
*
|
|
170
|
+
* This class provides a type-safe way to define HTTP API operations with:
|
|
171
|
+
* - Full TypeScript type inference for all components
|
|
172
|
+
* - Integration with Zod schemas for runtime validation
|
|
173
|
+
* - Support for multiple response definitions per operation
|
|
174
|
+
* - OpenAPI-compatible structure
|
|
175
|
+
*
|
|
176
|
+
* The extensive generic parameters enable complete type safety from
|
|
177
|
+
* definition through to runtime execution and code generation.
|
|
178
|
+
*
|
|
179
|
+
* @template TOperationId - The operation identifier literal type
|
|
180
|
+
* @template TPath - The URL path literal type
|
|
181
|
+
* @template TMethod - The HTTP method type
|
|
182
|
+
* @template TSummary - The operation summary literal type
|
|
183
|
+
* @template THeader - The header schema type
|
|
184
|
+
* @template TParam - The path parameter schema type
|
|
185
|
+
* @template TQuery - The query parameter schema type
|
|
186
|
+
* @template TBody - The request body schema type
|
|
187
|
+
* @template TRequest - The complete request definition type
|
|
188
|
+
* @template TResponses - The array of response definitions
|
|
189
|
+
*/
|
|
190
|
+
declare class HttpOperationDefinition<TOperationId extends string, TPath extends string, TMethod extends HttpMethod, TSummary extends string, THeader extends HttpHeaderSchema | undefined, TParam extends HttpParamSchema | undefined, TQuery extends HttpQuerySchema | undefined, TBody extends HttpBodySchema | undefined, TRequest extends IHttpRequestDefinition<THeader, TParam, TQuery, TBody>, TResponses extends IHttpResponseDefinition[]> implements IHttpOperationDefinition<TOperationId, TPath, TMethod, TSummary, THeader, TParam, TQuery, TBody, TRequest, TResponses> {
|
|
191
|
+
readonly operationId: TOperationId;
|
|
192
|
+
readonly path: TPath;
|
|
193
|
+
readonly method: TMethod;
|
|
194
|
+
readonly summary: TSummary;
|
|
195
|
+
readonly request: TRequest;
|
|
196
|
+
readonly responses: TResponses;
|
|
197
|
+
constructor(definition: IHttpOperationDefinition<TOperationId, TPath, TMethod, TSummary, THeader, TParam, TQuery, TBody, TRequest, TResponses>);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Input configuration for RequestValidationError.
|
|
202
|
+
*/
|
|
203
|
+
type RequestValidationErrorInput = {
|
|
204
|
+
/** Validation issues found in HTTP headers */
|
|
205
|
+
headerIssues?: z.core.$ZodRawIssue[];
|
|
206
|
+
/** Validation issues found in request body */
|
|
207
|
+
bodyIssues?: z.core.$ZodRawIssue[];
|
|
208
|
+
/** Validation issues found in query parameters */
|
|
209
|
+
queryIssues?: z.core.$ZodRawIssue[];
|
|
210
|
+
/** Validation issues found in path parameters */
|
|
211
|
+
pathParamIssues?: z.core.$ZodRawIssue[];
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* Error thrown when HTTP request validation fails.
|
|
215
|
+
*
|
|
216
|
+
* This error provides detailed information about validation failures across
|
|
217
|
+
* different parts of an HTTP request. Each category of issues is stored
|
|
218
|
+
* separately for precise error reporting and debugging.
|
|
219
|
+
*
|
|
220
|
+
* The error integrates with Zod's issue format, making it compatible with
|
|
221
|
+
* Zod schema validation while maintaining flexibility for custom validators.
|
|
222
|
+
*/
|
|
223
|
+
declare class RequestValidationError extends Error {
|
|
224
|
+
readonly message: string;
|
|
225
|
+
/** Validation issues found in HTTP headers */
|
|
226
|
+
readonly headerIssues: z.core.$ZodRawIssue[];
|
|
227
|
+
/** Validation issues found in request body */
|
|
228
|
+
readonly bodyIssues: z.core.$ZodRawIssue[];
|
|
229
|
+
/** Validation issues found in query parameters */
|
|
230
|
+
readonly queryIssues: z.core.$ZodRawIssue[];
|
|
231
|
+
/** Validation issues found in path parameters */
|
|
232
|
+
readonly pathParamIssues: z.core.$ZodRawIssue[];
|
|
233
|
+
constructor(input?: RequestValidationErrorInput);
|
|
234
|
+
/**
|
|
235
|
+
* Adds header validation issues to the error.
|
|
236
|
+
* @param issues - Array of Zod validation issues
|
|
237
|
+
*/
|
|
238
|
+
addHeaderIssues(issues: z.core.$ZodRawIssue[]): void;
|
|
239
|
+
/**
|
|
240
|
+
* Adds body validation issues to the error.
|
|
241
|
+
* @param issues - Array of Zod validation issues
|
|
242
|
+
*/
|
|
243
|
+
addBodyIssues(issues: z.core.$ZodRawIssue[]): void;
|
|
244
|
+
/**
|
|
245
|
+
* Adds query parameter validation issues to the error.
|
|
246
|
+
* @param issues - Array of Zod validation issues
|
|
247
|
+
*/
|
|
248
|
+
addQueryIssues(issues: z.core.$ZodRawIssue[]): void;
|
|
249
|
+
/**
|
|
250
|
+
* Adds path parameter validation issues to the error.
|
|
251
|
+
* @param issues - Array of Zod validation issues
|
|
252
|
+
*/
|
|
253
|
+
addPathParamIssues(issues: z.core.$ZodRawIssue[]): void;
|
|
254
|
+
/**
|
|
255
|
+
* Checks if this error contains any validation issues.
|
|
256
|
+
* @returns true if any category has issues, false otherwise
|
|
257
|
+
*/
|
|
258
|
+
hasIssues(): boolean;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
type ValidationSuccessResult$1<T> = {
|
|
262
|
+
isValid: true;
|
|
263
|
+
data: T;
|
|
264
|
+
};
|
|
265
|
+
type ValidationFailureResult$1 = {
|
|
266
|
+
isValid: false;
|
|
267
|
+
error: RequestValidationError;
|
|
268
|
+
};
|
|
269
|
+
type SafeRequestValidationResult<T> = ValidationSuccessResult$1<T> | ValidationFailureResult$1;
|
|
270
|
+
/**
|
|
271
|
+
* Interface for HTTP request validators.
|
|
272
|
+
*/
|
|
273
|
+
type IRequestValidator = {
|
|
274
|
+
/**
|
|
275
|
+
* Validates a request and returns a result object.
|
|
276
|
+
* Does not throw errors.
|
|
277
|
+
*/
|
|
278
|
+
safeValidate(request: IHttpRequest): SafeRequestValidationResult<IHttpRequest>;
|
|
279
|
+
/**
|
|
280
|
+
* Validates a request and returns the validated request.
|
|
281
|
+
* @throws {RequestValidationError} If validation fails
|
|
282
|
+
*/
|
|
283
|
+
validate(request: IHttpRequest): IHttpRequest;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
type ResponseValidationErrorInput = {
|
|
287
|
+
headerIssues?: z.core.$ZodRawIssue[];
|
|
288
|
+
bodyIssues?: z.core.$ZodRawIssue[];
|
|
289
|
+
};
|
|
290
|
+
declare class ResponseValidationError extends Error {
|
|
291
|
+
readonly statusCode: HttpStatusCode;
|
|
292
|
+
readonly message: string;
|
|
293
|
+
readonly headerIssues: z.core.$ZodRawIssue[];
|
|
294
|
+
readonly bodyIssues: z.core.$ZodRawIssue[];
|
|
295
|
+
constructor(statusCode: HttpStatusCode, input?: ResponseValidationErrorInput);
|
|
296
|
+
addHeaderIssues(issues: z.core.$ZodRawIssue[]): void;
|
|
297
|
+
addBodyIssues(issues: z.core.$ZodRawIssue[]): void;
|
|
298
|
+
hasIssues(): boolean;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
type ValidationSuccessResult<T> = {
|
|
302
|
+
isValid: true;
|
|
303
|
+
data: T;
|
|
304
|
+
};
|
|
305
|
+
type ValidationFailureResult = {
|
|
306
|
+
isValid: false;
|
|
307
|
+
error: ResponseValidationError;
|
|
308
|
+
};
|
|
309
|
+
type SafeResponseValidationResult<T> = ValidationSuccessResult<T> | ValidationFailureResult;
|
|
310
|
+
/**
|
|
311
|
+
* Interface for HTTP response validators.
|
|
312
|
+
*/
|
|
313
|
+
type IResponseValidator = {
|
|
314
|
+
/**
|
|
315
|
+
* Validates a response and returns a result object.
|
|
316
|
+
* Does not throw errors.
|
|
317
|
+
*/
|
|
318
|
+
safeValidate(response: IHttpResponse): SafeResponseValidationResult<IHttpResponse>;
|
|
319
|
+
/**
|
|
320
|
+
* Validates a response and returns the validated response.
|
|
321
|
+
* @throws {ResponseValidationError} If validation fails
|
|
322
|
+
*/
|
|
323
|
+
validate(response: IHttpResponse): IHttpResponse;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
export { type HttpBodySchema, type HttpHeaderSchema, HttpMethod, HttpOperationDefinition, type HttpParamSchema, type HttpQuerySchema, HttpRequestDefinition, HttpResponse, HttpResponseDefinition, HttpStatusCode, HttpStatusCodeNameMap, type IExtendHttpResponseDefinition, type IHttpBody, type IHttpHeader, type IHttpOperationDefinition, type IHttpParam, type IHttpQuery, type IHttpRequest, type IHttpRequestDefinition, type IHttpResponse, type IHttpResponseDefinition, type IRequestValidator, type IResponseValidator, RequestValidationError, type RequestValidationErrorInput, ResponseValidationError, type ResponseValidationErrorInput, type SafeRequestValidationResult, type SafeResponseValidationResult };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import z from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
var HttpStatusCode = /* @__PURE__ */ ((HttpStatusCode2) => {
|
|
4
|
+
HttpStatusCode2[HttpStatusCode2["OK"] = 200] = "OK";
|
|
5
|
+
HttpStatusCode2[HttpStatusCode2["CREATED"] = 201] = "CREATED";
|
|
6
|
+
HttpStatusCode2[HttpStatusCode2["ACCEPTED"] = 202] = "ACCEPTED";
|
|
7
|
+
HttpStatusCode2[HttpStatusCode2["NO_CONTENT"] = 204] = "NO_CONTENT";
|
|
8
|
+
HttpStatusCode2[HttpStatusCode2["RESET_CONTENT"] = 205] = "RESET_CONTENT";
|
|
9
|
+
HttpStatusCode2[HttpStatusCode2["PARTIAL_CONTENT"] = 206] = "PARTIAL_CONTENT";
|
|
10
|
+
HttpStatusCode2[HttpStatusCode2["MULTI_STATUS"] = 207] = "MULTI_STATUS";
|
|
11
|
+
HttpStatusCode2[HttpStatusCode2["ALREADY_REPORTED"] = 208] = "ALREADY_REPORTED";
|
|
12
|
+
HttpStatusCode2[HttpStatusCode2["IM_USED"] = 226] = "IM_USED";
|
|
13
|
+
HttpStatusCode2[HttpStatusCode2["BAD_REQUEST"] = 400] = "BAD_REQUEST";
|
|
14
|
+
HttpStatusCode2[HttpStatusCode2["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
|
|
15
|
+
HttpStatusCode2[HttpStatusCode2["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
|
|
16
|
+
HttpStatusCode2[HttpStatusCode2["FORBIDDEN"] = 403] = "FORBIDDEN";
|
|
17
|
+
HttpStatusCode2[HttpStatusCode2["NOT_FOUND"] = 404] = "NOT_FOUND";
|
|
18
|
+
HttpStatusCode2[HttpStatusCode2["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
|
|
19
|
+
HttpStatusCode2[HttpStatusCode2["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
|
|
20
|
+
HttpStatusCode2[HttpStatusCode2["PROXY_AUTHENTICATION_REQUIRED"] = 407] = "PROXY_AUTHENTICATION_REQUIRED";
|
|
21
|
+
HttpStatusCode2[HttpStatusCode2["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
|
|
22
|
+
HttpStatusCode2[HttpStatusCode2["CONFLICT"] = 409] = "CONFLICT";
|
|
23
|
+
HttpStatusCode2[HttpStatusCode2["GONE"] = 410] = "GONE";
|
|
24
|
+
HttpStatusCode2[HttpStatusCode2["LENGTH_REQUIRED"] = 411] = "LENGTH_REQUIRED";
|
|
25
|
+
HttpStatusCode2[HttpStatusCode2["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED";
|
|
26
|
+
HttpStatusCode2[HttpStatusCode2["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
|
|
27
|
+
HttpStatusCode2[HttpStatusCode2["URI_TOO_LONG"] = 414] = "URI_TOO_LONG";
|
|
28
|
+
HttpStatusCode2[HttpStatusCode2["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
|
|
29
|
+
HttpStatusCode2[HttpStatusCode2["RANGE_NOT_SATISFIABLE"] = 416] = "RANGE_NOT_SATISFIABLE";
|
|
30
|
+
HttpStatusCode2[HttpStatusCode2["EXPECTATION_FAILED"] = 417] = "EXPECTATION_FAILED";
|
|
31
|
+
HttpStatusCode2[HttpStatusCode2["IM_A_TEAPOT"] = 418] = "IM_A_TEAPOT";
|
|
32
|
+
HttpStatusCode2[HttpStatusCode2["MISDIRECTED_REQUEST"] = 421] = "MISDIRECTED_REQUEST";
|
|
33
|
+
HttpStatusCode2[HttpStatusCode2["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
|
|
34
|
+
HttpStatusCode2[HttpStatusCode2["LOCKED"] = 423] = "LOCKED";
|
|
35
|
+
HttpStatusCode2[HttpStatusCode2["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
|
|
36
|
+
HttpStatusCode2[HttpStatusCode2["UPGRADE_REQUIRED"] = 426] = "UPGRADE_REQUIRED";
|
|
37
|
+
HttpStatusCode2[HttpStatusCode2["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
|
|
38
|
+
HttpStatusCode2[HttpStatusCode2["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
|
|
39
|
+
HttpStatusCode2[HttpStatusCode2["REQUEST_HEADER_FIELDS_TOO_LARGE"] = 431] = "REQUEST_HEADER_FIELDS_TOO_LARGE";
|
|
40
|
+
HttpStatusCode2[HttpStatusCode2["UNAVAILABLE_FOR_LEGAL_REASONS"] = 451] = "UNAVAILABLE_FOR_LEGAL_REASONS";
|
|
41
|
+
HttpStatusCode2[HttpStatusCode2["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
|
|
42
|
+
HttpStatusCode2[HttpStatusCode2["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
|
|
43
|
+
HttpStatusCode2[HttpStatusCode2["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
|
|
44
|
+
HttpStatusCode2[HttpStatusCode2["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
|
|
45
|
+
HttpStatusCode2[HttpStatusCode2["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
|
|
46
|
+
HttpStatusCode2[HttpStatusCode2["HTTP_VERSION_NOT_SUPPORTED"] = 505] = "HTTP_VERSION_NOT_SUPPORTED";
|
|
47
|
+
HttpStatusCode2[HttpStatusCode2["VARIANT_ALSO_NEGOTIATES"] = 506] = "VARIANT_ALSO_NEGOTIATES";
|
|
48
|
+
HttpStatusCode2[HttpStatusCode2["INSUFFICIENT_STORAGE"] = 507] = "INSUFFICIENT_STORAGE";
|
|
49
|
+
HttpStatusCode2[HttpStatusCode2["LOOP_DETECTED"] = 508] = "LOOP_DETECTED";
|
|
50
|
+
HttpStatusCode2[HttpStatusCode2["NOT_EXTENDED"] = 510] = "NOT_EXTENDED";
|
|
51
|
+
HttpStatusCode2[HttpStatusCode2["NETWORK_AUTHENTICATION_REQUIRED"] = 511] = "NETWORK_AUTHENTICATION_REQUIRED";
|
|
52
|
+
return HttpStatusCode2;
|
|
53
|
+
})(HttpStatusCode || {});
|
|
54
|
+
const HttpStatusCodeNameMap = {
|
|
55
|
+
[200 /* OK */]: "Ok",
|
|
56
|
+
[201 /* CREATED */]: "Created",
|
|
57
|
+
[202 /* ACCEPTED */]: "Accepted",
|
|
58
|
+
[204 /* NO_CONTENT */]: "NoContent",
|
|
59
|
+
[205 /* RESET_CONTENT */]: "ResetContent",
|
|
60
|
+
[206 /* PARTIAL_CONTENT */]: "PartialContent",
|
|
61
|
+
[207 /* MULTI_STATUS */]: "MultiStatus",
|
|
62
|
+
[208 /* ALREADY_REPORTED */]: "AlreadyReported",
|
|
63
|
+
[226 /* IM_USED */]: "ImUsed",
|
|
64
|
+
[400 /* BAD_REQUEST */]: "BadRequest",
|
|
65
|
+
[401 /* UNAUTHORIZED */]: "Unauthorized",
|
|
66
|
+
[402 /* PAYMENT_REQUIRED */]: "PaymentRequired",
|
|
67
|
+
[403 /* FORBIDDEN */]: "Forbidden",
|
|
68
|
+
[404 /* NOT_FOUND */]: "NotFound",
|
|
69
|
+
[405 /* METHOD_NOT_ALLOWED */]: "MethodNotAllowed",
|
|
70
|
+
[406 /* NOT_ACCEPTABLE */]: "NotAcceptable",
|
|
71
|
+
[407 /* PROXY_AUTHENTICATION_REQUIRED */]: "ProxyAuthenticationRequired",
|
|
72
|
+
[408 /* REQUEST_TIMEOUT */]: "RequestTimeout",
|
|
73
|
+
[409 /* CONFLICT */]: "Conflict",
|
|
74
|
+
[410 /* GONE */]: "Gone",
|
|
75
|
+
[411 /* LENGTH_REQUIRED */]: "LengthRequired",
|
|
76
|
+
[412 /* PRECONDITION_FAILED */]: "PreconditionFailed",
|
|
77
|
+
[413 /* PAYLOAD_TOO_LARGE */]: "PayloadTooLarge",
|
|
78
|
+
[414 /* URI_TOO_LONG */]: "UriTooLong",
|
|
79
|
+
[415 /* UNSUPPORTED_MEDIA_TYPE */]: "UnsupportedMediaType",
|
|
80
|
+
[416 /* RANGE_NOT_SATISFIABLE */]: "RangeNotSatisfiable",
|
|
81
|
+
[417 /* EXPECTATION_FAILED */]: "ExpectationFailed",
|
|
82
|
+
[418 /* IM_A_TEAPOT */]: "ImATeapot",
|
|
83
|
+
[421 /* MISDIRECTED_REQUEST */]: "MisdirectedRequest",
|
|
84
|
+
[422 /* UNPROCESSABLE_ENTITY */]: "UnprocessableEntity",
|
|
85
|
+
[423 /* LOCKED */]: "Locked",
|
|
86
|
+
[424 /* FAILED_DEPENDENCY */]: "FailedDependency",
|
|
87
|
+
[426 /* UPGRADE_REQUIRED */]: "UpgradeRequired",
|
|
88
|
+
[428 /* PRECONDITION_REQUIRED */]: "PreconditionRequired",
|
|
89
|
+
[429 /* TOO_MANY_REQUESTS */]: "TooManyRequests",
|
|
90
|
+
[431 /* REQUEST_HEADER_FIELDS_TOO_LARGE */]: "RequestHeaderFieldsTooLarge",
|
|
91
|
+
[451 /* UNAVAILABLE_FOR_LEGAL_REASONS */]: "UnavailableForLegalReasons",
|
|
92
|
+
[500 /* INTERNAL_SERVER_ERROR */]: "InternalServerError",
|
|
93
|
+
[501 /* NOT_IMPLEMENTED */]: "NotImplemented",
|
|
94
|
+
[502 /* BAD_GATEWAY */]: "BadGateway",
|
|
95
|
+
[503 /* SERVICE_UNAVAILABLE */]: "ServiceUnavailable",
|
|
96
|
+
[504 /* GATEWAY_TIMEOUT */]: "GatewayTimeout",
|
|
97
|
+
[505 /* HTTP_VERSION_NOT_SUPPORTED */]: "HttpVersionNotSupported",
|
|
98
|
+
[506 /* VARIANT_ALSO_NEGOTIATES */]: "VariantAlsoNegotiates",
|
|
99
|
+
[507 /* INSUFFICIENT_STORAGE */]: "InsufficientStorage",
|
|
100
|
+
[508 /* LOOP_DETECTED */]: "LoopDetected",
|
|
101
|
+
[510 /* NOT_EXTENDED */]: "NotExtended",
|
|
102
|
+
[511 /* NETWORK_AUTHENTICATION_REQUIRED */]: "NetworkAuthenticationRequired"
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
class HttpResponse {
|
|
106
|
+
constructor(statusCode, header, body) {
|
|
107
|
+
this.statusCode = statusCode;
|
|
108
|
+
this.header = header;
|
|
109
|
+
this.body = body;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
|
|
114
|
+
HttpMethod2["GET"] = "GET";
|
|
115
|
+
HttpMethod2["POST"] = "POST";
|
|
116
|
+
HttpMethod2["PUT"] = "PUT";
|
|
117
|
+
HttpMethod2["DELETE"] = "DELETE";
|
|
118
|
+
HttpMethod2["PATCH"] = "PATCH";
|
|
119
|
+
HttpMethod2["OPTIONS"] = "OPTIONS";
|
|
120
|
+
HttpMethod2["HEAD"] = "HEAD";
|
|
121
|
+
HttpMethod2["TRACE"] = "TRACE";
|
|
122
|
+
HttpMethod2["CONNECT"] = "CONNECT";
|
|
123
|
+
return HttpMethod2;
|
|
124
|
+
})(HttpMethod || {});
|
|
125
|
+
|
|
126
|
+
class HttpOperationDefinition {
|
|
127
|
+
operationId;
|
|
128
|
+
path;
|
|
129
|
+
method;
|
|
130
|
+
summary;
|
|
131
|
+
request;
|
|
132
|
+
responses;
|
|
133
|
+
constructor(definition) {
|
|
134
|
+
this.operationId = definition.operationId;
|
|
135
|
+
this.path = definition.path;
|
|
136
|
+
this.method = definition.method;
|
|
137
|
+
this.summary = definition.summary;
|
|
138
|
+
this.request = definition.request;
|
|
139
|
+
this.responses = definition.responses;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
class HttpRequestDefinition {
|
|
144
|
+
header;
|
|
145
|
+
param;
|
|
146
|
+
query;
|
|
147
|
+
body;
|
|
148
|
+
constructor(definition) {
|
|
149
|
+
this.header = definition.header;
|
|
150
|
+
this.param = definition.param;
|
|
151
|
+
this.query = definition.query;
|
|
152
|
+
this.body = definition.body;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
class HttpResponseDefinition {
|
|
157
|
+
constructor(definition) {
|
|
158
|
+
this.definition = definition;
|
|
159
|
+
this.name = definition.name;
|
|
160
|
+
this.statusCode = definition.statusCode;
|
|
161
|
+
this.description = definition.description;
|
|
162
|
+
this.header = definition.header;
|
|
163
|
+
this.body = definition.body;
|
|
164
|
+
this.isShared = definition.isShared;
|
|
165
|
+
}
|
|
166
|
+
name;
|
|
167
|
+
statusCode;
|
|
168
|
+
description;
|
|
169
|
+
header;
|
|
170
|
+
body;
|
|
171
|
+
isShared;
|
|
172
|
+
extend(definition) {
|
|
173
|
+
const mergedHeader = (() => {
|
|
174
|
+
if (!this.header && !definition.header) return void 0;
|
|
175
|
+
if (!this.header) return definition.header;
|
|
176
|
+
if (!definition.header) return this.header;
|
|
177
|
+
return z.object({
|
|
178
|
+
...this.header.shape,
|
|
179
|
+
...definition.header.shape
|
|
180
|
+
});
|
|
181
|
+
})();
|
|
182
|
+
const mergedBody = (() => {
|
|
183
|
+
if (!this.body && !definition.body) return void 0;
|
|
184
|
+
if (!this.body) return definition.body;
|
|
185
|
+
if (!definition.body) return this.body;
|
|
186
|
+
if (this.body instanceof z.ZodObject && definition.body instanceof z.ZodObject) {
|
|
187
|
+
return z.object({
|
|
188
|
+
...this.body.shape,
|
|
189
|
+
...definition.body.shape
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return definition.body;
|
|
193
|
+
})();
|
|
194
|
+
const baseDefinition = {
|
|
195
|
+
...this.definition,
|
|
196
|
+
name: definition.name,
|
|
197
|
+
statusCode: definition.statusCode ?? this.statusCode,
|
|
198
|
+
description: definition.description ?? this.description,
|
|
199
|
+
isShared: definition.isShared ?? this.isShared,
|
|
200
|
+
header: mergedHeader,
|
|
201
|
+
body: mergedBody
|
|
202
|
+
};
|
|
203
|
+
return new HttpResponseDefinition(baseDefinition);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
class RequestValidationError extends Error {
|
|
208
|
+
message;
|
|
209
|
+
/** Validation issues found in HTTP headers */
|
|
210
|
+
headerIssues = [];
|
|
211
|
+
/** Validation issues found in request body */
|
|
212
|
+
bodyIssues = [];
|
|
213
|
+
/** Validation issues found in query parameters */
|
|
214
|
+
queryIssues = [];
|
|
215
|
+
/** Validation issues found in path parameters */
|
|
216
|
+
pathParamIssues = [];
|
|
217
|
+
constructor(input) {
|
|
218
|
+
const message = "Invalid request";
|
|
219
|
+
super(message);
|
|
220
|
+
this.message = message;
|
|
221
|
+
if (input?.headerIssues) {
|
|
222
|
+
this.headerIssues = input.headerIssues;
|
|
223
|
+
}
|
|
224
|
+
if (input?.bodyIssues) {
|
|
225
|
+
this.bodyIssues = input.bodyIssues;
|
|
226
|
+
}
|
|
227
|
+
if (input?.queryIssues) {
|
|
228
|
+
this.queryIssues = input.queryIssues;
|
|
229
|
+
}
|
|
230
|
+
if (input?.pathParamIssues) {
|
|
231
|
+
this.pathParamIssues = input.pathParamIssues;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Adds header validation issues to the error.
|
|
236
|
+
* @param issues - Array of Zod validation issues
|
|
237
|
+
*/
|
|
238
|
+
addHeaderIssues(issues) {
|
|
239
|
+
this.headerIssues.push(...issues);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Adds body validation issues to the error.
|
|
243
|
+
* @param issues - Array of Zod validation issues
|
|
244
|
+
*/
|
|
245
|
+
addBodyIssues(issues) {
|
|
246
|
+
this.bodyIssues.push(...issues);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Adds query parameter validation issues to the error.
|
|
250
|
+
* @param issues - Array of Zod validation issues
|
|
251
|
+
*/
|
|
252
|
+
addQueryIssues(issues) {
|
|
253
|
+
this.queryIssues.push(...issues);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Adds path parameter validation issues to the error.
|
|
257
|
+
* @param issues - Array of Zod validation issues
|
|
258
|
+
*/
|
|
259
|
+
addPathParamIssues(issues) {
|
|
260
|
+
this.pathParamIssues.push(...issues);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Checks if this error contains any validation issues.
|
|
264
|
+
* @returns true if any category has issues, false otherwise
|
|
265
|
+
*/
|
|
266
|
+
hasIssues() {
|
|
267
|
+
return this.headerIssues.length > 0 || this.bodyIssues.length > 0 || this.queryIssues.length > 0 || this.pathParamIssues.length > 0;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
class ResponseValidationError extends Error {
|
|
272
|
+
constructor(statusCode, input) {
|
|
273
|
+
const message = `Invalid response for status code '${statusCode}'`;
|
|
274
|
+
super(message);
|
|
275
|
+
this.statusCode = statusCode;
|
|
276
|
+
this.message = message;
|
|
277
|
+
if (input?.headerIssues) {
|
|
278
|
+
this.headerIssues = input.headerIssues;
|
|
279
|
+
}
|
|
280
|
+
if (input?.bodyIssues) {
|
|
281
|
+
this.bodyIssues = input.bodyIssues;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
message;
|
|
285
|
+
headerIssues = [];
|
|
286
|
+
bodyIssues = [];
|
|
287
|
+
addHeaderIssues(issues) {
|
|
288
|
+
this.headerIssues.push(...issues);
|
|
289
|
+
}
|
|
290
|
+
addBodyIssues(issues) {
|
|
291
|
+
this.bodyIssues.push(...issues);
|
|
292
|
+
}
|
|
293
|
+
hasIssues() {
|
|
294
|
+
return this.headerIssues.length > 0 || this.bodyIssues.length > 0;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export { HttpMethod, HttpOperationDefinition, HttpRequestDefinition, HttpResponse, HttpResponseDefinition, HttpStatusCode, HttpStatusCodeNameMap, RequestValidationError, ResponseValidationError };
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rexeus/typeweaver-core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Core TypeScript and Zod utilities for TypeWeaver API framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"package.json",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"api",
|
|
21
|
+
"spec",
|
|
22
|
+
"definition",
|
|
23
|
+
"typescript",
|
|
24
|
+
"zod",
|
|
25
|
+
"generator",
|
|
26
|
+
"typeweaver"
|
|
27
|
+
],
|
|
28
|
+
"author": "Dennis Wentzien <dw@rexeus.com>",
|
|
29
|
+
"license": "ISC",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/rexeus/typeweaver.git",
|
|
33
|
+
"directory": "packages/core"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/rexeus/typeweaver/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/rexeus/typeweaver#readme",
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"axios": "^1.9.0",
|
|
41
|
+
"hono": "^4.8.0",
|
|
42
|
+
"zod": "^3.25.28"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"axios": "^1.9.0",
|
|
46
|
+
"hono": "^4.8.0",
|
|
47
|
+
"zod": "^3.25.0"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@types/aws-lambda": "^8.10.149",
|
|
51
|
+
"case": "^1.6.3"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"format": "prettier --write .",
|
|
56
|
+
"build": "pkgroll --clean-dist",
|
|
57
|
+
"preversion": "npm run build"
|
|
58
|
+
}
|
|
59
|
+
}
|