vovk 3.1.3 → 3.2.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.
@@ -3,29 +3,34 @@ import type { VovkFetcherOptions, VovkFetcher } from '../types/client.js';
3
3
  import type { VovkHandlerSchema } from '../types/core.js';
4
4
  export declare const DEFAULT_ERROR_MESSAGE = "Unknown error at default fetcher";
5
5
  export type { VovkFetcher };
6
+ export type CreateFetcherOnSuccess<T> = (respData: unknown, options: VovkFetcherOptions<T>, info: {
7
+ response: Response;
8
+ init: RequestInit;
9
+ schema: VovkHandlerSchema;
10
+ }) => void | Promise<void>;
11
+ export type CreateFetcherOnError<T> = (error: HttpException, options: VovkFetcherOptions<T>, info: {
12
+ response: Response | null;
13
+ init: RequestInit | null;
14
+ respData: unknown | null;
15
+ schema: VovkHandlerSchema;
16
+ }) => void | Promise<void>;
6
17
  /**
7
18
  * Creates a customizable fetcher function for client requests.
8
19
  * @see https://vovk.dev/imports
9
20
  */
10
- export declare function createFetcher<T>({ prepareRequestInit, transformResponse, onSuccess, onError, }?: {
21
+ export declare function createFetcher<T>({ prepareRequestInit, transformResponse, onSuccess: onSuccessInit, onError: onErrorInit, }?: {
11
22
  prepareRequestInit?: (init: RequestInit, options: VovkFetcherOptions<T>) => RequestInit | Promise<RequestInit>;
12
23
  transformResponse?: (respData: unknown, options: VovkFetcherOptions<T>, info: {
13
24
  response: Response;
14
25
  init: RequestInit;
15
26
  schema: VovkHandlerSchema;
16
27
  }) => unknown | Promise<unknown>;
17
- onSuccess?: (respData: unknown, options: VovkFetcherOptions<T>, info: {
18
- response: Response;
19
- init: RequestInit;
20
- schema: VovkHandlerSchema;
21
- }) => void | Promise<void>;
22
- onError?: (error: HttpException, options: VovkFetcherOptions<T>, info: {
23
- response: Response | null;
24
- init: RequestInit | null;
25
- respData: unknown | null;
26
- schema: VovkHandlerSchema;
27
- }) => void | Promise<void>;
28
- }): VovkFetcher<VovkFetcherOptions<T>>;
28
+ onSuccess?: CreateFetcherOnSuccess<T>;
29
+ onError?: CreateFetcherOnError<T>;
30
+ }): VovkFetcher<VovkFetcherOptions<T>> & {
31
+ onSuccess(cb: CreateFetcherOnSuccess<T>): void;
32
+ onError(cb: CreateFetcherOnError<T>): void;
33
+ };
29
34
  /**
30
35
  * Default fetcher implementation for client requests.
31
36
  * @see https://vovk.dev/imports
@@ -38,4 +43,7 @@ export declare const fetcher: VovkFetcher<{
38
43
  }> | undefined;
39
44
  interpretAs?: string;
40
45
  init?: RequestInit;
41
- }>;
46
+ }> & {
47
+ onSuccess(cb: CreateFetcherOnSuccess<unknown>): void;
48
+ onError(cb: CreateFetcherOnError<unknown>): void;
49
+ };
@@ -6,7 +6,9 @@ export const DEFAULT_ERROR_MESSAGE = 'Unknown error at default fetcher';
6
6
  * Creates a customizable fetcher function for client requests.
7
7
  * @see https://vovk.dev/imports
8
8
  */
