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.
- package/CHANGELOG.md +74 -0
- package/dist/client/create-rpc.d.ts +3 -3
- package/dist/client/create-rpc.js +6 -8
- package/dist/client/default-stream-handler.d.ts +1 -5
- package/dist/client/default-stream-handler.js +53 -45
- package/dist/client/fetcher.d.ts +1 -1
- package/dist/client/fetcher.js +53 -4
- package/dist/client/progressive.d.ts +1 -5
- package/dist/client/progressive.js +19 -9
- package/dist/client/serialize-query.d.ts +0 -11
- package/dist/client/serialize-query.js +4 -28
- package/dist/core/controllers-to-static-params.d.ts +1 -2
- package/dist/core/controllers-to-static-params.js +1 -2
- package/dist/core/create-decorator.d.ts +1 -1
- package/dist/core/decorate.d.ts +2 -6
- package/dist/core/decorators.js +3 -3
- package/dist/core/get-schema.d.ts +1 -1
- package/dist/core/get-schema.js +1 -3
- package/dist/core/http-exception.d.ts +1 -1
- package/dist/core/http-exception.js +1 -1
- package/dist/core/init-segment.js +1 -1
- package/dist/core/json-lines-responder.d.ts +8 -12
- package/dist/core/json-lines-responder.js +42 -20
- package/dist/core/vovk-app.d.ts +1 -1
- package/dist/core/vovk-app.js +62 -16
- package/dist/index.d.ts +16 -18
- package/dist/index.js +14 -15
- package/dist/internal.d.ts +14 -12
- package/dist/internal.js +8 -7
- package/dist/openapi/error.js +2 -2
- package/dist/openapi/openapi-to-vovk-schema/apply-components-schemas.d.ts +1 -12
- package/dist/openapi/openapi-to-vovk-schema/apply-components-schemas.js +4 -10
- package/dist/openapi/openapi-to-vovk-schema/index.d.ts +1 -1
- package/dist/openapi/openapi-to-vovk-schema/index.js +20 -6
- package/dist/openapi/openapi-to-vovk-schema/inline-refs.d.ts +0 -7
- package/dist/openapi/openapi-to-vovk-schema/inline-refs.js +2 -13
- package/dist/openapi/openapi-to-vovk-schema/prune-components-schemas.d.ts +0 -5
- package/dist/openapi/openapi-to-vovk-schema/prune-components-schemas.js +3 -8
- package/dist/openapi/vovk-schema-to-openapi.d.ts +1 -1
- package/dist/openapi/vovk-schema-to-openapi.js +9 -3
- package/dist/req/parse-query.d.ts +0 -23
- package/dist/req/parse-query.js +51 -43
- package/dist/req/validate-content-type.js +1 -1
- package/dist/samples/create-code-samples.d.ts +1 -1
- package/dist/samples/create-code-samples.js +4 -3
- package/dist/samples/schema-to-code.d.ts +1 -1
- package/dist/samples/schema-to-code.js +18 -15
- package/dist/samples/schema-to-object.d.ts +1 -1
- package/dist/samples/schema-to-object.js +18 -15
- package/dist/tools/create-tool-factory.d.ts +2 -2
- package/dist/tools/derive-tools.d.ts +9 -13
- package/dist/tools/derive-tools.js +48 -47
- package/dist/tools/to-model-output-default.d.ts +2 -2
- package/dist/tools/to-model-output-default.js +20 -6
- package/dist/tools/to-model-output-mcp.d.ts +3 -2
- package/dist/tools/to-model-output.d.ts +1 -1
- package/dist/types/client.d.ts +4 -4
- package/dist/types/config.d.ts +5 -6
- package/dist/types/core.d.ts +4 -1
- package/dist/types/enums.d.ts +1 -1
- package/dist/types/enums.js +1 -1
- package/dist/types/inference.d.ts +2 -3
- package/dist/types/request.d.ts +1 -5
- package/dist/types/standard-schema.js +0 -2
- package/dist/types/standard-tool.d.ts +8 -12
- package/dist/types/tools.d.ts +2 -40
- package/dist/types/validation.d.ts +3 -3
- package/dist/utils/camel-case.d.ts +0 -5
- package/dist/utils/camel-case.js +2 -10
- package/dist/utils/deep-extend.d.ts +1 -10
- package/dist/utils/deep-extend.js +16 -4
- package/dist/validation/create-standard-validation.d.ts +3 -126
- package/dist/validation/create-standard-validation.js +2 -3
- package/dist/validation/create-validate-on-client.d.ts +3 -3
- package/dist/validation/json-schema-only-spec.d.ts +14 -0
- package/dist/validation/json-schema-only-spec.js +57 -0
- package/dist/validation/procedure.d.ts +1 -124
- package/dist/validation/validation-schemas-object-to-single-validation-schema.d.ts +0 -9
- package/dist/validation/validation-schemas-object-to-single-validation-schema.js +11 -14
- package/dist/validation/with-validation-library.d.ts +2 -2
- package/dist/validation/with-validation-library.js +11 -5
- package/package.json +3 -10
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsonSchemasObjectToSingleJSONSchemaOnlySpec, jsonSchemaToJSONSchemaOnlySpec, } from '../validation/json-schema-only-spec.js';
|
|
2
2
|
import { validationSchemasObjectToSingleValidationSchema } from '../validation/validation-schemas-object-to-single-validation-schema.js';
|
|
3
|
+
import { ToModelOutput } from './to-model-output.js';
|
|
4
|
+
function isAsyncIterable(value) {
|
|
5
|
+
return typeof value?.[Symbol.asyncIterator] === 'function';
|
|
6
|
+
}
|
|
3
7
|
async function caller({ handler, handlerName, body, query, params, meta, toModelOutput }, tool) {
|
|
4
8
|
if (!handler.isRPC && !handler.fn) {
|
|
5
9
|
throw new Error('Handler is not a valid RPC or controller method');
|
|
@@ -28,10 +32,26 @@ async function caller({ handler, handlerName, body, query, params, meta, toModel
|
|
|
28
32
|
else {
|
|
29
33
|
throw new Error(`Unable to call handler "${handlerName}". It's neither RPC nor controller method with "fn" interface.`);
|
|
30
34
|
}
|
|
31
|
-
|
|
35
|
+
// a streaming handler yields its items, collect them so the model sees data instead of an iterator
|
|
36
|
+
if (isAsyncIterable(result)) {
|
|
37
|
+
const items = [];
|
|
38
|
+
for await (const item of result)
|
|
39
|
+
items.push(item);
|
|
40
|
+
result = items;
|
|
41
|
+
}
|
|
42
|
+
return [
|
|
43
|
+
await toModelOutput(result, tool, req),
|
|
44
|
+
req,
|
|
45
|
+
null,
|
|
46
|
+
];
|
|
32
47
|
}
|
|
33
48
|
catch (e) {
|
|
34
|
-
|
|
49
|
+
// report the error separately, the formatted output is never an Error instance
|
|
50
|
+
return [
|
|
51
|
+
await toModelOutput(e, tool, null),
|
|
52
|
+
null,
|
|
53
|
+
e,
|
|
54
|
+
];
|
|
35
55
|
}
|
|
36
56
|
}
|
|
37
57
|
const makeTool = ({ moduleName, handlerName, module, meta, toModelOutput, onExecute, onError, }) => {
|
|
@@ -43,16 +63,25 @@ const makeTool = ({ moduleName, handlerName, module, meta, toModelOutput, onExec
|
|
|
43
63
|
throw new Error(`Handler "${handlerName}" not found in module "${moduleName}".`);
|
|
44
64
|
}
|
|
45
65
|
const { schema, definition } = handler;
|
|
66
|
+
const name = schema?.operationObject?.['x-tool']?.name ?? `${moduleName}_${handlerName}`;
|
|
46
67
|
const inputSchemas = Object.fromEntries(['body', 'query', 'params'].map((key) => [key, definition?.[key]]).filter(([, value]) => Boolean(value)));
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
// prefer real Standard Schemas from `definition` (procedures); RPC modules only have JSON Schemas
|
|
69
|
+
// in `schema.validation`, so wrap those (envelope-only validate, see json-schema-only-spec.ts)
|
|
70
|
+
const inputSchema = Object.keys(inputSchemas).length > 0
|
|
71
|
+
? validationSchemasObjectToSingleValidationSchema(inputSchemas)
|
|
72
|
+
: jsonSchemasObjectToSingleJSONSchemaOnlySpec({
|
|
73
|
+
schemas: {
|
|
74
|
+
body: schema?.validation?.body,
|
|
75
|
+
query: schema?.validation?.query,
|
|
76
|
+
params: schema?.validation?.params,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
const outputSchema = definition?.output ??
|
|
80
|
+
(schema?.validation?.output ? jsonSchemaToJSONSchemaOnlySpec({ jsonSchema: schema.validation.output }) : undefined);
|
|
51
81
|
const execute = async (input) => {
|
|
52
82
|
const { body, query, params } = input;
|
|
53
83
|
const callerInput = {
|
|
54
84
|
schema,
|
|
55
|
-
inputSchemas,
|
|
56
85
|
handler,
|
|
57
86
|
body,
|
|
58
87
|
query,
|
|
@@ -62,55 +91,32 @@ const makeTool = ({ moduleName, handlerName, module, meta, toModelOutput, onExec
|
|
|
62
91
|
moduleName,
|
|
63
92
|
toModelOutput,
|
|
64
93
|
};
|
|
65
|
-
const [result, req] = await caller(callerInput, tool);
|
|
66
|
-
if (
|
|
67
|
-
onError(
|
|
94
|
+
const [result, req, error] = await caller(callerInput, tool);
|
|
95
|
+
if (error) {
|
|
96
|
+
onError(error, tool, req);
|
|
68
97
|
}
|
|
69
98
|
else {
|
|
70
99
|
onExecute(result, tool, req);
|
|
71
100
|
}
|
|
72
101
|
return result;
|
|
73
102
|
};
|
|
74
|
-
const parametersProperties = {
|
|
75
|
-
...(schema?.validation?.body
|
|
76
|
-
? {
|
|
77
|
-
body: schema.validation.body,
|
|
78
|
-
}
|
|
79
|
-
: {}),
|
|
80
|
-
...(schema?.validation?.query
|
|
81
|
-
? {
|
|
82
|
-
query: schema.validation.query,
|
|
83
|
-
}
|
|
84
|
-
: {}),
|
|
85
|
-
...(schema?.validation?.params
|
|
86
|
-
? {
|
|
87
|
-
params: schema.validation.params,
|
|
88
|
-
}
|
|
89
|
-
: {}),
|
|
90
|
-
};
|
|
91
103
|
const tool = {
|
|
92
|
-
type: 'function',
|
|
93
104
|
execute,
|
|
94
|
-
name
|
|
105
|
+
name,
|
|
95
106
|
inputSchema: inputSchema,
|
|
96
|
-
outputSchema:
|
|
97
|
-
title: schema
|
|
98
|
-
description: schema
|
|
99
|
-
([schema
|
|
107
|
+
outputSchema: outputSchema,
|
|
108
|
+
title: schema?.operationObject?.['x-tool']?.title ?? schema?.operationObject?.summary,
|
|
109
|
+
description: schema?.operationObject?.['x-tool']?.description ??
|
|
110
|
+
([schema?.operationObject?.summary ?? '', schema?.operationObject?.description ?? '']
|
|
111
|
+
.filter(Boolean)
|
|
112
|
+
.join('\n') ||
|
|
100
113
|
handlerName),
|
|
101
|
-
parameters: {
|
|
102
|
-
type: 'object',
|
|
103
|
-
properties: parametersProperties,
|
|
104
|
-
required: Object.keys(parametersProperties),
|
|
105
|
-
additionalProperties: false,
|
|
106
|
-
},
|
|
107
|
-
inputSchemas,
|
|
108
114
|
};
|
|
109
115
|
return tool;
|
|
110
116
|
};
|
|
111
117
|
export function deriveTools(options) {
|
|
112
118
|
const { modules, meta, toModelOutput = ToModelOutput.DEFAULT, onExecute = (result) => result, onError = () => { }, } = options;
|
|
113
|
-
|
|
119
|
+
return Object.entries(modules ?? {}).flatMap(([moduleName, module]) => {
|
|
114
120
|
return Object.entries(module ?? {})
|
|
115
121
|
.filter(([, handler]) => handler?.schema?.operationObject && !handler?.schema?.operationObject?.['x-tool']?.hidden)
|
|
116
122
|
.map(([handlerName]) => makeTool({
|
|
@@ -123,9 +129,4 @@ export function deriveTools(options) {
|
|
|
123
129
|
onError,
|
|
124
130
|
}));
|
|
125
131
|
});
|
|
126
|
-
const toolsByName = Object.fromEntries(tools.map((tool) => [tool.name, tool]));
|
|
127
|
-
return {
|
|
128
|
-
tools,
|
|
129
|
-
toolsByName,
|
|
130
|
-
};
|
|
131
132
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VovkRequest } from '../types/request.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { StandardToolV0 } from '../types/standard-tool.js';
|
|
3
3
|
export type DefaultModelOutput<T> = T | {
|
|
4
4
|
error: string;
|
|
5
5
|
};
|
|
6
|
-
export type ToModelOutputDefaultFn = <TInput, TOutput>(result: TOutput | Error, tool:
|
|
6
|
+
export type ToModelOutputDefaultFn = <TInput, TOutput>(result: TOutput | Error, tool: StandardToolV0<TInput, TOutput, unknown>, req: Pick<VovkRequest, 'vovk'> | null) => Promise<DefaultModelOutput<TOutput>>;
|
|
7
7
|
export declare const toModelOutputDefault: ToModelOutputDefaultFn;
|
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
const toBase64 = (buf) => typeof Buffer !== 'undefined'
|
|
2
|
+
? Buffer.from(buf).toString('base64')
|
|
3
|
+
: btoa([...new Uint8Array(buf)].map((b) => String.fromCharCode(b)).join(''));
|
|
4
|
+
// a Response has no enumerable keys, so handing it to an SDK would serialize it as {} and leave the body unread
|
|
5
|
+
async function responseToData(res) {
|
|
6
|
+
const mimeType = res.headers.get('Content-Type')?.split(';')[0].trim() || '';
|
|
7
|
+
if (mimeType === 'application/json' || mimeType.endsWith('+json')) {
|
|
8
|
+
return res.json();
|
|
9
|
+
}
|
|
10
|
+
if (mimeType.startsWith('text/') || /xml|javascript|yaml/.test(mimeType)) {
|
|
11
|
+
return res.text();
|
|
12
|
+
}
|
|
13
|
+
return { mimeType, data: toBase64(await res.arrayBuffer()) };
|
|
14
|
+
}
|
|
15
|
+
export const toModelOutputDefault = async (result, _tool, _req) => {
|
|
16
|
+
if (result instanceof Error)
|
|
17
|
+
return { error: result.message };
|
|
18
|
+
if (result instanceof Response)
|
|
19
|
+
return (await responseToData(result));
|
|
20
|
+
return result;
|
|
7
21
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { VovkRequest } from '../types/request.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { StandardToolV0 } from '../types/standard-tool.js';
|
|
3
|
+
import type { KnownAny } from '../types/utils.js';
|
|
3
4
|
export type MCPModelOutput = {
|
|
4
5
|
content: [
|
|
5
6
|
{
|
|
@@ -25,6 +26,6 @@ export type MCPModelOutput = {
|
|
|
25
26
|
};
|
|
26
27
|
isError?: boolean;
|
|
27
28
|
};
|
|
28
|
-
type ToModelOutputMCPFn = <TOutput>(result: TOutput | Error, tool:
|
|
29
|
+
type ToModelOutputMCPFn = <TOutput>(result: TOutput | Error, tool: StandardToolV0<KnownAny, KnownAny, KnownAny>, req: Pick<VovkRequest, 'vovk'> | null) => Promise<MCPModelOutput>;
|
|
29
30
|
export declare const toModelOutputMCP: ToModelOutputMCPFn;
|
|
30
31
|
export {};
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const ToModelOutput: {
|
|
6
6
|
readonly DEFAULT: import("./to-model-output-default.js").ToModelOutputDefaultFn;
|
|
7
|
-
readonly MCP: <TOutput>(result: TOutput | Error, tool: import("../
|
|
7
|
+
readonly MCP: <TOutput>(result: TOutput | Error, tool: import("../internal.js").StandardToolV0<import("../types/utils.js").KnownAny, import("../types/utils.js").KnownAny, import("../types/utils.js").KnownAny>, req: Pick<import("../index.js").VovkRequest, "vovk"> | null) => Promise<import("./to-model-output-mcp.js").MCPModelOutput>;
|
|
8
8
|
};
|
package/dist/types/client.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { NextResponse } from 'next/server.js';
|
|
2
|
-
import type { JSONLinesResponder } from '../core/json-lines-responder.js';
|
|
3
|
-
import type { defaultStreamHandler } from '../client/default-stream-handler.js';
|
|
4
2
|
import type { defaultHandler } from '../client/default-handler.js';
|
|
5
|
-
import type {
|
|
3
|
+
import type { defaultStreamHandler } from '../client/default-stream-handler.js';
|
|
4
|
+
import type { JSONLinesResponder } from '../core/json-lines-responder.js';
|
|
6
5
|
import type { ControllerStaticMethod, VovkControllerSchema, VovkHandlerSchema, VovkSchema, VovkSegmentSchema } from './core.js';
|
|
7
|
-
import type { IsEmptyObject, KnownAny, Prettify } from './utils.js';
|
|
8
6
|
import type { HttpMethod } from './enums.js';
|
|
7
|
+
import type { VovkRequest } from './request.js';
|
|
8
|
+
import type { IsEmptyObject, KnownAny, Prettify } from './utils.js';
|
|
9
9
|
import type { BodyTypeFromContentType, ContentType, VovkValidateOnClient } from './validation.js';
|
|
10
10
|
type OmitNullable<T> = {
|
|
11
11
|
[K in keyof T as T[K] extends null | undefined ? never : K]: T[K];
|
package/dist/types/config.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { OpenAPIObject } from 'openapi3-ts/oas31';
|
|
2
|
-
import type { PackageJson } from './package.js';
|
|
3
2
|
import type { HttpMethod, VovkSchemaIdEnum } from './enums.js';
|
|
4
3
|
import type { VovkOperationObject } from './operation.js';
|
|
4
|
+
import type { PackageJson } from './package.js';
|
|
5
5
|
import type { KnownAny, RequireFields } from './utils.js';
|
|
6
6
|
export type VovkPackageJson = PackageJson & {
|
|
7
7
|
rs_name?: string;
|
|
@@ -86,17 +86,16 @@ export interface VovkOpenAPIMixin {
|
|
|
86
86
|
object: OpenAPIObject;
|
|
87
87
|
};
|
|
88
88
|
apiRoot?: string;
|
|
89
|
-
getModuleName?:
|
|
90
|
-
getMethodName?: '
|
|
89
|
+
getModuleName?: (string & {}) | 'api' | GetOpenAPINameFn;
|
|
90
|
+
getMethodName?: 'camel-case-operation-id' | 'auto' | GetOpenAPINameFn;
|
|
91
91
|
/**
|
|
92
92
|
* Keep only operations the predicate returns `true` for; omitted = keep all. Runs before
|
|
93
93
|
* `getModuleName`/`getMethodName`, so a module whose operations are all filtered out is never created.
|
|
94
94
|
*/
|
|
95
95
|
filterOperations?: (config: Parameters<GetOpenAPINameFn>[0]) => boolean;
|
|
96
96
|
/**
|
|
97
|
-
* Prune `meta.openAPIObject.components.schemas` to the
|
|
98
|
-
*
|
|
99
|
-
* components nothing kept references — keep `false` (default) if you import such types directly.
|
|
97
|
+
* Prune `meta.openAPIObject.components.schemas` to the `$ref` closure of kept operations (shrinks big
|
|
98
|
+
* specs); removes unreferenced `Mixins.*` types, keep `false` (default) if you import those directly.
|
|
100
99
|
*/
|
|
101
100
|
pruneComponents?: boolean;
|
|
102
101
|
errorMessageKey?: string;
|
package/dist/types/core.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { OpenAPIObject } from 'openapi3-ts/oas31';
|
|
2
|
+
import type { Responder } from '../core/json-lines-responder.js';
|
|
2
3
|
import type { VovkPackageJson, VovkStrictConfig } from './config.js';
|
|
3
4
|
import type { HttpStatus, VovkSchemaIdEnum } from './enums.js';
|
|
4
5
|
import type { VovkJSONSchemaBase } from './json-schema.js';
|
|
5
6
|
import type { VovkOperationObject } from './operation.js';
|
|
6
7
|
import type { VovkRequest } from './request.js';
|
|
7
8
|
import type { KnownAny, RequireFields, StaticClass } from './utils.js';
|
|
8
|
-
import type { Responder } from '../core/json-lines-responder.js';
|
|
9
9
|
/**
|
|
10
10
|
* Schema for an individual handler, available as MyRPC.myHandler.schema and MyController.myHandler.schema
|
|
11
11
|
*/
|
|
@@ -106,6 +106,9 @@ export type DecoratorOptions = {
|
|
|
106
106
|
};
|
|
107
107
|
export type RouteHandler = ((req: VovkRequest, params: Record<string, string>) => Response | Promise<Response> | Responder | Promise<Responder> | Iterable<unknown> | AsyncIterable<unknown>) & {
|
|
108
108
|
_options?: DecoratorOptions;
|
|
109
|
+
_sourceMethod?: {
|
|
110
|
+
wrapper?: RouteHandler;
|
|
111
|
+
};
|
|
109
112
|
};
|
|
110
113
|
export type ControllerStaticMethod<REQ extends VovkRequest = VovkRequest, TParams extends {
|
|
111
114
|
[key: string]: string;
|
package/dist/types/enums.d.ts
CHANGED
|
@@ -56,7 +56,7 @@ export declare enum HttpStatus {
|
|
|
56
56
|
UNPROCESSABLE_ENTITY = 422,
|
|
57
57
|
FAILED_DEPENDENCY = 424,
|
|
58
58
|
PRECONDITION_REQUIRED = 428,
|
|
59
|
-
|
|
59
|
+
TOO_MANY_REQUESTS = 429,
|
|
60
60
|
INTERNAL_SERVER_ERROR = 500,
|
|
61
61
|
NOT_IMPLEMENTED = 501,
|
|
62
62
|
BAD_GATEWAY = 502,
|
package/dist/types/enums.js
CHANGED
|
@@ -58,7 +58,7 @@ export var HttpStatus;
|
|
|
58
58
|
HttpStatus[HttpStatus["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
|
|
59
59
|
HttpStatus[HttpStatus["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
|
|
60
60
|
HttpStatus[HttpStatus["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
|
|
61
|
-
HttpStatus[HttpStatus["
|
|
61
|
+
HttpStatus[HttpStatus["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
|
|
62
62
|
HttpStatus[HttpStatus["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
|
|
63
63
|
HttpStatus[HttpStatus["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
|
|
64
64
|
HttpStatus[HttpStatus["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
|
|
@@ -113,9 +113,8 @@ type _OmitUndefinedOrUnknown<T> = {
|
|
|
113
113
|
[K in keyof T as unknown extends T[K] ? never : [T[K]] extends [undefined] ? never : K]: T[K];
|
|
114
114
|
};
|
|
115
115
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* Useful for Next.js server actions and other cases where you need all input types at once.
|
|
116
|
+
* Extracts the full input (params, query, body) from both controller and client methods,
|
|
117
|
+
* omitting keys that resolve to `undefined` or `unknown`.
|
|
119
118
|
* @see https://vovk.dev/inference
|
|
120
119
|
* @example
|
|
121
120
|
* ```ts
|
package/dist/types/request.d.ts
CHANGED
|
@@ -8,11 +8,7 @@ export type VovkRequestCookie = {
|
|
|
8
8
|
[key: string]: string;
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
|
-
* The Vovk.ts request object
|
|
12
|
-
* Accepts three generic parameters:
|
|
13
|
-
* - TBody: the expected shape of the request body (default: unknown)
|
|
14
|
-
* - TQuery: the expected shape of the query parameters (default: unknown)
|
|
15
|
-
* - TParams: the expected shape of the route parameters (default: unknown)
|
|
11
|
+
* The Vovk.ts request object extending Next.js's NextRequest, generics: TBody, TQuery, TParams.
|
|
16
12
|
* @see https://vovk.dev/procedure
|
|
17
13
|
*/
|
|
18
14
|
export interface VovkRequest<TBody = unknown, TQuery = unknown, TParams = unknown> extends Request {
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { KnownAny } from './utils.js';
|
|
1
|
+
import type { StandardJSONSchemaV1, StandardSchemaV1 } from './standard-schema.js';
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* (no logic) so `VovkTool` can extend it with zero added dependencies. Kept identical to the
|
|
7
|
-
* `StandardTool` type published by `standard-tool` (`meta` is `KnownAny`, i.e. its `any`).
|
|
3
|
+
* Vendored `standard-tool` type (https://standard-tool.js.org), no dependency, no logic.
|
|
4
|
+
* Keep it identical to the published `StandardToolV0` interface.
|
|
8
5
|
*/
|
|
9
|
-
export interface
|
|
10
|
-
error: string;
|
|
11
|
-
}> {
|
|
6
|
+
export interface StandardToolV0<Input = unknown, Output = unknown, FormattedOutput = Output, Meta = unknown> {
|
|
12
7
|
name: string;
|
|
8
|
+
title?: string;
|
|
13
9
|
description: string;
|
|
14
|
-
inputSchema?:
|
|
15
|
-
outputSchema?:
|
|
16
|
-
execute(input: Input, meta?:
|
|
10
|
+
inputSchema?: StandardSchemaV1<Input> & StandardJSONSchemaV1<Input>;
|
|
11
|
+
outputSchema?: StandardSchemaV1<Output> & StandardJSONSchemaV1<Output>;
|
|
12
|
+
execute(input: Input, meta?: Meta): FormattedOutput | Promise<FormattedOutput>;
|
|
17
13
|
}
|
package/dist/types/tools.d.ts
CHANGED
|
@@ -1,44 +1,6 @@
|
|
|
1
|
-
import type { VovkJSONSchemaBase } from './json-schema.js';
|
|
2
1
|
import type { VovkRequest } from './request.js';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
import type { KnownAny } from './utils.js';
|
|
6
|
-
export type ToModelOutputFn<TInput, TOutput, TFormattedOutput> = (result: TOutput | Error, tool: VovkTool<TInput, TOutput, unknown>, req: Pick<VovkRequest, 'vovk'> | null) => TFormattedOutput | Promise<TFormattedOutput>;
|
|
7
|
-
/**
|
|
8
|
-
* Vovk tool — produced by both `deriveTools` (procedures → tools) and
|
|
9
|
-
* `createTool` (standalone tools); both return the same shape. Extends the
|
|
10
|
-
* {@link StandardTool} convention with Vovk specifics (`title`, `parameters`, `type`).
|
|
11
|
-
* @see https://vovk.dev/tools
|
|
12
|
-
*/
|
|
13
|
-
export interface VovkTool<TInput = KnownAny, TOutput = KnownAny, TFormattedOutput = KnownAny> extends StandardTool<TInput, TOutput, TFormattedOutput> {
|
|
14
|
-
title: string | undefined;
|
|
15
|
-
parameters: {
|
|
16
|
-
type?: 'object';
|
|
17
|
-
properties?: {
|
|
18
|
-
body?: VovkJSONSchemaBase;
|
|
19
|
-
query?: VovkJSONSchemaBase;
|
|
20
|
-
params?: VovkJSONSchemaBase;
|
|
21
|
-
};
|
|
22
|
-
required?: ('body' | 'query' | 'params')[];
|
|
23
|
-
additionalProperties?: false;
|
|
24
|
-
};
|
|
25
|
-
inputSchema: TInput extends undefined ? undefined : CombinedSpec<TInput>;
|
|
26
|
-
outputSchema: TOutput extends undefined ? undefined : CombinedSpec<TOutput>;
|
|
27
|
-
/**
|
|
28
|
-
* Per-slot Standard Schemas, populated only when the tool was built via
|
|
29
|
-
* `deriveTools` from a procedure. Always `undefined` for tools built via
|
|
30
|
-
* `createTool`.
|
|
31
|
-
*
|
|
32
|
-
* @deprecated Use {@link VovkTool.inputSchema} (a merged Standard Schema)
|
|
33
|
-
* instead. This field will be removed in the next major version.
|
|
34
|
-
*/
|
|
35
|
-
inputSchemas?: {
|
|
36
|
-
body?: CombinedSpec;
|
|
37
|
-
query?: CombinedSpec;
|
|
38
|
-
params?: CombinedSpec;
|
|
39
|
-
};
|
|
40
|
-
type: 'function';
|
|
41
|
-
}
|
|
2
|
+
import type { StandardToolV0 } from './standard-tool.js';
|
|
3
|
+
export type ToModelOutputFn<TInput, TOutput, TFormattedOutput> = (result: TOutput | Error, tool: StandardToolV0<TInput, TOutput, unknown>, req: Pick<VovkRequest, 'vovk'> | null) => TFormattedOutput | Promise<TFormattedOutput>;
|
|
42
4
|
export type VovkToolOptions = {
|
|
43
5
|
hidden?: boolean;
|
|
44
6
|
name?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { StandardSchemaV1, StandardJSONSchemaV1 } from './standard-schema.js';
|
|
2
|
-
import type { KnownAny } from './utils.js';
|
|
3
|
-
import type { VovkHandlerSchema, VovkSchema } from './core.js';
|
|
4
1
|
import type { textTypes } from '../req/parse-body.js';
|
|
2
|
+
import type { VovkHandlerSchema, VovkSchema } from './core.js';
|
|
3
|
+
import type { StandardJSONSchemaV1, StandardSchemaV1 } from './standard-schema.js';
|
|
4
|
+
import type { KnownAny } from './utils.js';
|
|
5
5
|
export interface CombinedProps<Input = unknown, Output = Input> extends StandardSchemaV1.Props<Input, Output>, StandardJSONSchemaV1.Props<Input, Output> {
|
|
6
6
|
}
|
|
7
7
|
/**
|
package/dist/utils/camel-case.js
CHANGED
|
@@ -4,19 +4,11 @@ function valToString(value) {
|
|
|
4
4
|
}
|
|
5
5
|
// Regex to match words (including Unicode letters & digits)
|
|
6
6
|
const reUnicodeWord = /[\p{Lu}]{2,}(?=[\p{Lu}][\p{Ll}]+[0-9]*|\b)|[\p{Lu}]?[\p{Ll}]+[0-9]*|[\p{Lu}]|[0-9]+/gu;
|
|
7
|
-
|
|
8
|
-
* Splits string into an array of words based on Unicode word boundaries
|
|
9
|
-
* @param {string} str
|
|
10
|
-
* @returns {string[]}
|
|
11
|
-
*/
|
|
7
|
+
// splits string into words based on Unicode word boundaries
|
|
12
8
|
function unicodeWords(str) {
|
|
13
9
|
return str.match(reUnicodeWord) || [];
|
|
14
10
|
}
|
|
15
|
-
|
|
16
|
-
* Converts string to camel case.
|
|
17
|
-
* @param {*} input - The value to convert to camel case.
|
|
18
|
-
* @returns {string}
|
|
19
|
-
*/
|
|
11
|
+
// converts string to camel case
|
|
20
12
|
export function camelCase(input) {
|
|
21
13
|
const str = valToString(input);
|
|
22
14
|
// replace separators with space
|
|
@@ -36,19 +36,10 @@ declare function cloneSpecificValue(val: SpecificValue): SpecificValue;
|
|
|
36
36
|
*/
|
|
37
37
|
declare function deepCloneArray<T = KnownAny>(arr: T[]): T[];
|
|
38
38
|
declare function safeGetProperty<T extends object>(object: T, property: PropertyKey): KnownAny;
|
|
39
|
-
/**
|
|
40
|
-
* Extending object that entered in first argument.
|
|
41
|
-
*
|
|
42
|
-
* Returns extended object or false if have no target object or incorrect type.
|
|
43
|
-
*
|
|
44
|
-
* If you wish to clone source object (without modify it), just use empty new
|
|
45
|
-
* object as first argument, like this:
|
|
46
|
-
* deepExtend({}, yourObj_1, [yourObj_N]);
|
|
47
|
-
*/
|
|
48
39
|
declare function deepExtend<T extends object>(...args: [T, ...Partial<T>[]]): T;
|
|
49
40
|
declare function deepExtend<T extends object, U extends object>(target: T, source: U): T & U;
|
|
50
41
|
declare function deepExtend<T extends object, U extends object, V extends object>(target: T, source1: U, source2: V): T & U & V;
|
|
51
42
|
declare function deepExtend<T extends object, U extends object, V extends object, W extends object>(target: T, source1: U, source2: V, source3: W): T & U & V & W;
|
|
52
43
|
declare function deepExtend<T extends object>(target: T, ...sources: KnownAny[]): T;
|
|
53
|
-
export { deepExtend, deepCloneArray, isSpecificValue, cloneSpecificValue, safeGetProperty };
|
|
54
44
|
export type { DeepPartial, SpecificValue };
|
|
45
|
+
export { cloneSpecificValue, deepCloneArray, deepExtend, isSpecificValue, safeGetProperty };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
1
|
/*!
|
|
3
2
|
* @description Recursive object extending
|
|
4
3
|
* @author Viacheslav Lotsmanov <lotsmanov89@gmail.com>
|
|
@@ -28,6 +27,11 @@
|
|
|
28
27
|
function isSpecificValue(val) {
|
|
29
28
|
return val instanceof Buffer || val instanceof Date || val instanceof RegExp;
|
|
30
29
|
}
|
|
30
|
+
// class instances like Headers or AbortSignal have no enumerable keys and must not be fake-cloned into {}
|
|
31
|
+
function isPlainObject(val) {
|
|
32
|
+
const proto = Object.getPrototypeOf(val);
|
|
33
|
+
return proto === Object.prototype || proto === null;
|
|
34
|
+
}
|
|
31
35
|
function cloneSpecificValue(val) {
|
|
32
36
|
if (val instanceof Buffer) {
|
|
33
37
|
const x = Buffer.alloc ? Buffer.alloc(val.length) : Buffer.from(val);
|
|
@@ -57,6 +61,9 @@ function deepCloneArray(arr) {
|
|
|
57
61
|
else if (isSpecificValue(item)) {
|
|
58
62
|
clone[index] = cloneSpecificValue(item);
|
|
59
63
|
}
|
|
64
|
+
else if (!isPlainObject(item)) {
|
|
65
|
+
clone[index] = item;
|
|
66
|
+
}
|
|
60
67
|
else {
|
|
61
68
|
clone[index] = deepExtend({}, item);
|
|
62
69
|
}
|
|
@@ -110,8 +117,13 @@ function deepExtend(...args) {
|
|
|
110
117
|
target[key] = cloneSpecificValue(val);
|
|
111
118
|
return;
|
|
112
119
|
}
|
|
113
|
-
//
|
|
114
|
-
else if (
|
|
120
|
+
// pass class instances by reference, cloning by enumerable keys would produce {}
|
|
121
|
+
else if (!isPlainObject(val)) {
|
|
122
|
+
target[key] = val;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// overwrite by new value if source isn't a plain object or is an array
|
|
126
|
+
else if (typeof src !== 'object' || src === null || Array.isArray(src) || !isPlainObject(src)) {
|
|
115
127
|
target[key] = deepExtend({}, val);
|
|
116
128
|
return;
|
|
117
129
|
}
|
|
@@ -124,4 +136,4 @@ function deepExtend(...args) {
|
|
|
124
136
|
});
|
|
125
137
|
return target;
|
|
126
138
|
}
|
|
127
|
-
export {
|
|
139
|
+
export { cloneSpecificValue, deepCloneArray, deepExtend, isSpecificValue, safeGetProperty };
|