vovk 3.0.0-draft.85 → 3.0.0-draft.87

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/VovkApp.js CHANGED
@@ -81,12 +81,13 @@ class VovkApp {
81
81
  }
82
82
  const allMethodKeys = Object.keys(handlers);
83
83
  let methodKeys = [];
84
+ const pathStr = path.join('/');
84
85
  methodKeys = allMethodKeys
85
86
  // First, try to match literal routes exactly.
86
87
  .filter((p) => {
87
88
  if (p.includes(':'))
88
89
  return false; // Skip parameterized paths
89
- return p === path.join('/');
90
+ return p === pathStr;
90
91
  });
91
92
  if (!methodKeys.length) {
92
93
  methodKeys = allMethodKeys.filter((p) => {
@@ -1,4 +1,6 @@
1
1
  import type { VovkHandlerSchema, KnownAny, VovkController, VovkRequest } from './types';
2
2
  type Next = () => Promise<unknown>;
3
- export declare function createDecorator<ARGS extends unknown[], REQUEST = VovkRequest>(handler: null | ((this: VovkController, req: REQUEST, next: Next, ...args: ARGS) => unknown), initHandler?: (this: VovkController, ...args: ARGS) => Omit<VovkHandlerSchema, 'path' | 'httpMethod'> | ((handlerSchema: VovkHandlerSchema | null) => Omit<Partial<VovkHandlerSchema>, 'path' | 'httpMethod'>) | null | undefined): (...args: ARGS) => (target: KnownAny, propertyKey: string) => void;
3
+ export declare function createDecorator<ARGS extends unknown[], REQUEST = VovkRequest>(handler: null | ((this: VovkController, req: REQUEST, next: Next, ...args: ARGS) => unknown), initHandler?: (this: VovkController, ...args: ARGS) => Omit<VovkHandlerSchema, 'path' | 'httpMethod'> | ((handlerSchema: VovkHandlerSchema | null, options: {
4
+ handlerName: string;
5
+ }) => Omit<Partial<VovkHandlerSchema>, 'path' | 'httpMethod'>) | null | undefined): (...args: ARGS) => (target: KnownAny, propertyKey: string) => void;
4
6
  export {};
@@ -23,7 +23,11 @@ function createDecorator(handler, initHandler) {
23
23
  originalMethod._controller = controller;
24
24
  const handlerSchema = controller._handlers?.[propertyKey] ?? null;
25
25
  const initResultReturn = initHandler?.call(controller, ...args);
26
- const initResult = typeof initResultReturn === 'function' ? initResultReturn(handlerSchema) : initResultReturn;
26
+ const initResult = typeof initResultReturn === 'function'
27
+ ? initResultReturn(handlerSchema, {
28
+ handlerName: propertyKey,
29
+ })
30
+ : initResultReturn;
27
31
  controller._handlers = {
28
32
  ...controller._handlers,
29
33
  [propertyKey]: {
package/dist/index.d.ts CHANGED
@@ -1,13 +1,12 @@
1
1
  import { createVovkApp } from './createVovkApp';
2
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 VovkSchema, type VovkControllerSchema, type VovkHandlerSchema } from './types';
3
3
  import { type VovkClient, type VovkClientOptions, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkValidateOnClient, type VovkStreamAsyncIterable, createRPC } from './client';
4
- import { openapi } from './openapi';
5
4
  import { HttpException } from './HttpException';
6
5
  import { createDecorator } from './createDecorator';
7
6
  import { StreamJSONResponse } from './StreamJSONResponse';
8
7
  import { generateStaticAPI } from './utils/generateStaticAPI';
9
8
  import { setHandlerValidation } from './utils/setHandlerValidation';
10
- export { type KnownAny, type VovkClient, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkStreamAsyncIterable, type VovkValidateOnClient, type VovkSchema, type VovkErrorResponse, type VovkRequest, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkBody, type VovkQuery, type VovkParams, type VovkYieldType, type VovkReturnType, type VovkClientOptions, type VovkControllerSchema, type VovkHandlerSchema, StreamJSONResponse, HttpException, HttpStatus, HttpMethod, createVovkApp, createDecorator, createRPC, generateStaticAPI, openapi, setHandlerValidation, };
9
+ export { type KnownAny, type VovkClient, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkStreamAsyncIterable, type VovkValidateOnClient, type VovkSchema, type VovkErrorResponse, type VovkRequest, type VovkControllerBody, type VovkControllerQuery, type VovkControllerParams, type VovkControllerYieldType, type VovkBody, type VovkQuery, type VovkParams, type VovkYieldType, type VovkReturnType, type VovkClientOptions, type VovkControllerSchema, type VovkHandlerSchema, StreamJSONResponse, HttpException, HttpStatus, HttpMethod, createVovkApp, createDecorator, createRPC, generateStaticAPI, setHandlerValidation, };
11
10
  export declare const get: {
12
11
  (givenPath?: string | undefined, options?: import("./types").DecoratorOptions | undefined): ReturnType<(givenPath?: string, options?: import("./types").DecoratorOptions) => (givenTarget: KnownAny, propertyKey: string) => void>;
13
12
  auto: (options?: import("./types").DecoratorOptions) => (givenTarget: KnownAny, propertyKey: string) => void;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.initVovk = exports.prefix = exports.options = exports.head = exports.del = exports.patch = exports.put = exports.post = exports.get = exports.setHandlerValidation = exports.openapi = exports.generateStaticAPI = exports.createRPC = exports.createDecorator = exports.createVovkApp = exports.HttpMethod = exports.HttpStatus = exports.HttpException = exports.StreamJSONResponse = void 0;
4
+ exports.initVovk = exports.prefix = exports.options = exports.head = exports.del = exports.patch = exports.put = exports.post = exports.get = exports.setHandlerValidation = exports.generateStaticAPI = exports.createRPC = exports.createDecorator = exports.createVovkApp = exports.HttpMethod = exports.HttpStatus = exports.HttpException = exports.StreamJSONResponse = void 0;
5
5
  const createVovkApp_1 = require("./createVovkApp");
6
6
  Object.defineProperty(exports, "createVovkApp", { enumerable: true, get: function () { return createVovkApp_1.createVovkApp; } });
7
7
  const types_1 = require("./types");
@@ -9,8 +9,6 @@ Object.defineProperty(exports, "HttpStatus", { enumerable: true, get: function (
9
9
  Object.defineProperty(exports, "HttpMethod", { enumerable: true, get: function () { return types_1.HttpMethod; } });
10
10
  const client_1 = require("./client");
11
11
  Object.defineProperty(exports, "createRPC", { enumerable: true, get: function () { return client_1.createRPC; } });
12
- const openapi_1 = require("./openapi");
13
- Object.defineProperty(exports, "openapi", { enumerable: true, get: function () { return openapi_1.openapi; } });
14
12
  const HttpException_1 = require("./HttpException");
15
13
  Object.defineProperty(exports, "HttpException", { enumerable: true, get: function () { return HttpException_1.HttpException; } });
16
14
  const createDecorator_1 = require("./createDecorator");
package/dist/types.d.ts CHANGED
@@ -50,7 +50,7 @@ export type DecoratorOptions = {
50
50
  export type RouteHandler = ((req: VovkRequest, params: Record<string, string>) => Response | Promise<Response> | Iterable<unknown> | AsyncIterable<unknown>) & {
51
51
  _options?: DecoratorOptions;
52
52
  };
53
- export interface VovkRequest<BODY = undefined, QUERY extends object | undefined = undefined> extends Omit<NextRequest, 'json' | 'nextUrl'> {
53
+ export interface VovkRequest<BODY extends KnownAny = null, QUERY extends KnownAny = undefined, PARAMS extends KnownAny = undefined> extends Omit<NextRequest, 'json' | 'nextUrl'> {
54
54
  json: () => Promise<BODY>;
55
55
  nextUrl: Omit<NextRequest['nextUrl'], 'searchParams'> & {
56
56
  searchParams: Omit<NextRequest['nextUrl']['searchParams'], 'get' | 'getAll' | 'entries' | 'forEach' | 'keys' | 'values'> & {
@@ -67,7 +67,7 @@ export interface VovkRequest<BODY = undefined, QUERY extends object | undefined
67
67
  query: () => QUERY;
68
68
  meta: <T = Record<KnownAny, KnownAny>>(meta?: T | null) => T;
69
69
  form: <T = KnownAny>() => Promise<T>;
70
- params: <T extends Record<string, string> = Record<string, string>>() => T;
70
+ params: () => PARAMS;
71
71
  };
72
72
  }
73
73
  export type ControllerStaticMethod<REQ extends VovkRequest<KnownAny, KnownAny> = VovkRequest<undefined, Record<string, KnownAny>>, PARAMS extends {
@@ -77,7 +77,7 @@ export type ControllerStaticMethod<REQ extends VovkRequest<KnownAny, KnownAny> =
77
77
  };
78
78
  export type VovkControllerBody<T extends (...args: KnownAny) => KnownAny> = Awaited<ReturnType<Parameters<T>[0]['vovk']['body']>>;
79
79
  export type VovkControllerQuery<T extends (...args: KnownAny) => KnownAny> = ReturnType<Parameters<T>[0]['vovk']['query']>;
80
- export type VovkControllerParams<T extends (...args: KnownAny) => KnownAny> = Parameters<T>[1];
80
+ export type VovkControllerParams<T extends (...args: KnownAny) => KnownAny> = Parameters<T>[1] extends object ? Parameters<T>[1] : ReturnType<Parameters<T>[0]['vovk']['params']>;
81
81
  export type VovkControllerYieldType<T extends (req: VovkRequest<KnownAny, KnownAny>) => KnownAny> = T extends (...args: KnownAny[]) => AsyncGenerator<infer Y, KnownAny, KnownAny> ? Y : T extends (...args: KnownAny[]) => Generator<infer Y, KnownAny, KnownAny> ? Y : T extends (...args: KnownAny[]) => Promise<StreamJSONResponse<infer Y>> | StreamJSONResponse<infer Y> ? Y : never;
82
82
  export type VovkBody<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['body'];
83
83
  export type VovkQuery<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['query'];
@@ -1,4 +1,17 @@
1
- import type { VovkSchema, StaticClass } from '../types';
1
+ import type { VovkSchema, VovkController, StaticClass } from '../types';
2
+ export declare function getControllerSchema(controller: VovkController, controllerName: string, exposeValidation: boolean): {
3
+ controllerName: string;
4
+ originalControllerName: string;
5
+ prefix: string;
6
+ handlers: {
7
+ [x: string]: {
8
+ path: string;
9
+ httpMethod: string;
10
+ openapi?: import("openapi3-ts/oas31").OperationObject;
11
+ custom?: Record<string, import("../types").KnownAny>;
12
+ };
13
+ };
14
+ };
2
15
  export default function getSchema(options: {
3
16
  emitSchema?: boolean;
4
17
  segmentName?: string;
@@ -1,6 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getControllerSchema = getControllerSchema;
3
4
  exports.default = getSchema;
5
+ function getControllerSchema(controller, controllerName, exposeValidation) {
6
+ return {
7
+ controllerName,
8
+ originalControllerName: controller.name,
9
+ prefix: controller._prefix ?? '',
10
+ handlers: {
11
+ ...(exposeValidation
12
+ ? controller._handlers
13
+ : Object.fromEntries(
14
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
15
+ Object.entries(controller._handlers ?? {}).map(([key, { validation: _v, ...value }]) => [key, value]))),
16
+ },
17
+ };
18
+ }
4
19
  function getSchema(options) {
5
20
  const exposeValidation = options?.exposeValidation ?? true;
6
21
  const emitSchema = options.emitSchema ?? true;
@@ -12,18 +27,7 @@ function getSchema(options) {
12
27
  if (!emitSchema)
13
28
  return schema;
14
29
  for (const [controllerName, controller] of Object.entries(options.controllers)) {
15
- schema.controllers[controllerName] = {
16
- controllerName: controllerName,
17
- originalControllerName: controller.name,
18
- prefix: controller._prefix ?? '',
19
- handlers: {
20
- ...(exposeValidation
21
- ? controller._handlers
22
- : Object.fromEntries(
23
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
24
- Object.entries(controller._handlers ?? {}).map(([key, { validation: _v, ...value }]) => [key, value]))),
25
- },
26
- };
30
+ schema.controllers[controllerName] = getControllerSchema(controller, controllerName, exposeValidation);
27
31
  }
28
32
  return schema;
29
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk",
3
- "version": "3.0.0-draft.85",
3
+ "version": "3.0.0-draft.87",
4
4
  "main": "dist/index.js",
5
5
  "description": "RESTful RPC for Next.js - Transforms Next.js into a powerful REST API platform with RPC capabilities.",
6
6
  "repository": {
@@ -27,8 +27,5 @@
27
27
  "homepage": "https://vovk.dev",
28
28
  "peerDependencies": {
29
29
  "next": "*"
30
- },
31
- "optionalDependencies": {
32
- "openapi3-ts": "^4.4.0"
33
30
  }
34
31
  }
@@ -1,3 +0,0 @@
1
- import type { OpenAPIObject } from 'openapi3-ts/oas31';
2
- import type { VovkSchema } from '../types';
3
- export declare function fromSchema(apiRoot: string, vovkSchema: Record<string, VovkSchema>, extendWith?: Partial<OpenAPIObject>): OpenAPIObject;
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fromSchema = fromSchema;
4
- function fromSchema(apiRoot, vovkSchema, extendWith) {
5
- const paths = {};
6
- for (const [segmentName, schema] of Object.entries(vovkSchema)) {
7
- for (const c of Object.values(schema.controllers)) {
8
- for (const h of Object.values(c.handlers)) {
9
- if (h.openapi) {
10
- const path = '/' +
11
- [apiRoot.replace(/^\/+|\/+$/g, ''), segmentName, c.prefix, h.path]
12
- .filter(Boolean)
13
- .join('/')
14
- .replace(/:([a-zA-Z0-9_]+)/g, '{$1}');
15
- paths[path] = paths[path] ?? {};
16
- paths[path][h.httpMethod.toLowerCase()] = { ...h.openapi };
17
- }
18
- }
19
- }
20
- }
21
- return {
22
- ...extendWith,
23
- openapi: '3.1.0',
24
- info: extendWith?.info ?? {
25
- title: 'API',
26
- version: '1.0.0',
27
- },
28
- paths,
29
- };
30
- }
@@ -1 +0,0 @@
1
- export { openapi } from './openapi';
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.openapi = void 0;
4
- var openapi_1 = require("./openapi");
5
- Object.defineProperty(exports, "openapi", { enumerable: true, get: function () { return openapi_1.openapi; } });
@@ -1,11 +0,0 @@
1
- import type { OperationObject } from 'openapi3-ts/oas31';
2
- import { fromSchema } from './fromSchema';
3
- import type { KnownAny } from '../types';
4
- type OperationObjectWithCustomProperties = OperationObject & {
5
- [key in `${'x' | 'X'}-${string}`]: KnownAny;
6
- };
7
- declare const openapiDecorator: (openAPIOperationObject?: OperationObjectWithCustomProperties | undefined) => (target: KnownAny, propertyKey: string) => void;
8
- export declare const openapi: typeof openapiDecorator & {
9
- fromSchema: typeof fromSchema;
10
- };
11
- export {};
@@ -1,80 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.openapi = void 0;
4
- const createDecorator_1 = require("../createDecorator");
5
- const fromSchema_1 = require("./fromSchema");
6
- const openapiDecorator = (0, createDecorator_1.createDecorator)(null, (openAPIOperationObject = {}) => {
7
- return (handlerSchema) => {
8
- const queryParameters = handlerSchema?.validation?.query &&
9
- 'type' in handlerSchema.validation.query &&
10
- 'properties' in handlerSchema.validation.query
11
- ? Object.entries(handlerSchema.validation.query.properties).map(([propName, propSchema]) => ({
12
- name: propName,
13
- in: 'query',
14
- required: handlerSchema.validation?.query.required
15
- ? handlerSchema.validation.query.required.includes(propName)
16
- : false,
17
- schema: propSchema,
18
- }))
19
- : null;
20
- const pathParameters = handlerSchema?.validation?.params &&
21
- 'type' in handlerSchema.validation.params &&
22
- 'properties' in handlerSchema.validation.params
23
- ? Object.entries(handlerSchema.validation.params.properties).map(([propName, propSchema]) => ({
24
- name: propName,
25
- in: 'path',
26
- required: handlerSchema.validation?.params.required
27
- ? handlerSchema.validation.params.required.includes(propName)
28
- : false,
29
- schema: propSchema,
30
- }))
31
- : null;
32
- return {
33
- ...handlerSchema,
34
- openapi: {
35
- ...handlerSchema?.openapi,
36
- ...(handlerSchema?.validation?.output &&
37
- 'type' in handlerSchema.validation.output &&
38
- 'properties' in handlerSchema.validation.output
39
- ? {
40
- responses: {
41
- 200: {
42
- description: 'description' in handlerSchema.validation.output
43
- ? handlerSchema.validation.output.description
44
- : 'Success',
45
- content: {
46
- 'application/json': {
47
- schema: handlerSchema.validation.output,
48
- },
49
- },
50
- },
51
- },
52
- }
53
- : {}),
54
- ...(handlerSchema?.validation?.body &&
55
- 'type' in handlerSchema.validation.body &&
56
- 'properties' in handlerSchema.validation.body
57
- ? {
58
- requestBody: {
59
- description: 'description' in handlerSchema.validation.body
60
- ? handlerSchema.validation.body.description
61
- : 'Request body',
62
- required: true,
63
- content: {
64
- 'application/json': {
65
- schema: handlerSchema.validation.body,
66
- },
67
- },
68
- },
69
- }
70
- : {}),
71
- ...(queryParameters || pathParameters
72
- ? { parameters: [...(queryParameters || []), ...(pathParameters || [])] }
73
- : {}),
74
- ...openAPIOperationObject,
75
- },
76
- };
77
- };
78
- });
79
- exports.openapi = openapiDecorator;
80
- exports.openapi.fromSchema = fromSchema_1.fromSchema;