9
- export function createFetcher({ prepareRequestInit, transformResponse, onSuccess, onError, } = {}) {
9
+ export function createFetcher({ prepareRequestInit, transformResponse, onSuccess: onSuccessInit, onError: onErrorInit, } = {}) {
10
+ const onSuccessCallbacks = onSuccessInit ? [onSuccessInit] : [];
11
+ const onErrorCallbacks = onErrorInit ? [onErrorInit] : [];
10
12
  // fetcher uses HttpException class to throw errors of fake HTTP status 0 if client-side error occurs
11
13
  // For normal HTTP errors, it uses message and status code from the response of VovkErrorResponse type
12
14
  const newFetcher = async ({ httpMethod, getURL, validate, defaultHandler, defaultStreamHandler, schema }, inputOptions) => {
@@ -112,15 +114,26 @@ export function createFetcher({ prepareRequestInit, transformResponse, onSuccess
112
114
  respData = transformResponse
113
115
  ? await transformResponse(respData, inputOptions, { response, init: requestInit, schema })
114
116
  : respData;
115
- await onSuccess?.(respData, inputOptions, { response, init: requestInit, schema });
117
+ for (const cb of onSuccessCallbacks) {
118
+ await cb(respData, inputOptions, { response, init: requestInit, schema });
119
+ }
116
120
  return [respData, response];
117
121
  }
118
122
  catch (error) {
119
- await onError?.(error, inputOptions, { response, init: requestInit, respData, schema });
123
+ for (const cb of onErrorCallbacks) {
124
+ await cb(error, inputOptions, { response, init: requestInit, respData, schema });
125
+ }
120
126
  throw error;
121
127
  }
122
128
  };
123
- return newFetcher;
129
+ return Object.assign(newFetcher, {
130
+ onSuccess(cb) {
131
+ onSuccessCallbacks.push(cb);
132
+ },
133
+ onError(cb) {
134
+ onErrorCallbacks.push(cb);
135
+ },
136
+ });
124
137
  }
125
138
  /**
126
139
  * Default fetcher implementation for client requests.
package/dist/index.d.ts CHANGED
@@ -16,7 +16,7 @@ export { ToModelOutput } from './tools/ToModelOutput.js';
16
16
  export { createTool } from './tools/createTool.js';
17
17
  export { deriveTools } from './tools/deriveTools.js';
18
18
  export { HttpStatus, HttpMethod } from './types/enums.js';
19
- export type { VovkBody, VovkQuery, VovkParams, VovkReturnType, VovkYieldType, VovkOutput, VovkIteration, } from './types/inference.js';
19
+ export type { VovkBody, VovkQuery, VovkParams, VovkInput, VovkReturnType, VovkYieldType, VovkOutput, VovkIteration, } from './types/inference.js';
20
20
  export type { VovkRequest } from './types/request.js';
21
21
  export type { VovkJSONSchemaBase } from './types/json-schema.js';
22
22
  export type { VovkConfig } from './types/config.js';
@@ -104,6 +104,26 @@ export type VovkParams<T extends (...args: KnownAny[]) => unknown> = T extends {
104
104
  export type VovkYieldType<T extends (...args: KnownAny[]) => unknown> = T extends {
105
105
  isRPC: true;
106
106
  } ? VovkClientYieldType<T> : VovkControllerYieldType<T>;
107
+ type _VovkInputRaw<T extends (...args: KnownAny[]) => unknown> = {
108
+ params: VovkParams<T>;
109
+ query: VovkQuery<T>;
110
+ body: VovkBody<T>;
111
+ };
112
+ type _OmitUndefinedOrUnknown<T> = {
113
+ [K in keyof T as unknown extends T[K] ? never : [T[K]] extends [undefined] ? never : K]: T[K];
114
+ };
115
+ /**
116
+ * Utility type to extract the full input (params, query, body) from both controller and client methods.
117
+ * Only includes properties that are actually defined — omits keys whose types resolve to `undefined` or `unknown`.
118
+ * Useful for Next.js server actions and other cases where you need all input types at once.
119
+ * @see https://vovk.dev/inference
120
+ * @example
121
+ * ```ts
122
+ * type Input = VovkInput<typeof MyController.myMethod>;
123
+ * // { params: { id: string }; query: { search: string }; body: { name: string } }
124
+ * ```
125
+ */
126
+ export type VovkInput<T extends (...args: KnownAny[]) => unknown> = _OmitUndefinedOrUnknown<_VovkInputRaw<T>>;
107
127
  /**
108
128
  * Utility type to extract return type from both controller and client methods
109
129
  * @see https://vovk.dev/inference
@@ -115,3 +135,4 @@ export type VovkYieldType<T extends (...args: KnownAny[]) => unknown> = T extend
115
135
  export type VovkReturnType<T extends (...args: KnownAny) => unknown> = T extends {
116
136
  __handleFn: (...args: KnownAny[]) => infer R;
117
137
  } ? Awaited<R> : Awaited<ReturnType<T>>;
138
+ export {};
@@ -1,5 +1,5 @@
1
1
  import type { VovkRequest } from '../types/request.js';
2
- import type { CombinedSpec, ContentType, NormalizeContentType } from '../types/validation.js';
2
+ import type { BodyTypeFromContentType, CombinedSpec, ContentType, NormalizeContentType } from '../types/validation.js';
3
3
  import type { VovkValidationType } from '../types/core.js';
4
4
  import type { VovkOperationObject } from '../types/operation.js';
5
5
  import type { KnownAny } from '../types/utils.js';
@@ -36,7 +36,7 @@ export declare function createStandardValidation({ toJSONSchema, }: {
36
36
  isRPC?: boolean;
37
37
  fn: {
38
38
  <TTransformed>(input: {
39
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
39
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? BodyTypeFromContentType<NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
40
40
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
41
41
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
42
42
  meta?: Record<string, KnownAny>;
@@ -44,14 +44,14 @@ export declare function createStandardValidation({ toJSONSchema, }: {
44
44
  transform: (data: any, fakeReq: Pick<TReq, "vovk">) => TTransformed;
45
45
  }): Promise<TTransformed>;
46
46
  <TReturnType = any>(input?: {
47
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
47
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? BodyTypeFromContentType<NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
48
48
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
49
49
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
50
50
  meta?: Record<string, KnownAny>;
51
51
  disableClientValidation?: boolean;
52
52
  } | undefined): TReturnType;
53
53
  (input?: {
54
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
54
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? BodyTypeFromContentType<NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
55
55
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
56
56
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
57
57
  meta?: Record<string, KnownAny>;
@@ -76,7 +76,7 @@ export declare function createStandardValidation({ toJSONSchema, }: {
76
76
  isRPC?: boolean;
77
77
  fn: {
78
78
  <TTransformed>(input: {
79
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
79
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? BodyTypeFromContentType<NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
80
80
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
81
81
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
82
82
  meta?: Record<string, KnownAny>;
@@ -84,14 +84,14 @@ export declare function createStandardValidation({ toJSONSchema, }: {
84
84
  transform: (data: Awaited<ReturnType<THandleFn>>, fakeReq: Pick<TReq, "vovk">) => TTransformed;
85
85
  }): Promise<TTransformed>;
86
86
  <TReturnType = ReturnType<THandleFn>>(input?: {
87
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
87
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? BodyTypeFromContentType<NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
88
88
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
89
89
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
90
90
  meta?: Record<string, KnownAny>;
91
91
  disableClientValidation?: boolean;
92
92
  } | undefined): TReturnType;
93
93
  (input?: {
94
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
94
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? BodyTypeFromContentType<NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
95
95
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
96
96
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
97
97
  meta?: Record<string, KnownAny>;
@@ -115,7 +115,7 @@ export declare function createStandardValidation({ toJSONSchema, }: {
115
115
  isRPC?: boolean;
116
116
  fn: {
117
117
  <TTransformed>(input: {
118
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
118
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? BodyTypeFromContentType<NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
119
119
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
120
120
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
121
121
  meta?: Record<string, KnownAny>;
@@ -123,14 +123,14 @@ export declare function createStandardValidation({ toJSONSchema, }: {
123
123
  transform: (data: Awaited<unknown extends CombinedSpec.InferOutput<TOutput> ? any : CombinedSpec.InferOutput<TOutput> | Promise<CombinedSpec.InferOutput<TOutput>> | (unknown extends CombinedSpec.InferOutput<TIteration> ? never : AsyncGenerator<CombinedSpec.InferOutput<TIteration>, any, any>)>, fakeReq: Pick<TReq, "vovk">) => TTransformed;
124
124
  }): Promise<TTransformed>;
125
125
  <TReturnType = unknown extends CombinedSpec.InferOutput<TOutput> ? any : CombinedSpec.InferOutput<TOutput> | Promise<CombinedSpec.InferOutput<TOutput>> | (unknown extends CombinedSpec.InferOutput<TIteration> ? never : AsyncGenerator<CombinedSpec.InferOutput<TIteration>, any, any>)>(input?: {
126
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
126
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? BodyTypeFromContentType<NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
127
127
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
128
128
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
129
129
  meta?: Record<string, KnownAny>;
130
130
  disableClientValidation?: boolean;
131
131
  } | undefined): TReturnType;
132
132
  (input?: {
133
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
133
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? BodyTypeFromContentType<NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
134
134
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
135
135
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
136
136
  meta?: Record<string, KnownAny>;
@@ -30,7 +30,7 @@ export declare const procedure: (<TBody extends CombinedSpec, TQuery extends Com
30
30
  isRPC?: boolean;
31
31
  fn: {
32
32
  <TTransformed>(input: {
33
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
33
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? import("../types/validation.js").BodyTypeFromContentType<import("../types/validation.js").NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
34
34
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
35
35
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
36
36
  meta?: Record<string, import("../types/utils.js").KnownAny>;
@@ -38,14 +38,14 @@ export declare const procedure: (<TBody extends CombinedSpec, TQuery extends Com
38
38
  transform: (data: any, fakeReq: Pick<TReq, "vovk">) => TTransformed;
39
39
  }): Promise<TTransformed>;
40
40
  <TReturnType = any>(input?: {
41
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
41
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? import("../types/validation.js").BodyTypeFromContentType<import("../types/validation.js").NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
42
42
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
43
43
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
44
44
  meta?: Record<string, import("../types/utils.js").KnownAny>;
45
45
  disableClientValidation?: boolean;
46
46
  } | undefined): TReturnType;
47
47
  (input?: {
48
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
48
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? import("../types/validation.js").BodyTypeFromContentType<import("../types/validation.js").NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
49
49
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
50
50
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
51
51
  meta?: Record<string, import("../types/utils.js").KnownAny>;
@@ -70,7 +70,7 @@ export declare const procedure: (<TBody extends CombinedSpec, TQuery extends Com
70
70
  isRPC?: boolean;
71
71
  fn: {
72
72
  <TTransformed>(input: {
73
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
73
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? import("../types/validation.js").BodyTypeFromContentType<import("../types/validation.js").NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
74
74
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
75
75
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
76
76
  meta?: Record<string, import("../types/utils.js").KnownAny>;
@@ -78,14 +78,14 @@ export declare const procedure: (<TBody extends CombinedSpec, TQuery extends Com
78
78
  transform: (data: Awaited<ReturnType<THandleFn>>, fakeReq: Pick<TReq, "vovk">) => TTransformed;
79
79
  }): Promise<TTransformed>;
80
80
  <TReturnType = ReturnType<THandleFn>>(input?: {
81
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
81
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? import("../types/validation.js").BodyTypeFromContentType<import("../types/validation.js").NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
82
82
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
83
83
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
84
84
  meta?: Record<string, import("../types/utils.js").KnownAny>;
85
85
  disableClientValidation?: boolean;
86
86
  } | undefined): TReturnType;
87
87
  (input?: {
88
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
88
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? import("../types/validation.js").BodyTypeFromContentType<import("../types/validation.js").NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
89
89
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
90
90
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
91
91
  meta?: Record<string, import("../types/utils.js").KnownAny>;
@@ -109,7 +109,7 @@ export declare const procedure: (<TBody extends CombinedSpec, TQuery extends Com
109
109
  isRPC?: boolean;
110
110
  fn: {
111
111
  <TTransformed>(input: {
112
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
112
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? import("../types/validation.js").BodyTypeFromContentType<import("../types/validation.js").NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
113
113
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
114
114
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
115
115
  meta?: Record<string, import("../types/utils.js").KnownAny>;
@@ -117,14 +117,14 @@ export declare const procedure: (<TBody extends CombinedSpec, TQuery extends Com
117
117
  transform: (data: Awaited<unknown extends CombinedSpec.InferOutput<TOutput> ? any : CombinedSpec.InferOutput<TOutput> | Promise<CombinedSpec.InferOutput<TOutput>> | (unknown extends CombinedSpec.InferOutput<TIteration> ? never : AsyncGenerator<CombinedSpec.InferOutput<TIteration>, any, any>)>, fakeReq: Pick<TReq, "vovk">) => TTransformed;
118
118
  }): Promise<TTransformed>;
119
119
  <TReturnType = unknown extends CombinedSpec.InferOutput<TOutput> ? any : CombinedSpec.InferOutput<TOutput> | Promise<CombinedSpec.InferOutput<TOutput>> | (unknown extends CombinedSpec.InferOutput<TIteration> ? never : AsyncGenerator<CombinedSpec.InferOutput<TIteration>, any, any>)>(input?: {
120
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
120
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? import("../types/validation.js").BodyTypeFromContentType<import("../types/validation.js").NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
121
121
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
122
122
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
123
123
  meta?: Record<string, import("../types/utils.js").KnownAny>;
124
124
  disableClientValidation?: boolean;
125
125
  } | undefined): TReturnType;
126
126
  (input?: {
127
- body?: (TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined) | undefined;
127
+ body?: (TBody extends CombinedSpec<unknown, unknown> ? import("../types/validation.js").BodyTypeFromContentType<import("../types/validation.js").NormalizeContentType<TContentType>, CombinedSpec.InferOutput<TBody>> : undefined) | undefined;
128
128
  query?: (TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined) | undefined;
129
129
  params?: (TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined) | undefined;
130
130
  meta?: Record<string, import("../types/utils.js").KnownAny>;
@@ -1,6 +1,6 @@
1
1
  import type { VovkHandlerSchema, VovkValidationType } from '../types/core.js';
2
2
  import type { VovkRequest } from '../types/request.js';
3
- import type { ContentType, VovkTypedProcedure } from '../types/validation.js';
3
+ import type { BodyTypeFromContentType, ContentType, VovkTypedProcedure } from '../types/validation.js';
4
4
  import type { VovkOperationObject } from '../types/operation.js';
5
5
  import type { KnownAny } from '../types/utils.js';
6
6
  type VovkRequestAny = VovkRequest<KnownAny, KnownAny, KnownAny>;
@@ -39,9 +39,9 @@ export declare function withValidationLibrary<THandle extends VovkTypedProcedure
39
39
  disableClientValidation?: boolean;
40
40
  transform?: undefined;
41
41
  } & (undefined extends TBodyModel | undefined ? {
42
- body?: THandle["__types"]["body"];
42
+ body?: BodyTypeFromContentType<TContentType, THandle["__types"]["body"]>;
43
43
  } : {
44
- body: THandle["__types"]["body"];
44
+ body: BodyTypeFromContentType<TContentType, THandle["__types"]["body"]>;
45
45
  }) & (undefined extends TQueryModel | undefined ? {
46
46
  query?: THandle["__types"]["query"];
47
47
  } : {
@@ -59,9 +59,9 @@ export declare function withValidationLibrary<THandle extends VovkTypedProcedure
59
59
  disableClientValidation?: boolean;
60
60
  transform?: undefined;
61
61
  } & (undefined extends TBodyModel | undefined ? {
62
- body?: THandle["__types"]["body"];
62
+ body?: BodyTypeFromContentType<TContentType, THandle["__types"]["body"]>;
63
63
  } : {
64
- body: THandle["__types"]["body"];
64
+ body: BodyTypeFromContentType<TContentType, THandle["__types"]["body"]>;
65
65
  }) & (undefined extends TQueryModel | undefined ? {
66
66
  query?: THandle["__types"]["query"];
67
67
  } : {
@@ -77,9 +77,9 @@ export declare function withValidationLibrary<THandle extends VovkTypedProcedure
77
77
  disableClientValidation?: boolean;
78
78
  transform?: undefined;
79
79
  } & (undefined extends TBodyModel | undefined ? {
80
- body?: THandle["__types"]["body"];
80
+ body?: BodyTypeFromContentType<TContentType, THandle["__types"]["body"]>;
81
81
  } : {
82
- body: THandle["__types"]["body"];
82
+ body: BodyTypeFromContentType<TContentType, THandle["__types"]["body"]>;
83
83
  }) & (undefined extends TQueryModel | undefined ? {
84
84
  query?: THandle["__types"]["query"];
85
85
  } : {
@@ -5,6 +5,7 @@ import { JSONLinesResponder } from '../core/JSONLinesResponder.js';
5
5
  import { HttpStatus } from '../types/enums.js';
6
6
  import { validateContentType } from '../req/validateContentType.js';
7
7
  import { bufferBody } from '../req/bufferBody.js';
8
+ import { parseForm } from '../req/parseForm.js';
8
9
  const validationTypes = ['body', 'query', 'params', 'output', 'iteration'];
9
10
  export function withValidationLibrary({ contentType, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, preferTransformed, operationObject, }) {
10
11
  preferTransformed = preferTransformed ?? true;
@@ -97,11 +98,20 @@ export function withValidationLibrary({ contentType, disableServerSideValidation
97
98
  return outputHandler(req, handlerParams);
98
99
  });
99
100
  function fn(input) {
101
+ let bodyCache;
100
102
  const fakeReq = {
101
103
  vovk: {
102
- body: () => Promise.resolve((input?.body ?? {})),
103
- query: () => (input?.query ?? {}),
104
- params: () => (input?.params ?? {}),
104
+ body: () => {
105
+ if (input && input.body instanceof FormData) {
106
+ bodyCache ??= parseForm(input.body);
107
+ }
108
+ else {
109
+ bodyCache = input?.body;
110
+ }
111
+ return Promise.resolve(bodyCache ?? null);
112
+ },
113
+ query: () => input?.query ?? {},
114
+ params: () => input?.params ?? {},
105
115
  meta: (meta) => reqMeta(fakeReq, meta),
106
116
  },
107
117
  };
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  ],
8
8
  "main": "./dist/index.js",
9
9
  "types": "./dist/index.d.ts",
10
- "version": "3.1.3",
10
+ "version": "3.2.0",
11
11
  "bin": {
12
12
  "vovk-cli-npx": "./bin/index.mjs"
13
13
  },