@kaapi/validator-zod 0.0.17
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/LICENSE +21 -0
- package/README.md +231 -0
- package/lib/declarations.d.ts +13 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +6 -0
- package/lib/index.js.map +1 -0
- package/lib/types.d.ts +25 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- package/lib/utils.d.ts +5 -0
- package/lib/utils.js +80 -0
- package/lib/utils.js.map +1 -0
- package/lib/validator.d.ts +18 -0
- package/lib/validator.js +218 -0
- package/lib/validator.js.map +1 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 demingongo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# π§ͺ @kaapi/validator-zod
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
**Zod-powered validation plugin for [Kaapi](https://www.npmjs.com/package/@kaapi/kaapi)**. Validate request `params`, `payload`, `query`, `headers`, and `state` using [Zod 4](https://www.npmjs.com/package/zod) schemas. Includes built-in documentation helpers for seamless API docs generation.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## π Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @kaapi/validator-zod
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### π¦ Peer Dependency
|
|
17
|
+
|
|
18
|
+
Requires Zod v4:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install zod@^4.0.0
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## π οΈ Usage
|
|
27
|
+
|
|
28
|
+
### π Register the Plugin
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { z } from 'zod/v4'
|
|
32
|
+
import { Kaapi } from '@kaapi/kaapi'
|
|
33
|
+
import { validatorZod } from '@kaapi/validator-zod'
|
|
34
|
+
|
|
35
|
+
const app = new Kaapi({
|
|
36
|
+
port: 3000,
|
|
37
|
+
host: 'localhost',
|
|
38
|
+
docs: {
|
|
39
|
+
disabled: false // explicitly enables documentation generation
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await app.extend(validatorZod); // register the plugin
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### π Define a Schema
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { z } from 'zod/v4'
|
|
52
|
+
import { ValidatorZodSchema } from '@kaapi/validator-zod'
|
|
53
|
+
|
|
54
|
+
const routeSchema: ValidatorZodSchema = {
|
|
55
|
+
payload: z.object({
|
|
56
|
+
name: z.string()
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### π§ Create a Route
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
app.base().zod(routeSchema).route(
|
|
67
|
+
{
|
|
68
|
+
method: 'POST',
|
|
69
|
+
path: '/items'
|
|
70
|
+
},
|
|
71
|
+
req => ({ id: Date.now(), name: req.payload.name })
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
// or using inline handler
|
|
75
|
+
/*
|
|
76
|
+
app.base().zod(routeSchema).route({
|
|
77
|
+
method: 'POST',
|
|
78
|
+
path: '/items',
|
|
79
|
+
handler: req => ({ id: Date.now(), name: req.payload.name })
|
|
80
|
+
})
|
|
81
|
+
*/
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## βοΈ Advanced Configuration
|
|
87
|
+
|
|
88
|
+
### π§ `options`
|
|
89
|
+
|
|
90
|
+
Customize Zod parsing behavior:
|
|
91
|
+
|
|
92
|
+
| Property | Type | Default | Description |
|
|
93
|
+
|---------------|---------------------------|-------------|-----------------------------------------------------------------------------|
|
|
94
|
+
| `error` | `errors.$ZodErrorMap<T>` | `undefined` | Custom error map for localization or formatting |
|
|
95
|
+
| `reportInput` | `boolean` | `false` | When `true`, includes original input in error issues (useful for debugging) |
|
|
96
|
+
| `jitless` | `boolean` | `false` | When `true`, disables JIT optimizations for environments where `eval` is restricted (e.g., Cloudflare Workers). |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
### π¨ `failAction`
|
|
101
|
+
|
|
102
|
+
Control how validation failures are handled:
|
|
103
|
+
|
|
104
|
+
| Value | Behavior | Safe? | Description |
|
|
105
|
+
|---------------|------------------------------|-------|--------------------------------------------------|
|
|
106
|
+
| `'error'` | Reject with validation error | β
| Default safe behavior |
|
|
107
|
+
| `'log'` | Log and reject | β
| Useful for observability |
|
|
108
|
+
| `function` | Custom handler | β
(developer-controlled) | Must return or throw explicitly |
|
|
109
|
+
| `'ignore'` | β Not supported | β | Unsafe and not implemented |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### π§ͺ Example with Overrides
|
|
114
|
+
|
|
115
|
+
You can override Zod validation behavior **globally** for all routes, or **per route** as needed.
|
|
116
|
+
|
|
117
|
+
#### π Global Override (All Routes)
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
const app = new Kaapi({
|
|
121
|
+
// ...
|
|
122
|
+
routes: {
|
|
123
|
+
plugins: {
|
|
124
|
+
zod: {
|
|
125
|
+
options: {
|
|
126
|
+
reportInput: true
|
|
127
|
+
},
|
|
128
|
+
failAction: 'log'
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
await app.extend(validatorZod);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
This sets `reportInput` to `true` for all Zod-validated routes, and logs validation errors before throwing them.
|
|
138
|
+
|
|
139
|
+
#### π Per-Route Override
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
app.base().zod({
|
|
143
|
+
query: z.object({
|
|
144
|
+
name: z.string().trim().nonempty().max(10).meta({
|
|
145
|
+
description: 'Optional name to personalize the greeting response'
|
|
146
|
+
}).optional().default('World')
|
|
147
|
+
}),
|
|
148
|
+
options: {
|
|
149
|
+
reportInput: false
|
|
150
|
+
},
|
|
151
|
+
failAction: async (request, h, err) => {
|
|
152
|
+
if (Boom.isBoom(err)) {
|
|
153
|
+
return h.response({
|
|
154
|
+
...err.output.payload,
|
|
155
|
+
details: err.data.validationError.issues
|
|
156
|
+
}).code(err.output.statusCode).takeover()
|
|
157
|
+
}
|
|
158
|
+
return err
|
|
159
|
+
}
|
|
160
|
+
}).route({
|
|
161
|
+
path: '/greetings',
|
|
162
|
+
method: 'GET',
|
|
163
|
+
handler: ({ query: { name } }) => `Hello ${name}!`
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## π€ File Upload Example
|
|
170
|
+
|
|
171
|
+
Multipart file uploads with Zod validation is supported. Here's how to validate an uploaded image file and stream it back in the response:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
app.base().zod({
|
|
175
|
+
payload: z.object({
|
|
176
|
+
file: z.looseObject({
|
|
177
|
+
_data: z.instanceof(Buffer),
|
|
178
|
+
hapi: z.looseObject({
|
|
179
|
+
filename: z.string(),
|
|
180
|
+
headers: z.looseObject({
|
|
181
|
+
'content-type': z.enum(['image/jpeg', 'image/jpg', 'image/png'])
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
}).route({
|
|
187
|
+
method: 'POST',
|
|
188
|
+
path: '/upload-image',
|
|
189
|
+
options: {
|
|
190
|
+
description: 'Upload an image',
|
|
191
|
+
payload: {
|
|
192
|
+
output: 'stream',
|
|
193
|
+
parse: true,
|
|
194
|
+
allow: 'multipart/form-data',
|
|
195
|
+
multipart: { output: 'stream' },
|
|
196
|
+
maxBytes: 1024 * 3_000
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}, (req, h) =>
|
|
200
|
+
h.response(req.payload.file._data)
|
|
201
|
+
.type(req.payload.file.hapi.headers['content-type'])
|
|
202
|
+
);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### π§Ύ Notes
|
|
206
|
+
|
|
207
|
+
- `z.looseObject` is used to accommodate the structure of multipart file metadata.
|
|
208
|
+
- The `_data: z.instanceof(Buffer)` field is automatically interpreted as a binary field by the documentation generator.
|
|
209
|
+
- This ensures correct OpenAPI and Postman documentation is generated, with the file field shown as a binary upload.
|
|
210
|
+
- The route streams the uploaded image back with its original content type.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## π Flexible API Design
|
|
215
|
+
|
|
216
|
+
Prefer `Joi` or migrating gradually? No problem.
|
|
217
|
+
|
|
218
|
+
You can still use `app.route(...)` with Joi-based validation while adopting Zod via `app.base().zod(...).route(...)`. This dual-mode support ensures **graceful evolution**, allowing traditional and modern routes to coexist without breaking changes.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## π License
|
|
223
|
+
|
|
224
|
+
MIT
|
|
225
|
+
|
|
226
|
+
> This package is tested as part of the Kaapi monorepo. See the [main Kaapi README](../../README.md) for coverage details.
|
|
227
|
+
|
|
228
|
+
## π€ Contributing
|
|
229
|
+
|
|
230
|
+
Contributions, issues, and feature requests are welcome! Feel free to open a discussion or submit a pull request.
|
|
231
|
+
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,kDAAuB;AACvB,sDAA2B"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReqRefDefaults, ReqRef, KaapiServerRoute, HandlerDecorations, Lifecycle, Server } from '@kaapi/kaapi';
|
|
2
|
+
import { z, type ZodType } from 'zod';
|
|
3
|
+
import type { ParseContext, $ZodIssue } from 'zod/v4/core';
|
|
4
|
+
export type ZodSchema = ZodType<any, any> | undefined | null;
|
|
5
|
+
export type ValidatorZodOptions = ParseContext<$ZodIssue>;
|
|
6
|
+
export type ValidatorZodSchema = {
|
|
7
|
+
payload?: ZodSchema;
|
|
8
|
+
query?: ZodSchema;
|
|
9
|
+
params?: ZodSchema;
|
|
10
|
+
headers?: ZodSchema;
|
|
11
|
+
state?: ZodSchema;
|
|
12
|
+
options?: ParseContext<$ZodIssue>;
|
|
13
|
+
failAction?: 'error' | 'log' | Lifecycle.Method | undefined;
|
|
14
|
+
};
|
|
15
|
+
export type ZodlessReqRefDefaults = Omit<ReqRefDefaults, 'Query' | 'Headers' | 'Params' | 'Payload'>;
|
|
16
|
+
export type ZodlessReqRef = Omit<ReqRef, 'Query' | 'Headers' | 'Params' | 'Payload'>;
|
|
17
|
+
export interface ValidatorZodReqRef<RS extends ValidatorZodSchema = ValidatorZodSchema> {
|
|
18
|
+
Query: z.infer<RS['query']>;
|
|
19
|
+
Headers: z.infer<RS['headers']>;
|
|
20
|
+
Params: z.infer<RS['params']>;
|
|
21
|
+
Payload: z.infer<RS['payload']>;
|
|
22
|
+
}
|
|
23
|
+
export type ValidatorZod = <V extends ValidatorZodSchema>(schema: V) => {
|
|
24
|
+
route<R extends ZodlessReqRef = ZodlessReqRefDefaults>(serverRoute: KaapiServerRoute<ValidatorZodReqRef<V> & R>, handler?: HandlerDecorations | Lifecycle.Method<ValidatorZodReqRef<V> & R, Lifecycle.ReturnValue<ValidatorZodReqRef<V> & R>>): Server;
|
|
25
|
+
};
|
package/lib/types.js
ADDED
package/lib/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/lib/utils.d.ts
ADDED
package/lib/utils.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mapIssue = mapIssue;
|
|
4
|
+
/**
|
|
5
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#identifiers
|
|
6
|
+
*/
|
|
7
|
+
const identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u;
|
|
8
|
+
/**
|
|
9
|
+
* @see https://github.com/causaly/zod-validation-error/blob/main/lib/utils/joinPath.ts
|
|
10
|
+
*/
|
|
11
|
+
function joinPath(path) {
|
|
12
|
+
var _a;
|
|
13
|
+
if (path.length === 1) {
|
|
14
|
+
const propertyKey = path[0];
|
|
15
|
+
let propertyKeyString = '';
|
|
16
|
+
if (typeof propertyKey === 'symbol') {
|
|
17
|
+
propertyKeyString = (_a = propertyKey.description) !== null && _a !== void 0 ? _a : '';
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
propertyKeyString = String(propertyKey);
|
|
21
|
+
}
|
|
22
|
+
return propertyKeyString || '""';
|
|
23
|
+
}
|
|
24
|
+
return path.reduce((acc, propertyKey) => {
|
|
25
|
+
var _a;
|
|
26
|
+
let propertyKeyString = '';
|
|
27
|
+
// handle numeric indices
|
|
28
|
+
if (typeof propertyKey === 'number') {
|
|
29
|
+
return acc + '[' + propertyKey.toString() + ']';
|
|
30
|
+
}
|
|
31
|
+
// handle symbols
|
|
32
|
+
if (typeof propertyKey === 'symbol') {
|
|
33
|
+
propertyKeyString = (_a = propertyKey.description) !== null && _a !== void 0 ? _a : '';
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
propertyKeyString = propertyKey;
|
|
37
|
+
}
|
|
38
|
+
// handle quoted values
|
|
39
|
+
if (propertyKeyString.includes('"')) {
|
|
40
|
+
return acc + '["' + propertyKeyString.replace(/"/g, '\\"') + '"]';
|
|
41
|
+
}
|
|
42
|
+
// handle special characters
|
|
43
|
+
if (!identifierRegex.test(propertyKeyString)) {
|
|
44
|
+
return acc + '["' + propertyKeyString + '"]';
|
|
45
|
+
}
|
|
46
|
+
// handle normal values
|
|
47
|
+
const separator = acc.length === 0 ? '' : '.';
|
|
48
|
+
return acc + separator + propertyKeyString;
|
|
49
|
+
}, '');
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* @see https://github.com/causaly/zod-validation-error/blob/main/lib/v4/MessageBuilder.ts
|
|
53
|
+
*/
|
|
54
|
+
function mapIssue(issue) {
|
|
55
|
+
if (issue.code === 'invalid_union' && issue.errors.length !== 0) {
|
|
56
|
+
const individualMessages = issue.errors.map((issues) => issues
|
|
57
|
+
.map((subIssue) => mapIssue(Object.assign(Object.assign({}, subIssue), { path: issue.path.concat(subIssue.path) })))
|
|
58
|
+
.join('; '));
|
|
59
|
+
// deduplicate messages
|
|
60
|
+
// and join them with the union separator
|
|
61
|
+
// to create a single message for the invalid union issue
|
|
62
|
+
return Array.from(new Set(individualMessages)).join(' or ');
|
|
63
|
+
}
|
|
64
|
+
const buf = [];
|
|
65
|
+
buf.push(issue.message.length === 0 ? issue.message : issue.message.charAt(0).toUpperCase() + issue.message.slice(1));
|
|
66
|
+
pathCondition: if (issue.path !== undefined &&
|
|
67
|
+
issue.path.length !== 0) {
|
|
68
|
+
// handle array indices
|
|
69
|
+
if (issue.path.length === 1) {
|
|
70
|
+
const identifier = issue.path[0];
|
|
71
|
+
if (typeof identifier === 'number') {
|
|
72
|
+
buf.push(` at index ${identifier}`);
|
|
73
|
+
break pathCondition;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
buf.push(` at "${joinPath(issue.path)}"`);
|
|
77
|
+
}
|
|
78
|
+
return buf.join('');
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=utils.js.map
|
package/lib/utils.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { KaapiPlugin, KaapiOpenAPIHelperInterface } from '@kaapi/kaapi';
|
|
3
|
+
import { OpenAPIZodHelper, PostmanZodHelper } from '@novice1/api-doc-zod-helper';
|
|
4
|
+
export declare const supportedProps: readonly ["payload", "query", "params", "headers", "state"];
|
|
5
|
+
export declare class ZodDocHelper extends OpenAPIZodHelper implements KaapiOpenAPIHelperInterface {
|
|
6
|
+
isFile(): boolean;
|
|
7
|
+
getRawSchema(): Partial<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
8
|
+
getFilesChildren(): Record<string, typeof this._schema>;
|
|
9
|
+
}
|
|
10
|
+
export declare const zodDocsConfig: {
|
|
11
|
+
openAPIOptions: {
|
|
12
|
+
helperClass: typeof OpenAPIZodHelper;
|
|
13
|
+
};
|
|
14
|
+
postmanOptions: {
|
|
15
|
+
helperClass: typeof PostmanZodHelper;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export declare const validatorZod: KaapiPlugin;
|
package/lib/validator.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validatorZod = exports.zodDocsConfig = exports.ZodDocHelper = exports.supportedProps = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const boom_1 = tslib_1.__importDefault(require("@hapi/boom"));
|
|
6
|
+
const v4_1 = require("zod/v4");
|
|
7
|
+
const api_doc_zod_helper_1 = require("@novice1/api-doc-zod-helper");
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
const package_json_1 = tslib_1.__importDefault(require("../package.json"));
|
|
10
|
+
const { parse = { payload: true, query: true, params: true, headers: true, state: true } } = {};
|
|
11
|
+
exports.supportedProps = ['payload', 'query', 'params', 'headers', 'state'];
|
|
12
|
+
const normalizeBooleans = (obj) => {
|
|
13
|
+
for (const key in obj) {
|
|
14
|
+
const val = obj[key];
|
|
15
|
+
if (typeof val === 'string') {
|
|
16
|
+
if (val === 'true')
|
|
17
|
+
obj[key] = true;
|
|
18
|
+
else if (val === 'false')
|
|
19
|
+
obj[key] = false;
|
|
20
|
+
}
|
|
21
|
+
else if (Array.isArray(val)) {
|
|
22
|
+
obj[key] = val.map((v) => (v === 'true' ? true : v === 'false' ? false : v));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return obj;
|
|
26
|
+
};
|
|
27
|
+
class ZodDocHelper extends api_doc_zod_helper_1.OpenAPIZodHelper {
|
|
28
|
+
isFile() {
|
|
29
|
+
var _a;
|
|
30
|
+
const children = this.getChildren();
|
|
31
|
+
const dataType = (_a = children._data) === null || _a === void 0 ? void 0 : _a.getType();
|
|
32
|
+
return dataType === 'custom';
|
|
33
|
+
}
|
|
34
|
+
getRawSchema() {
|
|
35
|
+
return this._schema;
|
|
36
|
+
}
|
|
37
|
+
getFilesChildren() {
|
|
38
|
+
const r = {};
|
|
39
|
+
if (!this.isValid()) {
|
|
40
|
+
return r;
|
|
41
|
+
}
|
|
42
|
+
const schema = this.getMostInnerType();
|
|
43
|
+
if (schema === null || schema === void 0 ? void 0 : schema.def) {
|
|
44
|
+
if ('shape' in schema.def && typeof schema.def.shape === 'object' && schema.def.shape) {
|
|
45
|
+
const properties = schema.def.shape;
|
|
46
|
+
for (const p in properties) {
|
|
47
|
+
const ch = new ZodDocHelper({ value: properties[p] });
|
|
48
|
+
if (ch.isValid() && ch.isFile())
|
|
49
|
+
r[p] = ch.getRawSchema();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return r;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.ZodDocHelper = ZodDocHelper;
|
|
57
|
+
exports.zodDocsConfig = {
|
|
58
|
+
openAPIOptions: {
|
|
59
|
+
helperClass: api_doc_zod_helper_1.OpenAPIZodHelper
|
|
60
|
+
},
|
|
61
|
+
postmanOptions: {
|
|
62
|
+
helperClass: api_doc_zod_helper_1.PostmanZodHelper
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
exports.validatorZod = {
|
|
66
|
+
integrate(t) {
|
|
67
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
const validator = (schema) => {
|
|
69
|
+
return {
|
|
70
|
+
route(serverRoute, handler) {
|
|
71
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
72
|
+
if (!serverRoute.options) {
|
|
73
|
+
serverRoute.options = {};
|
|
74
|
+
}
|
|
75
|
+
if (typeof serverRoute.options === 'object') {
|
|
76
|
+
// validate
|
|
77
|
+
if (!serverRoute.options.plugins) {
|
|
78
|
+
serverRoute.options.plugins = {};
|
|
79
|
+
}
|
|
80
|
+
serverRoute.options.plugins.zod = schema;
|
|
81
|
+
// docs
|
|
82
|
+
serverRoute.options.plugins.kaapi = serverRoute.options.plugins.kaapi || {};
|
|
83
|
+
if (serverRoute.options.plugins.kaapi.docs != false && // docs not disabled
|
|
84
|
+
!((_a = serverRoute.options.plugins.kaapi.docs) === null || _a === void 0 ? void 0 : _a.disabled) // docs not disabled
|
|
85
|
+
) {
|
|
86
|
+
if (!((_d = (_c = (_b = serverRoute.options.plugins) === null || _b === void 0 ? void 0 : _b.kaapi) === null || _c === void 0 ? void 0 : _c.docs) === null || _d === void 0 ? void 0 : _d.helperSchemaProperty)) // docs have not helperSchemaProperty
|
|
87
|
+
serverRoute.options.plugins.kaapi.docs = Object.assign(Object.assign({}, serverRoute.options.plugins.kaapi.docs), { helperSchemaProperty: 'zod' });
|
|
88
|
+
if (!((_g = (_f = (_e = serverRoute.options.plugins) === null || _e === void 0 ? void 0 : _e.kaapi) === null || _f === void 0 ? void 0 : _f.docs) === null || _g === void 0 ? void 0 : _g.openAPIHelperClass)) // docs have not openAPIHelperClass
|
|
89
|
+
serverRoute.options.plugins.kaapi.docs = Object.assign(Object.assign({}, serverRoute.options.plugins.kaapi.docs), { openAPIHelperClass: ZodDocHelper });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
t.route(serverRoute, handler);
|
|
93
|
+
return t.server;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
yield t.server.register({
|
|
98
|
+
name: 'kaapi-validator-zod',
|
|
99
|
+
version: package_json_1.default.version,
|
|
100
|
+
register: function (server) {
|
|
101
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
102
|
+
server.ext('onPreHandler', (request, h) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
var _a, _b, _c;
|
|
104
|
+
const routeValidation = (_c = (_b = (_a = request === null || request === void 0 ? void 0 : request.route) === null || _a === void 0 ? void 0 : _a.settings) === null || _b === void 0 ? void 0 : _b.plugins) === null || _c === void 0 ? void 0 : _c.zod;
|
|
105
|
+
try {
|
|
106
|
+
// Initialize empty objects to hold the parsed data and corresponding Zod schemas
|
|
107
|
+
const data = {};
|
|
108
|
+
const dataSchema = {};
|
|
109
|
+
// Loop through all supported properties for this route
|
|
110
|
+
for (const prop of exports.supportedProps) {
|
|
111
|
+
// Check if validation exists for this property and there is a parser defined
|
|
112
|
+
if ((routeValidation === null || routeValidation === void 0 ? void 0 : routeValidation[prop]) && parse[prop]) {
|
|
113
|
+
// Add the Zod schema for this property to the dataSchema
|
|
114
|
+
dataSchema[prop] = routeValidation[prop];
|
|
115
|
+
// Prepare the value for parsing:
|
|
116
|
+
// - For query params, normalize boolean strings to actual booleans
|
|
117
|
+
// - Otherwise, take the raw value from the request object
|
|
118
|
+
data[prop] = prop === 'query' ? normalizeBooleans(request[prop]) : request[prop];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Determine if there are any properties to validate
|
|
122
|
+
let hasProps = false;
|
|
123
|
+
for (const key in dataSchema) {
|
|
124
|
+
// Safely check own properties to avoid inherited keys
|
|
125
|
+
if (Object.prototype.hasOwnProperty.call(dataSchema, key)) {
|
|
126
|
+
hasProps = true;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// If we have any props to validate, parse them using Zod
|
|
131
|
+
if (hasProps) {
|
|
132
|
+
// Create a Zod object from the collected schema and parse asynchronously
|
|
133
|
+
// Options (like error maps or jitless) can come from routeValidation.options
|
|
134
|
+
const parsedProps = yield v4_1.z.object(dataSchema).parseAsync(data, routeValidation === null || routeValidation === void 0 ? void 0 : routeValidation.options);
|
|
135
|
+
// Merge the parsed and validated properties back into the request object
|
|
136
|
+
Object.assign(request, parsedProps);
|
|
137
|
+
}
|
|
138
|
+
// Continue the Hapi request lifecycle
|
|
139
|
+
return h.continue;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
// Initialize a set to track which paths (properties) failed validation
|
|
143
|
+
const issuePaths = new Set();
|
|
144
|
+
let message;
|
|
145
|
+
// Check if the error is a Zod validation error
|
|
146
|
+
if (err instanceof Object &&
|
|
147
|
+
'name' in err &&
|
|
148
|
+
(err.name === 'ZodError' || err.name === '$ZodError') &&
|
|
149
|
+
'issues' in err &&
|
|
150
|
+
Array.isArray(err.issues)) {
|
|
151
|
+
const zodIssues = err.issues;
|
|
152
|
+
if (zodIssues.length !== 0) {
|
|
153
|
+
// Build a single error message string from all Zod issues
|
|
154
|
+
message = zodIssues
|
|
155
|
+
.map((issue) => {
|
|
156
|
+
// Track which property caused the issue
|
|
157
|
+
if (Array.isArray(issue.path) && issue.path.length !== 0) {
|
|
158
|
+
const key = issue.path[0];
|
|
159
|
+
if (typeof key === 'symbol') {
|
|
160
|
+
if (key.description) {
|
|
161
|
+
issuePaths.add(key.description);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
issuePaths.add(String(key));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Map the issue to a human-readable string
|
|
169
|
+
return (0, utils_1.mapIssue)(issue);
|
|
170
|
+
})
|
|
171
|
+
.join('; ');
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// Fallback if no issues array exists (rare)
|
|
175
|
+
message = 'message' in err && typeof err.message === 'string' ? err.message : '';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else if (err instanceof Error) {
|
|
179
|
+
// If itβs a regular Error, use its message
|
|
180
|
+
message = err.message;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
// Unknown error type
|
|
184
|
+
message = 'Unknown error';
|
|
185
|
+
}
|
|
186
|
+
// Create a Boom badRequest response with the error message
|
|
187
|
+
const response = boom_1.default.badRequest(message);
|
|
188
|
+
// Attach the raw validation error object for debugging/logging
|
|
189
|
+
response.data = {
|
|
190
|
+
validationError: err
|
|
191
|
+
};
|
|
192
|
+
// Handle custom failAction if itβs a function
|
|
193
|
+
if (typeof (routeValidation === null || routeValidation === void 0 ? void 0 : routeValidation.failAction) === 'function') {
|
|
194
|
+
return routeValidation.failAction(request, h, response);
|
|
195
|
+
}
|
|
196
|
+
// If failAction is 'log', log the validation error with the request
|
|
197
|
+
if ((routeValidation === null || routeValidation === void 0 ? void 0 : routeValidation.failAction) === 'log') {
|
|
198
|
+
request.log(['validation', 'error', 'zod', ...issuePaths], response);
|
|
199
|
+
// Note: unlike Hapi's failAction 'log', 'log' here still returns a Boom response
|
|
200
|
+
}
|
|
201
|
+
// Return the error response to halt request processing
|
|
202
|
+
return response;
|
|
203
|
+
}
|
|
204
|
+
}));
|
|
205
|
+
server.decorate('server', 'zod', validator);
|
|
206
|
+
});
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
if (t.openapi) {
|
|
210
|
+
t.openapi.addHelperClass(exports.zodDocsConfig.openAPIOptions.helperClass);
|
|
211
|
+
}
|
|
212
|
+
if (t.postman) {
|
|
213
|
+
t.postman.addHelperClass(exports.zodDocsConfig.postmanOptions.helperClass);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kaapi/validator-zod",
|
|
3
|
+
"version": "0.0.17",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Zod-powered request validation and documentation plugin for Kaapi.",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./lib/index.d.ts",
|
|
10
|
+
"default": "./lib/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"lint": "eslint .",
|
|
15
|
+
"build": "tsc && node ./scripts/buildDT.mjs",
|
|
16
|
+
"test": "kaukau --require ts-node/register --config kaukau.config.mjs",
|
|
17
|
+
"coverage": "c8 npm test"
|
|
18
|
+
},
|
|
19
|
+
"author": "demingongo",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/demingongo/kaapi.git",
|
|
23
|
+
"directory": "packages/validator-zod"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@hapi/boom": "^10.0.1",
|
|
28
|
+
"@kaapi/kaapi": "workspace:^",
|
|
29
|
+
"@novice1/api-doc-zod-helper": "^0.1.9",
|
|
30
|
+
"tslib": "^2.8.1",
|
|
31
|
+
"zod": "^4.1.12"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"zod": "^4.0.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/mocha": "^10.0.10"
|
|
38
|
+
}
|
|
39
|
+
}
|