vovk 3.0.0-draft.95 → 3.0.0-draft.96

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/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'];
@@ -150,6 +154,7 @@ export type VovkFullSchema = {
150
154
  config: Partial<VovkStrictConfig>;
151
155
  segments: Record<string, VovkSegmentSchema>;
152
156
  };
157
+ export type VovkValidationType = 'body' | 'query' | 'params' | 'output' | 'iteration';
153
158
  export declare enum HttpMethod {
154
159
  GET = "GET",
155
160
  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?: () => Omit<VovkHandlerSchema, 'httpMethod' | 'path'>;
9
- validate: (data: KnownAny, model: NonNullable<BODY_MODEL | QUERY_MODEL | PARAMS_MODEL | OUTPUT_MODEL>, meta: {
10
- type: 'body' | 'query' | 'params' | 'output';
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
- function withValidation({ body, query, params, output, handle, getHandlerSchema, validate, }) {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk",
3
- "version": "3.0.0-draft.95",
3
+ "version": "3.0.0-draft.96",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "description": "RESTful RPC for Next.js - Transforms Next.js into a powerful REST API platform with RPC capabilities.",