vovk 3.7.0 → 4.0.0-beta.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.
Files changed (82) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/dist/client/create-rpc.d.ts +3 -3
  3. package/dist/client/create-rpc.js +6 -8
  4. package/dist/client/default-stream-handler.d.ts +1 -5
  5. package/dist/client/default-stream-handler.js +53 -45
  6. package/dist/client/fetcher.d.ts +1 -1
  7. package/dist/client/fetcher.js +53 -4
  8. package/dist/client/progressive.d.ts +1 -5
  9. package/dist/client/progressive.js +19 -9
  10. package/dist/client/serialize-query.d.ts +0 -11
  11. package/dist/client/serialize-query.js +4 -28
  12. package/dist/core/controllers-to-static-params.d.ts +1 -2
  13. package/dist/core/controllers-to-static-params.js +1 -2
  14. package/dist/core/create-decorator.d.ts +1 -1
  15. package/dist/core/decorate.d.ts +2 -6
  16. package/dist/core/decorators.js +3 -3
  17. package/dist/core/get-schema.d.ts +1 -1
  18. package/dist/core/get-schema.js +1 -3
  19. package/dist/core/http-exception.d.ts +1 -1
  20. package/dist/core/http-exception.js +1 -1
  21. package/dist/core/init-segment.js +1 -1
  22. package/dist/core/json-lines-responder.d.ts +8 -12
  23. package/dist/core/json-lines-responder.js +42 -20
  24. package/dist/core/vovk-app.d.ts +1 -1
  25. package/dist/core/vovk-app.js +62 -16
  26. package/dist/index.d.ts +16 -18
  27. package/dist/index.js +14 -15
  28. package/dist/internal.d.ts +14 -12
  29. package/dist/internal.js +8 -7
  30. package/dist/openapi/error.js +2 -2
  31. package/dist/openapi/openapi-to-vovk-schema/apply-components-schemas.d.ts +1 -12
  32. package/dist/openapi/openapi-to-vovk-schema/apply-components-schemas.js +4 -10
  33. package/dist/openapi/openapi-to-vovk-schema/index.d.ts +1 -1
  34. package/dist/openapi/openapi-to-vovk-schema/index.js +20 -6
  35. package/dist/openapi/openapi-to-vovk-schema/inline-refs.d.ts +0 -7
  36. package/dist/openapi/openapi-to-vovk-schema/inline-refs.js +2 -13
  37. package/dist/openapi/openapi-to-vovk-schema/prune-components-schemas.d.ts +0 -5
  38. package/dist/openapi/openapi-to-vovk-schema/prune-components-schemas.js +3 -8
  39. package/dist/openapi/vovk-schema-to-openapi.d.ts +1 -1
  40. package/dist/openapi/vovk-schema-to-openapi.js +9 -3
  41. package/dist/req/parse-query.d.ts +0 -23
  42. package/dist/req/parse-query.js +51 -43
  43. package/dist/req/validate-content-type.js +1 -1
  44. package/dist/samples/create-code-samples.d.ts +1 -1
  45. package/dist/samples/create-code-samples.js +4 -3
  46. package/dist/samples/schema-to-code.d.ts +1 -1
  47. package/dist/samples/schema-to-code.js +18 -15
  48. package/dist/samples/schema-to-object.d.ts +1 -1
  49. package/dist/samples/schema-to-object.js +18 -15
  50. package/dist/tools/create-tool-factory.d.ts +2 -2
  51. package/dist/tools/derive-tools.d.ts +9 -13
  52. package/dist/tools/derive-tools.js +48 -47
  53. package/dist/tools/to-model-output-default.d.ts +2 -2
  54. package/dist/tools/to-model-output-default.js +20 -6
  55. package/dist/tools/to-model-output-mcp.d.ts +3 -2
  56. package/dist/tools/to-model-output.d.ts +1 -1
  57. package/dist/types/client.d.ts +4 -4
  58. package/dist/types/config.d.ts +5 -6
  59. package/dist/types/core.d.ts +4 -1
  60. package/dist/types/enums.d.ts +1 -1
  61. package/dist/types/enums.js +1 -1
  62. package/dist/types/inference.d.ts +2 -3
  63. package/dist/types/request.d.ts +1 -5
  64. package/dist/types/standard-schema.js +0 -2
  65. package/dist/types/standard-tool.d.ts +8 -12
  66. package/dist/types/tools.d.ts +2 -40
  67. package/dist/types/validation.d.ts +3 -3
  68. package/dist/utils/camel-case.d.ts +0 -5
  69. package/dist/utils/camel-case.js +2 -10
  70. package/dist/utils/deep-extend.d.ts +1 -10
  71. package/dist/utils/deep-extend.js +16 -4
  72. package/dist/validation/create-standard-validation.d.ts +3 -126
  73. package/dist/validation/create-standard-validation.js +2 -3
  74. package/dist/validation/create-validate-on-client.d.ts +3 -3
  75. package/dist/validation/json-schema-only-spec.d.ts +14 -0
  76. package/dist/validation/json-schema-only-spec.js +57 -0
  77. package/dist/validation/procedure.d.ts +1 -124
  78. package/dist/validation/validation-schemas-object-to-single-validation-schema.d.ts +0 -9
  79. package/dist/validation/validation-schemas-object-to-single-validation-schema.js +11 -14
  80. package/dist/validation/with-validation-library.d.ts +2 -2
  81. package/dist/validation/with-validation-library.js +11 -5
  82. package/package.json +3 -10
