vovk 3.0.0-draft.46 → 3.0.0-draft.460
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/LICENSE +1 -1
- package/README.md +8 -96
- package/bin/index.mjs +8 -0
- package/cjs/JSONLinesResponse.d.ts +19 -0
- package/cjs/JSONLinesResponse.js +95 -0
- package/{VovkApp.d.ts → cjs/VovkApp.d.ts} +14 -8
- package/cjs/VovkApp.js +304 -0
- package/cjs/client/createRPC.d.ts +5 -0
- package/cjs/client/createRPC.js +116 -0
- package/cjs/client/defaultHandler.d.ts +6 -0
- package/{client → cjs/client}/defaultHandler.js +9 -2
- package/cjs/client/defaultStreamHandler.d.ts +9 -0
- package/{client → cjs/client}/defaultStreamHandler.js +49 -26
- package/cjs/client/fetcher.d.ts +18 -0
- package/cjs/client/fetcher.js +97 -0
- package/cjs/client/index.d.ts +4 -0
- package/cjs/client/index.js +10 -0
- package/cjs/client/progressive.d.ts +9 -0
- package/cjs/client/progressive.js +54 -0
- package/cjs/client/types.d.ts +120 -0
- package/{createVovkApp.d.ts → cjs/createVovkApp.d.ts} +19 -16
- package/cjs/createVovkApp.js +146 -0
- package/cjs/index.d.ts +69 -0
- package/cjs/index.js +42 -0
- package/cjs/openapi/error.d.ts +2 -0
- package/cjs/openapi/error.js +100 -0
- package/cjs/openapi/index.d.ts +8 -0
- package/cjs/openapi/index.js +21 -0
- package/cjs/openapi/openAPIToVovkSchema/applyComponentsSchemas.d.ts +3 -0
- package/cjs/openapi/openAPIToVovkSchema/applyComponentsSchemas.js +67 -0
- package/cjs/openapi/openAPIToVovkSchema/index.d.ts +4 -0
- package/cjs/openapi/openAPIToVovkSchema/index.js +141 -0
- package/cjs/openapi/openAPIToVovkSchema/inlineRefs.d.ts +10 -0
- package/cjs/openapi/openAPIToVovkSchema/inlineRefs.js +102 -0
- package/cjs/openapi/vovkSchemaToOpenAPI.d.ts +8 -0
- package/cjs/openapi/vovkSchemaToOpenAPI.js +238 -0
- package/cjs/types.d.ts +466 -0
- package/{types.js → cjs/types.js} +14 -2
- package/cjs/utils/camelCase.d.ts +6 -0
- package/cjs/utils/camelCase.js +37 -0
- package/cjs/utils/createCodeSamples.d.ts +20 -0
- package/cjs/utils/createCodeSamples.js +279 -0
- package/cjs/utils/createDecorator.d.ts +6 -0
- package/{createDecorator.js → cjs/utils/createDecorator.js} +24 -14
- package/cjs/utils/createLLMTools.d.ts +50 -0
- package/cjs/utils/createLLMTools.js +168 -0
- package/cjs/utils/createStandardValidation.d.ts +82 -0
- package/cjs/utils/createStandardValidation.js +34 -0
- package/cjs/utils/createValidateOnClient.d.ts +7 -0
- package/cjs/utils/createValidateOnClient.js +19 -0
- package/cjs/utils/deepExtend.d.ts +54 -0
- package/cjs/utils/deepExtend.js +134 -0
- package/{utils → cjs/utils}/generateStaticAPI.d.ts +2 -2
- package/cjs/utils/generateStaticAPI.js +30 -0
- package/cjs/utils/getJSONSchemaExample.d.ts +11 -0
- package/cjs/utils/getJSONSchemaExample.js +264 -0
- package/cjs/utils/getJSONSchemaSample.d.ts +2 -0
- package/cjs/utils/getJSONSchemaSample.js +167 -0
- package/cjs/utils/getSampleFromObject.d.ts +9 -0
- package/cjs/utils/getSampleFromObject.js +41 -0
- package/cjs/utils/getSchema.d.ts +21 -0
- package/cjs/utils/getSchema.js +38 -0
- package/cjs/utils/multitenant.d.ts +24 -0
- package/cjs/utils/multitenant.js +131 -0
- package/cjs/utils/parseQuery.d.ts +25 -0
- package/cjs/utils/parseQuery.js +156 -0
- package/cjs/utils/reqForm.d.ts +2 -0
- package/cjs/utils/reqForm.js +33 -0
- package/cjs/utils/reqMeta.d.ts +2 -0
- package/cjs/utils/reqQuery.d.ts +2 -0
- package/cjs/utils/reqQuery.js +10 -0
- package/cjs/utils/resolveGeneratorConfigValues.d.ts +18 -0
- package/cjs/utils/resolveGeneratorConfigValues.js +82 -0
- package/cjs/utils/serializeQuery.d.ts +13 -0
- package/cjs/utils/serializeQuery.js +65 -0
- package/cjs/utils/setHandlerSchema.d.ts +4 -0
- package/cjs/utils/setHandlerSchema.js +15 -0
- package/cjs/utils/upperFirst.d.ts +1 -0
- package/cjs/utils/upperFirst.js +6 -0
- package/cjs/utils/withValidationLibrary.d.ts +77 -0
- package/cjs/utils/withValidationLibrary.js +124 -0
- package/mjs/HttpException.d.ts +7 -0
- package/mjs/HttpException.js +15 -0
- package/mjs/JSONLinesResponse.d.ts +19 -0
- package/mjs/JSONLinesResponse.js +95 -0
- package/mjs/VovkApp.d.ts +34 -0
- package/mjs/VovkApp.js +304 -0
- package/mjs/client/createRPC.d.ts +5 -0
- package/mjs/client/createRPC.js +116 -0
- package/mjs/client/defaultHandler.d.ts +6 -0
- package/mjs/client/defaultHandler.js +29 -0
- package/mjs/client/defaultStreamHandler.d.ts +9 -0
- package/mjs/client/defaultStreamHandler.js +105 -0
- package/mjs/client/fetcher.d.ts +18 -0
- package/mjs/client/fetcher.js +97 -0
- package/mjs/client/index.d.ts +4 -0
- package/mjs/client/index.js +10 -0
- package/mjs/client/progressive.d.ts +9 -0
- package/mjs/client/progressive.js +54 -0
- package/mjs/client/types.d.ts +120 -0
- package/mjs/createVovkApp.d.ts +65 -0
- package/mjs/createVovkApp.js +146 -0
- package/mjs/index.d.ts +69 -0
- package/mjs/index.js +42 -0
- package/mjs/openapi/error.d.ts +2 -0
- package/mjs/openapi/error.js +100 -0
- package/mjs/openapi/index.d.ts +8 -0
- package/mjs/openapi/index.js +21 -0
- package/mjs/openapi/openAPIToVovkSchema/applyComponentsSchemas.d.ts +3 -0
- package/mjs/openapi/openAPIToVovkSchema/applyComponentsSchemas.js +67 -0
- package/mjs/openapi/openAPIToVovkSchema/index.d.ts +4 -0
- package/mjs/openapi/openAPIToVovkSchema/index.js +141 -0
- package/mjs/openapi/openAPIToVovkSchema/inlineRefs.d.ts +10 -0
- package/mjs/openapi/openAPIToVovkSchema/inlineRefs.js +102 -0
- package/mjs/openapi/vovkSchemaToOpenAPI.d.ts +8 -0
- package/mjs/openapi/vovkSchemaToOpenAPI.js +238 -0
- package/mjs/types.d.ts +466 -0
- package/mjs/types.js +77 -0
- package/mjs/utils/camelCase.d.ts +6 -0
- package/mjs/utils/camelCase.js +37 -0
- package/mjs/utils/createCodeSamples.d.ts +20 -0
- package/mjs/utils/createCodeSamples.js +279 -0
- package/mjs/utils/createDecorator.d.ts +6 -0
- package/mjs/utils/createDecorator.js +48 -0
- package/mjs/utils/createLLMTools.d.ts +50 -0
- package/mjs/utils/createLLMTools.js +168 -0
- package/mjs/utils/createStandardValidation.d.ts +82 -0
- package/mjs/utils/createStandardValidation.js +34 -0
- package/mjs/utils/createValidateOnClient.d.ts +7 -0
- package/mjs/utils/createValidateOnClient.js +19 -0
- package/mjs/utils/deepExtend.d.ts +54 -0
- package/mjs/utils/deepExtend.js +134 -0
- package/mjs/utils/generateStaticAPI.d.ts +4 -0
- package/mjs/utils/generateStaticAPI.js +30 -0
- package/mjs/utils/getJSONSchemaExample.d.ts +11 -0
- package/mjs/utils/getJSONSchemaExample.js +264 -0
- package/mjs/utils/getJSONSchemaSample.d.ts +2 -0
- package/mjs/utils/getJSONSchemaSample.js +167 -0
- package/mjs/utils/getSampleFromObject.d.ts +9 -0
- package/mjs/utils/getSampleFromObject.js +41 -0
- package/mjs/utils/getSchema.d.ts +21 -0
- package/mjs/utils/getSchema.js +38 -0
- package/mjs/utils/multitenant.d.ts +24 -0
- package/mjs/utils/multitenant.js +131 -0
- package/mjs/utils/parseQuery.d.ts +25 -0
- package/mjs/utils/parseQuery.js +156 -0
- package/mjs/utils/reqForm.d.ts +2 -0
- package/mjs/utils/reqForm.js +33 -0
- package/mjs/utils/reqMeta.d.ts +2 -0
- package/mjs/utils/reqMeta.js +13 -0
- package/mjs/utils/reqQuery.d.ts +2 -0
- package/mjs/utils/reqQuery.js +10 -0
- package/mjs/utils/resolveGeneratorConfigValues.d.ts +18 -0
- package/mjs/utils/resolveGeneratorConfigValues.js +82 -0
- package/mjs/utils/serializeQuery.d.ts +13 -0
- package/mjs/utils/serializeQuery.js +65 -0
- package/mjs/utils/setHandlerSchema.d.ts +4 -0
- package/mjs/utils/setHandlerSchema.js +15 -0
- package/mjs/utils/shim.d.ts +1 -0
- package/mjs/utils/shim.js +18 -0
- package/mjs/utils/upperFirst.d.ts +1 -0
- package/mjs/utils/upperFirst.js +6 -0
- package/mjs/utils/withValidationLibrary.d.ts +77 -0
- package/mjs/utils/withValidationLibrary.js +124 -0
- package/package.json +28 -6
- package/.npmignore +0 -2
- package/StreamJSONResponse.d.ts +0 -17
- package/StreamJSONResponse.js +0 -54
- package/VovkApp.js +0 -185
- package/client/clientizeController.d.ts +0 -4
- package/client/clientizeController.js +0 -93
- package/client/defaultFetcher.d.ts +0 -4
- package/client/defaultFetcher.js +0 -49
- package/client/defaultHandler.d.ts +0 -2
- package/client/defaultStreamHandler.d.ts +0 -4
- package/client/index.d.ts +0 -4
- package/client/index.js +0 -5
- package/client/types.d.ts +0 -100
- package/createDecorator.d.ts +0 -4
- package/createVovkApp.js +0 -118
- package/index.d.ts +0 -60
- package/index.js +0 -20
- package/types.d.ts +0 -157
- package/utils/generateStaticAPI.js +0 -18
- package/utils/getSchema.d.ts +0 -8
- package/utils/getSchema.js +0 -38
- package/utils/reqForm.d.ts +0 -3
- package/utils/reqForm.js +0 -13
- package/utils/reqMeta.d.ts +0 -3
- package/utils/reqQuery.d.ts +0 -3
- package/utils/reqQuery.js +0 -25
- package/utils/setClientValidatorsForHandler.d.ts +0 -5
- package/utils/setClientValidatorsForHandler.js +0 -25
- package/worker/index.d.ts +0 -3
- package/worker/index.js +0 -7
- package/worker/promisifyWorker.d.ts +0 -2
- package/worker/promisifyWorker.js +0 -141
- package/worker/types.d.ts +0 -31
- package/worker/worker.d.ts +0 -1
- package/worker/worker.js +0 -43
- /package/{HttpException.d.ts → cjs/HttpException.d.ts} +0 -0
- /package/{HttpException.js → cjs/HttpException.js} +0 -0
- /package/{client → cjs/client}/types.js +0 -0
- /package/{utils → cjs/utils}/reqMeta.js +0 -0
- /package/{utils → cjs/utils}/shim.d.ts +0 -0
- /package/{utils → cjs/utils}/shim.js +0 -0
- /package/{worker → mjs/client}/types.js +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createRPC = void 0;
|
|
7
|
+
const fetcher_1 = require("./fetcher");
|
|
8
|
+
const defaultHandler_1 = require("./defaultHandler");
|
|
9
|
+
const defaultStreamHandler_1 = require("./defaultStreamHandler");
|
|
10
|
+
const serializeQuery_1 = __importDefault(require("../utils/serializeQuery"));
|
|
11
|
+
const trimPath = (path) => path.trim().replace(/^\/|\/$/g, '');
|
|
12
|
+
const getHandlerPath = (endpoint, params, query) => {
|
|
13
|
+
let result = endpoint;
|
|
14
|
+
const queryStr = query ? (0, serializeQuery_1.default)(query) : null;
|
|
15
|
+
for (const [key, value] of Object.entries(params ?? {})) {
|
|
16
|
+
result = result.replace(`{${key}}`, value);
|
|
17
|
+
}
|
|
18
|
+
return `${result}${queryStr ? '?' : ''}${queryStr}`;
|
|
19
|
+
};
|
|
20
|
+
const createRPC = (givenSchema, segmentName, rpcModuleName, givenFetcher, options) => {
|
|
21
|
+
const schema = givenSchema; // fixes incompatibilities with JSON module
|
|
22
|
+
// fetcher ??= defaultFetcher as NonNullable<typeof fetcher>;
|
|
23
|
+
const segmentNamePath = options?.segmentNameOverride ?? segmentName;
|
|
24
|
+
const segmentSchema = schema.segments[segmentName];
|
|
25
|
+
if (!segmentSchema)
|
|
26
|
+
throw new Error(`Unable to create RPC module. Segment schema is missing for segment "${segmentName}".`);
|
|
27
|
+
let controllerSchema = schema.segments[segmentName]?.controllers[rpcModuleName];
|
|
28
|
+
const client = {};
|
|
29
|
+
if (!controllerSchema) {
|
|
30
|
+
// eslint-disable-next-line no-console
|
|
31
|
+
console.warn(`🐺 Unable to create RPC module. Controller schema is missing for module "${rpcModuleName}" from segment "${segmentName}". Assuming that schema is not ready yet and a segment is importing an uncompiled RPC module.`);
|
|
32
|
+
controllerSchema = {
|
|
33
|
+
rpcModuleName,
|
|
34
|
+
prefix: '',
|
|
35
|
+
handlers: {},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const controllerPrefix = trimPath(controllerSchema.prefix ?? '');
|
|
39
|
+
const forceApiRoot = controllerSchema.forceApiRoot ?? segmentSchema.forceApiRoot;
|
|
40
|
+
const originalApiRoot = forceApiRoot ?? options?.apiRoot ?? '/api';
|
|
41
|
+
for (const [staticMethodName, handlerSchema] of Object.entries(controllerSchema.handlers ?? {})) {
|
|
42
|
+
const { path, httpMethod, validation } = handlerSchema;
|
|
43
|
+
const getEndpoint = ({ apiRoot, params, query }) => {
|
|
44
|
+
apiRoot = apiRoot ?? originalApiRoot;
|
|
45
|
+
const endpoint = [
|
|
46
|
+
apiRoot.startsWith('http://') || apiRoot.startsWith('https://') || apiRoot.startsWith('/') ? '' : '/',
|
|
47
|
+
apiRoot,
|
|
48
|
+
forceApiRoot ? '' : segmentNamePath,
|
|
49
|
+
getHandlerPath([controllerPrefix, path].filter(Boolean).join('/'), params, query),
|
|
50
|
+
]
|
|
51
|
+
.filter(Boolean)
|
|
52
|
+
.join('/')
|
|
53
|
+
.replace(/([^:])\/+/g, '$1/'); // replace // by / but not for protocols (http://, https://)
|
|
54
|
+
return endpoint;
|
|
55
|
+
};
|
|
56
|
+
const handler = (async (input = {}) => {
|
|
57
|
+
const fetcher = givenFetcher instanceof Promise
|
|
58
|
+
? (await givenFetcher).fetcher
|
|
59
|
+
: (givenFetcher ?? fetcher_1.fetcher);
|
|
60
|
+
const validate = async (validationInput, { endpoint, }) => {
|
|
61
|
+
const validateOnClient = input.validateOnClient ??
|
|
62
|
+
(options?.validateOnClient instanceof Promise
|
|
63
|
+
? (await options?.validateOnClient)?.validateOnClient
|
|
64
|
+
: options?.validateOnClient);
|
|
65
|
+
if (validateOnClient && validation) {
|
|
66
|
+
if (typeof validateOnClient !== 'function') {
|
|
67
|
+
throw new Error('validateOnClient must be a function');
|
|
68
|
+
}
|
|
69
|
+
return ((await validateOnClient({ ...validationInput }, validation, { fullSchema: schema, endpoint })) ??
|
|
70
|
+
validationInput);
|
|
71
|
+
}
|
|
72
|
+
return validationInput;
|
|
73
|
+
};
|
|
74
|
+
const internalOptions = {
|
|
75
|
+
name: staticMethodName,
|
|
76
|
+
httpMethod: httpMethod,
|
|
77
|
+
getEndpoint,
|
|
78
|
+
validate,
|
|
79
|
+
defaultHandler: defaultHandler_1.defaultHandler,
|
|
80
|
+
defaultStreamHandler: defaultStreamHandler_1.defaultStreamHandler,
|
|
81
|
+
schema: handlerSchema,
|
|
82
|
+
};
|
|
83
|
+
const internalInput = {
|
|
84
|
+
...options,
|
|
85
|
+
...input,
|
|
86
|
+
body: input.body ?? null,
|
|
87
|
+
query: input.query ?? {},
|
|
88
|
+
params: input.params ?? {},
|
|
89
|
+
};
|
|
90
|
+
if (!fetcher)
|
|
91
|
+
throw new Error('Fetcher is not provided');
|
|
92
|
+
const [respData, resp] = await fetcher(internalOptions, internalInput);
|
|
93
|
+
return input.transform ? input.transform(respData, resp) : respData;
|
|
94
|
+
});
|
|
95
|
+
// TODO use Object.freeze, Object.seal or Object.defineProperty to avoid mutation
|
|
96
|
+
handler.schema = handlerSchema;
|
|
97
|
+
handler.controllerSchema = controllerSchema;
|
|
98
|
+
handler.segmentSchema = segmentSchema;
|
|
99
|
+
handler.fullSchema = schema;
|
|
100
|
+
handler.isRPC = true;
|
|
101
|
+
handler.apiRoot = originalApiRoot;
|
|
102
|
+
handler.path = [segmentNamePath, controllerPrefix, path].filter(Boolean).join('/');
|
|
103
|
+
handler.queryKey = (key) => [
|
|
104
|
+
handler.segmentSchema.segmentName,
|
|
105
|
+
handler.controllerSchema.prefix ?? '',
|
|
106
|
+
handler.controllerSchema.rpcModuleName,
|
|
107
|
+
handler.schema.path,
|
|
108
|
+
handler.schema.httpMethod,
|
|
109
|
+
...(key ?? []),
|
|
110
|
+
];
|
|
111
|
+
// @ts-expect-error TODO
|
|
112
|
+
client[staticMethodName] = handler;
|
|
113
|
+
}
|
|
114
|
+
return client;
|
|
115
|
+
};
|
|
116
|
+
exports.createRPC = createRPC;
|
|
@@ -3,7 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.defaultHandler = exports.DEFAULT_ERROR_MESSAGE = void 0;
|
|
4
4
|
const HttpException_1 = require("../HttpException");
|
|
5
5
|
exports.DEFAULT_ERROR_MESSAGE = 'Unknown error at defaultHandler';
|
|
6
|
-
|
|
6
|
+
// Helper function to get a value from an object using dot notation path
|
|
7
|
+
const getNestedValue = (obj, path) => {
|
|
8
|
+
return path.split('.').reduce((o, key) => (o && typeof o === 'object' ? o[key] : undefined), obj);
|
|
9
|
+
};
|
|
10
|
+
const defaultHandler = async ({ response, schema }) => {
|
|
7
11
|
let result;
|
|
8
12
|
try {
|
|
9
13
|
result = await response.json();
|
|
@@ -13,9 +17,12 @@ const defaultHandler = async (response) => {
|
|
|
13
17
|
throw new HttpException_1.HttpException(response.status, e?.message ?? exports.DEFAULT_ERROR_MESSAGE);
|
|
14
18
|
}
|
|
15
19
|
if (!response.ok) {
|
|
20
|
+
const errorKey = schema.operationObject && 'x-errorMessageKey' in schema.operationObject
|
|
21
|
+
? schema.operationObject['x-errorMessageKey']
|
|
22
|
+
: 'message';
|
|
16
23
|
// handle server errors
|
|
17
24
|
const errorResponse = result;
|
|
18
|
-
throw new HttpException_1.HttpException(response.status, errorResponse
|
|
25
|
+
throw new HttpException_1.HttpException(response.status, getNestedValue(errorResponse, errorKey) ?? exports.DEFAULT_ERROR_MESSAGE, errorResponse?.cause ?? JSON.stringify(result));
|
|
19
26
|
}
|
|
20
27
|
return result;
|
|
21
28
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { VovkHandlerSchema } from '../types';
|
|
2
|
+
import type { VovkStreamAsyncIterable } from './types';
|
|
3
|
+
import '../utils/shim';
|
|
4
|
+
export declare const DEFAULT_ERROR_MESSAGE = "An unknown error at defaultStreamHandler";
|
|
5
|
+
export declare const defaultStreamHandler: ({ response, abortController, }: {
|
|
6
|
+
response: Response;
|
|
7
|
+
abortController: AbortController;
|
|
8
|
+
schema: VovkHandlerSchema;
|
|
9
|
+
}) => VovkStreamAsyncIterable<unknown>;
|
|
@@ -4,41 +4,42 @@ exports.defaultStreamHandler = exports.DEFAULT_ERROR_MESSAGE = void 0;
|
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const HttpException_1 = require("../HttpException");
|
|
6
6
|
require("../utils/shim");
|
|
7
|
-
exports.DEFAULT_ERROR_MESSAGE = '
|
|
8
|
-
const defaultStreamHandler =
|
|
7
|
+
exports.DEFAULT_ERROR_MESSAGE = 'An unknown error at defaultStreamHandler';
|
|
8
|
+
const defaultStreamHandler = ({ response, abortController, }) => {
|
|
9
9
|
if (!response.ok) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
response
|
|
11
|
+
.json()
|
|
12
|
+
.then((res) => {
|
|
13
|
+
throw new HttpException_1.HttpException(response.status, res.message ?? exports.DEFAULT_ERROR_MESSAGE);
|
|
14
|
+
})
|
|
15
|
+
.catch(() => {
|
|
16
|
+
throw new HttpException_1.HttpException(response.status, exports.DEFAULT_ERROR_MESSAGE);
|
|
17
|
+
});
|
|
17
18
|
// handle server errors
|
|
18
|
-
throw new HttpException_1.HttpException(response.status, result.message ?? exports.DEFAULT_ERROR_MESSAGE);
|
|
19
19
|
}
|
|
20
20
|
if (!response.body)
|
|
21
21
|
throw new HttpException_1.HttpException(types_1.HttpStatus.NULL, 'Stream body is falsy. Check your controller code.');
|
|
22
22
|
const reader = response.body.getReader();
|
|
23
|
-
|
|
24
|
-
let canceled = false;
|
|
23
|
+
const subscribers = new Set();
|
|
25
24
|
async function* asyncIterator() {
|
|
26
25
|
let prepend = '';
|
|
26
|
+
let i = 0;
|
|
27
27
|
while (true) {
|
|
28
28
|
let value;
|
|
29
|
-
let done = false;
|
|
30
29
|
try {
|
|
30
|
+
let done;
|
|
31
|
+
if (abortController.signal.aborted)
|
|
32
|
+
break;
|
|
31
33
|
({ value, done } = await reader.read());
|
|
34
|
+
if (done)
|
|
35
|
+
break;
|
|
32
36
|
}
|
|
33
37
|
catch (error) {
|
|
34
|
-
await reader.cancel();
|
|
35
|
-
const err = new Error('
|
|
38
|
+
// await reader.cancel(); // TODO in which cases it needs to be canceled?
|
|
39
|
+
const err = new Error('JSONLines stream error. ' + String(error));
|
|
36
40
|
err.cause = error;
|
|
37
41
|
throw err;
|
|
38
42
|
}
|
|
39
|
-
if (done) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
43
|
// typeof value === 'number' is a workaround for React Native
|
|
43
44
|
const string = typeof value === 'number' ? String.fromCharCode(value) : new TextDecoder().decode(value);
|
|
44
45
|
prepend += string;
|
|
@@ -47,35 +48,57 @@ const defaultStreamHandler = async (response) => {
|
|
|
47
48
|
let data;
|
|
48
49
|
try {
|
|
49
50
|
data = JSON.parse(line);
|
|
50
|
-
prepend =
|
|
51
|
+
prepend = prepend.slice(line.length + 1);
|
|
51
52
|
}
|
|
52
53
|
catch {
|
|
53
54
|
break;
|
|
54
55
|
}
|
|
55
56
|
if (data) {
|
|
57
|
+
subscribers.forEach((cb) => {
|
|
58
|
+
if (!abortController.signal.aborted)
|
|
59
|
+
cb(data, i);
|
|
60
|
+
});
|
|
61
|
+
i++;
|
|
56
62
|
if ('isError' in data && 'reason' in data) {
|
|
57
63
|
const upcomingError = data.reason;
|
|
58
|
-
|
|
64
|
+
abortController.abort(data.reason);
|
|
59
65
|
if (typeof upcomingError === 'string') {
|
|
60
66
|
throw new Error(upcomingError);
|
|
61
67
|
}
|
|
62
68
|
throw upcomingError;
|
|
63
69
|
}
|
|
64
|
-
else if (!
|
|
70
|
+
else if (!abortController.signal.aborted) {
|
|
65
71
|
yield data;
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
76
|
}
|
|
77
|
+
const asPromise = async () => {
|
|
78
|
+
const items = [];
|
|
79
|
+
for await (const item of asyncIterator()) {
|
|
80
|
+
items.push(item);
|
|
81
|
+
}
|
|
82
|
+
return items;
|
|
83
|
+
};
|
|
71
84
|
return {
|
|
72
85
|
status: response.status,
|
|
86
|
+
asPromise,
|
|
87
|
+
abortController,
|
|
73
88
|
[Symbol.asyncIterator]: asyncIterator,
|
|
74
|
-
[Symbol.dispose]: () =>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
89
|
+
[Symbol.dispose]: () => {
|
|
90
|
+
abortController.abort('Stream disposed');
|
|
91
|
+
},
|
|
92
|
+
[Symbol.asyncDispose]: () => {
|
|
93
|
+
abortController.abort('Stream async disposed');
|
|
94
|
+
},
|
|
95
|
+
onIterate: (cb) => {
|
|
96
|
+
if (abortController.signal.aborted)
|
|
97
|
+
return () => { };
|
|
98
|
+
subscribers.add(cb);
|
|
99
|
+
return () => {
|
|
100
|
+
subscribers.delete(cb);
|
|
101
|
+
};
|
|
79
102
|
},
|
|
80
103
|
};
|
|
81
104
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { VovkFetcherOptions, VovkFetcher } from './types';
|
|
2
|
+
import { HttpException } from '../HttpException';
|
|
3
|
+
export declare const DEFAULT_ERROR_MESSAGE = "Unknown error at default fetcher";
|
|
4
|
+
export declare function createFetcher<T>({ prepareRequestInit, transformResponse, onSuccess, onError, }?: {
|
|
5
|
+
prepareRequestInit?: (init: RequestInit, options: VovkFetcherOptions<T>) => RequestInit | Promise<RequestInit>;
|
|
6
|
+
transformResponse?: (respData: unknown, options: VovkFetcherOptions<T>, response: Response, init: RequestInit) => unknown | Promise<unknown>;
|
|
7
|
+
onSuccess?: (respData: unknown, options: VovkFetcherOptions<T>, response: Response, init: RequestInit) => void | Promise<void>;
|
|
8
|
+
onError?: (error: HttpException, options: VovkFetcherOptions<T>, response: Response | null, init: RequestInit | null, respData: unknown | null) => void | Promise<void>;
|
|
9
|
+
}): VovkFetcher<VovkFetcherOptions<T>>;
|
|
10
|
+
export declare const fetcher: VovkFetcher<{
|
|
11
|
+
apiRoot?: string;
|
|
12
|
+
disableClientValidation?: boolean;
|
|
13
|
+
validateOnClient?: import("./types").VovkValidateOnClient<unknown> | Promise<{
|
|
14
|
+
validateOnClient: import("./types").VovkValidateOnClient<unknown>;
|
|
15
|
+
}> | undefined;
|
|
16
|
+
interpretAs?: string;
|
|
17
|
+
init?: RequestInit;
|
|
18
|
+
}>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetcher = exports.DEFAULT_ERROR_MESSAGE = void 0;
|
|
4
|
+
exports.createFetcher = createFetcher;
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
const HttpException_1 = require("../HttpException");
|
|
7
|
+
exports.DEFAULT_ERROR_MESSAGE = 'Unknown error at default fetcher';
|
|
8
|
+
function createFetcher({ prepareRequestInit, transformResponse, onSuccess, onError, } = {}) {
|
|
9
|
+
// fetcher uses HttpException class to throw errors of fake HTTP status 0 if client-side error occurs
|
|
10
|
+
// For normal HTTP errors, it uses message and status code from the response of VovkErrorResponse type
|
|
11
|
+
const newFetcher = async ({ httpMethod, getEndpoint, validate, defaultHandler, defaultStreamHandler, schema }, inputOptions) => {
|
|
12
|
+
let response = null;
|
|
13
|
+
let respData = null;
|
|
14
|
+
let requestInit = null;
|
|
15
|
+
try {
|
|
16
|
+
const { meta, apiRoot, disableClientValidation, init, interpretAs } = inputOptions;
|
|
17
|
+
let { body, query, params } = inputOptions;
|
|
18
|
+
const endpoint = getEndpoint({ apiRoot, params, query });
|
|
19
|
+
const unusedParams = Array.from(new URL(endpoint.startsWith('/') ? `http://localhost${endpoint}` : endpoint).pathname.matchAll(/\{([^}]+)\}/g)).map((m) => m[1]);
|
|
20
|
+
if (unusedParams.length) {
|
|
21
|
+
throw new HttpException_1.HttpException(types_1.HttpStatus.NULL, `Unused params: ${unusedParams.join(', ')} in ${endpoint}`, {
|
|
22
|
+
body,
|
|
23
|
+
query,
|
|
24
|
+
params,
|
|
25
|
+
endpoint,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (!disableClientValidation) {
|
|
29
|
+
try {
|
|
30
|
+
({ body, query, params } = (await validate(inputOptions, { endpoint })) ?? { body, query, params });
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
// if HttpException is thrown, rethrow it
|
|
34
|
+
if (e instanceof HttpException_1.HttpException)
|
|
35
|
+
throw e;
|
|
36
|
+
// otherwise, throw HttpException with status 0
|
|
37
|
+
throw new HttpException_1.HttpException(types_1.HttpStatus.NULL, e.message ?? exports.DEFAULT_ERROR_MESSAGE, {
|
|
38
|
+
body,
|
|
39
|
+
query,
|
|
40
|
+
params,
|
|
41
|
+
endpoint,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
requestInit = {
|
|
46
|
+
method: httpMethod,
|
|
47
|
+
...init,
|
|
48
|
+
headers: {
|
|
49
|
+
accept: 'application/jsonl, application/json',
|
|
50
|
+
...(body instanceof FormData ? {} : { 'content-type': 'application/json' }),
|
|
51
|
+
...(meta ? { 'x-meta': JSON.stringify(meta) } : {}),
|
|
52
|
+
...init?.headers,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
if (body instanceof FormData) {
|
|
56
|
+
requestInit.body = body;
|
|
57
|
+
}
|
|
58
|
+
else if (body) {
|
|
59
|
+
requestInit.body = JSON.stringify(body);
|
|
60
|
+
}
|
|
61
|
+
const abortController = new AbortController();
|
|
62
|
+
requestInit.signal = abortController.signal;
|
|
63
|
+
requestInit = prepareRequestInit ? await prepareRequestInit(requestInit, inputOptions) : requestInit;
|
|
64
|
+
try {
|
|
65
|
+
response = await fetch(endpoint, requestInit);
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
// handle network errors
|
|
69
|
+
throw new HttpException_1.HttpException(types_1.HttpStatus.NULL, (e?.message ?? exports.DEFAULT_ERROR_MESSAGE) + ' ' + endpoint, {
|
|
70
|
+
body,
|
|
71
|
+
query,
|
|
72
|
+
params,
|
|
73
|
+
endpoint,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const contentType = interpretAs ?? response.headers.get('content-type');
|
|
77
|
+
if (contentType?.startsWith('application/jsonl')) {
|
|
78
|
+
respData = defaultStreamHandler({ response, abortController, schema });
|
|
79
|
+
}
|
|
80
|
+
else if (contentType?.startsWith('application/json')) {
|
|
81
|
+
respData = await defaultHandler({ response, schema });
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
respData = response;
|
|
85
|
+
}
|
|
86
|
+
respData = transformResponse ? await transformResponse(respData, inputOptions, response, requestInit) : respData;
|
|
87
|
+
await onSuccess?.(respData, inputOptions, response, requestInit);
|
|
88
|
+
return [respData, response];
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
await onError?.(error, inputOptions, response, requestInit, respData);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
return newFetcher;
|
|
96
|
+
}
|
|
97
|
+
exports.fetcher = createFetcher();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.progressive = exports.createFetcher = exports.fetcher = exports.createRPC = void 0;
|
|
4
|
+
var createRPC_1 = require("./createRPC");
|
|
5
|
+
Object.defineProperty(exports, "createRPC", { enumerable: true, get: function () { return createRPC_1.createRPC; } });
|
|
6
|
+
var fetcher_1 = require("./fetcher");
|
|
7
|
+
Object.defineProperty(exports, "fetcher", { enumerable: true, get: function () { return fetcher_1.fetcher; } });
|
|
8
|
+
Object.defineProperty(exports, "createFetcher", { enumerable: true, get: function () { return fetcher_1.createFetcher; } });
|
|
9
|
+
var progressive_1 = require("./progressive");
|
|
10
|
+
Object.defineProperty(exports, "progressive", { enumerable: true, get: function () { return progressive_1.progressive; } });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { VovkStreamAsyncIterable } from './types';
|
|
2
|
+
import type { KnownAny, VovkYieldType } from '../types';
|
|
3
|
+
type UnionToIntersection<U> = (U extends KnownAny ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
4
|
+
type PromisifyProperties<T> = {
|
|
5
|
+
[K in keyof T]: Promise<T[K]>;
|
|
6
|
+
};
|
|
7
|
+
type TransformUnionToPromises<T> = PromisifyProperties<UnionToIntersection<T>>;
|
|
8
|
+
export declare function progressive<T extends (...args: KnownAny[]) => Promise<VovkStreamAsyncIterable<KnownAny>>>(fn: T, ...args: undefined extends Parameters<T>[0] ? [arg?: Parameters<T>[0]] : [arg: Parameters<T>[0]]): TransformUnionToPromises<VovkYieldType<T>>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.progressive = progressive;
|
|
4
|
+
function progressive(fn, ...args) {
|
|
5
|
+
const [arg] = args;
|
|
6
|
+
const reg = {};
|
|
7
|
+
void fn(arg)
|
|
8
|
+
.then(async (result) => {
|
|
9
|
+
for await (const item of result) {
|
|
10
|
+
for (const [key, value] of Object.entries(item)) {
|
|
11
|
+
if (key in reg) {
|
|
12
|
+
if (!reg[key].isSettled) {
|
|
13
|
+
reg[key].isSettled = true;
|
|
14
|
+
reg[key].resolve(value);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
19
|
+
reg[key] = { resolve, reject, promise, isSettled: true };
|
|
20
|
+
reg[key].resolve(value);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
Object.keys(reg).forEach((key) => {
|
|
25
|
+
if (reg[key].isSettled)
|
|
26
|
+
return;
|
|
27
|
+
reg[key].isSettled = true;
|
|
28
|
+
reg[key].reject(new Error(`The connection was closed without sending a value for "${key}"`));
|
|
29
|
+
});
|
|
30
|
+
return result;
|
|
31
|
+
})
|
|
32
|
+
.catch((error) => {
|
|
33
|
+
Object.keys(reg).forEach((key) => {
|
|
34
|
+
if (reg[key].isSettled)
|
|
35
|
+
return;
|
|
36
|
+
reg[key].isSettled = true;
|
|
37
|
+
reg[key].reject(error);
|
|
38
|
+
});
|
|
39
|
+
return error;
|
|
40
|
+
});
|
|
41
|
+
return new Proxy({}, {
|
|
42
|
+
get(_target, prop) {
|
|
43
|
+
if (prop in reg) {
|
|
44
|
+
return reg[prop].promise;
|
|
45
|
+
}
|
|
46
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
47
|
+
reg[prop] = { resolve, reject, promise, isSettled: false };
|
|
48
|
+
return promise;
|
|
49
|
+
},
|
|
50
|
+
ownKeys: () => {
|
|
51
|
+
throw new Error('Getting own keys is not possible as they are dynamically created');
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { NextResponse } from 'next/server';
|
|
2
|
+
import type { KnownAny, HttpMethod, ControllerStaticMethod, VovkHandlerSchema, VovkControllerSchema, VovkSegmentSchema, VovkSchema, VovkRequest, Prettify, IsEmptyObject } from '../types';
|
|
3
|
+
import type { JSONLinesResponse } from '../JSONLinesResponse';
|
|
4
|
+
import type { defaultStreamHandler } from './defaultStreamHandler';
|
|
5
|
+
import type { defaultHandler } from './defaultHandler';
|
|
6
|
+
type OmitNullable<T> = {
|
|
7
|
+
[K in keyof T as T[K] extends null | undefined ? never : K]: T[K];
|
|
8
|
+
};
|
|
9
|
+
type Empty = {};
|
|
10
|
+
export type StaticMethodInput<T extends ((req: VovkRequest<KnownAny, KnownAny, KnownAny>, params: KnownAny) => KnownAny) & {
|
|
11
|
+
__types?: {
|
|
12
|
+
isForm: boolean;
|
|
13
|
+
};
|
|
14
|
+
}> = OmitNullable<(Parameters<T>[0] extends VovkRequest<infer TBody, infer TQuery, infer TParams> ? (TBody extends Record<KnownAny, KnownAny> ? {
|
|
15
|
+
body: T['__types'] extends {
|
|
16
|
+
isForm: true;
|
|
17
|
+
} ? FormData : TBody;
|
|
18
|
+
} : Empty) & (TQuery extends Record<KnownAny, KnownAny> ? {
|
|
19
|
+
query: TQuery;
|
|
20
|
+
} : Empty) & (TParams extends Record<KnownAny, KnownAny> ? {
|
|
21
|
+
params: TParams;
|
|
22
|
+
} : Empty) & {
|
|
23
|
+
meta?: {
|
|
24
|
+
[key: string]: KnownAny;
|
|
25
|
+
};
|
|
26
|
+
} : Empty) & (Parameters<T>[1] extends Record<KnownAny, KnownAny> ? {
|
|
27
|
+
params: Parameters<T>[1];
|
|
28
|
+
} : Empty)>;
|
|
29
|
+
type ToPromise<T> = T extends PromiseLike<unknown> ? T : Promise<T>;
|
|
30
|
+
export type VovkStreamAsyncIterable<T> = {
|
|
31
|
+
status: number;
|
|
32
|
+
asPromise: () => Promise<T[]>;
|
|
33
|
+
[Symbol.dispose](): Promise<void> | void;
|
|
34
|
+
[Symbol.asyncDispose](): Promise<void> | void;
|
|
35
|
+
[Symbol.asyncIterator](): AsyncIterator<T>;
|
|
36
|
+
onIterate: (cb: (data: T, i: number) => void) => () => void;
|
|
37
|
+
abortController: AbortController;
|
|
38
|
+
};
|
|
39
|
+
type StaticMethodReturn<T extends ControllerStaticMethod> = ReturnType<T> extends NextResponse<infer U> | Promise<NextResponse<infer U>> ? U : ReturnType<T> extends Response | Promise<Response> ? Awaited<ReturnType<T>> : ReturnType<T>;
|
|
40
|
+
type StaticMethodReturnPromise<T extends ControllerStaticMethod> = ToPromise<StaticMethodReturn<T>>;
|
|
41
|
+
type StaticMethodOptions<T extends (req: VovkRequest<KnownAny, KnownAny, KnownAny>, params: KnownAny) => void | object | JSONLinesResponse<TStreamIteration> | Promise<JSONLinesResponse<TStreamIteration>>, TFetcherOptions extends Record<string, KnownAny>, TStreamIteration, R, F extends VovkFetcherOptions<KnownAny>> = Partial<TFetcherOptions & {
|
|
42
|
+
transform: (staticMethodReturn: Awaited<StaticMethodReturn<T>>, resp: Response) => R;
|
|
43
|
+
fetcher: VovkFetcher<F>;
|
|
44
|
+
}>;
|
|
45
|
+
export type ClientMethodReturn<T extends (req: VovkRequest<KnownAny, KnownAny, KnownAny>, params: KnownAny) => void | object | JSONLinesResponse<TStreamIteration> | Promise<JSONLinesResponse<TStreamIteration>>, TStreamIteration, R> = ReturnType<T> extends Promise<JSONLinesResponse<infer U>> | JSONLinesResponse<infer U> | Iterator<infer U> | AsyncIterator<infer U> ? Promise<VovkStreamAsyncIterable<U>> : R extends object ? Promise<Awaited<R>> : StaticMethodReturnPromise<T>;
|
|
46
|
+
export type ClientMethod<T extends ((req: VovkRequest<KnownAny, KnownAny, KnownAny>, params: KnownAny) => void | object | JSONLinesResponse<TStreamIteration> | Promise<JSONLinesResponse<TStreamIteration>>) & {
|
|
47
|
+
__types?: {
|
|
48
|
+
body: KnownAny;
|
|
49
|
+
query: KnownAny;
|
|
50
|
+
params: KnownAny;
|
|
51
|
+
output: KnownAny;
|
|
52
|
+
iteration: KnownAny;
|
|
53
|
+
isForm: boolean;
|
|
54
|
+
};
|
|
55
|
+
}, TFetcherOptions extends Record<string, KnownAny>, TStreamIteration extends KnownAny = unknown> = (IsEmptyObject<StaticMethodInput<T>> extends true ? <R, F extends VovkFetcherOptions<KnownAny> = VovkFetcherOptions<TFetcherOptions>>(options?: Prettify<StaticMethodOptions<T, TFetcherOptions, TStreamIteration, R, F>>) => ClientMethodReturn<T, TStreamIteration, R> : <R, F extends VovkFetcherOptions<KnownAny> = VovkFetcherOptions<TFetcherOptions>>(options: Prettify<StaticMethodInput<T> & StaticMethodOptions<T, TFetcherOptions, TStreamIteration, R, F>>) => ClientMethodReturn<T, TStreamIteration, R>) & {
|
|
56
|
+
isRPC: true;
|
|
57
|
+
schema: VovkHandlerSchema;
|
|
58
|
+
controllerSchema: VovkControllerSchema;
|
|
59
|
+
segmentSchema: VovkSegmentSchema;
|
|
60
|
+
fullSchema: VovkSchema;
|
|
61
|
+
path: string;
|
|
62
|
+
apiRoot: string;
|
|
63
|
+
queryKey: (key?: unknown[]) => unknown[];
|
|
64
|
+
__types: T['__types'];
|
|
65
|
+
};
|
|
66
|
+
type OmitNever<T> = {
|
|
67
|
+
[K in keyof T as T[K] extends never ? never : K]: T[K];
|
|
68
|
+
};
|
|
69
|
+
type VovkClientWithNever<T, TFetcherOptions extends {
|
|
70
|
+
[key: string]: KnownAny;
|
|
71
|
+
}> = {
|
|
72
|
+
[K in keyof T]: T[K] extends (...args: KnownAny) => KnownAny ? ClientMethod<T[K], TFetcherOptions> : never;
|
|
73
|
+
};
|
|
74
|
+
export type VovkRPCModule<T, TFetcherOptions extends {
|
|
75
|
+
[key: string]: KnownAny;
|
|
76
|
+
}> = OmitNever<VovkClientWithNever<T, TFetcherOptions>>;
|
|
77
|
+
export type VovkFetcher<TFetcherOptions> = (options: {
|
|
78
|
+
name: string;
|
|
79
|
+
httpMethod: HttpMethod;
|
|
80
|
+
getEndpoint: (data: {
|
|
81
|
+
apiRoot: string | undefined;
|
|
82
|
+
params: unknown;
|
|
83
|
+
query: unknown;
|
|
84
|
+
}) => string;
|
|
85
|
+
validate: (inputOptions: {
|
|
86
|
+
body?: unknown;
|
|
87
|
+
query?: unknown;
|
|
88
|
+
params?: unknown;
|
|
89
|
+
meta?: unknown;
|
|
90
|
+
} & TFetcherOptions, meta: {
|
|
91
|
+
endpoint: string;
|
|
92
|
+
}) => KnownAny | Promise<KnownAny>;
|
|
93
|
+
defaultStreamHandler: typeof defaultStreamHandler;
|
|
94
|
+
defaultHandler: typeof defaultHandler;
|
|
95
|
+
schema: VovkHandlerSchema;
|
|
96
|
+
}, input: {
|
|
97
|
+
body?: unknown;
|
|
98
|
+
query?: unknown;
|
|
99
|
+
params?: unknown;
|
|
100
|
+
meta?: unknown;
|
|
101
|
+
} & TFetcherOptions) => Promise<[KnownAny, Response]>;
|
|
102
|
+
export type VovkFetcherOptions<T> = T & {
|
|
103
|
+
apiRoot?: string;
|
|
104
|
+
disableClientValidation?: boolean;
|
|
105
|
+
validateOnClient?: VovkValidateOnClient<T> | Promise<{
|
|
106
|
+
validateOnClient: VovkValidateOnClient<T>;
|
|
107
|
+
}>;
|
|
108
|
+
interpretAs?: string;
|
|
109
|
+
init?: RequestInit;
|
|
110
|
+
};
|
|
111
|
+
export type VovkValidateOnClient<TFetcherOptions> = (input: {
|
|
112
|
+
body?: unknown;
|
|
113
|
+
query?: unknown;
|
|
114
|
+
params?: unknown;
|
|
115
|
+
meta?: unknown;
|
|
116
|
+
} & TFetcherOptions, validation: Omit<Exclude<VovkHandlerSchema['validation'], undefined>, 'output' | 'iteration'>, meta: {
|
|
117
|
+
fullSchema: VovkSchema;
|
|
118
|
+
endpoint: string;
|
|
119
|
+
}) => KnownAny | Promise<KnownAny>;
|
|
120
|
+
export {};
|