vovk 3.0.0-draft.460 → 3.0.0-draft.462

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,24 +1,22 @@
1
- <p align="center">
2
- <picture>
3
- <source width="300" media="(prefers-color-scheme: dark)" srcset="https://vovk.dev/vovk-logo-white.svg">
4
- <source width="300" media="(prefers-color-scheme: light)" srcset="https://vovk.dev/vovk-logo.svg">
5
- <img width="300" alt="vovk" src="https://vovk.dev/vovk-logo.svg">
6
- </picture><br>
7
- <strong>RESTful + RPC = ♥️</strong>
8
- </p>
9
-
10
1
  <p align="center">
11
- Back-end meta-framework for <a href="https://nextjs.org/docs/app">Next.js</a>
2
+ <a href="https://vovk.dev">
3
+ <picture>
4
+ <source width="300" media="(prefers-color-scheme: dark)" srcset="https://vovk.dev/vovk-logo-white.svg">
5
+ <source width="300" media="(prefers-color-scheme: light)" srcset="https://vovk.dev/vovk-logo.svg">
6
+ <img width="300" alt="vovk" src="https://vovk.dev/vovk-logo.svg">
7
+ </picture>
8
+ </a>
9
+ <br>
10
+ <strong>Back-end for <a href="https://nextjs.org/">Next.js</a></strong>
12
11
  </p>
13
12
 
14
13
  ---
15
14
 
16
15
  ## vovk [![npm version](https://badge.fury.io/js/vovk.svg)](https://www.npmjs.com/package/vovk)
17
16
 
