vovk 3.0.0-draft.95 → 3.0.0-draft.96
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/dist/index.d.ts +2 -2
- package/dist/types.d.ts +6 -1
- package/dist/utils/withValidation.d.ts +12 -5
- package/dist/utils/withValidation.js +36 -6
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createVovkApp } from './createVovkApp';
|
|
2
|
-
import { HttpStatus as HttpStatus, HttpMethod as HttpMethod, type KnownAny, type VovkErrorResponse, type VovkRequest, type VovkBody, type VovkQuery, type VovkParams, type VovkReturnType, type VovkYieldType, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkControllerOutput, type VovkSegmentSchema, type VovkControllerSchema, type VovkHandlerSchema, type VovkFullSchema, type VovkConfig, type VovkStrictConfig, type VovkEnv } from './types';
|
|
2
|
+
import { HttpStatus as HttpStatus, HttpMethod as HttpMethod, type KnownAny, type VovkErrorResponse, type VovkRequest, type VovkBody, type VovkQuery, type VovkParams, type VovkReturnType, type VovkYieldType, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkControllerOutput, type VovkSegmentSchema, type VovkControllerSchema, type VovkHandlerSchema, type VovkFullSchema, type VovkConfig, type VovkStrictConfig, type VovkEnv, type VovkValidationType } from './types';
|
|
3
3
|
import { type VovkClient, type VovkClientOptions, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkValidateOnClient, type VovkStreamAsyncIterable, createRPC, fetcher } from './client';
|
|
4
4
|
import { HttpException } from './HttpException';
|
|
5
5
|
import { createDecorator } from './createDecorator';
|
|
6
6
|
import { StreamJSONResponse } from './StreamJSONResponse';
|
|
7
7
|
import { generateStaticAPI } from './utils/generateStaticAPI';
|
|
8
8
|
import { withValidation } from './utils/withValidation';
|
|
9
|
-
export { type KnownAny, type VovkClient, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkStreamAsyncIterable, type VovkValidateOnClient, type VovkSegmentSchema, type VovkErrorResponse, type VovkRequest, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkControllerOutput, type VovkBody, type VovkQuery, type VovkParams, type VovkYieldType, type VovkReturnType, type VovkClientOptions, type VovkControllerSchema, type VovkHandlerSchema, type VovkFullSchema, type VovkConfig, type VovkStrictConfig, type VovkEnv, StreamJSONResponse, HttpException, HttpStatus, HttpMethod, createVovkApp, createDecorator, createRPC, fetcher, generateStaticAPI, withValidation, };
|
|
9
|
+
export { type KnownAny, type VovkClient, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkStreamAsyncIterable, type VovkValidateOnClient, type VovkSegmentSchema, type VovkErrorResponse, type VovkRequest, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkControllerOutput, type VovkBody, type VovkQuery, type VovkParams, type VovkYieldType, type VovkReturnType, type VovkClientOptions, type VovkControllerSchema, type VovkHandlerSchema, type VovkFullSchema, type VovkConfig, type VovkStrictConfig, type VovkEnv, type VovkValidationType, StreamJSONResponse, HttpException, HttpStatus, HttpMethod, createVovkApp, createDecorator, createRPC, fetcher, generateStaticAPI, withValidation, };
|
|
10
10
|
export declare const get: {
|
|
11
11
|
(givenPath?: string | undefined, options?: import("./types").DecoratorOptions | undefined): ReturnType<(givenPath?: string, options?: import("./types").DecoratorOptions) => (givenTarget: KnownAny, propertyKey: string) => void>;
|
|
12
12
|
auto: (options?: import("./types").DecoratorOptions) => (givenTarget: KnownAny, propertyKey: string) => void;
|
package/dist/types.d.ts
CHANGED
|
@@ -10,8 +10,9 @@ export type VovkHandlerSchema = {
|
|
|
10
10
|
validation?: {
|
|
11
11
|
query?: KnownAny;
|
|
12
12
|
body?: KnownAny;
|
|
13
|
-
output?: KnownAny;
|
|
14
13
|
params?: KnownAny;
|
|
14
|
+
output?: KnownAny;
|
|
15
|
+
iteration?: KnownAny;
|
|
15
16
|
};
|
|
16
17
|
openapi?: OperationObject;
|
|
17
18
|
custom?: Record<string, KnownAny>;
|
|
@@ -82,6 +83,9 @@ export type VovkControllerYieldType<T extends (req: VovkRequest<KnownAny, KnownA
|
|
|
82
83
|
export type VovkControllerOutput<T extends ((...args: KnownAny) => KnownAny) & {
|
|
83
84
|
__output?: KnownAny;
|
|
84
85
|
}> = T['__output'];
|
|
86
|
+
export type VovkControllerIteration<T extends ((...args: KnownAny) => KnownAny) & {
|
|
87
|
+
__iteration?: KnownAny;
|
|
88
|
+
}> = T['__iteration'];
|
|
85
89
|
export type VovkBody<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['body'];
|
|
86
90
|
export type VovkQuery<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['query'];
|
|
87
91
|
export type VovkParams<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['params'];
|
|
@@ -150,6 +154,7 @@ export type VovkFullSchema = {
|
|
|
150
154
|
config: Partial<VovkStrictConfig>;
|
|
151
155
|
segments: Record<string, VovkSegmentSchema>;
|
|
152
156
|
};
|
|
157
|
+
export type VovkValidationType = 'body' | 'query' | 'params' | 'output' | 'iteration';
|
|
153
158
|
export declare enum HttpMethod {
|
|
154
159
|
GET = "GET",
|
|
155
160
|
POST = "POST",
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import { VovkHandlerSchema, type KnownAny, type VovkRequest } from '../types';
|
|
2
|
-
export declare function withValidation<T extends (req: KnownAny, params: KnownAny) => KnownAny, BODY_MODEL, QUERY_MODEL, PARAMS_MODEL, OUTPUT_MODEL>({ body, query, params, output, handle, getHandlerSchema, validate, }: {
|
|
1
|
+
import { VovkHandlerSchema, VovkValidationType, type KnownAny, type VovkRequest } from '../types';
|
|
2
|
+
export declare function withValidation<T extends (req: KnownAny, params: KnownAny) => KnownAny, BODY_MODEL, QUERY_MODEL, PARAMS_MODEL, OUTPUT_MODEL, ITERATION_MODEL>({ skipServerSideValidation, skipSchemaEmission, validateEveryIteration, body, query, params, output, iteration, handle, getHandlerSchema, validate, }: {
|
|
3
|
+
skipServerSideValidation?: boolean | VovkValidationType[];
|
|
4
|
+
skipSchemaEmission?: boolean | VovkValidationType[];
|
|
5
|
+
validateEveryIteration?: boolean;
|
|
3
6
|
body?: BODY_MODEL;
|
|
4
7
|
query?: QUERY_MODEL;
|
|
5
8
|
params?: PARAMS_MODEL;
|
|
6
9
|
output?: OUTPUT_MODEL;
|
|
10
|
+
iteration?: ITERATION_MODEL;
|
|
7
11
|
handle: T;
|
|
8
|
-
getHandlerSchema?: (
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
getHandlerSchema?: (options: {
|
|
13
|
+
skipSchemaEmissionKeys: VovkValidationType[];
|
|
14
|
+
}) => Omit<VovkHandlerSchema, 'httpMethod' | 'path'>;
|
|
15
|
+
validate: (data: KnownAny, model: NonNullable<BODY_MODEL | QUERY_MODEL | PARAMS_MODEL | OUTPUT_MODEL | ITERATION_MODEL>, meta: {
|
|
16
|
+
type: VovkValidationType;
|
|
11
17
|
req: VovkRequest<KnownAny, KnownAny>;
|
|
18
|
+
status?: number;
|
|
12
19
|
}) => KnownAny;
|
|
13
20
|
}): T;
|
|
@@ -4,31 +4,61 @@ exports.withValidation = withValidation;
|
|
|
4
4
|
const HttpException_1 = require("../HttpException");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
const setHandlerSchema_1 = require("./setHandlerSchema");
|
|
7
|
-
|
|
7
|
+
const validationTypes = ['body', 'query', 'params', 'output', 'iteration'];
|
|
8
|
+
function withValidation({ skipServerSideValidation, skipSchemaEmission, validateEveryIteration, body, query, params, output, iteration, handle, getHandlerSchema, validate, }) {
|
|
9
|
+
const skipServerSideValidationKeys = skipServerSideValidation === false
|
|
10
|
+
? []
|
|
11
|
+
: skipServerSideValidation === true
|
|
12
|
+
? validationTypes
|
|
13
|
+
: (skipServerSideValidation ?? []);
|
|
14
|
+
const skipSchemaEmissionKeys = skipSchemaEmission === false ? [] : skipSchemaEmission === true ? validationTypes : (skipSchemaEmission ?? []);
|
|
8
15
|
const outputHandler = async (req, handlerParams) => {
|
|
9
16
|
const data = await handle(req, handlerParams);
|
|
10
|
-
if (output) {
|
|
17
|
+
if (output && iteration) {
|
|
18
|
+
throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, "Output and iteration are mutually exclusive. You can't use them together.");
|
|
19
|
+
}
|
|
20
|
+
if (output && !skipServerSideValidationKeys.includes('output')) {
|
|
11
21
|
if (!data) {
|
|
12
22
|
throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, 'Output is required. You probably forgot to return something from your handler.');
|
|
13
23
|
}
|
|
14
24
|
await validate(data, output, { type: 'output', req });
|
|
15
25
|
}
|
|
26
|
+
if (iteration && !skipServerSideValidationKeys.includes('iteration')) {
|
|
27
|
+
// We assume `data` is an async iterable here; you might want to check that:
|
|
28
|
+
if (!data || typeof data[Symbol.asyncIterator] !== 'function') {
|
|
29
|
+
throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, 'Data is not an async iterable but iteration validation is defined.');
|
|
30
|
+
}
|
|
31
|
+
// Return a brand-new async generator that yields validated items
|
|
32
|
+
return (async function* () {
|
|
33
|
+
let i = 0;
|
|
34
|
+
for await (const item of data) {
|
|
35
|
+
if (validateEveryIteration || i === 0) {
|
|
36
|
+
await validate(item, iteration, { type: 'iteration', req, status: 200 });
|
|
37
|
+
}
|
|
38
|
+
i++;
|
|
39
|
+
yield item;
|
|
40
|
+
}
|
|
41
|
+
})();
|
|
42
|
+
}
|
|
43
|
+
else if (validateEveryIteration) {
|
|
44
|
+
throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, 'validateEveryIteration is set but iteration is not defined.');
|
|
45
|
+
}
|
|
16
46
|
return data;
|
|
17
47
|
};
|
|
18
48
|
const resultHandler = async (req, handlerParams) => {
|
|
19
|
-
if (body) {
|
|
49
|
+
if (body && !skipServerSideValidationKeys.includes('body')) {
|
|
20
50
|
const data = await req.json();
|
|
21
51
|
const instance = (await validate(data, body, { type: 'body', req })) ?? data;
|
|
22
52
|
// redeclare to add ability to call req.json() again
|
|
23
53
|
req.json = () => Promise.resolve(data);
|
|
24
54
|
req.vovk.body = () => Promise.resolve(instance);
|
|
25
55
|
}
|
|
26
|
-
if (query) {
|
|
56
|
+
if (query && !skipServerSideValidationKeys.includes('query')) {
|
|
27
57
|
const data = req.vovk.query();
|
|
28
58
|
const instance = (await validate(data, query, { type: 'query', req })) ?? data;
|
|
29
59
|
req.vovk.query = () => instance;
|
|
30
60
|
}
|
|
31
|
-
if (params) {
|
|
61
|
+
if (params && !skipServerSideValidationKeys.includes('params')) {
|
|
32
62
|
const data = req.vovk.params();
|
|
33
63
|
const instance = (await validate(data, params, { type: 'params', req })) ?? data;
|
|
34
64
|
req.vovk.params = () => instance;
|
|
@@ -36,7 +66,7 @@ function withValidation({ body, query, params, output, handle, getHandlerSchema,
|
|
|
36
66
|
return outputHandler(req, handlerParams);
|
|
37
67
|
};
|
|
38
68
|
if (getHandlerSchema) {
|
|
39
|
-
(0, setHandlerSchema_1.setHandlerSchema)(resultHandler, getHandlerSchema());
|
|
69
|
+
(0, setHandlerSchema_1.setHandlerSchema)(resultHandler, getHandlerSchema({ skipSchemaEmissionKeys }));
|
|
40
70
|
}
|
|
41
71
|
return resultHandler;
|
|
42
72
|
}
|
package/package.json
CHANGED