@kaapi/validator-arktype 0.0.19
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/chunk-3R3TW4ZK.js +142 -0
- package/lib/chunk-3R3TW4ZK.js.map +1 -0
- package/lib/chunk-55J6XMHW.js +1 -0
- package/lib/chunk-55J6XMHW.js.map +1 -0
- package/lib/chunk-K4WN6QYS.js +182 -0
- package/lib/chunk-K4WN6QYS.js.map +1 -0
- package/lib/declarations.d.ts +13 -0
- package/lib/doc-helpers.d.ts +28 -0
- package/lib/doc-helpers.js +9 -0
- package/lib/doc-helpers.js.map +1 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +16 -0
- package/lib/index.js.map +1 -0
- package/lib/metafile-esm.json +1 -0
- package/lib/types.d.ts +27 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/lib/validator.d.ts +6 -0
- package/lib/validator.js +10 -0
- package/lib/validator.js.map +1 -0
- package/package.json +54 -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-arktype
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
**ArkType-powered validation plugin for [Kaapi](https://www.npmjs.com/package/@kaapi/kaapi)**. Validate request `params`, `payload`, `query`, `headers`, and `state` using [ArkType](https://www.npmjs.com/package/arktype) schemas. Includes built-in documentation helpers for seamless API docs generation.
|
|
8
|
+
|
|
9
|
+
> ⚠️ This library is ESM‑only. It requires an environment that supports ESM imports.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 🚀 Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @kaapi/validator-arktype
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 📦 Peer Dependency
|
|
20
|
+
|
|
21
|
+
Requires ArkType:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install arktype@^2.1.25
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 🛠️ Usage
|
|
30
|
+
|
|
31
|
+
### 🔌 Register the Plugin
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { Kaapi } from '@kaapi/kaapi';
|
|
35
|
+
import { validatorArk } from '@kaapi/validator-arktype';
|
|
36
|
+
import { type } from 'arktype';
|
|
37
|
+
|
|
38
|
+
const app = new Kaapi({
|
|
39
|
+
port: 3000,
|
|
40
|
+
host: 'localhost',
|
|
41
|
+
docs: {
|
|
42
|
+
disabled: false, // explicitly enables documentation generation
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await app.extend(validatorArk); // register the plugin
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### 📐 Define a Schema
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { ValidatorArkSchema } from '@kaapi/validator-arktype';
|
|
55
|
+
import { type } from 'arktype';
|
|
56
|
+
|
|
57
|
+
const routeSchema: ValidatorArkSchema = {
|
|
58
|
+
payload: type({
|
|
59
|
+
name: 'string',
|
|
60
|
+
}),
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### 🧭 Create a Route
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
app.base()
|
|
70
|
+
.ark(routeSchema)
|
|
71
|
+
.route(
|
|
72
|
+
{
|
|
73
|
+
method: 'POST',
|
|
74
|
+
path: '/items',
|
|
75
|
+
},
|
|
76
|
+
(req) => ({ id: Date.now(), name: req.payload.name })
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// or using inline handler
|
|
80
|
+
/*
|
|
81
|
+
app.base().ark(routeSchema).route({
|
|
82
|
+
method: 'POST',
|
|
83
|
+
path: '/items',
|
|
84
|
+
handler: req => ({ id: Date.now(), name: req.payload.name })
|
|
85
|
+
})
|
|
86
|
+
*/
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## ⚙️ Advanced Configuration
|
|
92
|
+
|
|
93
|
+
### 🚨 `failAction`
|
|
94
|
+
|
|
95
|
+
Control how validation failures are handled:
|
|
96
|
+
|
|
97
|
+
| Value | Behavior | Safe? | Description |
|
|
98
|
+
| ---------- | ---------------------------- | ------------------------- | ------------------------------- |
|
|
99
|
+
| `'error'` | Reject with validation error | ✅ | Default safe behavior |
|
|
100
|
+
| `'log'` | Log and reject | ✅ | Useful for observability |
|
|
101
|
+
| `function` | Custom handler | ✅ (developer-controlled) | Must return or throw explicitly |
|
|
102
|
+
| `'ignore'` | ❌ Not supported | ❌ | Unsafe and not implemented |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### 🧪 Example with Overrides
|
|
107
|
+
|
|
108
|
+
You can override ArkType validation behavior **globally** for all routes, or **per route** as needed.
|
|
109
|
+
|
|
110
|
+
#### 🔁 Global Override (All Routes)
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
const app = new Kaapi({
|
|
114
|
+
// ...
|
|
115
|
+
routes: {
|
|
116
|
+
plugins: {
|
|
117
|
+
ark: {
|
|
118
|
+
failAction: 'log',
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
await app.extend(validatorArk);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
This logs validation errors before throwing them for all ArkType-validated routes.
|
|
128
|
+
|
|
129
|
+
#### 🔂 Per-Route Override
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
app.base()
|
|
133
|
+
.ark({
|
|
134
|
+
query: z.object({
|
|
135
|
+
name: z
|
|
136
|
+
.string()
|
|
137
|
+
.trim()
|
|
138
|
+
.nonempty()
|
|
139
|
+
.max(10)
|
|
140
|
+
.meta({
|
|
141
|
+
description: 'Optional name to personalize the greeting response',
|
|
142
|
+
})
|
|
143
|
+
.optional()
|
|
144
|
+
.default('World'),
|
|
145
|
+
}),
|
|
146
|
+
failAction: async (request, h, err) => {
|
|
147
|
+
if (Boom.isBoom(err)) {
|
|
148
|
+
return h
|
|
149
|
+
.response({
|
|
150
|
+
...err.output.payload,
|
|
151
|
+
details: err.data.validationError.issues,
|
|
152
|
+
})
|
|
153
|
+
.code(err.output.statusCode)
|
|
154
|
+
.takeover();
|
|
155
|
+
}
|
|
156
|
+
return err;
|
|
157
|
+
},
|
|
158
|
+
})
|
|
159
|
+
.route({
|
|
160
|
+
path: '/greetings',
|
|
161
|
+
method: 'GET',
|
|
162
|
+
handler: ({ query: { name } }) => `Hello ${name}!`,
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 📤 File Upload Example
|
|
169
|
+
|
|
170
|
+
Multipart file uploads with ArkType validation is supported. Here's how to validate an uploaded image file and stream it back in the response:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
app.base()
|
|
174
|
+
.ark({
|
|
175
|
+
payload: type({
|
|
176
|
+
file: type({
|
|
177
|
+
_data: type.instanceOf(Buffer),
|
|
178
|
+
hapi: type({
|
|
179
|
+
filename: 'string',
|
|
180
|
+
headers: {
|
|
181
|
+
'content-type': "'image/jpeg' | 'image/jpg' | 'image/png'",
|
|
182
|
+
},
|
|
183
|
+
}),
|
|
184
|
+
}),
|
|
185
|
+
}),
|
|
186
|
+
})
|
|
187
|
+
.route(
|
|
188
|
+
{
|
|
189
|
+
method: 'POST',
|
|
190
|
+
path: '/upload-image',
|
|
191
|
+
options: {
|
|
192
|
+
description: 'Upload an image',
|
|
193
|
+
payload: {
|
|
194
|
+
output: 'stream',
|
|
195
|
+
parse: true,
|
|
196
|
+
allow: 'multipart/form-data',
|
|
197
|
+
multipart: { output: 'stream' },
|
|
198
|
+
maxBytes: 1024 * 3_000,
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
(req, h) => h.response(req.payload.file._data).type(req.payload.file.hapi.headers['content-type'])
|
|
203
|
+
);
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### 🧾 Notes
|
|
207
|
+
|
|
208
|
+
- `type({ ... })` is used to accommodate the structure of multipart file metadata.
|
|
209
|
+
- The `_data: type.instanceOf(Buffer)` field is automatically interpreted as a binary field by the documentation generator.
|
|
210
|
+
- This ensures correct OpenAPI and Postman documentation is generated, with the file field shown as a binary upload.
|
|
211
|
+
- The route streams the uploaded image back with its original content type.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 🔄 Flexible API Design
|
|
216
|
+
|
|
217
|
+
Prefer `Joi` or migrating gradually? No problem.
|
|
218
|
+
|
|
219
|
+
You can still use `app.route(...)` with Joi-based validation while adopting ArkType via `app.base().ark(...).route(...)`. This dual-mode support ensures **graceful evolution**, allowing traditional and modern routes to coexist without breaking changes.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 📚 License
|
|
224
|
+
|
|
225
|
+
MIT
|
|
226
|
+
|
|
227
|
+
> This package is tested as part of the Kaapi monorepo. See the [main Kaapi README](../../README.md) for coverage details.
|
|
228
|
+
|
|
229
|
+
## 🤝 Contributing
|
|
230
|
+
|
|
231
|
+
Contributions, issues, and feature requests are welcome! Feel free to open a discussion or submit a pull request.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// src/doc-helpers.ts
|
|
2
|
+
import { OpenAPIJsonHelper, PostmanJsonHelper } from "@novice1/api-doc-json-helper";
|
|
3
|
+
function transformValue(value) {
|
|
4
|
+
let r = value;
|
|
5
|
+
if (value && typeof value === "function" && "toJsonSchema" in value && typeof value.toJsonSchema === "function") {
|
|
6
|
+
r = value.toJsonSchema({
|
|
7
|
+
fallback: (v) => {
|
|
8
|
+
let r2 = {};
|
|
9
|
+
let _instanceof = "";
|
|
10
|
+
if (v && "proto" in v && v.proto && typeof v.proto === "function" && "name" in v.proto) {
|
|
11
|
+
r2.type = "object";
|
|
12
|
+
r2._instanceof = `${v.proto.name}`;
|
|
13
|
+
_instanceof = `${v.proto.name}`;
|
|
14
|
+
}
|
|
15
|
+
if (v.base) {
|
|
16
|
+
r2 = { ...r2, ...v.base };
|
|
17
|
+
if ("out" in v && v.out) {
|
|
18
|
+
if ("anyOf" in r2 && "type" in v.out) {
|
|
19
|
+
const description = r2.anyOf[0]?.description;
|
|
20
|
+
r2 = { ...v.out };
|
|
21
|
+
if (description) {
|
|
22
|
+
r2.description = description;
|
|
23
|
+
}
|
|
24
|
+
if (_instanceof) {
|
|
25
|
+
r2._instanceof = _instanceof;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
r2 = { ...r2, ...v.out };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return r2;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return r;
|
|
37
|
+
}
|
|
38
|
+
var OpenAPIArkHelper = class _OpenAPIArkHelper extends OpenAPIJsonHelper {
|
|
39
|
+
constructor(params, isRequired) {
|
|
40
|
+
super({ ...params, value: transformValue(params.value) }, isRequired);
|
|
41
|
+
}
|
|
42
|
+
isValid() {
|
|
43
|
+
return !!(this._schema && typeof this._schema === "object" && !("~standard" in this._schema) && ("type" in this._schema && typeof this._schema.type === "string" || "oneOf" in this._schema && Array.isArray(this._schema.oneOf) || "anyOf" in this._schema && Array.isArray(this._schema.anyOf) || "enum" in this._schema && Array.isArray(this._schema.enum)));
|
|
44
|
+
}
|
|
45
|
+
getFirstItem() {
|
|
46
|
+
const schema = this._schema;
|
|
47
|
+
if ("items" in schema && typeof schema.items === "object") {
|
|
48
|
+
return new _OpenAPIArkHelper({ value: schema.items });
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
getChildren() {
|
|
53
|
+
const r = {};
|
|
54
|
+
const schema = this._schema;
|
|
55
|
+
if ("properties" in schema && typeof schema.properties === "object" && schema.properties) {
|
|
56
|
+
const properties = schema.properties;
|
|
57
|
+
for (const p in properties) {
|
|
58
|
+
const isRequired = "required" in schema && Array.isArray(schema.required) && schema.required.includes(p);
|
|
59
|
+
r[p] = new _OpenAPIArkHelper({ value: properties[p] }, isRequired);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return r;
|
|
63
|
+
}
|
|
64
|
+
getAlternatives() {
|
|
65
|
+
const r = [];
|
|
66
|
+
const schema = this._schema;
|
|
67
|
+
if ("oneOf" in schema && Array.isArray(schema.oneOf)) {
|
|
68
|
+
for (const p of schema.oneOf) {
|
|
69
|
+
r.push(new _OpenAPIArkHelper({ value: p }));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return r;
|
|
73
|
+
}
|
|
74
|
+
isFile() {
|
|
75
|
+
if (!this.isValid()) return false;
|
|
76
|
+
let r = false;
|
|
77
|
+
const schema = this._schema;
|
|
78
|
+
if ("properties" in schema && typeof schema.properties === "object" && schema.properties) {
|
|
79
|
+
const properties = schema.properties;
|
|
80
|
+
r = !!("_data" in properties && properties._data && typeof properties._data === "object" && "_instanceof" in properties._data && properties._data._instanceof === "Buffer");
|
|
81
|
+
}
|
|
82
|
+
return r;
|
|
83
|
+
}
|
|
84
|
+
getFilesChildren() {
|
|
85
|
+
const r = {};
|
|
86
|
+
const schema = this._schema;
|
|
87
|
+
if ("properties" in schema && typeof schema.properties === "object" && schema.properties) {
|
|
88
|
+
const properties = schema.properties;
|
|
89
|
+
for (const p in properties) {
|
|
90
|
+
const isRequired = "required" in schema && Array.isArray(schema.required) && schema.required.includes(p);
|
|
91
|
+
const ch = new _OpenAPIArkHelper({ value: properties[p] }, isRequired);
|
|
92
|
+
if (ch.isFile()) {
|
|
93
|
+
r[p] = properties[p];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return r;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var PostmanArkHelper = class _PostmanArkHelper extends PostmanJsonHelper {
|
|
101
|
+
constructor(params, isRequired) {
|
|
102
|
+
super({ ...params, value: transformValue(params.value) }, isRequired);
|
|
103
|
+
}
|
|
104
|
+
isValid() {
|
|
105
|
+
return !!(this._schema && typeof this._schema === "object" && ("type" in this._schema && typeof this._schema.type === "string" || "oneOf" in this._schema && Array.isArray(this._schema.oneOf) || "anyOf" in this._schema && Array.isArray(this._schema.anyOf) || "enum" in this._schema && Array.isArray(this._schema.enum)));
|
|
106
|
+
}
|
|
107
|
+
getFirstItem() {
|
|
108
|
+
const schema = this._schema;
|
|
109
|
+
if ("items" in schema && typeof schema.items === "object") {
|
|
110
|
+
return new _PostmanArkHelper({ value: schema.items });
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
getChildren() {
|
|
115
|
+
const r = {};
|
|
116
|
+
const schema = this._schema;
|
|
117
|
+
if ("properties" in schema && typeof schema.properties === "object" && schema.properties) {
|
|
118
|
+
const properties = schema.properties;
|
|
119
|
+
for (const p in properties) {
|
|
120
|
+
const isRequired = "required" in schema && Array.isArray(schema.required) && schema.required.includes(p);
|
|
121
|
+
r[p] = new _PostmanArkHelper({ value: properties[p] }, isRequired);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return r;
|
|
125
|
+
}
|
|
126
|
+
getAlternatives() {
|
|
127
|
+
const r = [];
|
|
128
|
+
const schema = this._schema;
|
|
129
|
+
if ("oneOf" in schema && Array.isArray(schema.oneOf)) {
|
|
130
|
+
for (const p of schema.oneOf) {
|
|
131
|
+
r.push(new _PostmanArkHelper({ value: p }));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return r;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export {
|
|
139
|
+
OpenAPIArkHelper,
|
|
140
|
+
PostmanArkHelper
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=chunk-3R3TW4ZK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/doc-helpers.ts"],"sourcesContent":["import type { KaapiOpenAPIHelperInterface } from '@kaapi/kaapi';\nimport { OpenAPIJsonHelper, PostmanJsonHelper } from '@novice1/api-doc-json-helper';\nimport type { Type, JsonSchema } from 'arktype';\n\nfunction transformValue(value?: Type | object | unknown) {\n let r: unknown = value;\n if (value && typeof value === 'function' && 'toJsonSchema' in value && typeof value.toJsonSchema === 'function') {\n r = (value as Type).toJsonSchema({\n fallback: (v) => {\n let r: JsonSchema & { _instanceof?: string } = {};\n let _instanceof = '';\n if (v && 'proto' in v && v.proto && typeof v.proto === 'function' && 'name' in v.proto) {\n r.type = 'object';\n r._instanceof = `${v.proto.name}`;\n _instanceof = `${v.proto.name}`;\n }\n if (v.base) {\n r = { ...r, ...v.base };\n if ('out' in v && v.out) {\n if ('anyOf' in r && 'type' in v.out) {\n const description = r.anyOf[0]?.description;\n r = { ...v.out };\n if (description) {\n r.description = description;\n }\n if (_instanceof) {\n r._instanceof = _instanceof;\n }\n } else {\n r = { ...r, ...v.out };\n }\n }\n }\n return r;\n },\n });\n }\n\n return r;\n}\n\nexport class OpenAPIArkHelper extends OpenAPIJsonHelper implements KaapiOpenAPIHelperInterface {\n constructor(\n params: {\n value?: Type | object | unknown;\n isRoot?: boolean;\n },\n isRequired?: boolean\n ) {\n super({ ...params, value: transformValue(params.value) }, isRequired);\n }\n isValid(): boolean {\n return !!(\n this._schema &&\n typeof this._schema === 'object' &&\n !('~standard' in this._schema) &&\n (('type' in this._schema && typeof this._schema.type === 'string') ||\n ('oneOf' in this._schema && Array.isArray(this._schema.oneOf)) ||\n ('anyOf' in this._schema && Array.isArray(this._schema.anyOf)) ||\n ('enum' in this._schema && Array.isArray(this._schema.enum)))\n );\n }\n getFirstItem(): OpenAPIArkHelper | undefined {\n const schema = this._schema;\n\n if ('items' in schema && typeof schema.items === 'object') {\n return new OpenAPIArkHelper({ value: schema.items });\n }\n\n return;\n }\n getChildren(): Record<string, OpenAPIArkHelper> {\n const r: Record<string, OpenAPIArkHelper> = {};\n const schema = this._schema;\n if ('properties' in schema && typeof schema.properties === 'object' && schema.properties) {\n const properties: Record<string, unknown> = schema.properties as Record<string, unknown>;\n for (const p in properties) {\n const isRequired: boolean =\n 'required' in schema && Array.isArray(schema.required) && schema.required.includes(p);\n r[p] = new OpenAPIArkHelper({ value: properties[p] }, isRequired);\n }\n }\n return r;\n }\n getAlternatives(): OpenAPIArkHelper[] {\n const r: OpenAPIArkHelper[] = [];\n const schema = this._schema;\n if ('oneOf' in schema && Array.isArray(schema.oneOf)) {\n for (const p of schema.oneOf) {\n r.push(new OpenAPIArkHelper({ value: p }));\n }\n }\n return r;\n }\n isFile(): boolean | undefined {\n if (!this.isValid()) return false;\n let r: boolean = false;\n const schema = this._schema;\n if ('properties' in schema && typeof schema.properties === 'object' && schema.properties) {\n const properties: Record<string, unknown> = schema.properties as Record<string, unknown>;\n r = !!(\n '_data' in properties &&\n properties._data &&\n typeof properties._data === 'object' &&\n '_instanceof' in properties._data &&\n properties._data._instanceof === 'Buffer'\n );\n }\n return r;\n }\n getFilesChildren(): Record<string, unknown> {\n const r: Record<string, unknown> = {};\n const schema = this._schema;\n if ('properties' in schema && typeof schema.properties === 'object' && schema.properties) {\n const properties: Record<string, unknown> = schema.properties as Record<string, unknown>;\n for (const p in properties) {\n const isRequired: boolean =\n 'required' in schema && Array.isArray(schema.required) && schema.required.includes(p);\n const ch = new OpenAPIArkHelper({ value: properties[p] }, isRequired);\n if (ch.isFile()) {\n r[p] = properties[p];\n }\n }\n }\n return r;\n }\n}\n\nexport class PostmanArkHelper extends PostmanJsonHelper {\n constructor(\n params: {\n value?: Type | object | unknown;\n isRoot?: boolean;\n },\n isRequired?: boolean\n ) {\n super({ ...params, value: transformValue(params.value) }, isRequired);\n }\n isValid(): boolean {\n return !!(\n this._schema &&\n typeof this._schema === 'object' &&\n (('type' in this._schema && typeof this._schema.type === 'string') ||\n ('oneOf' in this._schema && Array.isArray(this._schema.oneOf)) ||\n ('anyOf' in this._schema && Array.isArray(this._schema.anyOf)) ||\n ('enum' in this._schema && Array.isArray(this._schema.enum)))\n );\n }\n getFirstItem(): PostmanArkHelper | undefined {\n const schema = this._schema;\n\n if ('items' in schema && typeof schema.items === 'object') {\n return new PostmanArkHelper({ value: schema.items });\n }\n\n return;\n }\n getChildren(): Record<string, PostmanArkHelper> {\n const r: Record<string, PostmanArkHelper> = {};\n const schema = this._schema;\n if ('properties' in schema && typeof schema.properties === 'object' && schema.properties) {\n const properties: Record<string, unknown> = schema.properties as Record<string, unknown>;\n for (const p in properties) {\n const isRequired: boolean =\n 'required' in schema && Array.isArray(schema.required) && schema.required.includes(p);\n r[p] = new PostmanArkHelper({ value: properties[p] }, isRequired);\n }\n }\n return r;\n }\n getAlternatives(): PostmanArkHelper[] {\n const r: PostmanArkHelper[] = [];\n const schema = this._schema;\n if ('oneOf' in schema && Array.isArray(schema.oneOf)) {\n for (const p of schema.oneOf) {\n r.push(new PostmanArkHelper({ value: p }));\n }\n }\n return r;\n }\n}\n"],"mappings":"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","names":["r"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-55J6XMHW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OpenAPIArkHelper,
|
|
3
|
+
PostmanArkHelper
|
|
4
|
+
} from "./chunk-3R3TW4ZK.js";
|
|
5
|
+
|
|
6
|
+
// package.json
|
|
7
|
+
var package_default = {
|
|
8
|
+
name: "@kaapi/validator-arktype",
|
|
9
|
+
type: "module",
|
|
10
|
+
version: "0.0.19",
|
|
11
|
+
private: false,
|
|
12
|
+
description: "ArkType-powered request validation and documentation plugin for Kaapi.",
|
|
13
|
+
main: "lib/index.js",
|
|
14
|
+
exports: {
|
|
15
|
+
".": {
|
|
16
|
+
types: "./lib/index.d.ts",
|
|
17
|
+
default: "./lib/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
scripts: {
|
|
21
|
+
build: "tsup src !src/**/*.d.ts --format esm --outDir lib --clean --metafile --dts --sourcemap && node ./scripts/buildDT.mjs",
|
|
22
|
+
check: "tsc --noEmit",
|
|
23
|
+
"check:deps": "depcruise src --validate",
|
|
24
|
+
ci: "npm run verify",
|
|
25
|
+
coverage: "c8 node --loader ts-node/esm --experimental-specifier-resolution=node --no-warnings ../../node_modules/mocha/bin/mocha test/**/*.spec.ts",
|
|
26
|
+
format: "prettier --write ./",
|
|
27
|
+
"format:check": "prettier --check ./",
|
|
28
|
+
lint: "eslint .",
|
|
29
|
+
test: "node --loader ts-node/esm --experimental-specifier-resolution=node --no-warnings ../../node_modules/mocha/bin/mocha test/**/*.spec.ts",
|
|
30
|
+
"type-coverage": "type-coverage --at-least 90 --detail",
|
|
31
|
+
verify: "npm run lint && npm run format:check && npm run check && npm run check:deps && npm run type-coverage && npm run test:kaukau && npm run coverage"
|
|
32
|
+
},
|
|
33
|
+
keywords: [
|
|
34
|
+
"kaapi",
|
|
35
|
+
"hapi",
|
|
36
|
+
"arktype",
|
|
37
|
+
"typescript",
|
|
38
|
+
"validation"
|
|
39
|
+
],
|
|
40
|
+
author: "demingongo",
|
|
41
|
+
repository: {
|
|
42
|
+
type: "git",
|
|
43
|
+
url: "git+https://github.com/demingongo/kaapi.git",
|
|
44
|
+
directory: "packages/validator-arktype"
|
|
45
|
+
},
|
|
46
|
+
license: "MIT",
|
|
47
|
+
dependencies: {
|
|
48
|
+
"@hapi/boom": "^10.0.1",
|
|
49
|
+
"@kaapi/kaapi": "workspace:^",
|
|
50
|
+
"@novice1/api-doc-json-helper": "^1.0.6",
|
|
51
|
+
arktype: "^2.1.25",
|
|
52
|
+
tslib: "^2.8.1"
|
|
53
|
+
},
|
|
54
|
+
devDependencies: {
|
|
55
|
+
"@types/mocha": "^10.0.10"
|
|
56
|
+
},
|
|
57
|
+
peerDependencies: {
|
|
58
|
+
arktype: "^2.1.25"
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// src/validator.ts
|
|
63
|
+
import Boom from "@hapi/boom";
|
|
64
|
+
import { type } from "arktype";
|
|
65
|
+
var { parse = { payload: true, query: true, params: true, headers: true, state: true } } = {};
|
|
66
|
+
var supportedProps = ["payload", "query", "params", "headers", "state"];
|
|
67
|
+
var normalizeBooleans = (obj) => {
|
|
68
|
+
for (const key in obj) {
|
|
69
|
+
const val = obj[key];
|
|
70
|
+
if (typeof val === "string") {
|
|
71
|
+
if (val === "true") obj[key] = true;
|
|
72
|
+
else if (val === "false") obj[key] = false;
|
|
73
|
+
} else if (Array.isArray(val)) {
|
|
74
|
+
obj[key] = val.map((v) => v === "true" ? true : v === "false" ? false : v);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return obj;
|
|
78
|
+
};
|
|
79
|
+
var validatorArk = {
|
|
80
|
+
async integrate(t) {
|
|
81
|
+
const validator = (schema) => {
|
|
82
|
+
return {
|
|
83
|
+
route(serverRoute, handler) {
|
|
84
|
+
if (!serverRoute.options) {
|
|
85
|
+
serverRoute.options = {};
|
|
86
|
+
}
|
|
87
|
+
if (typeof serverRoute.options === "object") {
|
|
88
|
+
if (!serverRoute.options.plugins) {
|
|
89
|
+
serverRoute.options.plugins = {};
|
|
90
|
+
}
|
|
91
|
+
serverRoute.options.plugins.ark = schema;
|
|
92
|
+
serverRoute.options.plugins.kaapi = serverRoute.options.plugins.kaapi || {};
|
|
93
|
+
if (serverRoute.options.plugins.kaapi.docs != false && // docs not disabled
|
|
94
|
+
!serverRoute.options.plugins.kaapi.docs?.disabled) {
|
|
95
|
+
if (!serverRoute.options.plugins?.kaapi?.docs?.helperSchemaProperty)
|
|
96
|
+
serverRoute.options.plugins.kaapi.docs = {
|
|
97
|
+
...serverRoute.options.plugins.kaapi.docs,
|
|
98
|
+
helperSchemaProperty: "ark"
|
|
99
|
+
};
|
|
100
|
+
if (!serverRoute.options.plugins?.kaapi?.docs?.openAPIHelperClass)
|
|
101
|
+
serverRoute.options.plugins.kaapi.docs = {
|
|
102
|
+
...serverRoute.options.plugins.kaapi.docs,
|
|
103
|
+
openAPIHelperClass: OpenAPIArkHelper
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
t.route(serverRoute, handler);
|
|
108
|
+
return t.server;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
await t.server.register({
|
|
113
|
+
name: "kaapi-validator-arktype",
|
|
114
|
+
version: package_default.version,
|
|
115
|
+
register: async function(server) {
|
|
116
|
+
server.ext("onPreHandler", async (request, h) => {
|
|
117
|
+
const routeValidation = request?.route?.settings?.plugins?.ark;
|
|
118
|
+
try {
|
|
119
|
+
const data = {};
|
|
120
|
+
const dataSchema = {};
|
|
121
|
+
for (const prop of supportedProps) {
|
|
122
|
+
if (routeValidation?.[prop] && parse[prop]) {
|
|
123
|
+
dataSchema[prop] = routeValidation[prop];
|
|
124
|
+
data[prop] = prop === "query" ? normalizeBooleans(request[prop]) : request[prop];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
let hasProps = false;
|
|
128
|
+
for (const key in dataSchema) {
|
|
129
|
+
if (Object.prototype.hasOwnProperty.call(dataSchema, key)) {
|
|
130
|
+
hasProps = true;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (hasProps) {
|
|
135
|
+
const parsedProps = type(dataSchema)(data);
|
|
136
|
+
if (parsedProps instanceof type.errors) {
|
|
137
|
+
throw parsedProps;
|
|
138
|
+
}
|
|
139
|
+
Object.assign(request, parsedProps);
|
|
140
|
+
}
|
|
141
|
+
return h.continue;
|
|
142
|
+
} catch (err) {
|
|
143
|
+
const issuePaths = /* @__PURE__ */ new Set();
|
|
144
|
+
let message;
|
|
145
|
+
if (err instanceof type.errors && err.issues.length) {
|
|
146
|
+
const firstIssue = err.issues[0];
|
|
147
|
+
message = firstIssue.message;
|
|
148
|
+
} else if (err instanceof Error) {
|
|
149
|
+
message = err.message;
|
|
150
|
+
} else {
|
|
151
|
+
message = "Unknown error";
|
|
152
|
+
}
|
|
153
|
+
const response = Boom.badRequest(message);
|
|
154
|
+
response.data = {
|
|
155
|
+
validationError: err
|
|
156
|
+
};
|
|
157
|
+
if (typeof routeValidation?.failAction === "function") {
|
|
158
|
+
return routeValidation.failAction(request, h, response);
|
|
159
|
+
}
|
|
160
|
+
if (routeValidation?.failAction === "log") {
|
|
161
|
+
request.log(["validation", "error", "arktype", ...issuePaths], response);
|
|
162
|
+
}
|
|
163
|
+
return response;
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
server.decorate("server", "ark", validator);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
if (t.openapi) {
|
|
170
|
+
t.openapi.addHelperClass(OpenAPIArkHelper);
|
|
171
|
+
}
|
|
172
|
+
if (t.postman) {
|
|
173
|
+
t.postman.addHelperClass(PostmanArkHelper);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export {
|
|
179
|
+
supportedProps,
|
|
180
|
+
validatorArk
|
|
181
|
+
};
|
|
182
|
+
//# sourceMappingURL=chunk-K4WN6QYS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/validator.ts"],"sourcesContent":["{\n \"name\": \"@kaapi/validator-arktype\",\n \"type\": \"module\",\n \"version\": \"0.0.19\",\n \"private\": false,\n \"description\": \"ArkType-powered request validation and documentation plugin for Kaapi.\",\n \"main\": \"lib/index.js\",\n \"exports\": {\n \".\": {\n \"types\": \"./lib/index.d.ts\",\n \"default\": \"./lib/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"tsup src !src/**/*.d.ts --format esm --outDir lib --clean --metafile --dts --sourcemap && node ./scripts/buildDT.mjs\",\n \"check\": \"tsc --noEmit\",\n \"check:deps\": \"depcruise src --validate\",\n \"ci\": \"npm run verify\",\n \"coverage\": \"c8 node --loader ts-node/esm --experimental-specifier-resolution=node --no-warnings ../../node_modules/mocha/bin/mocha test/**/*.spec.ts\",\n \"format\": \"prettier --write ./\",\n \"format:check\": \"prettier --check ./\",\n \"lint\": \"eslint .\",\n \"test\": \"node --loader ts-node/esm --experimental-specifier-resolution=node --no-warnings ../../node_modules/mocha/bin/mocha test/**/*.spec.ts\",\n \"type-coverage\": \"type-coverage --at-least 90 --detail\",\n \"verify\": \"npm run lint && npm run format:check && npm run check && npm run check:deps && npm run type-coverage && npm run test:kaukau && npm run coverage\"\n },\n \"keywords\": [\n \"kaapi\",\n \"hapi\",\n \"arktype\",\n \"typescript\",\n \"validation\"\n ],\n \"author\": \"demingongo\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/demingongo/kaapi.git\",\n \"directory\": \"packages/validator-arktype\"\n },\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@hapi/boom\": \"^10.0.1\",\n \"@kaapi/kaapi\": \"workspace:^\",\n \"@novice1/api-doc-json-helper\": \"^1.0.6\",\n \"arktype\": \"^2.1.25\",\n \"tslib\": \"^2.8.1\"\n },\n \"devDependencies\": {\n \"@types/mocha\": \"^10.0.10\"\n },\n \"peerDependencies\": {\n \"arktype\": \"^2.1.25\"\n }\n}\n","import pkg from '../package.json' with { type: 'json' };\nimport { OpenAPIArkHelper, PostmanArkHelper } from './doc-helpers.js';\nimport type {\n ArklessReqRef,\n ArklessReqRefDefaults,\n ValidatorArk,\n ValidatorArkReqRef,\n ValidatorArkSchema,\n} from './types.js';\nimport Boom from '@hapi/boom';\nimport type {\n KaapiServerRoute,\n HandlerDecorations,\n Lifecycle,\n KaapiPlugin,\n Request,\n ResponseToolkit,\n} from '@kaapi/kaapi';\nimport { type, type Type } from 'arktype';\n\nconst { parse = { payload: true, query: true, params: true, headers: true, state: true } } = {};\nexport const supportedProps = ['payload', 'query', 'params', 'headers', 'state'] as const;\nconst normalizeBooleans = (obj: Record<string, unknown>) => {\n for (const key in obj) {\n const val = obj[key];\n if (typeof val === 'string') {\n if (val === 'true') obj[key] = true;\n else if (val === 'false') obj[key] = false;\n } else if (Array.isArray(val)) {\n obj[key] = val.map((v) => (v === 'true' ? true : v === 'false' ? false : v));\n }\n }\n return obj;\n};\n\nexport const validatorArk: KaapiPlugin = {\n async integrate(t) {\n const validator: ValidatorArk = <V extends ValidatorArkSchema>(schema: V) => {\n return {\n route<R extends ArklessReqRef = ArklessReqRefDefaults>(\n serverRoute: KaapiServerRoute<ValidatorArkReqRef<V> & R>,\n handler?:\n | HandlerDecorations\n | Lifecycle.Method<ValidatorArkReqRef<V> & R, Lifecycle.ReturnValue<ValidatorArkReqRef<V> & R>>\n ) {\n if (!serverRoute.options) {\n serverRoute.options = {};\n }\n if (typeof serverRoute.options === 'object') {\n // validate\n if (!serverRoute.options.plugins) {\n serverRoute.options.plugins = {};\n }\n serverRoute.options.plugins.ark = schema;\n\n // docs\n serverRoute.options.plugins.kaapi = serverRoute.options.plugins.kaapi || {};\n if (\n serverRoute.options.plugins.kaapi.docs != false && // docs not disabled\n !serverRoute.options.plugins.kaapi.docs?.disabled // docs not disabled\n ) {\n if (!serverRoute.options.plugins?.kaapi?.docs?.helperSchemaProperty)\n // docs have not helperSchemaProperty\n serverRoute.options.plugins.kaapi.docs = {\n ...serverRoute.options.plugins.kaapi.docs,\n helperSchemaProperty: 'ark',\n };\n if (!serverRoute.options.plugins?.kaapi?.docs?.openAPIHelperClass)\n // docs have not openAPIHelperClass\n serverRoute.options.plugins.kaapi.docs = {\n ...serverRoute.options.plugins.kaapi.docs,\n openAPIHelperClass: OpenAPIArkHelper,\n };\n }\n }\n t.route(serverRoute, handler);\n return t.server;\n },\n };\n };\n\n await t.server.register({\n name: 'kaapi-validator-arktype',\n version: pkg.version,\n register: async function (server) {\n server.ext('onPreHandler', async (request: Request, h: ResponseToolkit) => {\n const routeValidation = request?.route?.settings?.plugins?.ark as ValidatorArkSchema | undefined;\n try {\n // Initialize empty objects to hold the parsed data and corresponding ArkType schemas\n const data: Record<string, unknown> = {};\n const dataSchema: Record<string, Type> = {};\n\n // Loop through all supported properties for this route\n for (const prop of supportedProps) {\n // Check if validation exists for this property and there is a parser defined\n if (routeValidation?.[prop] && parse[prop]) {\n // Add the ArkType schema for this property to the dataSchema\n dataSchema[prop] = routeValidation[prop];\n // Prepare the value for parsing:\n // - For query params, normalize boolean strings to actual booleans\n // - Otherwise, take the raw value from the request object\n data[prop] = prop === 'query' ? normalizeBooleans(request[prop]) : request[prop];\n }\n }\n\n // Determine if there are any properties to validate\n let hasProps = false;\n for (const key in dataSchema) {\n // Safely check own properties to avoid inherited keys\n if (Object.prototype.hasOwnProperty.call(dataSchema, key)) {\n hasProps = true;\n break;\n }\n }\n\n // If we have any props to validate, parse them using ArkType\n if (hasProps) {\n // Create an ArkType object from the collected schema and parse\n const parsedProps = type(dataSchema)(data);\n if (parsedProps instanceof type.errors) {\n // throw ArkErrors\n throw parsedProps;\n }\n // Merge the parsed and validated properties back into the request object\n Object.assign(request, parsedProps);\n }\n\n // Continue the Hapi request lifecycle\n return h.continue;\n } catch (err) {\n // Initialize a set to track which paths (properties) failed validation\n const issuePaths = new Set<string>();\n let message: string;\n\n // Check if the error is instance of ValiError\n if (err instanceof type.errors && err.issues.length) {\n const firstIssue = err.issues[0];\n message = firstIssue.message;\n } else if (err instanceof Error) {\n // If it’s a regular Error, use its message\n message = err.message;\n } else {\n // Unknown error type\n message = 'Unknown error';\n }\n\n // Create a Boom badRequest response with the error message\n const response = Boom.badRequest(message);\n\n // Attach the raw validation error object for debugging/logging\n response.data = {\n validationError: err,\n };\n\n // Handle custom failAction if it’s a function\n if (typeof routeValidation?.failAction === 'function') {\n return routeValidation.failAction(request, h, response);\n }\n\n // If failAction is 'log', log the validation error with the request\n if (routeValidation?.failAction === 'log') {\n request.log(['validation', 'error', 'arktype', ...issuePaths], response);\n // Note: unlike Hapi's failAction 'log', 'log' here still returns a Boom response\n }\n\n // Return the error response to halt request processing\n return response;\n }\n });\n server.decorate('server', 'ark', validator);\n },\n });\n\n if (t.openapi) {\n t.openapi.addHelperClass(OpenAPIArkHelper);\n }\n if (t.postman) {\n t.postman.addHelperClass(PostmanArkHelper);\n }\n },\n};\n"],"mappings":";;;;;;AAAA;AAAA,EACE,MAAQ;AAAA,EACR,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,SAAW;AAAA,EACX,aAAe;AAAA,EACf,MAAQ;AAAA,EACR,SAAW;AAAA,IACT,KAAK;AAAA,MACH,OAAS;AAAA,MACT,SAAW;AAAA,IACb;AAAA,EACF;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,OAAS;AAAA,IACT,cAAc;AAAA,IACd,IAAM;AAAA,IACN,UAAY;AAAA,IACZ,QAAU;AAAA,IACV,gBAAgB;AAAA,IAChB,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,QAAU;AAAA,EACZ;AAAA,EACA,UAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAU;AAAA,EACV,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,IACP,WAAa;AAAA,EACf;AAAA,EACA,SAAW;AAAA,EACX,cAAgB;AAAA,IACd,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gCAAgC;AAAA,IAChC,SAAW;AAAA,IACX,OAAS;AAAA,EACX;AAAA,EACA,iBAAmB;AAAA,IACjB,gBAAgB;AAAA,EAClB;AAAA,EACA,kBAAoB;AAAA,IAClB,SAAW;AAAA,EACb;AACF;;;AC5CA,OAAO,UAAU;AASjB,SAAS,YAAuB;AAEhC,IAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,OAAO,MAAM,QAAQ,MAAM,SAAS,MAAM,OAAO,KAAK,EAAE,IAAI,CAAC;AACvF,IAAM,iBAAiB,CAAC,WAAW,SAAS,UAAU,WAAW,OAAO;AAC/E,IAAM,oBAAoB,CAAC,QAAiC;AACxD,aAAW,OAAO,KAAK;AACnB,UAAM,MAAM,IAAI,GAAG;AACnB,QAAI,OAAO,QAAQ,UAAU;AACzB,UAAI,QAAQ,OAAQ,KAAI,GAAG,IAAI;AAAA,eACtB,QAAQ,QAAS,KAAI,GAAG,IAAI;AAAA,IACzC,WAAW,MAAM,QAAQ,GAAG,GAAG;AAC3B,UAAI,GAAG,IAAI,IAAI,IAAI,CAAC,MAAO,MAAM,SAAS,OAAO,MAAM,UAAU,QAAQ,CAAE;AAAA,IAC/E;AAAA,EACJ;AACA,SAAO;AACX;AAEO,IAAM,eAA4B;AAAA,EACrC,MAAM,UAAU,GAAG;AACf,UAAM,YAA0B,CAA+B,WAAc;AACzE,aAAO;AAAA,QACH,MACI,aACA,SAGF;AACE,cAAI,CAAC,YAAY,SAAS;AACtB,wBAAY,UAAU,CAAC;AAAA,UAC3B;AACA,cAAI,OAAO,YAAY,YAAY,UAAU;AAEzC,gBAAI,CAAC,YAAY,QAAQ,SAAS;AAC9B,0BAAY,QAAQ,UAAU,CAAC;AAAA,YACnC;AACA,wBAAY,QAAQ,QAAQ,MAAM;AAGlC,wBAAY,QAAQ,QAAQ,QAAQ,YAAY,QAAQ,QAAQ,SAAS,CAAC;AAC1E,gBACI,YAAY,QAAQ,QAAQ,MAAM,QAAQ;AAAA,YAC1C,CAAC,YAAY,QAAQ,QAAQ,MAAM,MAAM,UAC3C;AACE,kBAAI,CAAC,YAAY,QAAQ,SAAS,OAAO,MAAM;AAE3C,4BAAY,QAAQ,QAAQ,MAAM,OAAO;AAAA,kBACrC,GAAG,YAAY,QAAQ,QAAQ,MAAM;AAAA,kBACrC,sBAAsB;AAAA,gBAC1B;AACJ,kBAAI,CAAC,YAAY,QAAQ,SAAS,OAAO,MAAM;AAE3C,4BAAY,QAAQ,QAAQ,MAAM,OAAO;AAAA,kBACrC,GAAG,YAAY,QAAQ,QAAQ,MAAM;AAAA,kBACrC,oBAAoB;AAAA,gBACxB;AAAA,YACR;AAAA,UACJ;AACA,YAAE,MAAM,aAAa,OAAO;AAC5B,iBAAO,EAAE;AAAA,QACb;AAAA,MACJ;AAAA,IACJ;AAEA,UAAM,EAAE,OAAO,SAAS;AAAA,MACpB,MAAM;AAAA,MACN,SAAS,gBAAI;AAAA,MACb,UAAU,eAAgB,QAAQ;AAC9B,eAAO,IAAI,gBAAgB,OAAO,SAAkB,MAAuB;AACvE,gBAAM,kBAAkB,SAAS,OAAO,UAAU,SAAS;AAC3D,cAAI;AAEA,kBAAM,OAAgC,CAAC;AACvC,kBAAM,aAAmC,CAAC;AAG1C,uBAAW,QAAQ,gBAAgB;AAE/B,kBAAI,kBAAkB,IAAI,KAAK,MAAM,IAAI,GAAG;AAExC,2BAAW,IAAI,IAAI,gBAAgB,IAAI;AAIvC,qBAAK,IAAI,IAAI,SAAS,UAAU,kBAAkB,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI;AAAA,cACnF;AAAA,YACJ;AAGA,gBAAI,WAAW;AACf,uBAAW,OAAO,YAAY;AAE1B,kBAAI,OAAO,UAAU,eAAe,KAAK,YAAY,GAAG,GAAG;AACvD,2BAAW;AACX;AAAA,cACJ;AAAA,YACJ;AAGA,gBAAI,UAAU;AAEV,oBAAM,cAAc,KAAK,UAAU,EAAE,IAAI;AACzC,kBAAI,uBAAuB,KAAK,QAAQ;AAEpC,sBAAM;AAAA,cACV;AAEA,qBAAO,OAAO,SAAS,WAAW;AAAA,YACtC;AAGA,mBAAO,EAAE;AAAA,UACb,SAAS,KAAK;AAEV,kBAAM,aAAa,oBAAI,IAAY;AACnC,gBAAI;AAGJ,gBAAI,eAAe,KAAK,UAAU,IAAI,OAAO,QAAQ;AACjD,oBAAM,aAAa,IAAI,OAAO,CAAC;AAC/B,wBAAU,WAAW;AAAA,YACzB,WAAW,eAAe,OAAO;AAE7B,wBAAU,IAAI;AAAA,YAClB,OAAO;AAEH,wBAAU;AAAA,YACd;AAGA,kBAAM,WAAW,KAAK,WAAW,OAAO;AAGxC,qBAAS,OAAO;AAAA,cACZ,iBAAiB;AAAA,YACrB;AAGA,gBAAI,OAAO,iBAAiB,eAAe,YAAY;AACnD,qBAAO,gBAAgB,WAAW,SAAS,GAAG,QAAQ;AAAA,YAC1D;AAGA,gBAAI,iBAAiB,eAAe,OAAO;AACvC,sBAAQ,IAAI,CAAC,cAAc,SAAS,WAAW,GAAG,UAAU,GAAG,QAAQ;AAAA,YAE3E;AAGA,mBAAO;AAAA,UACX;AAAA,QACJ,CAAC;AACD,eAAO,SAAS,UAAU,OAAO,SAAS;AAAA,MAC9C;AAAA,IACJ,CAAC;AAED,QAAI,EAAE,SAAS;AACX,QAAE,QAAQ,eAAe,gBAAgB;AAAA,IAC7C;AACA,QAAI,EAAE,SAAS;AACX,QAAE,QAAQ,eAAe,gBAAgB;AAAA,IAC7C;AAAA,EACJ;AACJ;","names":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { KaapiOpenAPIHelperInterface } from '@kaapi/kaapi';
|
|
2
|
+
import { OpenAPIJsonHelper, PostmanJsonHelper } from '@novice1/api-doc-json-helper';
|
|
3
|
+
import { Type } from 'arktype';
|
|
4
|
+
|
|
5
|
+
declare class OpenAPIArkHelper extends OpenAPIJsonHelper implements KaapiOpenAPIHelperInterface {
|
|
6
|
+
constructor(params: {
|
|
7
|
+
value?: Type | object | unknown;
|
|
8
|
+
isRoot?: boolean;
|
|
9
|
+
}, isRequired?: boolean);
|
|
10
|
+
isValid(): boolean;
|
|
11
|
+
getFirstItem(): OpenAPIArkHelper | undefined;
|
|
12
|
+
getChildren(): Record<string, OpenAPIArkHelper>;
|
|
13
|
+
getAlternatives(): OpenAPIArkHelper[];
|
|
14
|
+
isFile(): boolean | undefined;
|
|
15
|
+
getFilesChildren(): Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
declare class PostmanArkHelper extends PostmanJsonHelper {
|
|
18
|
+
constructor(params: {
|
|
19
|
+
value?: Type | object | unknown;
|
|
20
|
+
isRoot?: boolean;
|
|
21
|
+
}, isRequired?: boolean);
|
|
22
|
+
isValid(): boolean;
|
|
23
|
+
getFirstItem(): PostmanArkHelper | undefined;
|
|
24
|
+
getChildren(): Record<string, PostmanArkHelper>;
|
|
25
|
+
getAlternatives(): PostmanArkHelper[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { OpenAPIArkHelper, PostmanArkHelper };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import './declarations.d.ts'
|
|
2
|
+
export { ArkSchema, ArklessReqRef, ArklessReqRefDefaults, Infer, ValidatorArk, ValidatorArkReqRef, ValidatorArkSchema, output } from './types.js';
|
|
3
|
+
export { OpenAPIArkHelper, PostmanArkHelper } from './doc-helpers.js';
|
|
4
|
+
export { supportedProps, validatorArk } from './validator.js';
|
|
5
|
+
import '@kaapi/kaapi';
|
|
6
|
+
import 'arktype';
|
|
7
|
+
import '@novice1/api-doc-json-helper';
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import "./chunk-55J6XMHW.js";
|
|
2
|
+
import {
|
|
3
|
+
supportedProps,
|
|
4
|
+
validatorArk
|
|
5
|
+
} from "./chunk-K4WN6QYS.js";
|
|
6
|
+
import {
|
|
7
|
+
OpenAPIArkHelper,
|
|
8
|
+
PostmanArkHelper
|
|
9
|
+
} from "./chunk-3R3TW4ZK.js";
|
|
10
|
+
export {
|
|
11
|
+
OpenAPIArkHelper,
|
|
12
|
+
PostmanArkHelper,
|
|
13
|
+
supportedProps,
|
|
14
|
+
validatorArk
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"inputs":{"src/doc-helpers.ts":{"bytes":7238,"imports":[{"path":"@novice1/api-doc-json-helper","kind":"import-statement","external":true}],"format":"esm"},"src/types.ts":{"bytes":1833,"imports":[],"format":"esm"},"package.json":{"bytes":1797,"imports":[],"format":"esm","with":{"type":"json"}},"src/validator.ts":{"bytes":8695,"imports":[{"path":"package.json","kind":"import-statement","original":"../package.json","with":{"type":"json"}},{"path":"src/doc-helpers.ts","kind":"import-statement","original":"./doc-helpers.js"},{"path":"@hapi/boom","kind":"import-statement","external":true},{"path":"arktype","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":94,"imports":[{"path":"src/types.ts","kind":"import-statement","original":"./types.js"},{"path":"src/doc-helpers.ts","kind":"import-statement","original":"./doc-helpers.js"},{"path":"src/validator.ts","kind":"import-statement","original":"./validator.js"}],"format":"esm"}},"outputs":{"lib/doc-helpers.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"lib/doc-helpers.js":{"imports":[{"path":"lib/chunk-3R3TW4ZK.js","kind":"import-statement"}],"exports":["OpenAPIArkHelper","PostmanArkHelper"],"entryPoint":"src/doc-helpers.ts","inputs":{},"bytes":129},"lib/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"lib/index.js":{"imports":[{"path":"lib/chunk-55J6XMHW.js","kind":"import-statement"},{"path":"lib/chunk-K4WN6QYS.js","kind":"import-statement"},{"path":"lib/chunk-3R3TW4ZK.js","kind":"import-statement"}],"exports":["OpenAPIArkHelper","PostmanArkHelper","supportedProps","validatorArk"],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0}},"bytes":265},"lib/types.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"lib/types.js":{"imports":[{"path":"lib/chunk-55J6XMHW.js","kind":"import-statement"}],"exports":[],"entryPoint":"src/types.ts","inputs":{},"bytes":30},"lib/chunk-55J6XMHW.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"lib/chunk-55J6XMHW.js":{"imports":[],"exports":[],"inputs":{"src/types.ts":{"bytesInOutput":0}},"bytes":0},"lib/validator.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"lib/validator.js":{"imports":[{"path":"lib/chunk-K4WN6QYS.js","kind":"import-statement"},{"path":"lib/chunk-3R3TW4ZK.js","kind":"import-statement"}],"exports":["supportedProps","validatorArk"],"entryPoint":"src/validator.ts","inputs":{},"bytes":147},"lib/chunk-K4WN6QYS.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":14467},"lib/chunk-K4WN6QYS.js":{"imports":[{"path":"lib/chunk-3R3TW4ZK.js","kind":"import-statement"},{"path":"@hapi/boom","kind":"import-statement","external":true},{"path":"arktype","kind":"import-statement","external":true}],"exports":["supportedProps","validatorArk"],"inputs":{"package.json":{"bytesInOutput":1758},"src/validator.ts":{"bytesInOutput":4285}},"bytes":6205},"lib/chunk-3R3TW4ZK.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":11310},"lib/chunk-3R3TW4ZK.js":{"imports":[{"path":"@novice1/api-doc-json-helper","kind":"import-statement","external":true}],"exports":["OpenAPIArkHelper","PostmanArkHelper"],"inputs":{"src/doc-helpers.ts":{"bytesInOutput":5107}},"bytes":5181}}}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Lifecycle, ReqRefDefaults, ReqRef, MergeRefs, KaapiServerRoute, HandlerDecorations, Server } from '@kaapi/kaapi';
|
|
2
|
+
import { Type } from 'arktype';
|
|
3
|
+
|
|
4
|
+
type ArkSchema = Type<any, any> | undefined | null;
|
|
5
|
+
type ValidatorArkSchema = {
|
|
6
|
+
payload?: ArkSchema;
|
|
7
|
+
query?: ArkSchema;
|
|
8
|
+
params?: ArkSchema;
|
|
9
|
+
headers?: ArkSchema;
|
|
10
|
+
state?: ArkSchema;
|
|
11
|
+
failAction?: 'error' | 'log' | Lifecycle.Method | undefined;
|
|
12
|
+
};
|
|
13
|
+
type ArklessReqRefDefaults = Omit<ReqRefDefaults, 'Query' | 'Headers' | 'Params' | 'Payload'>;
|
|
14
|
+
type ArklessReqRef = Omit<ReqRef, 'Query' | 'Headers' | 'Params' | 'Payload'>;
|
|
15
|
+
type Infer<T extends Type<any, any>> = T['infer'];
|
|
16
|
+
type output<T, D = unknown> = T extends Type<any, any> ? Infer<T> : D;
|
|
17
|
+
interface ValidatorArkReqRef<RS extends ValidatorArkSchema = ValidatorArkSchema> {
|
|
18
|
+
Query: output<RS['query'], MergeRefs<ArklessReqRefDefaults>['Query']>;
|
|
19
|
+
Headers: output<RS['headers'], MergeRefs<ArklessReqRefDefaults>['Headers']>;
|
|
20
|
+
Params: output<RS['params'], MergeRefs<ArklessReqRefDefaults>['Params']>;
|
|
21
|
+
Payload: output<RS['payload'], MergeRefs<ArklessReqRefDefaults>['Payload']>;
|
|
22
|
+
}
|
|
23
|
+
type ValidatorArk = <V extends ValidatorArkSchema>(schema: V) => {
|
|
24
|
+
route<R extends ArklessReqRef = ArklessReqRefDefaults>(serverRoute: KaapiServerRoute<ValidatorArkReqRef<V> & R>, handler?: HandlerDecorations | Lifecycle.Method<ValidatorArkReqRef<V> & R, Lifecycle.ReturnValue<ValidatorArkReqRef<V> & R>>): Server;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type { ArkSchema, ArklessReqRef, ArklessReqRefDefaults, Infer, ValidatorArk, ValidatorArkReqRef, ValidatorArkSchema, output };
|
package/lib/types.js
ADDED
package/lib/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/lib/validator.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kaapi/validator-arktype",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.19",
|
|
5
|
+
"private": false,
|
|
6
|
+
"description": "ArkType-powered request validation and documentation plugin for Kaapi.",
|
|
7
|
+
"main": "lib/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsup src !src/**/*.d.ts --format esm --outDir lib --clean --metafile --dts --sourcemap && node ./scripts/buildDT.mjs",
|
|
16
|
+
"check": "tsc --noEmit",
|
|
17
|
+
"check:deps": "depcruise src --validate",
|
|
18
|
+
"ci": "npm run verify",
|
|
19
|
+
"coverage": "c8 node --loader ts-node/esm --experimental-specifier-resolution=node --no-warnings ../../node_modules/mocha/bin/mocha test/**/*.spec.ts",
|
|
20
|
+
"format": "prettier --write ./",
|
|
21
|
+
"format:check": "prettier --check ./",
|
|
22
|
+
"lint": "eslint .",
|
|
23
|
+
"test": "node --loader ts-node/esm --experimental-specifier-resolution=node --no-warnings ../../node_modules/mocha/bin/mocha test/**/*.spec.ts",
|
|
24
|
+
"type-coverage": "type-coverage --at-least 90 --detail",
|
|
25
|
+
"verify": "npm run lint && npm run format:check && npm run check && npm run check:deps && npm run type-coverage && npm run test:kaukau && npm run coverage"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"kaapi",
|
|
29
|
+
"hapi",
|
|
30
|
+
"arktype",
|
|
31
|
+
"typescript",
|
|
32
|
+
"validation"
|
|
33
|
+
],
|
|
34
|
+
"author": "demingongo",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/demingongo/kaapi.git",
|
|
38
|
+
"directory": "packages/validator-arktype"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@hapi/boom": "^10.0.1",
|
|
43
|
+
"@kaapi/kaapi": "workspace:^",
|
|
44
|
+
"@novice1/api-doc-json-helper": "^1.0.6",
|
|
45
|
+
"arktype": "^2.1.25",
|
|
46
|
+
"tslib": "^2.8.1"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/mocha": "^10.0.10"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"arktype": "^2.1.25"
|
|
53
|
+
}
|
|
54
|
+
}
|