@@ -1,8 +1,8 @@
1
- import type { VovkRequest } from '../types/request.js';
2
- import type { BodyTypeFromContentType, CombinedSpec, ContentType, NormalizeContentType } from '../types/validation.js';
3
1
  import type { VovkValidationType } from '../types/core.js';
4
2
  import type { VovkOperationObject } from '../types/operation.js';
3
+ import type { VovkRequest } from '../types/request.js';
5
4
  import type { KnownAny } from '../types/utils.js';
5
+ import type { BodyTypeFromContentType, CombinedSpec, ContentType, NormalizeContentType } from '../types/validation.js';
6
6
  type ProcedureOptions<TBody extends CombinedSpec, TQuery extends CombinedSpec, TParams extends CombinedSpec, TOutput extends CombinedSpec, TIteration extends CombinedSpec, TContentType extends ContentType | ContentType[]> = {
7
7
  contentType?: TContentType;
8
8
  body?: TBody;
@@ -22,7 +22,7 @@ export declare function createStandardValidation({ toJSONSchema, }: {
22
22
  validationType: VovkValidationType;
23
23
  target: CombinedSpec.Target | undefined;
24
24
  }) => KnownAny;
25
- }): (<TBody extends CombinedSpec, TQuery extends CombinedSpec, TParams extends CombinedSpec, TOutput extends CombinedSpec, TIteration extends CombinedSpec, TReq extends VovkRequest<KnownAny, KnownAny, KnownAny> = VovkRequest<TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined, TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined, TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined>, TContentType extends ContentType | ContentType[] = ["application/json"]>(options?: ProcedureOptions<TBody, TQuery, TParams, TOutput, TIteration, TContentType>) => {
25
+ }): <TBody extends CombinedSpec, TQuery extends CombinedSpec, TParams extends CombinedSpec, TOutput extends CombinedSpec, TIteration extends CombinedSpec, TReq extends VovkRequest<KnownAny, KnownAny, KnownAny> = VovkRequest<TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined, TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined, TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined>, TContentType extends ContentType | ContentType[] = ["application/json"]>(options?: ProcedureOptions<TBody, TQuery, TParams, TOutput, TIteration, TContentType>) => {
26
26
  (req: TReq, params: TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : Record<string, string>): KnownAny;
27
27
  __types: {
28
28
  body: TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : any;
@@ -141,128 +141,5 @@ export declare function createStandardValidation({ toJSONSchema, }: {
141
141
  schema: KnownAny;
142
142
  wrapper?: KnownAny;
143
143
  };
144
- }) & {
145
- createTool: {
146
- <TInput, TOutput, TToModelOutput extends (...args: KnownAny[]) => KnownAny>(options: {
147
- name: string;
148
- title?: string;
149
- description: string;
150
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
151
- onError?: ((error: Error, tool: import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
152
- target?: CombinedSpec.Target;
153
- } & {
154
- inputSchema: CombinedSpec<TInput, TInput>;
155
- } & {
156
- outputSchema: CombinedSpec<TOutput, TOutput>;
157
- } & {
158
- execute: (input: TInput, processingMeta?: KnownAny) => TOutput | Promise<TOutput>;
159
- toModelOutput: TToModelOutput;
160
- }): import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>;
161
- <TInput, TOutput>(options: {
162
- name: string;
163
- title?: string;
164
- description: string;
165
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
166
- onError?: ((error: Error, tool: import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
167
- target?: CombinedSpec.Target;
168
- } & {
169
- inputSchema: CombinedSpec<TInput, TInput>;
170
- } & {
171
- outputSchema: CombinedSpec<TOutput, TOutput>;
172
- } & {
173
- execute: (input: TInput, processingMeta?: KnownAny) => TOutput | Promise<TOutput>;
174
- toModelOutput?: undefined;
175
- }): import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>;
176
- <TInput, TOutput, TToModelOutput extends (...args: KnownAny[]) => KnownAny>(options: {
177
- name: string;
178
- title?: string;
179
- description: string;
180
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
181
- onError?: ((error: Error, tool: import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
182
- target?: CombinedSpec.Target;
183
- } & {
184
- inputSchema: CombinedSpec<TInput, TInput>;
185
- } & {
186
- outputSchema?: undefined;
187
- } & {
188
- execute: (input: TInput, processingMeta?: KnownAny) => TOutput | Promise<TOutput>;
189
- toModelOutput: TToModelOutput;
190
- }): import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>;
191
- <TInput, TOutput>(options: {
192
- name: string;
193
- title?: string;
194
- description: string;
195
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
196
- onError?: ((error: Error, tool: import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
197
- target?: CombinedSpec.Target;
198
- } & {
199
- inputSchema: CombinedSpec<TInput, TInput>;
200
- } & {
201
- outputSchema?: undefined;
202
- } & {
203
- execute: (input: TInput, processingMeta?: KnownAny) => TOutput | Promise<TOutput>;
204
- toModelOutput?: undefined;
205
- }): import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>;
206
- <TOutput, TToModelOutput extends (...args: KnownAny[]) => KnownAny>(options: {
207
- name: string;
208
- title?: string;
209
- description: string;
210
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
211
- onError?: ((error: Error, tool: import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
212
- target?: CombinedSpec.Target;
213
- } & {
214
- inputSchema?: undefined;
215
- } & {
216
- outputSchema: CombinedSpec<TOutput, TOutput>;
217
- } & {
218
- execute: (input: null, processingMeta?: KnownAny) => TOutput | Promise<TOutput>;
219
- toModelOutput: TToModelOutput;
220
- }): import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>;
221
- <TOutput>(options: {
222
- name: string;
223
- title?: string;
224
- description: string;
225
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
226
- onError?: ((error: Error, tool: import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
227
- target?: CombinedSpec.Target;
228
- } & {
229
- inputSchema?: undefined;
230
- } & {
231
- outputSchema: CombinedSpec<TOutput, TOutput>;
232
- } & {
233
- execute: (input: null, processingMeta?: KnownAny) => TOutput | Promise<TOutput>;
234
- toModelOutput?: undefined;
235
- }): import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>;
236
- <TOutput, TToModelOutput extends (...args: KnownAny[]) => KnownAny>(options: {
237
- name: string;
238
- title?: string;
239
- description: string;
240
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
241
- onError?: ((error: Error, tool: import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
242
- target?: CombinedSpec.Target;
243
- } & {
244
- inputSchema?: undefined;
245
- } & {
246
- outputSchema?: undefined;
247
- } & {
248
- execute: (input: null, processingMeta?: KnownAny) => TOutput | Promise<TOutput>;
249
- toModelOutput: TToModelOutput;
250
- }): import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>;
251
- <TOutput>(options: {
252
- name: string;
253
- title?: string;
254
- description: string;
255
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
256
- onError?: ((error: Error, tool: import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
257
- target?: CombinedSpec.Target;
258
- } & {
259
- inputSchema?: undefined;
260
- } & {
261
- outputSchema?: undefined;
262
- } & {
263
- execute: (input: null, processingMeta?: KnownAny) => TOutput | Promise<TOutput>;
264
- toModelOutput?: undefined;
265
- }): import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>;
266
- };
267
144
  };
268
145
  export {};
@@ -1,7 +1,6 @@
1
- import { withValidationLibrary } from './with-validation-library.js';
2
1
  import { HttpException } from '../core/http-exception.js';
3
- import { createToolFactory } from '../tools/create-tool-factory.js';
4
2
  import { HttpStatus } from './create-validate-on-client.js';
3
+ import { withValidationLibrary } from './with-validation-library.js';
5
4
  export function createStandardValidation({ toJSONSchema, }) {
6
5
  function callWithValidationLibrary(options, handle) {
7
6
  const normalizedContentType = (typeof options.contentType === 'string' ? [options.contentType] : options.contentType);
@@ -41,5 +40,5 @@ export function createStandardValidation({ toJSONSchema, }) {
41
40
  },
42
41
  });
43
42
  }
44
- return Object.assign(procedure, { createTool: createToolFactory({ toJSONSchema }) });
43
+ return procedure;
45
44
  }
@@ -1,9 +1,9 @@
1
1
  import { HttpException } from '../core/http-exception.js';
2
+ import type { VovkSchema } from '../types/core.js';
2
3
  import { HttpStatus } from '../types/enums.js';
3
- import type { VovkValidateOnClient } from '../types/validation.js';
4
4
  import type { VovkJSONSchemaBase } from '../types/json-schema.js';
5
- import type { VovkSchema } from '../types/core.js';
6
- export { createValidateOnClient, HttpException, HttpStatus, type VovkJSONSchemaBase, type VovkValidateOnClient, type VovkSchema, };
5
+ import type { VovkValidateOnClient } from '../types/validation.js';
6
+ export { createValidateOnClient, HttpException, HttpStatus, type VovkJSONSchemaBase, type VovkSchema, type VovkValidateOnClient, };
7
7
  /**
8
8
  * Creates a validation function for client-side input validation.
9
9
  */
@@ -0,0 +1,14 @@
1
+ import type { VovkJSONSchemaBase } from '../types/json-schema.js';
2
+ import type { CombinedSpec } from '../types/validation.js';
3
+ type JSONSchemasObject = {
4
+ body?: VovkJSONSchemaBase;
5
+ query?: VovkJSONSchemaBase;
6
+ params?: VovkJSONSchemaBase;
7
+ };
8
+ export declare function jsonSchemaToJSONSchemaOnlySpec({ jsonSchema }: {
9
+ jsonSchema: VovkJSONSchemaBase;
10
+ }): CombinedSpec;
11
+ export declare function jsonSchemasObjectToSingleJSONSchemaOnlySpec({ schemas, }: {
12
+ schemas: JSONSchemasObject;
13
+ }): CombinedSpec | undefined;
14
+ export {};
@@ -0,0 +1,57 @@
1
+ const SLOT_KEYS = ['body', 'query', 'params'];
2
+ function makeSpec(jsonSchema, validate) {
3
+ return {
4
+ '~standard': {
5
+ version: 1,
6
+ vendor: 'vovk',
7
+ validate,
8
+ jsonSchema: {
9
+ input: () => jsonSchema,
10
+ output: () => jsonSchema,
11
+ },
12
+ },
13
+ };
14
+ }
15
+ // CombinedSpec from a plain JSON Schema: jsonSchema.input/output return it as is, validate always
16
+ // passes since the real validation happens during tool execution, not here
17
+ export function jsonSchemaToJSONSchemaOnlySpec({ jsonSchema }) {
18
+ return makeSpec(jsonSchema, (value) => ({ value }));
19
+ }
20
+ // Same, but combines body/query/params into one object schema (same envelope as
21
+ // validationSchemasObjectToSingleValidationSchema); validate checks the envelope only
22
+ // (object shape, required slots, unknown keys) and lets slot contents pass
23
+ export function jsonSchemasObjectToSingleJSONSchemaOnlySpec({ schemas, }) {
24
+ const definedEntries = SLOT_KEYS.flatMap((key) => {
25
+ const schema = schemas[key];
26
+ return schema ? [[key, schema]] : [];
27
+ });
28
+ if (definedEntries.length === 0) {
29
+ return undefined;
30
+ }
31
+ const definedSlots = definedEntries.map(([key]) => key);
32
+ const definedSlotSet = new Set(definedSlots);
33
+ const validate = (input) => {
34
+ if (typeof input !== 'object' || input === null || Array.isArray(input)) {
35
+ return { issues: [{ message: 'Expected object', path: [] }] };
36
+ }
37
+ const issues = [];
38
+ const inputRecord = input;
39
+ for (const slot of definedSlots) {
40
+ if (!(slot in inputRecord)) {
41
+ issues.push({ message: 'Required', path: [{ key: slot }] });
42
+ }
43
+ }
44
+ for (const key of Object.keys(inputRecord)) {
45
+ if (!definedSlotSet.has(key)) {
46
+ issues.push({ message: 'Unexpected key', path: [{ key }] });
47
+ }
48
+ }
49
+ return issues.length > 0 ? { issues } : { value: input };
50
+ };
51
+ return makeSpec({
52
+ type: 'object',
53
+ properties: Object.fromEntries(definedEntries),
54
+ required: definedSlots,
55
+ additionalProperties: false,
56
+ }, validate);
57
+ }
@@ -3,7 +3,7 @@ import type { CombinedSpec } from '../types/validation.js';
3
3
  * Procedure function for defining validation schemas for API procedures.
4
4
  * @see https://vovk.dev/procedure
5
5
  */
6
- export declare const procedure: (<TBody extends CombinedSpec, TQuery extends CombinedSpec, TParams extends CombinedSpec, TOutput extends CombinedSpec, TIteration extends CombinedSpec, TReq extends import("../index.js").VovkRequest<import("../types/utils.js").KnownAny, import("../types/utils.js").KnownAny, import("../types/utils.js").KnownAny> = import("../index.js").VovkRequest<TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined, TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined, TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined>, TContentType extends import("../types/validation.js").ContentType | import("../types/validation.js").ContentType[] = ["application/json"]>(options?: {
6
+ export declare const procedure: <TBody extends CombinedSpec, TQuery extends CombinedSpec, TParams extends CombinedSpec, TOutput extends CombinedSpec, TIteration extends CombinedSpec, TReq extends import("../index.js").VovkRequest<import("../types/utils.js").KnownAny, import("../types/utils.js").KnownAny, import("../types/utils.js").KnownAny> = import("../index.js").VovkRequest<TBody extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TBody> : undefined, TQuery extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TQuery> : undefined, TParams extends CombinedSpec<unknown, unknown> ? CombinedSpec.InferOutput<TParams> : undefined>, TContentType extends import("../types/validation.js").ContentType | import("../types/validation.js").ContentType[] = ["application/json"]>(options?: {
7
7
  contentType?: TContentType | undefined;
8
8
  body?: TBody | undefined;
9
9
  query?: TQuery | undefined;
@@ -135,127 +135,4 @@ export declare const procedure: (<TBody extends CombinedSpec, TQuery extends Com
135
135
  schema: import("../types/utils.js").KnownAny;
136
136
  wrapper?: import("../types/utils.js").KnownAny;
137
137
  };
138
- }) & {
139
- createTool: {
140
- <TInput, TOutput, TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => import("../types/utils.js").KnownAny>(options: {
141
- name: string;
142
- title?: string;
143
- description: string;
144
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
145
- onError?: ((error: Error, tool: import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
146
- target?: CombinedSpec.Target;
147
- } & {
148
- inputSchema: CombinedSpec<TInput, TInput>;
149
- } & {
150
- outputSchema: CombinedSpec<TOutput, TOutput>;
151
- } & {
152
- execute: (input: TInput, processingMeta?: import("../types/utils.js").KnownAny) => TOutput | Promise<TOutput>;
153
- toModelOutput: TToModelOutput;
154
- }): import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>;
155
- <TInput, TOutput>(options: {
156
- name: string;
157
- title?: string;
158
- description: string;
159
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
160
- onError?: ((error: Error, tool: import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
161
- target?: CombinedSpec.Target;
162
- } & {
163
- inputSchema: CombinedSpec<TInput, TInput>;
164
- } & {
165
- outputSchema: CombinedSpec<TOutput, TOutput>;
166
- } & {
167
- execute: (input: TInput, processingMeta?: import("../types/utils.js").KnownAny) => TOutput | Promise<TOutput>;
168
- toModelOutput?: undefined;
169
- }): import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>;
170
- <TInput, TOutput, TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => import("../types/utils.js").KnownAny>(options: {
171
- name: string;
172
- title?: string;
173
- description: string;
174
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
175
- onError?: ((error: Error, tool: import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
176
- target?: CombinedSpec.Target;
177
- } & {
178
- inputSchema: CombinedSpec<TInput, TInput>;
179
- } & {
180
- outputSchema?: undefined;
181
- } & {
182
- execute: (input: TInput, processingMeta?: import("../types/utils.js").KnownAny) => TOutput | Promise<TOutput>;
183
- toModelOutput: TToModelOutput;
184
- }): import("../index.js").VovkTool<TInput, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>;
185
- <TInput, TOutput>(options: {
186
- name: string;
187
- title?: string;
188
- description: string;
189
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
190
- onError?: ((error: Error, tool: import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
191
- target?: CombinedSpec.Target;
192
- } & {
193
- inputSchema: CombinedSpec<TInput, TInput>;
194
- } & {
195
- outputSchema?: undefined;
196
- } & {
197
- execute: (input: TInput, processingMeta?: import("../types/utils.js").KnownAny) => TOutput | Promise<TOutput>;
198
- toModelOutput?: undefined;
199
- }): import("../index.js").VovkTool<TInput, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>;
200
- <TOutput, TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => import("../types/utils.js").KnownAny>(options: {
201
- name: string;
202
- title?: string;
203
- description: string;
204
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
205
- onError?: ((error: Error, tool: import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
206
- target?: CombinedSpec.Target;
207
- } & {
208
- inputSchema?: undefined;
209
- } & {
210
- outputSchema: CombinedSpec<TOutput, TOutput>;
211
- } & {
212
- execute: (input: null, processingMeta?: import("../types/utils.js").KnownAny) => TOutput | Promise<TOutput>;
213
- toModelOutput: TToModelOutput;
214
- }): import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>;
215
- <TOutput>(options: {
216
- name: string;
217
- title?: string;
218
- description: string;
219
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
220
- onError?: ((error: Error, tool: import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
221
- target?: CombinedSpec.Target;
222
- } & {
223
- inputSchema?: undefined;
224
- } & {
225
- outputSchema: CombinedSpec<TOutput, TOutput>;
226
- } & {
227
- execute: (input: null, processingMeta?: import("../types/utils.js").KnownAny) => TOutput | Promise<TOutput>;
228
- toModelOutput?: undefined;
229
- }): import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>;
230
- <TOutput, TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => import("../types/utils.js").KnownAny>(options: {
231
- name: string;
232
- title?: string;
233
- description: string;
234
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
235
- onError?: ((error: Error, tool: import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>) => void) | undefined;
236
- target?: CombinedSpec.Target;
237
- } & {
238
- inputSchema?: undefined;
239
- } & {
240
- outputSchema?: undefined;
241
- } & {
242
- execute: (input: null, processingMeta?: import("../types/utils.js").KnownAny) => TOutput | Promise<TOutput>;
243
- toModelOutput: TToModelOutput;
244
- }): import("../index.js").VovkTool<null, TOutput, TToModelOutput extends import("../tools/to-model-output-default.js").ToModelOutputDefaultFn ? import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput> : TToModelOutput extends (...args: import("../types/utils.js").KnownAny[]) => infer R ? R extends Promise<infer U> ? U : R : unknown>;
245
- <TOutput>(options: {
246
- name: string;
247
- title?: string;
248
- description: string;
249
- onExecute?: ((result: unknown, tool: import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
250
- onError?: ((error: Error, tool: import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>) => void) | undefined;
251
- target?: CombinedSpec.Target;
252
- } & {
253
- inputSchema?: undefined;
254
- } & {
255
- outputSchema?: undefined;
256
- } & {
257
- execute: (input: null, processingMeta?: import("../types/utils.js").KnownAny) => TOutput | Promise<TOutput>;
258
- toModelOutput?: undefined;
259
- }): import("../index.js").VovkTool<null, TOutput, import("../tools/to-model-output-default.js").DefaultModelOutput<TOutput>>;
260
- };
261
138
  };
@@ -4,14 +4,5 @@ type SchemasObject = {
4
4
  query?: CombinedSpec;
5
5
  params?: CombinedSpec;
6
6
  };
7
- /**
8
- * Combine optional `body` / `query` / `params` Standard Schemas into a single
9
- * `CombinedSpec` whose `~standard` interface fully conforms to Standard Schema
10
- * + Standard JSON Schema. Top-level validation (object shape, key presence,
11
- * rejection of unknown keys) is handled here; per-slot value validation and
12
- * JSON Schema conversion are delegated to the slot schemas.
13
- *
14
- * Internal helper. Not exported from the public `vovk` entrypoint.
15
- */
16
7
  export declare function validationSchemasObjectToSingleValidationSchema<TSchemas extends SchemasObject>(schemas: TSchemas): CombinedSpec & TSchemas;
17
8
  export {};
@@ -8,17 +8,14 @@ function prefixIssues(issues, slot) {
8
8
  path: [{ key: slot }, ...(issue.path ?? [])],
9
9
  }));
10
10
  }
11
- /**
12
- * Combine optional `body` / `query` / `params` Standard Schemas into a single
13
- * `CombinedSpec` whose `~standard` interface fully conforms to Standard Schema
14
- * + Standard JSON Schema. Top-level validation (object shape, key presence,
15
- * rejection of unknown keys) is handled here; per-slot value validation and
16
- * JSON Schema conversion are delegated to the slot schemas.
17
- *
18
- * Internal helper. Not exported from the public `vovk` entrypoint.
19
- */
11
+ // combines body/query/params Standard Schemas into a single CombinedSpec; top level object
12
+ // shape is validated here, per slot validation and JSON Schema are delegated to slot schemas
20
13
  export function validationSchemasObjectToSingleValidationSchema(schemas) {
21
- const definedSlots = SLOT_KEYS.filter((key) => schemas[key] !== undefined);
14
+ const definedEntries = SLOT_KEYS.flatMap((key) => {
15
+ const schema = schemas[key];
16
+ return schema ? [[key, schema]] : [];
17
+ });
18
+ const definedSlots = definedEntries.map(([key]) => key);
22
19
  const definedSlotSet = new Set(definedSlots);
23
20
  const validate = (input) => {
24
21
  if (typeof input !== 'object' || input === null || Array.isArray(input)) {
@@ -37,9 +34,9 @@ export function validationSchemasObjectToSingleValidationSchema(schemas) {
37
34
  }
38
35
  }
39
36
  const pending = [];
40
- for (const slot of definedSlots) {
37
+ for (const [slot, schema] of definedEntries) {
41
38
  if (slot in inputRecord) {
42
- pending.push({ slot, result: schemas[slot]['~standard'].validate(inputRecord[slot]) });
39
+ pending.push({ slot, result: schema['~standard'].validate(inputRecord[slot]) });
43
40
  }
44
41
  }
45
42
  const combine = (resolved) => {
@@ -62,8 +59,8 @@ export function validationSchemasObjectToSingleValidationSchema(schemas) {
62
59
  };
63
60
  const buildJSONSchema = (options, direction) => {
64
61
  const properties = {};
65
- for (const slot of definedSlots) {
66
- properties[slot] = schemas[slot]['~standard'].jsonSchema?.[direction](options) ?? {};
62
+ for (const [slot, schema] of definedEntries) {
63
+ properties[slot] = schema['~standard'].jsonSchema?.[direction](options) ?? {};
67
64
  }
68
65
  return {
69
66
  type: 'object',
@@ -1,8 +1,8 @@
1
1
  import type { VovkHandlerSchema, VovkValidationType } from '../types/core.js';
2
- import type { VovkRequest } from '../types/request.js';
3
- import type { BodyTypeFromContentType, ContentType, VovkTypedProcedure } from '../types/validation.js';
4
2
  import type { VovkOperationObject } from '../types/operation.js';
3
+ import type { VovkRequest } from '../types/request.js';
5
4
  import type { KnownAny } from '../types/utils.js';
5
+ import type { BodyTypeFromContentType, ContentType, VovkTypedProcedure } from '../types/validation.js';
6
6
  type VovkRequestAny = VovkRequest<KnownAny, KnownAny, KnownAny>;
7
7
  type Meta = {
8
8
  __disableClientValidation?: boolean;
@@ -1,11 +1,11 @@
1
1
  import { HttpException } from '../core/http-exception.js';
2
- import { reqMeta } from '../req/req-meta.js';
3
- import { setHandlerSchema } from '../core/set-handler-schema.js';
4
2
  import { JSONLinesResponder } from '../core/json-lines-responder.js';
5
- import { HttpStatus } from '../types/enums.js';
6
- import { validateContentType } from '../req/validate-content-type.js';
3
+ import { setHandlerSchema } from '../core/set-handler-schema.js';
7
4
  import { bufferBody } from '../req/buffer-body.js';
8
5
  import { parseForm } from '../req/parse-form.js';
6
+ import { reqMeta } from '../req/req-meta.js';
7
+ import { validateContentType } from '../req/validate-content-type.js';
8
+ import { HttpStatus } from '../types/enums.js';
9
9
  const validationTypes = ['body', 'query', 'params', 'output', 'iteration'];
10
10
  export function withValidationLibrary({ contentType, disableServerSideValidation, skipSchemaEmission, validateEachIteration, body, query, params, output, iteration, handle, toJSONSchema, validate, preferTransformed, operationObject, }) {
11
11
  preferTransformed = preferTransformed ?? true;
@@ -25,7 +25,8 @@ export function withValidationLibrary({ contentType, disableServerSideValidation
25
25
  throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR, "Output and iteration are mutually exclusive. You can't use them together.");
26
26
  }
27
27
  if (output && !disableServerSideValidationKeys.includes('output')) {
28
- if (!data) {
28
+ // only undefined means a missing return, falsy values like false or 0 are valid outputs
29
+ if (data === undefined) {
29
30
  throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR, 'Output is required. You probably forgot to return something from your handler.');
30
31
  }
31
32
  const parsed = (await validate(data, output, { validationType: 'output', req })) ?? data;
@@ -73,6 +74,11 @@ export function withValidationLibrary({ contentType, disableServerSideValidation
73
74
  const resultHandler = (async (req, handlerParams) => {
74
75
  const { __disableClientValidation } = req.vovk.meta();
75
76
  if (!__disableClientValidation) {
77
+ // a declared contentType is enforced even with no body schema to validate against,
78
+ // disabling body validation still opts out of it, same as in the body branch below
79
+ if (contentType && !body && !disableServerSideValidationKeys.includes('body')) {
80
+ validateContentType(req, contentType);
81
+ }
76
82
  if (body && !disableServerSideValidationKeys.includes('body')) {
77
83
  if (typeof req.url === 'string')
78
84
  await bufferBody(req); // buffer the body to make it replayable for validation and actual parsing
package/package.json CHANGED
@@ -3,11 +3,12 @@
3
3
  "type": "module",
4
4
  "files": [
5
5
  "dist",
6
- "bin"
6
+ "bin",
7
+ "CHANGELOG.md"
7
8
  ],
8
9
  "main": "./dist/index.js",
9
10
  "types": "./dist/index.d.ts",
10
- "version": "3.7.0",
11
+ "version": "4.0.0-beta.0",
11
12
  "bin": {
12
13
  "vovk-cli-npx": "./bin/index.mjs"
13
14
  },
@@ -31,14 +32,6 @@
31
32
  "./create-validate-on-client": {
32
33
  "types": "./dist/validation/create-validate-on-client.d.ts",
33
34
  "default": "./dist/validation/create-validate-on-client.js"
34
- },
35
- "./createRPC": {
36
- "types": "./dist/client/create-rpc.d.ts",
37
- "default": "./dist/client/create-rpc.js"
38
- },
39
- "./createValidateOnClient": {
40
- "types": "./dist/validation/create-validate-on-client.d.ts",
41
- "default": "./dist/validation/create-validate-on-client.js"
42
35
  }
43
36
  },
44
37
  "description": "Back-end Framework for Next.js App Router",