vovk 3.0.3 → 3.1.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/dist/core/applyDecoratorAdapter.d.ts +7 -0
- package/dist/core/applyDecoratorAdapter.js +50 -0
- package/dist/core/compose.d.ts +38 -0
- package/dist/core/compose.js +34 -0
- package/dist/core/createDecorator.d.ts +1 -7
- package/dist/core/createDecorator.js +2 -10
- package/dist/core/decorators.d.ts +14 -21
- package/dist/core/decorators.js +12 -33
- package/dist/core/initSegment.js +32 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/openapi/error.d.ts +1 -5
- package/dist/openapi/operation.d.ts +4 -20
- package/dist/openapi/tool.d.ts +1 -5
- package/package.json +1 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { VovkController } from '../types/core.js';
|
|
2
|
+
import type { KnownAny } from '../types/utils.js';
|
|
3
|
+
/**
|
|
4
|
+
* Adapts a decorator callback to work with experimental, 2018-09, and TC39 Stage 3 decorator formats.
|
|
5
|
+
* The callback receives (controller, propertyKey) when the class and field/method value are available.
|
|
6
|
+
*/
|
|
7
|
+
export declare function applyDecoratorAdapter(arg1: unknown, arg2: unknown, callback: (controller: VovkController, propertyKey: string) => void): KnownAny;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapts a decorator callback to work with experimental, 2018-09, and TC39 Stage 3 decorator formats.
|
|
3
|
+
* The callback receives (controller, propertyKey) when the class and field/method value are available.
|
|
4
|
+
*/
|
|
5
|
+
export function applyDecoratorAdapter(arg1, arg2, callback) {
|
|
6
|
+
// Experimental decorators: (target, propertyKey: string)
|
|
7
|
+
if (typeof arg2 === 'string') {
|
|
8
|
+
callback(arg1, arg2);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
// TC39 Stage 3: (value, context: { kind, name, addInitializer })
|
|
12
|
+
if (typeof arg2 === 'object' && arg2 !== null && 'name' in arg2) {
|
|
13
|
+
const ctx = arg2;
|
|
14
|
+
const propertyKey = String(ctx.name);
|
|
15
|
+
if (ctx.kind === 'field') {
|
|
16
|
+
return function (initialValue) {
|
|
17
|
+
this[propertyKey] = initialValue;
|
|
18
|
+
callback(this, propertyKey);
|
|
19
|
+
return this[propertyKey];
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
ctx.addInitializer(function () {
|
|
23
|
+
callback(this, propertyKey);
|
|
24
|
+
});
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// 2018-09 proposal: (descriptor: { kind, key, placement, initializer? })
|
|
28
|
+
if (typeof arg1 === 'object' && arg1 !== null && 'kind' in arg1 && 'key' in arg1) {
|
|
29
|
+
const desc = arg1;
|
|
30
|
+
const propertyKey = String(desc.key);
|
|
31
|
+
if (desc.kind === 'field') {
|
|
32
|
+
const origInit = desc.initializer;
|
|
33
|
+
return {
|
|
34
|
+
...desc,
|
|
35
|
+
initializer() {
|
|
36
|
+
const value = origInit?.call(this);
|
|
37
|
+
this[propertyKey] = value;
|
|
38
|
+
callback(this, propertyKey);
|
|
39
|
+
return this[propertyKey];
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
...desc,
|
|
45
|
+
finisher(klass) {
|
|
46
|
+
callback(klass, propertyKey);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { KnownAny } from '../types/utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* Metadata stored on a handler by HTTP decorators and custom decorators when used outside decorator context (via compose).
|
|
4
|
+
*/
|
|
5
|
+
export type ComposeMetadata = {
|
|
6
|
+
httpMethod?: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
options?: KnownAny;
|
|
9
|
+
decoratorAppliers?: ((controller: KnownAny, propertyKey: string) => void)[];
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Composes decorators and a handler/class into a single value.
|
|
13
|
+
*
|
|
14
|
+
* For method-level composition, decorators are stored and applied later by initSegment.
|
|
15
|
+
* For class-level composition, decorators like prefix() and cloneControllerMetadata()
|
|
16
|
+
* are applied immediately to the class in reverse order (matching stacked decorator semantics).
|
|
17
|
+
*
|
|
18
|
+
* @example Method-level
|
|
19
|
+
* ```ts
|
|
20
|
+
* static handleParams = compose(
|
|
21
|
+
* put('x/{foo}/{bar}/y'),
|
|
22
|
+
* authGuard(null),
|
|
23
|
+
* procedure({ params: z.object({ foo: z.string(), bar: z.string() }) })
|
|
24
|
+
* .handle(async (req) => req.vovk.params())
|
|
25
|
+
* );
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example Class-level
|
|
29
|
+
* ```ts
|
|
30
|
+
* const MyController = compose(
|
|
31
|
+
* prefix('users'),
|
|
32
|
+
* cloneControllerMetadata(),
|
|
33
|
+
* class extends ParentController {}
|
|
34
|
+
* );
|
|
35
|
+
* export default MyController;
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function compose<T>(...args: [...unknown[], T]): T;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function compose(...args) {
|
|
2
|
+
if (args.length === 0)
|
|
3
|
+
throw new Error('compose() requires at least one argument');
|
|
4
|
+
const last = args[args.length - 1];
|
|
5
|
+
const decoratorFns = args.slice(0, -1);
|
|
6
|
+
if (typeof last !== 'function') {
|
|
7
|
+
throw new Error('The last argument to compose() must be a function, handler, or class');
|
|
8
|
+
}
|
|
9
|
+
for (const decoratorFn of decoratorFns) {
|
|
10
|
+
if (typeof decoratorFn !== 'function') {
|
|
11
|
+
throw new Error('All arguments to compose() except the last must be decorator functions');
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// Detect class: native ES class constructors' toString() starts with "class"
|
|
15
|
+
if (last.toString().startsWith('class ')) {
|
|
16
|
+
// Apply class decorators immediately in reverse order (bottom-up, matching stacked decorator semantics)
|
|
17
|
+
let result = last;
|
|
18
|
+
for (let i = decoratorFns.length - 1; i >= 0; i--) {
|
|
19
|
+
const transformed = decoratorFns[i](result);
|
|
20
|
+
if (transformed !== undefined) {
|
|
21
|
+
result = transformed;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
// Method-level compose: store decorator appliers for deferred execution by initSegment
|
|
27
|
+
const handler = last;
|
|
28
|
+
handler._composeMetadata = handler._composeMetadata ?? {};
|
|
29
|
+
handler._composeMetadata.decoratorAppliers = handler._composeMetadata.decoratorAppliers ?? [];
|
|
30
|
+
for (const decoratorFn of decoratorFns) {
|
|
31
|
+
handler._composeMetadata.decoratorAppliers.push(decoratorFn);
|
|
32
|
+
}
|
|
33
|
+
return handler;
|
|
34
|
+
}
|
|
@@ -2,17 +2,11 @@ import type { VovkHandlerSchema, VovkController } from '../types/core.js';
|
|
|
2
2
|
import type { VovkRequest } from '../types/request.js';
|
|
3
3
|
import type { KnownAny } from '../types/utils.js';
|
|
4
4
|
type Next = () => Promise<unknown>;
|
|
5
|
-
/** Minimal shape shared by all TC39 Stage 3 decorator context objects. */
|
|
6
|
-
type _Stage3Context = {
|
|
7
|
-
kind: string;
|
|
8
|
-
name: string | symbol;
|
|
9
|
-
addInitializer: (fn: () => void) => void;
|
|
10
|
-
};
|
|
11
5
|
/**
|
|
12
6
|
* Creates a custom decorator for Vovk controllers.
|
|
13
7
|
* @see https://vovk.dev/decorator
|
|
14
8
|
*/
|
|
15
9
|
export declare function createDecorator<TArgs extends unknown[], TRequest = VovkRequest>(handler: null | ((this: VovkController, req: TRequest, next: Next, ...args: TArgs) => unknown), initHandler?: (this: VovkController, ...args: TArgs) => Omit<VovkHandlerSchema, 'path' | 'httpMethod'> | ((handlerSchema: VovkHandlerSchema | null, options: {
|
|
16
10
|
handlerName: string;
|
|
17
|
-
}) => Omit<Partial<VovkHandlerSchema>, 'path' | 'httpMethod'>) | null | undefined): (...args: TArgs) => (target: KnownAny, propertyKeyOrContext
|
|
11
|
+
}) => Omit<Partial<VovkHandlerSchema>, 'path' | 'httpMethod'>) | null | undefined): (...args: TArgs) => (target: KnownAny, propertyKeyOrContext?: unknown) => KnownAny;
|
|
18
12
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { applyDecoratorAdapter } from './applyDecoratorAdapter.js';
|
|
1
2
|
/**
|
|
2
3
|
* Creates a custom decorator for Vovk controllers.
|
|
3
4
|
* @see https://vovk.dev/decorator
|
|
@@ -5,16 +6,7 @@
|
|
|
5
6
|
export function createDecorator(handler, initHandler) {
|
|
6
7
|
return function decoratorCreator(...args) {
|
|
7
8
|
return function decorator(target, propertyKeyOrContext) {
|
|
8
|
-
|
|
9
|
-
// TC39 Stage 3 decorator — defer to addInitializer where `this` is the class
|
|
10
|
-
const propertyKey = String(propertyKeyOrContext.name);
|
|
11
|
-
propertyKeyOrContext.addInitializer(function () {
|
|
12
|
-
applyDecorator(this, propertyKey);
|
|
13
|
-
});
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
// Experimental decorator — target is the class for static members
|
|
17
|
-
applyDecorator(target, propertyKeyOrContext);
|
|
9
|
+
return applyDecoratorAdapter(target, propertyKeyOrContext, applyDecorator);
|
|
18
10
|
function applyDecorator(controller, propertyKey) {
|
|
19
11
|
const originalMethod = controller[propertyKey];
|
|
20
12
|
if (typeof originalMethod !== 'function') {
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { DecoratorOptions } from '../types/core.js';
|
|
2
2
|
import type { KnownAny } from '../types/utils.js';
|
|
3
|
-
/** Minimal shape shared by all TC39 Stage 3 decorator context objects. */
|
|
4
|
-
type _Stage3Context = {
|
|
5
|
-
kind: string;
|
|
6
|
-
name: string | symbol;
|
|
7
|
-
addInitializer: (fn: () => void) => void;
|
|
8
|
-
};
|
|
9
3
|
/**
|
|
10
4
|
* Prefix for all routes in the controller.
|
|
11
5
|
*/
|
|
@@ -18,49 +12,48 @@ export declare function cloneControllerMetadata(): <T extends new (...args: Know
|
|
|
18
12
|
* GET HTTP method decorator.
|
|
19
13
|
*/
|
|
20
14
|
export declare const get: {
|
|
21
|
-
(givenPath?: string | undefined, options?: DecoratorOptions | undefined): (givenTarget: unknown, propertyKeyOrContext
|
|
22
|
-
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext
|
|
15
|
+
(givenPath?: string | undefined, options?: DecoratorOptions | undefined): (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
16
|
+
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
23
17
|
};
|
|
24
18
|
/**
|
|
25
19
|
* POST HTTP method decorator.
|
|
26
20
|
*/
|
|
27
21
|
export declare const post: {
|
|
28
|
-
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext
|
|
29
|
-
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext
|
|
22
|
+
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
23
|
+
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
30
24
|
};
|
|
31
25
|
/**
|
|
32
26
|
* PUT HTTP method decorator.
|
|
33
27
|
*/
|
|
34
28
|
export declare const put: {
|
|
35
|
-
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext
|
|
36
|
-
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext
|
|
29
|
+
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
30
|
+
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
37
31
|
};
|
|
38
32
|
/**
|
|
39
33
|
* PATCH HTTP method decorator.
|
|
40
34
|
*/
|
|
41
35
|
export declare const patch: {
|
|
42
|
-
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext
|
|
43
|
-
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext
|
|
36
|
+
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
37
|
+
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
44
38
|
};
|
|
45
39
|
/**
|
|
46
40
|
* DELETE HTTP method decorator.
|
|
47
41
|
*/
|
|
48
42
|
export declare const del: {
|
|
49
|
-
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext
|
|
50
|
-
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext
|
|
43
|
+
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
44
|
+
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
51
45
|
};
|
|
52
46
|
/**
|
|
53
47
|
* HEAD HTTP method decorator.
|
|
54
48
|
*/
|
|
55
49
|
export declare const head: {
|
|
56
|
-
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext
|
|
57
|
-
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext
|
|
50
|
+
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
51
|
+
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
58
52
|
};
|
|
59
53
|
/**
|
|
60
54
|
* OPTIONS HTTP method decorator.
|
|
61
55
|
*/
|
|
62
56
|
export declare const options: {
|
|
63
|
-
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext
|
|
64
|
-
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext
|
|
57
|
+
(givenPath?: string | undefined, options?: Omit<DecoratorOptions, "staticParams"> | undefined): (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
58
|
+
auto: (options?: DecoratorOptions) => (givenTarget: unknown, propertyKeyOrContext?: unknown) => KnownAny;
|
|
65
59
|
};
|
|
66
|
-
export {};
|
package/dist/core/decorators.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { vovkApp } from './vovkApp.js';
|
|
2
2
|
import { trimPath } from '../utils/trimPath.js';
|
|
3
3
|
import { toKebabCase } from '../utils/toKebabCase.js';
|
|
4
|
+
import { applyDecoratorAdapter } from './applyDecoratorAdapter.js';
|
|
4
5
|
import { HttpMethod } from '../types/enums.js';
|
|
5
6
|
const isClass = (func) => typeof func === 'function' && /class/.test(func.toString());
|
|
6
|
-
/** Detects whether the second decorator argument is a TC39 Stage 3 context object. */
|
|
7
|
-
const _isStage3 = (arg) => typeof arg === 'object' && arg !== null && 'kind' in arg;
|
|
8
7
|
const assignSchema = ({ controller, propertyKey, path, options, httpMethod, }) => {
|
|
9
8
|
if (typeof window !== 'undefined') {
|
|
10
9
|
throw new Error('HTTP decorators can be used on server-side only. You have probably imported a controller on the client-side.');
|
|
@@ -55,42 +54,22 @@ function createHTTPDecorator(httpMethod) {
|
|
|
55
54
|
function decoratorFactory(givenPath = '', options) {
|
|
56
55
|
const path = trimPath(givenPath);
|
|
57
56
|
function decorator(givenTarget, propertyKeyOrContext) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
assignSchema({ controller: this, propertyKey, path, options, httpMethod });
|
|
62
|
-
});
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
const controller = givenTarget;
|
|
66
|
-
assignSchema({ controller, propertyKey: propertyKeyOrContext, path, options, httpMethod });
|
|
57
|
+
return applyDecoratorAdapter(givenTarget, propertyKeyOrContext, (controller, propertyKey) => {
|
|
58
|
+
assignSchema({ controller, propertyKey, path, options, httpMethod });
|
|
59
|
+
});
|
|
67
60
|
}
|
|
68
61
|
return decorator;
|
|
69
62
|
}
|
|
70
63
|
const auto = (options) => {
|
|
71
64
|
function decorator(givenTarget, propertyKeyOrContext) {
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
? `${kebabCasePath}/${properties.map((prop) => `{${prop}}`).join('/')}`
|
|
81
|
-
: kebabCasePath;
|
|
82
|
-
assignSchema({ controller, propertyKey, path, options, httpMethod });
|
|
83
|
-
});
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const controller = givenTarget;
|
|
87
|
-
// validation is already assigned at procedure function
|
|
88
|
-
const properties = Object.keys(controller._handlers?.[propertyKeyOrContext]?.validation?.params?.properties ?? {});
|
|
89
|
-
const kebabCasePath = toKebabCase(propertyKeyOrContext);
|
|
90
|
-
const path = properties.length
|
|
91
|
-
? `${kebabCasePath}/${properties.map((prop) => `{${prop}}`).join('/')}`
|
|
92
|
-
: kebabCasePath;
|
|
93
|
-
assignSchema({ controller, propertyKey: propertyKeyOrContext, path, options, httpMethod });
|
|
65
|
+
return applyDecoratorAdapter(givenTarget, propertyKeyOrContext, (controller, propertyKey) => {
|
|
66
|
+
const properties = Object.keys(controller._handlers?.[propertyKey]?.validation?.params?.properties ?? {});
|
|
67
|
+
const kebabCasePath = toKebabCase(propertyKey);
|
|
68
|
+
const path = properties.length
|
|
69
|
+
? `${kebabCasePath}/${properties.map((prop) => `{${prop}}`).join('/')}`
|
|
70
|
+
: kebabCasePath;
|
|
71
|
+
assignSchema({ controller, propertyKey, path, options, httpMethod });
|
|
72
|
+
});
|
|
94
73
|
}
|
|
95
74
|
return decorator;
|
|
96
75
|
};
|
package/dist/core/initSegment.js
CHANGED
|
@@ -4,12 +4,43 @@ import { getSchema } from './getSchema.js';
|
|
|
4
4
|
export const initSegment = (options) => {
|
|
5
5
|
const segmentName = trimPath(options.segmentName ?? '');
|
|
6
6
|
options.segmentName = segmentName;
|
|
7
|
-
|
|
7
|
+
const controllerEntries = Object.entries(options.controllers ?? {});
|
|
8
|
+
// Phase 1: Apply compose metadata for all controllers
|
|
9
|
+
for (const [rpcModuleName, controller] of controllerEntries) {
|
|
8
10
|
controller._segmentName = segmentName;
|
|
9
11
|
controller._rpcModuleName = rpcModuleName;
|
|
10
12
|
controller._onError = options?.onError;
|
|
11
13
|
controller._onSuccess = options?.onSuccess;
|
|
12
14
|
controller._onBefore = options?.onBefore;
|
|
15
|
+
// Apply compose() metadata: call decorator appliers for each composed handler
|
|
16
|
+
for (const key of Object.getOwnPropertyNames(controller)) {
|
|
17
|
+
const method = controller[key];
|
|
18
|
+
if (typeof method === 'function' && method._composeMetadata) {
|
|
19
|
+
const metadata = method._composeMetadata;
|
|
20
|
+
if (metadata.decoratorAppliers) {
|
|
21
|
+
// Apply in reverse order to match decorator semantics (bottom-up)
|
|
22
|
+
for (let i = metadata.decoratorAppliers.length - 1; i >= 0; i--) {
|
|
23
|
+
// Call decorator function with (controller, propertyKey) simulating experimental decorator context
|
|
24
|
+
metadata.decoratorAppliers[i](controller, key);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Phase 2: Re-clone metadata for controllers that extend another registered controller.
|
|
31
|
+
// This is needed because cloneControllerMetadata() may run before compose metadata is applied
|
|
32
|
+
// (e.g., when using class-level compose with a parent that uses method-level compose).
|
|
33
|
+
const controllerSet = new Set(controllerEntries.map(([, c]) => c));
|
|
34
|
+
for (const [, controller] of controllerEntries) {
|
|
35
|
+
const parent = Object.getPrototypeOf(controller);
|
|
36
|
+
if (parent && controllerSet.has(parent) && parent._handlers) {
|
|
37
|
+
controller._handlers = { ...parent._handlers, ...controller._handlers };
|
|
38
|
+
controller._handlersMetadata = { ...parent._handlersMetadata, ...controller._handlersMetadata };
|
|
39
|
+
Object.values(vovkApp.routes).forEach((methods) => {
|
|
40
|
+
const parentMethods = methods.get(parent) ?? {};
|
|
41
|
+
methods.set(controller, { ...parentMethods, ...methods.get(controller) });
|
|
42
|
+
});
|
|
43
|
+
}
|
|
13
44
|
}
|
|
14
45
|
async function GET_DEV(req, data) {
|
|
15
46
|
const params = await data.params;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { multitenant } from './core/multitenant.js';
|
|
|
5
5
|
export { JSONLinesResponder } from './core/JSONLinesResponder.js';
|
|
6
6
|
export { toDownloadResponse } from './core/toDownloadResponse.js';
|
|
7
7
|
export { get, post, put, patch, del, head, options, prefix, cloneControllerMetadata } from './core/decorators.js';
|
|
8
|
+
export { compose } from './core/compose.js';
|
|
8
9
|
export { progressive } from './client/progressive.js';
|
|
9
10
|
export { fetcher, createFetcher } from './client/fetcher.js';
|
|
10
11
|
export { initSegment } from './core/initSegment.js';
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { multitenant } from './core/multitenant.js';
|
|
|
6
6
|
export { JSONLinesResponder } from './core/JSONLinesResponder.js';
|
|
7
7
|
export { toDownloadResponse } from './core/toDownloadResponse.js';
|
|
8
8
|
export { get, post, put, patch, del, head, options, prefix, cloneControllerMetadata } from './core/decorators.js';
|
|
9
|
+
export { compose } from './core/compose.js';
|
|
9
10
|
// client
|
|
10
11
|
export { progressive } from './client/progressive.js';
|
|
11
12
|
export { fetcher, createFetcher } from './client/fetcher.js';
|
package/dist/openapi/error.d.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
1
|
import { HttpStatus } from '../types/enums.js';
|
|
2
|
-
export declare const error: (status: HttpStatus, message: string) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext
|
|
3
|
-
kind: string;
|
|
4
|
-
name: string | symbol;
|
|
5
|
-
addInitializer: (fn: () => void) => void;
|
|
6
|
-
}) => void;
|
|
2
|
+
export declare const error: (status: HttpStatus, message: string) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext?: unknown) => import("../types/utils.js").KnownAny;
|
|
@@ -1,26 +1,10 @@
|
|
|
1
1
|
import type { VovkOperationObject } from '../types/operation.js';
|
|
2
|
-
export declare const operationDecorator: (openAPIOperationObject?: VovkOperationObject | undefined) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext
|
|
3
|
-
kind: string;
|
|
4
|
-
name: string | symbol;
|
|
5
|
-
addInitializer: (fn: () => void) => void;
|
|
6
|
-
}) => void;
|
|
2
|
+
export declare const operationDecorator: (openAPIOperationObject?: VovkOperationObject | undefined) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext?: unknown) => import("../types/utils.js").KnownAny;
|
|
7
3
|
/**
|
|
8
4
|
* OpenAPI operation decorator to add metadata to API operations. Also includes `error` and `tool` utilities.
|
|
9
5
|
* @see https://vovk.dev/openapi
|
|
10
6
|
*/
|
|
11
|
-
export declare const operation: ((openAPIOperationObject?: VovkOperationObject | undefined) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
addInitializer: (fn: () => void) => void;
|
|
15
|
-
}) => void) & {
|
|
16
|
-
error: (status: import("../index.js").HttpStatus, message: string) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext: string | {
|
|
17
|
-
kind: string;
|
|
18
|
-
name: string | symbol;
|
|
19
|
-
addInitializer: (fn: () => void) => void;
|
|
20
|
-
}) => void;
|
|
21
|
-
tool: (toolOptions: import("../types/tools.js").VovkToolOptions) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext: string | {
|
|
22
|
-
kind: string;
|
|
23
|
-
name: string | symbol;
|
|
24
|
-
addInitializer: (fn: () => void) => void;
|
|
25
|
-
}) => void;
|
|
7
|
+
export declare const operation: ((openAPIOperationObject?: VovkOperationObject | undefined) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext?: unknown) => import("../types/utils.js").KnownAny) & {
|
|
8
|
+
error: (status: import("../index.js").HttpStatus, message: string) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext?: unknown) => import("../types/utils.js").KnownAny;
|
|
9
|
+
tool: (toolOptions: import("../types/tools.js").VovkToolOptions) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext?: unknown) => import("../types/utils.js").KnownAny;
|
|
26
10
|
};
|
package/dist/openapi/tool.d.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
1
|
import type { VovkToolOptions } from '../types/tools.js';
|
|
2
|
-
export declare const tool: (toolOptions: VovkToolOptions) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext
|
|
3
|
-
kind: string;
|
|
4
|
-
name: string | symbol;
|
|
5
|
-
addInitializer: (fn: () => void) => void;
|
|
6
|
-
}) => void;
|
|
2
|
+
export declare const tool: (toolOptions: VovkToolOptions) => (target: import("../types/utils.js").KnownAny, propertyKeyOrContext?: unknown) => import("../types/utils.js").KnownAny;
|