@darksheep/json-schema 0.0.0 โ 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +57 -55
- package/package.json +4 -3
- package/src/async.js +150 -0
- package/src/errors.js +85 -13
- package/src/index.js +12 -17
- package/src/sync.js +112 -0
- package/src/types.js +32 -0
- package/types/async.d.ts +76 -0
- package/types/errors.d.ts +25 -15
- package/types/index.d.ts +6 -20
- package/types/sync.d.ts +28 -0
- package/types/types.d.ts +12 -0
- package/src/validator.js +0 -122
- package/types/validator.d.ts +0 -32
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (2025-01-28)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### ๐ Features
|
|
7
|
+
|
|
8
|
+
* **json-schema:** Extract schema tool to a package ([292c5a0](https://github.com/DarkSheepSoftware/node-packages/commit/292c5a0c4cfd1b9e82bd179db76c47aa979480bb))
|
|
9
|
+
* Refactor json-schema and add tests. ([5f9669b](https://github.com/DarkSheepSoftware/node-packages/commit/5f9669baddc0d31d1faa5c26c319ec664c2c746b))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### ๐งน Chores
|
|
13
|
+
|
|
14
|
+
* Install ajv-formats ([9ce1702](https://github.com/DarkSheepSoftware/node-packages/commit/9ce170223b8e9dd16cae4a019170d90999589d45))
|
package/README.md
CHANGED
|
@@ -1,63 +1,65 @@
|
|
|
1
|
-
# @darksheep/
|
|
2
|
-
|
|
3
|
-
This is primarily useful when you're making a package, and you need to find the package.json for the service that is executing your package.
|
|
4
|
-
When using pnpm you need to be cautious to set the root directory correctly.
|
|
5
|
-
|
|
6
|
-
## Examples
|
|
7
|
-
### Common JS
|
|
8
|
-
```js
|
|
9
|
-
const { getPackageJson } = require('@darksheep/package.json');
|
|
10
|
-
(async () => {
|
|
11
|
-
const { name, version } = await getPackageJson();
|
|
12
|
-
|
|
13
|
-
console.info({ name, version });
|
|
14
|
-
})()
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### Module JS
|
|
18
|
-
```js
|
|
19
|
-
import { getPackageJson } from '@darksheep/package.json';
|
|
20
|
-
const { name, version } = await getPackageJson();
|
|
1
|
+
# @darksheep/json-schema
|
|
2
|
+
Validate your unkown json types in style!
|
|
21
3
|
|
|
22
|
-
|
|
23
|
-
```
|
|
4
|
+
## Example
|
|
24
5
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
If you intend on using this inside a module file, please reconsider!
|
|
6
|
+
```ts
|
|
7
|
+
import { createValidator } from '@darksheep/json-schema';
|
|
28
8
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
9
|
+
const validate = createValidator({
|
|
10
|
+
type: 'object',
|
|
11
|
+
required: [ 'name', 'updatedAt' ],
|
|
12
|
+
properties: {
|
|
13
|
+
name: { type: 'string' },
|
|
14
|
+
description: { type: 'string' },
|
|
15
|
+
// Defaults are supported!
|
|
16
|
+
stared: {
|
|
17
|
+
type: 'boolean',
|
|
18
|
+
default: false,
|
|
19
|
+
},
|
|
20
|
+
// Formats are supported!
|
|
21
|
+
updatedAt: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
format: 'date-time',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
});
|
|
32
27
|
|
|
33
|
-
|
|
28
|
+
// typeof validate is equal to: (
|
|
29
|
+
// data: {
|
|
30
|
+
// description?: string;
|
|
31
|
+
// stared?: boolean;
|
|
32
|
+
// name: string;
|
|
33
|
+
// updatedAt: string;
|
|
34
|
+
// }
|
|
35
|
+
// ) => Promise<{
|
|
36
|
+
// description?: string;
|
|
37
|
+
// name: string;
|
|
38
|
+
// updatedAt: string;
|
|
39
|
+
// stared: boolean;
|
|
40
|
+
// }>
|
|
34
41
|
```
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
### Example with untrusted input
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { createValidator, defineSchema } from '@darksheep/json-schema';
|
|
47
|
+
|
|
48
|
+
const TransferRequestSchema = defineSchema({
|
|
49
|
+
type: 'object',
|
|
50
|
+
required: [ 'source', 'destination', 'amount' ],
|
|
51
|
+
unevaluatedProperties: false,
|
|
52
|
+
properties: {
|
|
53
|
+
source: { type: 'string' },
|
|
54
|
+
destination: { type: 'string' },
|
|
55
|
+
amount: { type: 'integer' },
|
|
56
|
+
}
|
|
57
|
+
})
|
|
50
58
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
*
|
|
58
|
-
* @param {string} [packageName] The name of the npm package (the main package if blank)
|
|
59
|
-
* @param {string | URL} [root] an optional root file url to start from
|
|
60
|
-
* @returns {PackageJson | null}
|
|
61
|
-
*/
|
|
62
|
-
export function getPackageJson(packageName, root);
|
|
59
|
+
const validateTransferRequest = createValidator(
|
|
60
|
+
TransferRequestSchema,
|
|
61
|
+
{ allowUnknown: true },
|
|
62
|
+
)
|
|
63
|
+
// The `typeof validateTransferRequest` is:
|
|
64
|
+
// (data: unknown) => Promise<{ source: string; destination: string; amount: number }>
|
|
63
65
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@darksheep/json-schema",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "JSON schema validation (with types)",
|
|
5
5
|
"license": "UNLICENCED",
|
|
6
6
|
"type": "module",
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"prepack": "yarn dlx -q -p typescript tsc",
|
|
20
|
-
"test": "node --test src/**/*.test.js",
|
|
21
|
-
"test:watch": "node --watch --
|
|
20
|
+
"test": "node --test --experimental-strip-types src/**/*.test.{ts,js}",
|
|
21
|
+
"test:watch": "node --test --watch --experimental-strip-types src/**/*.test.{ts,js}"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@darksheep/errors": "",
|
|
25
25
|
"ajv": "8.17.1",
|
|
26
|
+
"ajv-formats": "3.0.1",
|
|
26
27
|
"json-schema-to-ts": "3.1.1"
|
|
27
28
|
},
|
|
28
29
|
"engines": {
|
package/src/async.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { Ajv2019 as Ajv } from 'ajv/dist/2019.js';
|
|
2
|
+
import AddFormats from 'ajv-formats';
|
|
3
|
+
import { isSchemaError } from './errors.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @import {
|
|
7
|
+
* AsyncSchema,
|
|
8
|
+
* AsyncValidateFunction,
|
|
9
|
+
* } from 'ajv';
|
|
10
|
+
* @import {
|
|
11
|
+
* FromSchema,
|
|
12
|
+
* JSONSchema,
|
|
13
|
+
* TargetError,
|
|
14
|
+
* } from './types.js';
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {(
|
|
19
|
+
* & { schema: JSONSchema }
|
|
20
|
+
* )} ToJsonOptions
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const ajv = new Ajv({
|
|
24
|
+
allErrors: true,
|
|
25
|
+
verbose: false,
|
|
26
|
+
allowUnionTypes: false,
|
|
27
|
+
multipleOfPrecision: 5,
|
|
28
|
+
ownProperties: true,
|
|
29
|
+
strict: true,
|
|
30
|
+
useDefaults: true,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
AddFormats.default(ajv);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @type {WeakMap<JSONSchema, AsyncValidateFunction>}
|
|
37
|
+
*/
|
|
38
|
+
const validatorSchema = new WeakMap();
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {JSONSchema} schema - The original JSONSchema.
|
|
42
|
+
* @param {{ meta?: boolean | undefined }} [options] - The options for ajv compile.
|
|
43
|
+
* @returns {AsyncValidateFunction}
|
|
44
|
+
*/
|
|
45
|
+
export function getValidator(schema, options) {
|
|
46
|
+
const Compiled = validatorSchema.get(schema);
|
|
47
|
+
if (Compiled != null) {
|
|
48
|
+
return Compiled;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const validator = ajv.compile(
|
|
52
|
+
/** @type {AsyncSchema} */ ({
|
|
53
|
+
...schema,
|
|
54
|
+
$async: true,
|
|
55
|
+
}),
|
|
56
|
+
options?.meta,
|
|
57
|
+
);
|
|
58
|
+
validatorSchema.set(schema, validator);
|
|
59
|
+
|
|
60
|
+
return validator;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @template {JSONSchema} const Schema - The raw schema type.
|
|
65
|
+
* @template {boolean} [AllowUnknown=false]
|
|
66
|
+
* @template {boolean} [ParseNot=false]
|
|
67
|
+
* @template {boolean} [ParseIfThenElse=false]
|
|
68
|
+
* @template [DataOptional=FromSchema<Schema, {
|
|
69
|
+
* keepDefaultedPropertiesOptional: true,
|
|
70
|
+
* parseIfThenElseKeywords: ParseIfThenElse,
|
|
71
|
+
* parseNotKeyword: ParseNot,
|
|
72
|
+
* }>].
|
|
73
|
+
* @template [DataDefaults=FromSchema<Schema, {
|
|
74
|
+
* keepDefaultedPropertiesOptional: false,
|
|
75
|
+
* parseIfThenElseKeywords: ParseIfThenElse,
|
|
76
|
+
* parseNotKeyword: ParseNot,
|
|
77
|
+
* }>].
|
|
78
|
+
* @param {Schema} schema - The request body json schema.
|
|
79
|
+
* @param {{
|
|
80
|
+
* meta?: boolean | undefined,
|
|
81
|
+
* allowUnknown?: AllowUnknown | undefined,
|
|
82
|
+
* parseIfThenElseKeywords?: ParseIfThenElse | undefined,
|
|
83
|
+
* parseNotKeyword?: ParseNot | undefined,
|
|
84
|
+
* }} [options] - The request body json schema.
|
|
85
|
+
* @param {TargetError | undefined} [ParentThrownError] - The error type.
|
|
86
|
+
* @returns {(
|
|
87
|
+
* data: AllowUnknown extends true ? unknown : DataOptional,
|
|
88
|
+
* TargetError?: TargetError | undefined
|
|
89
|
+
* ) => Promise<DataDefaults>}
|
|
90
|
+
*/
|
|
91
|
+
export function createValidator(schema, options, ParentThrownError) {
|
|
92
|
+
/** @type {AsyncValidateFunction<DataDefaults>} */
|
|
93
|
+
const validator = getValidator(schema, options);
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {unknown} data - The raw data.
|
|
97
|
+
* @param {TargetError | undefined} [ThrownError] - The error type.
|
|
98
|
+
* @returns {Promise<DataDefaults>}
|
|
99
|
+
*/
|
|
100
|
+
return async (data, ThrownError = ParentThrownError) => {
|
|
101
|
+
try {
|
|
102
|
+
return await validator(data);
|
|
103
|
+
} catch (error) {
|
|
104
|
+
if (
|
|
105
|
+
ThrownError == null ||
|
|
106
|
+
isSchemaError(error) === false
|
|
107
|
+
) {
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
throw new ThrownError(
|
|
112
|
+
{ cause: error, errors: error.errors },
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @template {JSONSchema} const Schema - The raw schema type.
|
|
120
|
+
* @template {boolean} [ParseNot=false]
|
|
121
|
+
* @template {boolean} [ParseIfThenElse=false]
|
|
122
|
+
* @template [DataDefaults=FromSchema<Schema, {
|
|
123
|
+
* keepDefaultedPropertiesOptional: false,
|
|
124
|
+
* parseIfThenElseKeywords: ParseIfThenElse,
|
|
125
|
+
* parseNotKeyword: ParseNot,
|
|
126
|
+
* }>].
|
|
127
|
+
* @param {Schema} schema - The request body json schema.
|
|
128
|
+
* @param {unknown} data - The data to validate.
|
|
129
|
+
* @param {TargetError | undefined} [ThrownError] - The error type.
|
|
130
|
+
* @returns {Promise<DataDefaults>}
|
|
131
|
+
*/
|
|
132
|
+
export async function validate(schema, data, ThrownError) {
|
|
133
|
+
/** @type {AsyncValidateFunction<DataDefaults>} */
|
|
134
|
+
const validator = getValidator(schema);
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
return await validator(data);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
if (
|
|
140
|
+
ThrownError == null ||
|
|
141
|
+
isSchemaError(error) === false
|
|
142
|
+
) {
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
throw new ThrownError(
|
|
147
|
+
{ cause: error, errors: error.errors },
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
}
|
package/src/errors.js
CHANGED
|
@@ -1,26 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { DefinedError } from 'ajv'
|
|
3
|
+
* @import { ErrorOptions } from '@darksheep/errors'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ValidationError } from 'ajv';
|
|
1
7
|
import { BadRequest, InternalServerError } from '@darksheep/errors';
|
|
2
8
|
|
|
3
9
|
/**
|
|
4
10
|
* @typedef {(
|
|
5
|
-
* &
|
|
6
|
-
* & { errors:
|
|
7
|
-
* )}
|
|
11
|
+
* & ErrorOptions
|
|
12
|
+
* & { errors: DefinedError[] }
|
|
13
|
+
* )} SchemaErrorOptions
|
|
8
14
|
*/
|
|
9
15
|
|
|
10
16
|
/**
|
|
11
17
|
* The server will not process the request body not matching the expected request schema.
|
|
12
18
|
*/
|
|
13
19
|
export class RequestSchemaError extends BadRequest {
|
|
14
|
-
/** @type {
|
|
20
|
+
/** @type {DefinedError[]} */
|
|
15
21
|
errors = [];
|
|
16
22
|
name = 'RequestSchemaError';
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
|
-
* @param {
|
|
20
|
-
* @param {ErrorOptions} options - The custom message for the http error.
|
|
25
|
+
* @param {SchemaErrorOptions} options - The custom message for the http error.
|
|
21
26
|
*/
|
|
22
|
-
constructor(
|
|
23
|
-
super(
|
|
27
|
+
constructor({ errors, ...options }) {
|
|
28
|
+
super('Request.body does not match Schema', options);
|
|
24
29
|
|
|
25
30
|
this.errors = errors;
|
|
26
31
|
}
|
|
@@ -30,17 +35,84 @@ export class RequestSchemaError extends BadRequest {
|
|
|
30
35
|
* The server tried sending a response that did not match the expected response schema.
|
|
31
36
|
*/
|
|
32
37
|
export class ResponseSchemaError extends InternalServerError {
|
|
33
|
-
/** @type {
|
|
38
|
+
/** @type {DefinedError[]} */
|
|
34
39
|
errors = [];
|
|
35
40
|
name = 'ResponseSchemaError';
|
|
36
41
|
|
|
37
42
|
/**
|
|
38
|
-
* @param {
|
|
39
|
-
* @param {ErrorOptions} options - The custom message for the http error.
|
|
43
|
+
* @param {SchemaErrorOptions} options - The custom message for the http error.
|
|
40
44
|
*/
|
|
41
|
-
constructor(
|
|
42
|
-
super(
|
|
45
|
+
constructor({ errors, ...options }) {
|
|
46
|
+
super('Response.body does not match Schema', options);
|
|
43
47
|
|
|
44
48
|
this.errors = errors;
|
|
45
49
|
}
|
|
46
50
|
}
|
|
51
|
+
|
|
52
|
+
/** @type {Set<string>} */
|
|
53
|
+
const keywords = new Set(
|
|
54
|
+
/** @type {DefinedError['keyword'][]} */ ([
|
|
55
|
+
'false schema',
|
|
56
|
+
'anyOf',
|
|
57
|
+
'not',
|
|
58
|
+
'type',
|
|
59
|
+
'additionalItems',
|
|
60
|
+
'items',
|
|
61
|
+
'contains',
|
|
62
|
+
'additionalProperties',
|
|
63
|
+
'dependencies',
|
|
64
|
+
'if',
|
|
65
|
+
'oneOf',
|
|
66
|
+
'propertyNames',
|
|
67
|
+
'maxItems',
|
|
68
|
+
'minItems',
|
|
69
|
+
'maxProperties',
|
|
70
|
+
'minProperties',
|
|
71
|
+
'minLength',
|
|
72
|
+
'maxLength',
|
|
73
|
+
'maximum',
|
|
74
|
+
'minimum',
|
|
75
|
+
'exclusiveMaximum',
|
|
76
|
+
'exclusiveMinimum',
|
|
77
|
+
'multipleOf',
|
|
78
|
+
'pattern',
|
|
79
|
+
'required',
|
|
80
|
+
'uniqueItems',
|
|
81
|
+
'const',
|
|
82
|
+
'enum',
|
|
83
|
+
'format',
|
|
84
|
+
'unevaluatedProperties',
|
|
85
|
+
'unevaluatedItems',
|
|
86
|
+
'dependentRequired',
|
|
87
|
+
'discriminator',
|
|
88
|
+
]),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {unknown} input - The value to check.
|
|
93
|
+
* @returns {input is DefinedError}
|
|
94
|
+
*/
|
|
95
|
+
export function isDefinedError(input) {
|
|
96
|
+
return (
|
|
97
|
+
input != null &&
|
|
98
|
+
typeof input === 'object' &&
|
|
99
|
+
'keyword' in input &&
|
|
100
|
+
typeof input.keyword === 'string' &&
|
|
101
|
+
keywords.has(input.keyword) &&
|
|
102
|
+
'instancePath' in input &&
|
|
103
|
+
typeof input.instancePath === 'string' &&
|
|
104
|
+
'schemaPath' in input &&
|
|
105
|
+
typeof input.schemaPath === 'string'
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {unknown} input - The value to check.
|
|
111
|
+
* @returns {input is import('./types.js').ValidationError}
|
|
112
|
+
*/
|
|
113
|
+
export function isSchemaError(input) {
|
|
114
|
+
return (
|
|
115
|
+
input instanceof ValidationError &&
|
|
116
|
+
input.errors.every(isDefinedError)
|
|
117
|
+
);
|
|
118
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
* @typedef {import('ajv').DefinedError} DefinedError
|
|
3
|
-
* @typedef {Exclude<import('json-schema-to-ts').JSONSchema, boolean>} JSONSchema
|
|
4
|
-
* @typedef {import('json-schema-to-ts').FromSchemaOptions} FromSchemaOptions
|
|
5
|
-
* @typedef {import('json-schema-to-ts').FromSchemaDefaultOptions} FromSchemaDefaultOptions
|
|
6
|
-
*/
|
|
1
|
+
export * from './types.js';
|
|
7
2
|
|
|
8
3
|
/**
|
|
9
|
-
* @template {JSONSchema} Schema
|
|
10
|
-
* @template {FromSchemaOptions} [Options=FromSchemaDefaultOptions]
|
|
11
|
-
* @typedef {import('json-schema-to-ts').FromSchema<Schema, Options>} FromSchema
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @template {JSONSchema} const Schema - The raw schema type.
|
|
4
|
+
* @template {import('./types.js').JSONSchema} const Schema - The raw schema type.
|
|
16
5
|
* @param {Schema} schema - The raw JSON schema.
|
|
17
6
|
* @returns {Schema}
|
|
18
7
|
*/
|
|
@@ -21,12 +10,18 @@ export function defineSchema(schema) {
|
|
|
21
10
|
}
|
|
22
11
|
|
|
23
12
|
export {
|
|
13
|
+
isDefinedError,
|
|
14
|
+
isSchemaError,
|
|
24
15
|
RequestSchemaError,
|
|
25
16
|
ResponseSchemaError,
|
|
26
17
|
} from './errors.js';
|
|
27
18
|
|
|
28
19
|
export {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
createValidator,
|
|
21
|
+
validate,
|
|
22
|
+
} from './async.js';
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
createAssertSchema,
|
|
26
|
+
assertSchema,
|
|
27
|
+
} from './sync.js';
|
package/src/sync.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Ajv2019 as Ajv, ValidationError } from 'ajv/dist/2019.js';
|
|
2
|
+
import AddFormats from 'ajv-formats';
|
|
3
|
+
import { isDefinedError } from './errors.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @import {
|
|
7
|
+
* SchemaObject,
|
|
8
|
+
* ValidateFunction
|
|
9
|
+
* } from 'ajv'
|
|
10
|
+
* @import {
|
|
11
|
+
* FromSchema,
|
|
12
|
+
* JSONSchema,
|
|
13
|
+
* TargetError,
|
|
14
|
+
* } from './types.js'
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {(
|
|
19
|
+
* & { schema: JSONSchema }
|
|
20
|
+
* )} ToJsonOptions
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const ajv = new Ajv({
|
|
24
|
+
allErrors: true,
|
|
25
|
+
verbose: false,
|
|
26
|
+
allowUnionTypes: false,
|
|
27
|
+
multipleOfPrecision: 5,
|
|
28
|
+
ownProperties: true,
|
|
29
|
+
strict: true,
|
|
30
|
+
useDefaults: false,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
AddFormats.default(ajv);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @type {WeakMap<JSONSchema, ValidateFunction>}
|
|
37
|
+
*/
|
|
38
|
+
const enforcerSchema = new WeakMap();
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {JSONSchema} schema - The original JSONSchema.
|
|
42
|
+
* @returns {ValidateFunction}
|
|
43
|
+
*/
|
|
44
|
+
export function getValidator(schema) {
|
|
45
|
+
const Compiled = enforcerSchema.get(schema);
|
|
46
|
+
if (Compiled != null) {
|
|
47
|
+
return Compiled;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const enforcer = ajv.compile(
|
|
51
|
+
/** @type {SchemaObject} */ ({
|
|
52
|
+
...schema,
|
|
53
|
+
$async: false,
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
enforcerSchema.set(schema, enforcer);
|
|
57
|
+
|
|
58
|
+
return enforcer;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @template {JSONSchema} const Schema - The raw schema type.
|
|
63
|
+
* @template [Data=FromSchema<Schema>]
|
|
64
|
+
* @param {Schema} schema - The request body json schema.
|
|
65
|
+
* @returns {(data: unknown, TargetError?: TargetError | undefined) => asserts data is Data}
|
|
66
|
+
*/
|
|
67
|
+
export function createAssertSchema(schema) {
|
|
68
|
+
/** @type {ValidateFunction<Data>} */
|
|
69
|
+
const validator = getValidator(schema);
|
|
70
|
+
|
|
71
|
+
/** @type {(data: unknown, TargetError?: TargetError | undefined) => asserts data is Data} */
|
|
72
|
+
return (data, TargetError) => {
|
|
73
|
+
if (validator(data)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const errors = validator.errors
|
|
78
|
+
?.filter(isDefinedError) ?? [];
|
|
79
|
+
|
|
80
|
+
if (TargetError == null) {
|
|
81
|
+
throw new ValidationError(errors);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
throw new TargetError({ errors });
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @template {JSONSchema} const Schema - The raw schema type.
|
|
90
|
+
* @template [Data=FromSchema<Schema>]
|
|
91
|
+
* @param {Schema} schema - The request body json schema.
|
|
92
|
+
* @param {unknown} data - The raw data.
|
|
93
|
+
* @param {TargetError | undefined} [TargetError] - The error type.
|
|
94
|
+
* @returns {asserts data is Data}
|
|
95
|
+
*/
|
|
96
|
+
export function assertSchema(schema, data, TargetError) {
|
|
97
|
+
/** @type {ValidateFunction<Data>} */
|
|
98
|
+
const validator = getValidator(schema);
|
|
99
|
+
|
|
100
|
+
if (validator(data)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const errors = validator.errors
|
|
105
|
+
?.filter(isDefinedError) ?? [];
|
|
106
|
+
|
|
107
|
+
if (TargetError == null) {
|
|
108
|
+
throw new ValidationError(errors);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
throw new TargetError({ errors });
|
|
112
|
+
}
|
package/src/types.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { DefinedError } from 'ajv'
|
|
3
|
+
*/
|
|
4
|
+
export {};
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {(
|
|
8
|
+
* & Omit<import('ajv').ValidationError, 'errors'>
|
|
9
|
+
* & { errors: DefinedError[] }
|
|
10
|
+
* )} ValidationError
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {new (options: { cause?: Error, errors: DefinedError[] }) => Error} TargetError
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {Exclude<import('json-schema-to-ts').JSONSchema, boolean>} JSONSchema
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {import('json-schema-to-ts').FromSchemaOptions} FromSchemaOptions
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @typedef {import('json-schema-to-ts').FromSchemaDefaultOptions} FromSchemaDefaultOptions
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @template {JSONSchema} Schema - The raw schema type.
|
|
30
|
+
* @template {FromSchemaOptions} [Options=FromSchemaDefaultOptions] - The schema typing options.
|
|
31
|
+
* @typedef {import('json-schema-to-ts').FromSchema<Schema, Options>} FromSchema
|
|
32
|
+
*/
|
package/types/async.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {JSONSchema} schema - The original JSONSchema.
|
|
3
|
+
* @param {{ meta?: boolean | undefined }} [options] - The options for ajv compile.
|
|
4
|
+
* @returns {AsyncValidateFunction}
|
|
5
|
+
*/
|
|
6
|
+
export function getValidator(schema: JSONSchema, options?: {
|
|
7
|
+
meta?: boolean | undefined;
|
|
8
|
+
}): AsyncValidateFunction;
|
|
9
|
+
/**
|
|
10
|
+
* @template {JSONSchema} const Schema - The raw schema type.
|
|
11
|
+
* @template {boolean} [AllowUnknown=false]
|
|
12
|
+
* @template {boolean} [ParseNot=false]
|
|
13
|
+
* @template {boolean} [ParseIfThenElse=false]
|
|
14
|
+
* @template [DataOptional=FromSchema<Schema, {
|
|
15
|
+
* keepDefaultedPropertiesOptional: true,
|
|
16
|
+
* parseIfThenElseKeywords: ParseIfThenElse,
|
|
17
|
+
* parseNotKeyword: ParseNot,
|
|
18
|
+
* }>].
|
|
19
|
+
* @template [DataDefaults=FromSchema<Schema, {
|
|
20
|
+
* keepDefaultedPropertiesOptional: false,
|
|
21
|
+
* parseIfThenElseKeywords: ParseIfThenElse,
|
|
22
|
+
* parseNotKeyword: ParseNot,
|
|
23
|
+
* }>].
|
|
24
|
+
* @param {Schema} schema - The request body json schema.
|
|
25
|
+
* @param {{
|
|
26
|
+
* meta?: boolean | undefined,
|
|
27
|
+
* allowUnknown?: AllowUnknown | undefined,
|
|
28
|
+
* parseIfThenElseKeywords?: ParseIfThenElse | undefined,
|
|
29
|
+
* parseNotKeyword?: ParseNot | undefined,
|
|
30
|
+
* }} [options] - The request body json schema.
|
|
31
|
+
* @param {TargetError | undefined} [ParentThrownError] - The error type.
|
|
32
|
+
* @returns {(
|
|
33
|
+
* data: AllowUnknown extends true ? unknown : DataOptional,
|
|
34
|
+
* TargetError?: TargetError | undefined
|
|
35
|
+
* ) => Promise<DataDefaults>}
|
|
36
|
+
*/
|
|
37
|
+
export function createValidator<const Schema extends JSONSchema, AllowUnknown extends boolean = false, ParseNot extends boolean = false, ParseIfThenElse extends boolean = false, DataOptional = FromSchema<Schema, {
|
|
38
|
+
keepDefaultedPropertiesOptional: true;
|
|
39
|
+
parseIfThenElseKeywords: ParseIfThenElse;
|
|
40
|
+
parseNotKeyword: ParseNot;
|
|
41
|
+
}>, DataDefaults = FromSchema<Schema, {
|
|
42
|
+
keepDefaultedPropertiesOptional: false;
|
|
43
|
+
parseIfThenElseKeywords: ParseIfThenElse;
|
|
44
|
+
parseNotKeyword: ParseNot;
|
|
45
|
+
}>>(schema: Schema, options?: {
|
|
46
|
+
meta?: boolean | undefined;
|
|
47
|
+
allowUnknown?: AllowUnknown | undefined;
|
|
48
|
+
parseIfThenElseKeywords?: ParseIfThenElse | undefined;
|
|
49
|
+
parseNotKeyword?: ParseNot | undefined;
|
|
50
|
+
}, ParentThrownError?: TargetError | undefined): (data: AllowUnknown extends true ? unknown : DataOptional, TargetError?: TargetError | undefined) => Promise<DataDefaults>;
|
|
51
|
+
/**
|
|
52
|
+
* @template {JSONSchema} const Schema - The raw schema type.
|
|
53
|
+
* @template {boolean} [ParseNot=false]
|
|
54
|
+
* @template {boolean} [ParseIfThenElse=false]
|
|
55
|
+
* @template [DataDefaults=FromSchema<Schema, {
|
|
56
|
+
* keepDefaultedPropertiesOptional: false,
|
|
57
|
+
* parseIfThenElseKeywords: ParseIfThenElse,
|
|
58
|
+
* parseNotKeyword: ParseNot,
|
|
59
|
+
* }>].
|
|
60
|
+
* @param {Schema} schema - The request body json schema.
|
|
61
|
+
* @param {unknown} data - The data to validate.
|
|
62
|
+
* @param {TargetError | undefined} [ThrownError] - The error type.
|
|
63
|
+
* @returns {Promise<DataDefaults>}
|
|
64
|
+
*/
|
|
65
|
+
export function validate<const Schema extends JSONSchema, ParseNot extends boolean = false, ParseIfThenElse extends boolean = false, DataDefaults = FromSchema<Schema, {
|
|
66
|
+
keepDefaultedPropertiesOptional: false;
|
|
67
|
+
parseIfThenElseKeywords: ParseIfThenElse;
|
|
68
|
+
parseNotKeyword: ParseNot;
|
|
69
|
+
}>>(schema: Schema, data: unknown, ThrownError?: TargetError | undefined): Promise<DataDefaults>;
|
|
70
|
+
export type ToJsonOptions = ({
|
|
71
|
+
schema: JSONSchema;
|
|
72
|
+
});
|
|
73
|
+
import type { JSONSchema } from './types.js';
|
|
74
|
+
import type { AsyncValidateFunction } from 'ajv';
|
|
75
|
+
import type { FromSchema } from './types.js';
|
|
76
|
+
import type { TargetError } from './types.js';
|
package/types/errors.d.ts
CHANGED
|
@@ -1,35 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {unknown} input - The value to check.
|
|
3
|
+
* @returns {input is DefinedError}
|
|
4
|
+
*/
|
|
5
|
+
export function isDefinedError(input: unknown): input is DefinedError;
|
|
6
|
+
/**
|
|
7
|
+
* @param {unknown} input - The value to check.
|
|
8
|
+
* @returns {input is import('./types.js').ValidationError}
|
|
9
|
+
*/
|
|
10
|
+
export function isSchemaError(input: unknown): input is import("./types.js").ValidationError;
|
|
1
11
|
/**
|
|
2
12
|
* @typedef {(
|
|
3
|
-
* &
|
|
4
|
-
* & { errors:
|
|
5
|
-
* )}
|
|
13
|
+
* & ErrorOptions
|
|
14
|
+
* & { errors: DefinedError[] }
|
|
15
|
+
* )} SchemaErrorOptions
|
|
6
16
|
*/
|
|
7
17
|
/**
|
|
8
18
|
* The server will not process the request body not matching the expected request schema.
|
|
9
19
|
*/
|
|
10
20
|
export class RequestSchemaError extends BadRequest {
|
|
11
21
|
/**
|
|
12
|
-
* @param {
|
|
13
|
-
* @param {ErrorOptions} options - The custom message for the http error.
|
|
22
|
+
* @param {SchemaErrorOptions} options - The custom message for the http error.
|
|
14
23
|
*/
|
|
15
|
-
constructor(
|
|
16
|
-
/** @type {
|
|
17
|
-
errors:
|
|
24
|
+
constructor({ errors, ...options }: SchemaErrorOptions);
|
|
25
|
+
/** @type {DefinedError[]} */
|
|
26
|
+
errors: DefinedError[];
|
|
18
27
|
}
|
|
19
28
|
/**
|
|
20
29
|
* The server tried sending a response that did not match the expected response schema.
|
|
21
30
|
*/
|
|
22
31
|
export class ResponseSchemaError extends InternalServerError {
|
|
23
32
|
/**
|
|
24
|
-
* @param {
|
|
25
|
-
* @param {ErrorOptions} options - The custom message for the http error.
|
|
33
|
+
* @param {SchemaErrorOptions} options - The custom message for the http error.
|
|
26
34
|
*/
|
|
27
|
-
constructor(
|
|
28
|
-
/** @type {
|
|
29
|
-
errors:
|
|
35
|
+
constructor({ errors, ...options }: SchemaErrorOptions);
|
|
36
|
+
/** @type {DefinedError[]} */
|
|
37
|
+
errors: DefinedError[];
|
|
30
38
|
}
|
|
31
|
-
export type
|
|
32
|
-
errors:
|
|
39
|
+
export type SchemaErrorOptions = (ErrorOptions & {
|
|
40
|
+
errors: DefinedError[];
|
|
33
41
|
});
|
|
42
|
+
import type { DefinedError } from 'ajv';
|
|
34
43
|
import { BadRequest } from '@darksheep/errors';
|
|
35
44
|
import { InternalServerError } from '@darksheep/errors';
|
|
45
|
+
import type { ErrorOptions } from '@darksheep/errors';
|
package/types/index.d.ts
CHANGED
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
3
|
-
* @typedef {Exclude<import('json-schema-to-ts').JSONSchema, boolean>} JSONSchema
|
|
4
|
-
* @typedef {import('json-schema-to-ts').FromSchemaOptions} FromSchemaOptions
|
|
5
|
-
* @typedef {import('json-schema-to-ts').FromSchemaDefaultOptions} FromSchemaDefaultOptions
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* @template {JSONSchema} Schema
|
|
9
|
-
* @template {FromSchemaOptions} [Options=FromSchemaDefaultOptions]
|
|
10
|
-
* @typedef {import('json-schema-to-ts').FromSchema<Schema, Options>} FromSchema
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* @template {JSONSchema} const Schema - The raw schema type.
|
|
2
|
+
* @template {import('./types.js').JSONSchema} const Schema - The raw schema type.
|
|
14
3
|
* @param {Schema} schema - The raw JSON schema.
|
|
15
4
|
* @returns {Schema}
|
|
16
5
|
*/
|
|
17
|
-
export function defineSchema<const Schema extends JSONSchema>(schema: Schema): Schema;
|
|
18
|
-
export
|
|
19
|
-
export
|
|
20
|
-
export
|
|
21
|
-
export
|
|
22
|
-
export type FromSchema<Schema extends JSONSchema, Options extends FromSchemaOptions = import("json-schema-to-ts").FromSchemaDefaultOptions> = import("json-schema-to-ts").FromSchema<Schema, Options>;
|
|
23
|
-
export { RequestSchemaError, ResponseSchemaError } from "./errors.js";
|
|
24
|
-
export { validateData, validateRequestBody, validateResponseBody } from "./validator.js";
|
|
6
|
+
export function defineSchema<const Schema extends import("./types.js").JSONSchema>(schema: Schema): Schema;
|
|
7
|
+
export * from "./types.js";
|
|
8
|
+
export { isDefinedError, isSchemaError, RequestSchemaError, ResponseSchemaError } from "./errors.js";
|
|
9
|
+
export { createValidator, validate } from "./async.js";
|
|
10
|
+
export { createAssertSchema, assertSchema } from "./sync.js";
|
package/types/sync.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {JSONSchema} schema - The original JSONSchema.
|
|
3
|
+
* @returns {ValidateFunction}
|
|
4
|
+
*/
|
|
5
|
+
export function getValidator(schema: JSONSchema): ValidateFunction;
|
|
6
|
+
/**
|
|
7
|
+
* @template {JSONSchema} const Schema - The raw schema type.
|
|
8
|
+
* @template [Data=FromSchema<Schema>]
|
|
9
|
+
* @param {Schema} schema - The request body json schema.
|
|
10
|
+
* @returns {(data: unknown, TargetError?: TargetError | undefined) => asserts data is Data}
|
|
11
|
+
*/
|
|
12
|
+
export function createAssertSchema<const Schema extends JSONSchema, Data = FromSchema<Schema>>(schema: Schema): (data: unknown, TargetError?: TargetError | undefined) => asserts data is Data;
|
|
13
|
+
/**
|
|
14
|
+
* @template {JSONSchema} const Schema - The raw schema type.
|
|
15
|
+
* @template [Data=FromSchema<Schema>]
|
|
16
|
+
* @param {Schema} schema - The request body json schema.
|
|
17
|
+
* @param {unknown} data - The raw data.
|
|
18
|
+
* @param {TargetError | undefined} [TargetError] - The error type.
|
|
19
|
+
* @returns {asserts data is Data}
|
|
20
|
+
*/
|
|
21
|
+
export function assertSchema<const Schema extends JSONSchema, Data = FromSchema<Schema>>(schema: Schema, data: unknown, TargetError?: TargetError | undefined): asserts data is Data;
|
|
22
|
+
export type ToJsonOptions = ({
|
|
23
|
+
schema: JSONSchema;
|
|
24
|
+
});
|
|
25
|
+
import type { JSONSchema } from './types.js';
|
|
26
|
+
import type { ValidateFunction } from 'ajv';
|
|
27
|
+
import type { FromSchema } from './types.js';
|
|
28
|
+
import type { TargetError } from './types.js';
|
package/types/types.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ValidationError = (Omit<import("ajv").ValidationError, "errors"> & {
|
|
2
|
+
errors: DefinedError[];
|
|
3
|
+
});
|
|
4
|
+
export type TargetError = new (options: {
|
|
5
|
+
cause?: Error;
|
|
6
|
+
errors: DefinedError[];
|
|
7
|
+
}) => Error;
|
|
8
|
+
export type JSONSchema = Exclude<import("json-schema-to-ts").JSONSchema, boolean>;
|
|
9
|
+
export type FromSchemaOptions = import("json-schema-to-ts").FromSchemaOptions;
|
|
10
|
+
export type FromSchemaDefaultOptions = import("json-schema-to-ts").FromSchemaDefaultOptions;
|
|
11
|
+
export type FromSchema<Schema extends JSONSchema, Options extends FromSchemaOptions = import("json-schema-to-ts").FromSchemaDefaultOptions> = import("json-schema-to-ts").FromSchema<Schema, Options>;
|
|
12
|
+
import type { DefinedError } from 'ajv';
|
package/src/validator.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { Ajv } from 'ajv';
|
|
2
|
-
import { RequestSchemaError, ResponseSchemaError } from './errors.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @import { DefinedError, AsyncSchema, AsyncValidateFunction, ValidationError } from 'ajv'
|
|
6
|
-
* @import { FromSchema, JSONSchema } from 'json-schema-to-ts'
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @typedef {(
|
|
11
|
-
* & { schema: JSONSchema }
|
|
12
|
-
* )} ToJsonOptions
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const ajv = new Ajv({
|
|
16
|
-
allErrors: true,
|
|
17
|
-
verbose: false,
|
|
18
|
-
allowUnionTypes: false,
|
|
19
|
-
multipleOfPrecision: 5,
|
|
20
|
-
ownProperties: true,
|
|
21
|
-
strict: true,
|
|
22
|
-
useDefaults: false,
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @type {WeakMap<Exclude<JSONSchema, boolean>, AsyncValidateFunction>}
|
|
27
|
-
*/
|
|
28
|
-
const compiled = new WeakMap();
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @param {unknown} input - The value to check.
|
|
32
|
-
* @returns {input is ValidationError & { errors: DefinedError[] }}
|
|
33
|
-
*/
|
|
34
|
-
function isAjvError(input) {
|
|
35
|
-
return (
|
|
36
|
-
input instanceof Error &&
|
|
37
|
-
'errors' in input &&
|
|
38
|
-
Array.isArray(input.errors)
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @param {Exclude<JSONSchema, boolean>} schema - The original JSONSchema.
|
|
44
|
-
* @returns {AsyncValidateFunction}
|
|
45
|
-
*/
|
|
46
|
-
function getValidator(schema) {
|
|
47
|
-
const Compiled = compiled.get(schema);
|
|
48
|
-
if (Compiled != null) {
|
|
49
|
-
return Compiled;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const validator = ajv.compile(
|
|
53
|
-
/** @type {AsyncSchema} */ ({
|
|
54
|
-
...schema,
|
|
55
|
-
$async: true,
|
|
56
|
-
}),
|
|
57
|
-
);
|
|
58
|
-
compiled.set(schema, validator);
|
|
59
|
-
|
|
60
|
-
return validator;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @template {Exclude<JSONSchema, boolean>} Schema
|
|
65
|
-
* @template [Data=FromSchema<Schema>]
|
|
66
|
-
* @param {Schema} schema - The request body json schema.
|
|
67
|
-
* @param {unknown} data - The data to validate.
|
|
68
|
-
* @returns {Promise<Data>}
|
|
69
|
-
* @throws {ValidationError & { errors: DefinedError[] }}
|
|
70
|
-
*/
|
|
71
|
-
export async function validateData(schema, data) {
|
|
72
|
-
/** @type {AsyncValidateFunction<Data>} */
|
|
73
|
-
const validator = getValidator(schema);
|
|
74
|
-
|
|
75
|
-
return await validator(data);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @template {Exclude<JSONSchema, boolean>} Schema
|
|
80
|
-
* @template [Data=FromSchema<Schema>]
|
|
81
|
-
* @param {Schema} schema - The request body json schema.
|
|
82
|
-
* @param {unknown} data - The data to validate.
|
|
83
|
-
* @returns {Promise<Data>}
|
|
84
|
-
* @throws {RequestSchemaError}
|
|
85
|
-
*/
|
|
86
|
-
export async function validateRequestBody(schema, data) {
|
|
87
|
-
try {
|
|
88
|
-
return await validateData(schema, data);
|
|
89
|
-
} catch (error) {
|
|
90
|
-
if (isAjvError(error)) {
|
|
91
|
-
throw new RequestSchemaError(
|
|
92
|
-
'Request.body does not match Schema',
|
|
93
|
-
{ cause: error, errors: error.errors },
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
throw error;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* @template {Exclude<JSONSchema, boolean>} Schema
|
|
103
|
-
* @template [Data=FromSchema<Schema>]
|
|
104
|
-
* @param {Schema} schema - The response body json schema.
|
|
105
|
-
* @param {unknown} data - The data to validate.
|
|
106
|
-
* @returns {Promise<Data>}
|
|
107
|
-
* @throws {ResponseSchemaError}
|
|
108
|
-
*/
|
|
109
|
-
export async function validateResponseBody(schema, data) {
|
|
110
|
-
try {
|
|
111
|
-
return await validateData(schema, data);
|
|
112
|
-
} catch (error) {
|
|
113
|
-
if (isAjvError(error)) {
|
|
114
|
-
throw new ResponseSchemaError(
|
|
115
|
-
'Response.body does not match Schema',
|
|
116
|
-
{ cause: error, errors: error.errors },
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
throw error;
|
|
121
|
-
}
|
|
122
|
-
}
|
package/types/validator.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @template {Exclude<JSONSchema, boolean>} Schema
|
|
3
|
-
* @template [Data=FromSchema<Schema>]
|
|
4
|
-
* @param {Schema} schema - The request body json schema.
|
|
5
|
-
* @param {unknown} data - The data to validate.
|
|
6
|
-
* @returns {Promise<Data>}
|
|
7
|
-
* @throws {ValidationError & { errors: DefinedError[] }}
|
|
8
|
-
*/
|
|
9
|
-
export function validateData<Schema extends Exclude<JSONSchema, boolean>, Data = FromSchema<Schema>>(schema: Schema, data: unknown): Promise<Data>;
|
|
10
|
-
/**
|
|
11
|
-
* @template {Exclude<JSONSchema, boolean>} Schema
|
|
12
|
-
* @template [Data=FromSchema<Schema>]
|
|
13
|
-
* @param {Schema} schema - The request body json schema.
|
|
14
|
-
* @param {unknown} data - The data to validate.
|
|
15
|
-
* @returns {Promise<Data>}
|
|
16
|
-
* @throws {RequestSchemaError}
|
|
17
|
-
*/
|
|
18
|
-
export function validateRequestBody<Schema extends Exclude<JSONSchema, boolean>, Data = FromSchema<Schema>>(schema: Schema, data: unknown): Promise<Data>;
|
|
19
|
-
/**
|
|
20
|
-
* @template {Exclude<JSONSchema, boolean>} Schema
|
|
21
|
-
* @template [Data=FromSchema<Schema>]
|
|
22
|
-
* @param {Schema} schema - The response body json schema.
|
|
23
|
-
* @param {unknown} data - The data to validate.
|
|
24
|
-
* @returns {Promise<Data>}
|
|
25
|
-
* @throws {ResponseSchemaError}
|
|
26
|
-
*/
|
|
27
|
-
export function validateResponseBody<Schema extends Exclude<JSONSchema, boolean>, Data = FromSchema<Schema>>(schema: Schema, data: unknown): Promise<Data>;
|
|
28
|
-
export type ToJsonOptions = ({
|
|
29
|
-
schema: JSONSchema;
|
|
30
|
-
});
|
|
31
|
-
import type { JSONSchema } from 'json-schema-to-ts';
|
|
32
|
-
import type { FromSchema } from 'json-schema-to-ts';
|