18
- The main library with [zero dependencies](https://bundlephobia.com/result?p=vovk) that's going to be used in production. It provides a wrapper for Next.js API routes, internal RPC API, utilities and types.
17
+ The main library with [100% self-composition](https://bundlephobia.com/result?p=vovk) that's going to be used in production. It provides a wrapper for Next.js API routes, client-side RPC tooling, utilities and types.
19
18
 
20
19
  ```sh
21
20
  npm install vovk
22
21
  ```
23
22
 
24
- For more information, please visit the [getting started guide](https://vovk.dev/getting-started) or check out the [Vovk.ts examples](https://vovk-examples.vercel.app/).
@@ -12,8 +12,8 @@ const defaultStreamHandler = ({ response, abortController, }) => {
12
12
  .then((res) => {
13
13
  throw new HttpException_1.HttpException(response.status, res.message ?? exports.DEFAULT_ERROR_MESSAGE);
14
14
  })
15
- .catch(() => {
16
- throw new HttpException_1.HttpException(response.status, exports.DEFAULT_ERROR_MESSAGE);
15
+ .catch((e) => {
16
+ throw new HttpException_1.HttpException(response.status, e.message ?? exports.DEFAULT_ERROR_MESSAGE, e);
17
17
  });
18
18
  // handle server errors
19
19
  }
@@ -1,11 +1,25 @@
1
1
  import type { VovkFetcherOptions, VovkFetcher } from './types';
2
+ import { type VovkHandlerSchema } from '../types';
2
3
  import { HttpException } from '../HttpException';
3
4
  export declare const DEFAULT_ERROR_MESSAGE = "Unknown error at default fetcher";
4
5
  export declare function createFetcher<T>({ prepareRequestInit, transformResponse, onSuccess, onError, }?: {
5
6
  prepareRequestInit?: (init: RequestInit, options: VovkFetcherOptions<T>) => RequestInit | Promise<RequestInit>;
6
- transformResponse?: (respData: unknown, options: VovkFetcherOptions<T>, response: Response, init: RequestInit) => unknown | Promise<unknown>;
7
- onSuccess?: (respData: unknown, options: VovkFetcherOptions<T>, response: Response, init: RequestInit) => void | Promise<void>;
8
- onError?: (error: HttpException, options: VovkFetcherOptions<T>, response: Response | null, init: RequestInit | null, respData: unknown | null) => void | Promise<void>;
7
+ transformResponse?: (respData: unknown, options: VovkFetcherOptions<T>, info: {
8
+ response: Response;
9
+ init: RequestInit;
10
+ schema: VovkHandlerSchema;
11
+ }) => unknown | Promise<unknown>;
12
+ onSuccess?: (respData: unknown, options: VovkFetcherOptions<T>, info: {
13
+ response: Response;
14
+ init: RequestInit;
15
+ schema: VovkHandlerSchema;
16
+ }) => void | Promise<void>;
17
+ onError?: (error: HttpException, options: VovkFetcherOptions<T>, info: {
18
+ response: Response | null;
19
+ init: RequestInit | null;
20
+ respData: unknown | null;
21
+ schema: VovkHandlerSchema;
22
+ }) => void | Promise<void>;
9
23
  }): VovkFetcher<VovkFetcherOptions<T>>;
10
24
  export declare const fetcher: VovkFetcher<{
11
25
  apiRoot?: string;
@@ -83,12 +83,14 @@ function createFetcher({ prepareRequestInit, transformResponse, onSuccess, onErr
83
83
  else {
84
84
  respData = response;
85
85
  }
86
- respData = transformResponse ? await transformResponse(respData, inputOptions, response, requestInit) : respData;
87
- await onSuccess?.(respData, inputOptions, response, requestInit);
86
+ respData = transformResponse
87
+ ? await transformResponse(respData, inputOptions, { response, init: requestInit, schema })
88
+ : respData;
89
+ await onSuccess?.(respData, inputOptions, { response, init: requestInit, schema });
88
90
  return [respData, response];
89
91
  }
90
92
  catch (error) {
91
- await onError?.(error, inputOptions, response, requestInit, respData);
93
+ await onError?.(error, inputOptions, { response, init: requestInit, respData, schema });
92
94
  throw error;
93
95
  }
94
96
  };
package/cjs/types.d.ts CHANGED
@@ -346,9 +346,12 @@ type BundleConfig = {
346
346
  requires?: Record<string, string>;
347
347
  prebundleOutDir?: string;
348
348
  keepPrebundleDir?: boolean;
349
- tsdownBuildOptions?: Parameters<typeof import('tsdown') extends {
350
- build: infer T;
351
- } ? T : never>[0];
349
+ outDir?: string;
350
+ build: (options: {
351
+ outDir: string;
352
+ prebundleDir: string;
353
+ entry: string;
354
+ }) => Promise<void>;
352
355
  generatorConfig?: VovkGeneratorConfig<GeneratorConfigImports>;
353
356
  } & ({
354
357
  excludeSegments?: never;
@@ -4,7 +4,7 @@ export declare function createStandardValidation({ toJSONSchema, }: {
4
4
  toJSONSchema: (model: KnownAny, meta: {
5
5
  type: VovkValidationType;
6
6
  }) => KnownAny;
7
- }): <T extends (req: REQ, params: TParams extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<TParams> : Record<string, string>) => KnownAny, TBody extends StandardSchemaV1, TQuery extends StandardSchemaV1, TParams extends StandardSchemaV1, OUTPUT extends StandardSchemaV1, ITERATION extends StandardSchemaV1, REQ extends VovkRequest<KnownAny, KnownAny, KnownAny> = VovkRequest<TBody extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TBody> : undefined, TQuery extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TQuery> : undefined, TParams extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TParams> : undefined>, IS_FORM extends boolean = false>({ isForm, body, query, params, output, iteration, handle, disableServerSideValidation, skipSchemaEmission, validateEachIteration, operationObject, }: {
7
+ }): <T extends (req: REQ, params: TParams extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<TParams> : Record<string, string>) => KnownAny, TBody extends StandardSchemaV1, TQuery extends StandardSchemaV1, TParams extends StandardSchemaV1, OUTPUT extends StandardSchemaV1, ITERATION extends StandardSchemaV1, REQ extends VovkRequest<KnownAny, KnownAny, KnownAny> = VovkRequest<TBody extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TBody> : undefined, TQuery extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TQuery> : undefined, TParams extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TParams> : undefined>, IS_FORM extends boolean = false>({ isForm, body, query, params, output, iteration, handle, disableServerSideValidation, skipSchemaEmission, validateEachIteration, preferTransformed, operationObject, }: {
8
8
  isForm?: IS_FORM;
9
9
  body?: TBody;
10
10
  query?: TQuery;
@@ -15,6 +15,7 @@ export declare function createStandardValidation({ toJSONSchema, }: {
15
15
  disableServerSideValidation?: boolean | VovkValidationType[];
16
16
  skipSchemaEmission?: boolean | VovkValidationType[];
17
17
  validateEachIteration?: boolean;
18
+ preferTransformed?: boolean;
18
19
  operationObject?: VovkOperationObject;
19
20
  }) => T & {
20
21
  __types: {
@@ -5,7 +5,7 @@ const types_1 = require("../types");
5
5
  const withValidationLibrary_1 = require("./withValidationLibrary");
6
6
  const HttpException_1 = require("../HttpException");
7
7
  function createStandardValidation({ toJSONSchema, }) {
8
- function withStandard({ isForm, body, query, params, output, iteration, handle, disableServerSideValidation, skipSchemaEmission, validateEachIteration, operationObject, }) {
8
+ function withStandard({ isForm, body, query, params, output, iteration, handle, disableServerSideValidation, skipSchemaEmission, validateEachIteration, preferTransformed, operationObject, }) {
9
9
  return (0, withValidationLibrary_1.withValidationLibrary)({
10
10
  isForm,
11
11
  body,
@@ -27,6 +27,7 @@ function createStandardValidation({ toJSONSchema, }) {
27
27
  }
28
28
  return result.value;
29
29
  },
30
+ preferTransformed,
30
31
  operationObject,
31
32
  });
32
33
  }
@@ -4,28 +4,29 @@ type Meta = {
4
4
  __disableClientValidation?: boolean;
5
5
  [key: string]: KnownAny;
6
6
  };
7
- export declare function withValidationLibrary<T extends VovkTypedMethod<(req: KnownAny, params: KnownAny) => KnownAny, KnownAny, KnownAny, KnownAny, KnownAny, KnownAny, boolean>, TBody_MODEL, TQuery_MODEL, TParams_MODEL, OUTPUT_MODEL, ITERATION_MODEL, IS_FORM extends boolean = false>({ isForm, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, operationObject, }: {
8
- isForm?: IS_FORM;
9
- disableServerSideValidation?: boolean | VovkValidationType[];
10
- skipSchemaEmission?: boolean | VovkValidationType[];
11
- validateEachIteration?: boolean;
12
- body?: TBody_MODEL;
13
- query?: TQuery_MODEL;
14
- params?: TParams_MODEL;
15
- output?: OUTPUT_MODEL;
16
- iteration?: ITERATION_MODEL;
7
+ export declare function withValidationLibrary<T extends VovkTypedMethod<(req: KnownAny, params: KnownAny) => KnownAny, KnownAny, KnownAny, KnownAny, KnownAny, KnownAny, boolean>, TBody_MODEL, TQuery_MODEL, TParams_MODEL, OUTPUT_MODEL, ITERATION_MODEL, IS_FORM extends boolean = false>({ isForm, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, preferTransformed, operationObject, }: {
8
+ isForm: IS_FORM | undefined;
9
+ disableServerSideValidation: boolean | VovkValidationType[] | undefined;
10
+ skipSchemaEmission: boolean | VovkValidationType[] | undefined;
11
+ validateEachIteration: boolean | undefined;
12
+ body: TBody_MODEL | undefined;
13
+ query: TQuery_MODEL | undefined;
14
+ params: TParams_MODEL | undefined;
15
+ output: OUTPUT_MODEL | undefined;
16
+ iteration: ITERATION_MODEL | undefined;
17
17
  handle: T;
18
- toJSONSchema?: (model: KnownAny, // performance concern
18
+ toJSONSchema: ((model: KnownAny, // performance concern
19
19
  meta: {
20
20
  type: VovkValidationType;
21
- }) => KnownAny;
21
+ }) => KnownAny) | undefined;
22
22
  validate: (data: KnownAny, model: NonNullable<TBody_MODEL | TQuery_MODEL | TParams_MODEL | OUTPUT_MODEL | ITERATION_MODEL>, meta: {
23
23
  type: VovkValidationType | 'form';
24
24
  req: VovkRequestAny;
25
25
  status?: number;
26
26
  i?: number;
27
27
  }) => KnownAny;
28
- operationObject?: VovkOperationObject;
28
+ preferTransformed: boolean | undefined;
29
+ operationObject: VovkOperationObject | undefined;
29
30
  }): T & {
30
31
  schema: Omit<VovkHandlerSchema, "httpMethod" | "path"> & Partial<VovkHandlerSchema>;
31
32
  wrapper?: (req: VovkRequestAny, params: Parameters<T>[1]) => ReturnType<T>;
@@ -9,7 +9,8 @@ const types_1 = require("../types");
9
9
  const reqMeta_1 = __importDefault(require("./reqMeta"));
10
10
  const setHandlerSchema_1 = require("./setHandlerSchema");
11
11
  const validationTypes = ['body', 'query', 'params', 'output', 'iteration'];
12
- function withValidationLibrary({ isForm, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, operationObject, }) {
12
+ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, preferTransformed, operationObject, }) {
13
+ preferTransformed = preferTransformed ?? true;
13
14
  const disableServerSideValidationKeys = disableServerSideValidation === false
14
15
  ? []
15
16
  : disableServerSideValidation === true
@@ -18,7 +19,7 @@ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchema
18
19
  const skipSchemaEmissionKeys = skipSchemaEmission === false ? [] : skipSchemaEmission === true ? validationTypes : (skipSchemaEmission ?? []);
19
20
  const outputHandler = async (req, handlerParams) => {
20
21
  const { __disableClientValidation } = req.vovk.meta();
21
- let data = await handle(req, handlerParams);
22
+ const data = await handle(req, handlerParams);
22
23
  if (__disableClientValidation) {
23
24
  return data;
24
25
  }
@@ -29,7 +30,8 @@ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchema
29
30
  if (!data) {
30
31
  throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, 'Output is required. You probably forgot to return something from your handler.');
31
32
  }
32
- data = (await validate(data, output, { type: 'output', req })) ?? data;
33
+ const parsed = (await validate(data, output, { type: 'output', req })) ?? data;
34
+ return preferTransformed ? parsed : data;
33
35
  }
34
36
  if (iteration && !disableServerSideValidationKeys.includes('iteration')) {
35
37
  // We assume `data` is an async iterable here; you might want to check that:
@@ -40,11 +42,15 @@ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchema
40
42
  return (async function* () {
41
43
  let i = 0;
42
44
  for await (const item of data) {
45
+ let parsed;
43
46
  if (validateEachIteration || i === 0) {
44
- await validate(item, iteration, { type: 'iteration', req, status: 200, i });
47
+ parsed = (await validate(item, iteration, { type: 'iteration', req, status: 200, i })) ?? item;
48
+ }
49
+ else {
50
+ parsed = item;
45
51
  }
46
52
  i++;
47
- yield item;
53
+ yield preferTransformed ? parsed : item;
48
54
  }
49
55
  })();
50
56
  }
@@ -58,19 +64,22 @@ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchema
58
64
  if (!__disableClientValidation) {
59
65
  if (body && !disableServerSideValidationKeys.includes('body')) {
60
66
  const data = await req.vovk[isForm ? 'form' : 'body']();
61
- const instance = (await validate(data, body, { type: isForm ? 'form' : 'body', req })) ?? data;
67
+ const parsed = (await validate(data, body, { type: isForm ? 'form' : 'body', req })) ?? data;
68
+ const instance = preferTransformed ? parsed : data;
62
69
  // redeclare to add ability to call req.json() and req.vovk.body() again
63
70
  req.json = () => Promise.resolve(data);
64
71
  req.vovk[isForm ? 'form' : 'body'] = () => Promise.resolve(instance);
65
72
  }
66
73
  if (query && !disableServerSideValidationKeys.includes('query')) {
67
74
  const data = req.vovk.query();
68
- const instance = (await validate(data, query, { type: 'query', req })) ?? data;
75
+ const parsed = (await validate(data, query, { type: 'query', req })) ?? data;
76
+ const instance = preferTransformed ? parsed : data;
69
77
  req.vovk.query = () => instance;
70
78
  }
71
79
  if (params && !disableServerSideValidationKeys.includes('params')) {
72
80
  const data = req.vovk.params();
73
- const instance = (await validate(data, params, { type: 'params', req })) ?? data;
81
+ const parsed = (await validate(data, params, { type: 'params', req })) ?? data;
82
+ const instance = preferTransformed ? parsed : data;
74
83
  req.vovk.params = () => instance;
75
84
  }
76
85
  }
@@ -12,8 +12,8 @@ const defaultStreamHandler = ({ response, abortController, }) => {
12
12
  .then((res) => {
13
13
  throw new HttpException_1.HttpException(response.status, res.message ?? exports.DEFAULT_ERROR_MESSAGE);
14
14
  })
15
- .catch(() => {
16
- throw new HttpException_1.HttpException(response.status, exports.DEFAULT_ERROR_MESSAGE);
15
+ .catch((e) => {
16
+ throw new HttpException_1.HttpException(response.status, e.message ?? exports.DEFAULT_ERROR_MESSAGE, e);
17
17
  });
18
18
  // handle server errors
19
19
  }
@@ -1,11 +1,25 @@
1
1
  import type { VovkFetcherOptions, VovkFetcher } from './types';
2
+ import { type VovkHandlerSchema } from '../types';
2
3
  import { HttpException } from '../HttpException';
3
4
  export declare const DEFAULT_ERROR_MESSAGE = "Unknown error at default fetcher";
4
5
  export declare function createFetcher<T>({ prepareRequestInit, transformResponse, onSuccess, onError, }?: {
5
6
  prepareRequestInit?: (init: RequestInit, options: VovkFetcherOptions<T>) => RequestInit | Promise<RequestInit>;
6
- transformResponse?: (respData: unknown, options: VovkFetcherOptions<T>, response: Response, init: RequestInit) => unknown | Promise<unknown>;
7
- onSuccess?: (respData: unknown, options: VovkFetcherOptions<T>, response: Response, init: RequestInit) => void | Promise<void>;
8
- onError?: (error: HttpException, options: VovkFetcherOptions<T>, response: Response | null, init: RequestInit | null, respData: unknown | null) => void | Promise<void>;
7
+ transformResponse?: (respData: unknown, options: VovkFetcherOptions<T>, info: {
8
+ response: Response;
9
+ init: RequestInit;
10
+ schema: VovkHandlerSchema;
11
+ }) => unknown | Promise<unknown>;
12
+ onSuccess?: (respData: unknown, options: VovkFetcherOptions<T>, info: {
13
+ response: Response;
14
+ init: RequestInit;
15
+ schema: VovkHandlerSchema;
16
+ }) => void | Promise<void>;
17
+ onError?: (error: HttpException, options: VovkFetcherOptions<T>, info: {
18
+ response: Response | null;
19
+ init: RequestInit | null;
20
+ respData: unknown | null;
21
+ schema: VovkHandlerSchema;
22
+ }) => void | Promise<void>;
9
23
  }): VovkFetcher<VovkFetcherOptions<T>>;
10
24
  export declare const fetcher: VovkFetcher<{
11
25
  apiRoot?: string;
@@ -83,12 +83,14 @@ function createFetcher({ prepareRequestInit, transformResponse, onSuccess, onErr
83
83
  else {
84
84
  respData = response;
85
85
  }
86
- respData = transformResponse ? await transformResponse(respData, inputOptions, response, requestInit) : respData;
87
- await onSuccess?.(respData, inputOptions, response, requestInit);
86
+ respData = transformResponse
87
+ ? await transformResponse(respData, inputOptions, { response, init: requestInit, schema })
88
+ : respData;
89
+ await onSuccess?.(respData, inputOptions, { response, init: requestInit, schema });
88
90
  return [respData, response];
89
91
  }
90
92
  catch (error) {
91
- await onError?.(error, inputOptions, response, requestInit, respData);
93
+ await onError?.(error, inputOptions, { response, init: requestInit, respData, schema });
92
94
  throw error;
93
95
  }
94
96
  };
package/mjs/types.d.ts CHANGED
@@ -346,9 +346,12 @@ type BundleConfig = {
346
346
  requires?: Record<string, string>;
347
347
  prebundleOutDir?: string;
348
348
  keepPrebundleDir?: boolean;
349
- tsdownBuildOptions?: Parameters<typeof import('tsdown') extends {
350
- build: infer T;
351
- } ? T : never>[0];
349
+ outDir?: string;
350
+ build: (options: {
351
+ outDir: string;
352
+ prebundleDir: string;
353
+ entry: string;
354
+ }) => Promise<void>;
352
355
  generatorConfig?: VovkGeneratorConfig<GeneratorConfigImports>;
353
356
  } & ({
354
357
  excludeSegments?: never;
@@ -4,7 +4,7 @@ export declare function createStandardValidation({ toJSONSchema, }: {
4
4
  toJSONSchema: (model: KnownAny, meta: {
5
5
  type: VovkValidationType;
6
6
  }) => KnownAny;
7
- }): <T extends (req: REQ, params: TParams extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<TParams> : Record<string, string>) => KnownAny, TBody extends StandardSchemaV1, TQuery extends StandardSchemaV1, TParams extends StandardSchemaV1, OUTPUT extends StandardSchemaV1, ITERATION extends StandardSchemaV1, REQ extends VovkRequest<KnownAny, KnownAny, KnownAny> = VovkRequest<TBody extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TBody> : undefined, TQuery extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TQuery> : undefined, TParams extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TParams> : undefined>, IS_FORM extends boolean = false>({ isForm, body, query, params, output, iteration, handle, disableServerSideValidation, skipSchemaEmission, validateEachIteration, operationObject, }: {
7
+ }): <T extends (req: REQ, params: TParams extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<TParams> : Record<string, string>) => KnownAny, TBody extends StandardSchemaV1, TQuery extends StandardSchemaV1, TParams extends StandardSchemaV1, OUTPUT extends StandardSchemaV1, ITERATION extends StandardSchemaV1, REQ extends VovkRequest<KnownAny, KnownAny, KnownAny> = VovkRequest<TBody extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TBody> : undefined, TQuery extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TQuery> : undefined, TParams extends StandardSchemaV1<unknown, unknown> ? StandardSchemaV1.InferOutput<TParams> : undefined>, IS_FORM extends boolean = false>({ isForm, body, query, params, output, iteration, handle, disableServerSideValidation, skipSchemaEmission, validateEachIteration, preferTransformed, operationObject, }: {
8
8
  isForm?: IS_FORM;
9
9
  body?: TBody;
10
10
  query?: TQuery;
@@ -15,6 +15,7 @@ export declare function createStandardValidation({ toJSONSchema, }: {
15
15
  disableServerSideValidation?: boolean | VovkValidationType[];
16
16
  skipSchemaEmission?: boolean | VovkValidationType[];
17
17
  validateEachIteration?: boolean;
18
+ preferTransformed?: boolean;
18
19
  operationObject?: VovkOperationObject;
19
20
  }) => T & {
20
21
  __types: {
@@ -5,7 +5,7 @@ const types_1 = require("../types");
5
5
  const withValidationLibrary_1 = require("./withValidationLibrary");
6
6
  const HttpException_1 = require("../HttpException");
7
7
  function createStandardValidation({ toJSONSchema, }) {
8
- function withStandard({ isForm, body, query, params, output, iteration, handle, disableServerSideValidation, skipSchemaEmission, validateEachIteration, operationObject, }) {
8
+ function withStandard({ isForm, body, query, params, output, iteration, handle, disableServerSideValidation, skipSchemaEmission, validateEachIteration, preferTransformed, operationObject, }) {
9
9
  return (0, withValidationLibrary_1.withValidationLibrary)({
10
10
  isForm,
11
11
  body,
@@ -27,6 +27,7 @@ function createStandardValidation({ toJSONSchema, }) {
27
27
  }
28
28
  return result.value;
29
29
  },
30
+ preferTransformed,
30
31
  operationObject,
31
32
  });
32
33
  }
@@ -4,28 +4,29 @@ type Meta = {
4
4
  __disableClientValidation?: boolean;
5
5
  [key: string]: KnownAny;
6
6
  };
7
- export declare function withValidationLibrary<T extends VovkTypedMethod<(req: KnownAny, params: KnownAny) => KnownAny, KnownAny, KnownAny, KnownAny, KnownAny, KnownAny, boolean>, TBody_MODEL, TQuery_MODEL, TParams_MODEL, OUTPUT_MODEL, ITERATION_MODEL, IS_FORM extends boolean = false>({ isForm, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, operationObject, }: {
8
- isForm?: IS_FORM;
9
- disableServerSideValidation?: boolean | VovkValidationType[];
10
- skipSchemaEmission?: boolean | VovkValidationType[];
11
- validateEachIteration?: boolean;
12
- body?: TBody_MODEL;
13
- query?: TQuery_MODEL;
14
- params?: TParams_MODEL;
15
- output?: OUTPUT_MODEL;
16
- iteration?: ITERATION_MODEL;
7
+ export declare function withValidationLibrary<T extends VovkTypedMethod<(req: KnownAny, params: KnownAny) => KnownAny, KnownAny, KnownAny, KnownAny, KnownAny, KnownAny, boolean>, TBody_MODEL, TQuery_MODEL, TParams_MODEL, OUTPUT_MODEL, ITERATION_MODEL, IS_FORM extends boolean = false>({ isForm, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, preferTransformed, operationObject, }: {
8
+ isForm: IS_FORM | undefined;
9
+ disableServerSideValidation: boolean | VovkValidationType[] | undefined;
10
+ skipSchemaEmission: boolean | VovkValidationType[] | undefined;
11
+ validateEachIteration: boolean | undefined;
12
+ body: TBody_MODEL | undefined;
13
+ query: TQuery_MODEL | undefined;
14
+ params: TParams_MODEL | undefined;
15
+ output: OUTPUT_MODEL | undefined;
16
+ iteration: ITERATION_MODEL | undefined;
17
17
  handle: T;
18
- toJSONSchema?: (model: KnownAny, // performance concern
18
+ toJSONSchema: ((model: KnownAny, // performance concern
19
19
  meta: {
20
20
  type: VovkValidationType;
21
- }) => KnownAny;
21
+ }) => KnownAny) | undefined;
22
22
  validate: (data: KnownAny, model: NonNullable<TBody_MODEL | TQuery_MODEL | TParams_MODEL | OUTPUT_MODEL | ITERATION_MODEL>, meta: {
23
23
  type: VovkValidationType | 'form';
24
24
  req: VovkRequestAny;
25
25
  status?: number;
26
26
  i?: number;
27
27
  }) => KnownAny;
28
- operationObject?: VovkOperationObject;
28
+ preferTransformed: boolean | undefined;
29
+ operationObject: VovkOperationObject | undefined;
29
30
  }): T & {
30
31
  schema: Omit<VovkHandlerSchema, "httpMethod" | "path"> & Partial<VovkHandlerSchema>;
31
32
  wrapper?: (req: VovkRequestAny, params: Parameters<T>[1]) => ReturnType<T>;
@@ -9,7 +9,8 @@ const types_1 = require("../types");
9
9
  const reqMeta_1 = __importDefault(require("./reqMeta"));
10
10
  const setHandlerSchema_1 = require("./setHandlerSchema");
11
11
  const validationTypes = ['body', 'query', 'params', 'output', 'iteration'];
12
- function withValidationLibrary({ isForm, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, operationObject, }) {
12
+ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, preferTransformed, operationObject, }) {
13
+ preferTransformed = preferTransformed ?? true;
13
14
  const disableServerSideValidationKeys = disableServerSideValidation === false
14
15
  ? []
15
16
  : disableServerSideValidation === true
@@ -18,7 +19,7 @@ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchema
18
19
  const skipSchemaEmissionKeys = skipSchemaEmission === false ? [] : skipSchemaEmission === true ? validationTypes : (skipSchemaEmission ?? []);
19
20
  const outputHandler = async (req, handlerParams) => {
20
21
  const { __disableClientValidation } = req.vovk.meta();
21
- let data = await handle(req, handlerParams);
22
+ const data = await handle(req, handlerParams);
22
23
  if (__disableClientValidation) {
23
24
  return data;
24
25
  }
@@ -29,7 +30,8 @@ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchema
29
30
  if (!data) {
30
31
  throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, 'Output is required. You probably forgot to return something from your handler.');
31
32
  }
32
- data = (await validate(data, output, { type: 'output', req })) ?? data;
33
+ const parsed = (await validate(data, output, { type: 'output', req })) ?? data;
34
+ return preferTransformed ? parsed : data;
33
35
  }
34
36
  if (iteration && !disableServerSideValidationKeys.includes('iteration')) {
35
37
  // We assume `data` is an async iterable here; you might want to check that:
@@ -40,11 +42,15 @@ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchema
40
42
  return (async function* () {
41
43
  let i = 0;
42
44
  for await (const item of data) {
45
+ let parsed;
43
46
  if (validateEachIteration || i === 0) {
44
- await validate(item, iteration, { type: 'iteration', req, status: 200, i });
47
+ parsed = (await validate(item, iteration, { type: 'iteration', req, status: 200, i })) ?? item;
48
+ }
49
+ else {
50
+ parsed = item;
45
51
  }
46
52
  i++;
47
- yield item;
53
+ yield preferTransformed ? parsed : item;
48
54
  }
49
55
  })();
50
56
  }
@@ -58,19 +64,22 @@ function withValidationLibrary({ isForm, disableServerSideValidation, skipSchema
58
64
  if (!__disableClientValidation) {
59
65
  if (body && !disableServerSideValidationKeys.includes('body')) {
60
66
  const data = await req.vovk[isForm ? 'form' : 'body']();
61
- const instance = (await validate(data, body, { type: isForm ? 'form' : 'body', req })) ?? data;
67
+ const parsed = (await validate(data, body, { type: isForm ? 'form' : 'body', req })) ?? data;
68
+ const instance = preferTransformed ? parsed : data;
62
69
  // redeclare to add ability to call req.json() and req.vovk.body() again
63
70
  req.json = () => Promise.resolve(data);
64
71
  req.vovk[isForm ? 'form' : 'body'] = () => Promise.resolve(instance);
65
72
  }
66
73
  if (query && !disableServerSideValidationKeys.includes('query')) {
67
74
  const data = req.vovk.query();
68
- const instance = (await validate(data, query, { type: 'query', req })) ?? data;
75
+ const parsed = (await validate(data, query, { type: 'query', req })) ?? data;
76
+ const instance = preferTransformed ? parsed : data;
69
77
  req.vovk.query = () => instance;
70
78
  }
71
79
  if (params && !disableServerSideValidationKeys.includes('params')) {
72
80
  const data = req.vovk.params();
73
- const instance = (await validate(data, params, { type: 'params', req })) ?? data;
81
+ const parsed = (await validate(data, params, { type: 'params', req })) ?? data;
82
+ const instance = preferTransformed ? parsed : data;
74
83
  req.vovk.params = () => instance;
75
84
  }
76
85
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk",
3
- "version": "3.0.0-draft.460",
3
+ "version": "3.0.0-draft.462",
4
4
  "main": "./cjs/index.js",
5
5
  "module": "./mjs/index.js",
6
6
  "types": "./mjs/index.d.ts",