vovk 3.0.0-draft.95 → 3.0.0-draft.97
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/dist/StreamJSONResponse.d.ts +2 -4
- package/dist/StreamJSONResponse.js +9 -5
- package/dist/VovkApp.js +2 -2
- package/dist/client/fetcher.js +4 -0
- package/dist/index.d.ts +2 -2
- package/dist/types.d.ts +13 -6
- package/dist/utils/withValidation.d.ts +12 -5
- package/dist/utils/withValidation.js +36 -6
- package/package.json +1 -1
|
@@ -1,14 +1,12 @@
|
|
|
1
|
+
import type { headers } from 'next/headers';
|
|
1
2
|
import type { KnownAny, StreamAbortMessage } from './types';
|
|
2
3
|
import './utils/shim';
|
|
3
4
|
export declare class StreamJSONResponse<T> extends Response {
|
|
4
|
-
static defaultHeaders: {
|
|
5
|
-
'content-type': string;
|
|
6
|
-
};
|
|
7
5
|
isClosed: boolean;
|
|
8
6
|
controller?: ReadableStreamDefaultController;
|
|
9
7
|
readonly encoder: TextEncoder;
|
|
10
8
|
readonly readableStream: ReadableStream;
|
|
11
|
-
constructor(init?: ResponseInit);
|
|
9
|
+
constructor(requestHeaders: Awaited<ReturnType<typeof headers>>, init?: ResponseInit);
|
|
12
10
|
send(data: T | StreamAbortMessage): void;
|
|
13
11
|
close(): void;
|
|
14
12
|
throw(e: KnownAny): void;
|
|
@@ -3,14 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.StreamJSONResponse = void 0;
|
|
4
4
|
require("./utils/shim");
|
|
5
5
|
class StreamJSONResponse extends Response {
|
|
6
|
-
static defaultHeaders = {
|
|
7
|
-
'content-type': 'text/plain; x-format=jsonlines',
|
|
8
|
-
};
|
|
9
6
|
isClosed = false;
|
|
10
7
|
controller;
|
|
11
8
|
encoder;
|
|
12
9
|
readableStream;
|
|
13
|
-
constructor(init) {
|
|
10
|
+
constructor(requestHeaders, init) {
|
|
14
11
|
const encoder = new TextEncoder();
|
|
15
12
|
let readableController;
|
|
16
13
|
const readableStream = new ReadableStream({
|
|
@@ -21,9 +18,16 @@ class StreamJSONResponse extends Response {
|
|
|
21
18
|
readableController = controller;
|
|
22
19
|
},
|
|
23
20
|
});
|
|
21
|
+
if (!requestHeaders) {
|
|
22
|
+
throw new Error('Request headers are required');
|
|
23
|
+
}
|
|
24
|
+
const accept = requestHeaders.get('accept');
|
|
24
25
|
super(readableStream, {
|
|
25
26
|
...init,
|
|
26
|
-
headers:
|
|
27
|
+
headers: {
|
|
28
|
+
...init?.headers,
|
|
29
|
+
'Content-Type': accept?.includes('application/jsonl') ? 'application/jsonl' : 'plain/text',
|
|
30
|
+
},
|
|
27
31
|
});
|
|
28
32
|
this.readableStream = readableStream;
|
|
29
33
|
this.encoder = encoder;
|
package/dist/VovkApp.js
CHANGED
|
@@ -11,6 +11,7 @@ const StreamJSONResponse_1 = require("./StreamJSONResponse");
|
|
|
11
11
|
const reqQuery_1 = __importDefault(require("./utils/reqQuery"));
|
|
12
12
|
const reqMeta_1 = __importDefault(require("./utils/reqMeta"));
|
|
13
13
|
const reqForm_1 = __importDefault(require("./utils/reqForm"));
|
|
14
|
+
const headers_1 = require("next/headers");
|
|
14
15
|
class VovkApp {
|
|
15
16
|
static getHeadersFromOptions(options) {
|
|
16
17
|
if (!options)
|
|
@@ -143,9 +144,8 @@ class VovkApp {
|
|
|
143
144
|
(Reflect.has(result, Symbol.asyncIterator) &&
|
|
144
145
|
typeof result[Symbol.asyncIterator] === 'function'));
|
|
145
146
|
if (isIterator && !(result instanceof Array)) {
|
|
146
|
-
const streamResponse = new StreamJSONResponse_1.StreamJSONResponse({
|
|
147
|
+
const streamResponse = new StreamJSONResponse_1.StreamJSONResponse(await (0, headers_1.headers)(), {
|
|
147
148
|
headers: {
|
|
148
|
-
...StreamJSONResponse_1.StreamJSONResponse.defaultHeaders,
|
|
149
149
|
..._a.getHeadersFromOptions(staticMethod._options),
|
|
150
150
|
},
|
|
151
151
|
});
|
package/dist/client/fetcher.js
CHANGED
|
@@ -28,6 +28,10 @@ const fetcher = async ({ httpMethod, getEndpoint, validate, defaultHandler, defa
|
|
|
28
28
|
const init = {
|
|
29
29
|
method: httpMethod,
|
|
30
30
|
...options,
|
|
31
|
+
headers: {
|
|
32
|
+
...options.headers,
|
|
33
|
+
accept: 'application/jsonl, application/json',
|
|
34
|
+
},
|
|
31
35
|
};
|
|
32
36
|
if (body instanceof FormData) {
|
|
33
37
|
init.body = body;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createVovkApp } from './createVovkApp';
|
|
2
|
-
import { HttpStatus as HttpStatus, HttpMethod as HttpMethod, type KnownAny, type VovkErrorResponse, type VovkRequest, type VovkBody, type VovkQuery, type VovkParams, type VovkReturnType, type VovkYieldType, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkControllerOutput, type VovkSegmentSchema, type VovkControllerSchema, type VovkHandlerSchema, type VovkFullSchema, type VovkConfig, type VovkStrictConfig, type VovkEnv } from './types';
|
|
2
|
+
import { HttpStatus as HttpStatus, HttpMethod as HttpMethod, type KnownAny, type VovkErrorResponse, type VovkRequest, type VovkBody, type VovkQuery, type VovkParams, type VovkReturnType, type VovkYieldType, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkControllerOutput, type VovkSegmentSchema, type VovkControllerSchema, type VovkHandlerSchema, type VovkFullSchema, type VovkConfig, type VovkStrictConfig, type VovkEnv, type VovkValidationType } from './types';
|
|
3
3
|
import { type VovkClient, type VovkClientOptions, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkValidateOnClient, type VovkStreamAsyncIterable, createRPC, fetcher } from './client';
|
|
4
4
|
import { HttpException } from './HttpException';
|
|
5
5
|
import { createDecorator } from './createDecorator';
|
|
6
6
|
import { StreamJSONResponse } from './StreamJSONResponse';
|
|
7
7
|
import { generateStaticAPI } from './utils/generateStaticAPI';
|
|
8
8
|
import { withValidation } from './utils/withValidation';
|
|
9
|
-
export { type KnownAny, type VovkClient, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkStreamAsyncIterable, type VovkValidateOnClient, type VovkSegmentSchema, type VovkErrorResponse, type VovkRequest, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkControllerOutput, type VovkBody, type VovkQuery, type VovkParams, type VovkYieldType, type VovkReturnType, type VovkClientOptions, type VovkControllerSchema, type VovkHandlerSchema, type VovkFullSchema, type VovkConfig, type VovkStrictConfig, type VovkEnv, StreamJSONResponse, HttpException, HttpStatus, HttpMethod, createVovkApp, createDecorator, createRPC, fetcher, generateStaticAPI, withValidation, };
|
|
9
|
+
export { type KnownAny, type VovkClient, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkStreamAsyncIterable, type VovkValidateOnClient, type VovkSegmentSchema, type VovkErrorResponse, type VovkRequest, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkControllerOutput, type VovkBody, type VovkQuery, type VovkParams, type VovkYieldType, type VovkReturnType, type VovkClientOptions, type VovkControllerSchema, type VovkHandlerSchema, type VovkFullSchema, type VovkConfig, type VovkStrictConfig, type VovkEnv, type VovkValidationType, StreamJSONResponse, HttpException, HttpStatus, HttpMethod, createVovkApp, createDecorator, createRPC, fetcher, generateStaticAPI, withValidation, };
|
|
10
10
|
export declare const get: {
|
|
11
11
|
(givenPath?: string | undefined, options?: import("./types").DecoratorOptions | undefined): ReturnType<(givenPath?: string, options?: import("./types").DecoratorOptions) => (givenTarget: KnownAny, propertyKey: string) => void>;
|
|
12
12
|
auto: (options?: import("./types").DecoratorOptions) => (givenTarget: KnownAny, propertyKey: string) => void;
|
package/dist/types.d.ts
CHANGED
|
@@ -10,8 +10,9 @@ export type VovkHandlerSchema = {
|
|
|
10
10
|
validation?: {
|
|
11
11
|
query?: KnownAny;
|
|
12
12
|
body?: KnownAny;
|
|
13
|
-
output?: KnownAny;
|
|
14
13
|
params?: KnownAny;
|
|
14
|
+
output?: KnownAny;
|
|
15
|
+
iteration?: KnownAny;
|
|
15
16
|
};
|
|
16
17
|
openapi?: OperationObject;
|
|
17
18
|
custom?: Record<string, KnownAny>;
|
|
@@ -82,6 +83,9 @@ export type VovkControllerYieldType<T extends (req: VovkRequest<KnownAny, KnownA
|
|
|
82
83
|
export type VovkControllerOutput<T extends ((...args: KnownAny) => KnownAny) & {
|
|
83
84
|
__output?: KnownAny;
|
|
84
85
|
}> = T['__output'];
|
|
86
|
+
export type VovkControllerIteration<T extends ((...args: KnownAny) => KnownAny) & {
|
|
87
|
+
__iteration?: KnownAny;
|
|
88
|
+
}> = T['__iteration'];
|
|
85
89
|
export type VovkBody<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['body'];
|
|
86
90
|
export type VovkQuery<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['query'];
|
|
87
91
|
export type VovkParams<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['params'];
|
|
@@ -110,12 +114,14 @@ export type VovkEnv = {
|
|
|
110
114
|
__VOVK_START_WATCHER_IN_STANDALONE_MODE__?: 'true';
|
|
111
115
|
__VOVK_EXIT__?: 'true' | 'false';
|
|
112
116
|
};
|
|
113
|
-
type
|
|
117
|
+
export type GenerateFromTemplate = {
|
|
114
118
|
templatePath: string;
|
|
115
119
|
outDir?: string;
|
|
116
120
|
templateName?: string;
|
|
117
121
|
fullSchema?: string | boolean;
|
|
118
|
-
|
|
122
|
+
origin?: string | null;
|
|
123
|
+
};
|
|
124
|
+
type GenerateFrom = (string | GenerateFromTemplate)[];
|
|
119
125
|
export type VovkConfig = {
|
|
120
126
|
emitConfig?: boolean | (keyof VovkStrictConfig)[];
|
|
121
127
|
clientOutDir?: string;
|
|
@@ -136,20 +142,21 @@ export type VovkConfig = {
|
|
|
136
142
|
controller?: string;
|
|
137
143
|
[key: string]: string | undefined;
|
|
138
144
|
};
|
|
139
|
-
|
|
145
|
+
libs?: Record<string, KnownAny>;
|
|
140
146
|
};
|
|
141
|
-
export type VovkStrictConfig = Required<Omit<VovkConfig, 'emitConfig' | 'validateOnClientImport' | 'fetcherImport' | 'createRPCImport' | 'generateFrom' | '
|
|
147
|
+
export type VovkStrictConfig = Required<Omit<VovkConfig, 'emitConfig' | 'validateOnClientImport' | 'fetcherImport' | 'createRPCImport' | 'generateFrom' | 'libs'>> & {
|
|
142
148
|
emitConfig: (keyof VovkStrictConfig)[];
|
|
143
149
|
validateOnClientImport: string[] | null;
|
|
144
150
|
fetcherImport: string[];
|
|
145
151
|
createRPCImport: string[];
|
|
146
152
|
generateFrom: GenerateFrom;
|
|
147
|
-
|
|
153
|
+
libs: Record<string, KnownAny>;
|
|
148
154
|
};
|
|
149
155
|
export type VovkFullSchema = {
|
|
150
156
|
config: Partial<VovkStrictConfig>;
|
|
151
157
|
segments: Record<string, VovkSegmentSchema>;
|
|
152
158
|
};
|
|
159
|
+
export type VovkValidationType = 'body' | 'query' | 'params' | 'output' | 'iteration';
|
|
153
160
|
export declare enum HttpMethod {
|
|
154
161
|
GET = "GET",
|
|
155
162
|
POST = "POST",
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import { VovkHandlerSchema, type KnownAny, type VovkRequest } from '../types';
|
|
2
|
-
export declare function withValidation<T extends (req: KnownAny, params: KnownAny) => KnownAny, BODY_MODEL, QUERY_MODEL, PARAMS_MODEL, OUTPUT_MODEL>({ body, query, params, output, handle, getHandlerSchema, validate, }: {
|
|
1
|
+
import { VovkHandlerSchema, VovkValidationType, type KnownAny, type VovkRequest } from '../types';
|
|
2
|
+
export declare function withValidation<T extends (req: KnownAny, params: KnownAny) => KnownAny, BODY_MODEL, QUERY_MODEL, PARAMS_MODEL, OUTPUT_MODEL, ITERATION_MODEL>({ skipServerSideValidation, skipSchemaEmission, validateEveryIteration, body, query, params, output, iteration, handle, getHandlerSchema, validate, }: {
|
|
3
|
+
skipServerSideValidation?: boolean | VovkValidationType[];
|
|
4
|
+
skipSchemaEmission?: boolean | VovkValidationType[];
|
|
5
|
+
validateEveryIteration?: boolean;
|
|
3
6
|
body?: BODY_MODEL;
|
|
4
7
|
query?: QUERY_MODEL;
|
|
5
8
|
params?: PARAMS_MODEL;
|
|
6
9
|
output?: OUTPUT_MODEL;
|
|
10
|
+
iteration?: ITERATION_MODEL;
|
|
7
11
|
handle: T;
|
|
8
|
-
getHandlerSchema?: (
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
getHandlerSchema?: (options: {
|
|
13
|
+
skipSchemaEmissionKeys: VovkValidationType[];
|
|
14
|
+
}) => Omit<VovkHandlerSchema, 'httpMethod' | 'path'>;
|
|
15
|
+
validate: (data: KnownAny, model: NonNullable<BODY_MODEL | QUERY_MODEL | PARAMS_MODEL | OUTPUT_MODEL | ITERATION_MODEL>, meta: {
|
|
16
|
+
type: VovkValidationType;
|
|
11
17
|
req: VovkRequest<KnownAny, KnownAny>;
|
|
18
|
+
status?: number;
|
|
12
19
|
}) => KnownAny;
|
|
13
20
|
}): T;
|
|
@@ -4,31 +4,61 @@ exports.withValidation = withValidation;
|
|
|
4
4
|
const HttpException_1 = require("../HttpException");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
const setHandlerSchema_1 = require("./setHandlerSchema");
|
|
7
|
-
|
|
7
|
+
const validationTypes = ['body', 'query', 'params', 'output', 'iteration'];
|
|
8
|
+
function withValidation({ skipServerSideValidation, skipSchemaEmission, validateEveryIteration, body, query, params, output, iteration, handle, getHandlerSchema, validate, }) {
|
|
9
|
+
const skipServerSideValidationKeys = skipServerSideValidation === false
|
|
10
|
+
? []
|
|
11
|
+
: skipServerSideValidation === true
|
|
12
|
+
? validationTypes
|
|
13
|
+
: (skipServerSideValidation ?? []);
|
|
14
|
+
const skipSchemaEmissionKeys = skipSchemaEmission === false ? [] : skipSchemaEmission === true ? validationTypes : (skipSchemaEmission ?? []);
|
|
8
15
|
const outputHandler = async (req, handlerParams) => {
|
|
9
16
|
const data = await handle(req, handlerParams);
|
|
10
|
-
if (output) {
|
|
17
|
+
if (output && iteration) {
|
|
18
|
+
throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, "Output and iteration are mutually exclusive. You can't use them together.");
|
|
19
|
+
}
|
|
20
|
+
if (output && !skipServerSideValidationKeys.includes('output')) {
|
|
11
21
|
if (!data) {
|
|
12
22
|
throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, 'Output is required. You probably forgot to return something from your handler.');
|
|
13
23
|
}
|
|
14
24
|
await validate(data, output, { type: 'output', req });
|
|
15
25
|
}
|
|
26
|
+
if (iteration && !skipServerSideValidationKeys.includes('iteration')) {
|
|
27
|
+
// We assume `data` is an async iterable here; you might want to check that:
|
|
28
|
+
if (!data || typeof data[Symbol.asyncIterator] !== 'function') {
|
|
29
|
+
throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, 'Data is not an async iterable but iteration validation is defined.');
|
|
30
|
+
}
|
|
31
|
+
// Return a brand-new async generator that yields validated items
|
|
32
|
+
return (async function* () {
|
|
33
|
+
let i = 0;
|
|
34
|
+
for await (const item of data) {
|
|
35
|
+
if (validateEveryIteration || i === 0) {
|
|
36
|
+
await validate(item, iteration, { type: 'iteration', req, status: 200 });
|
|
37
|
+
}
|
|
38
|
+
i++;
|
|
39
|
+
yield item;
|
|
40
|
+
}
|
|
41
|
+
})();
|
|
42
|
+
}
|
|
43
|
+
else if (validateEveryIteration) {
|
|
44
|
+
throw new HttpException_1.HttpException(types_1.HttpStatus.INTERNAL_SERVER_ERROR, 'validateEveryIteration is set but iteration is not defined.');
|
|
45
|
+
}
|
|
16
46
|
return data;
|
|
17
47
|
};
|
|
18
48
|
const resultHandler = async (req, handlerParams) => {
|
|
19
|
-
if (body) {
|
|
49
|
+
if (body && !skipServerSideValidationKeys.includes('body')) {
|
|
20
50
|
const data = await req.json();
|
|
21
51
|
const instance = (await validate(data, body, { type: 'body', req })) ?? data;
|
|
22
52
|
// redeclare to add ability to call req.json() again
|
|
23
53
|
req.json = () => Promise.resolve(data);
|
|
24
54
|
req.vovk.body = () => Promise.resolve(instance);
|
|
25
55
|
}
|
|
26
|
-
if (query) {
|
|
56
|
+
if (query && !skipServerSideValidationKeys.includes('query')) {
|
|
27
57
|
const data = req.vovk.query();
|
|
28
58
|
const instance = (await validate(data, query, { type: 'query', req })) ?? data;
|
|
29
59
|
req.vovk.query = () => instance;
|
|
30
60
|
}
|
|
31
|
-
if (params) {
|
|
61
|
+
if (params && !skipServerSideValidationKeys.includes('params')) {
|
|
32
62
|
const data = req.vovk.params();
|
|
33
63
|
const instance = (await validate(data, params, { type: 'params', req })) ?? data;
|
|
34
64
|
req.vovk.params = () => instance;
|
|
@@ -36,7 +66,7 @@ function withValidation({ body, query, params, output, handle, getHandlerSchema,
|
|
|
36
66
|
return outputHandler(req, handlerParams);
|
|
37
67
|
};
|
|
38
68
|
if (getHandlerSchema) {
|
|
39
|
-
(0, setHandlerSchema_1.setHandlerSchema)(resultHandler, getHandlerSchema());
|
|
69
|
+
(0, setHandlerSchema_1.setHandlerSchema)(resultHandler, getHandlerSchema({ skipSchemaEmissionKeys }));
|
|
40
70
|
}
|
|
41
71
|
return resultHandler;
|
|
42
72
|
}
|
package/package.json
CHANGED