vovk 3.0.2 → 3.0.4
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/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/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
|
+
}
|
|
@@ -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/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;
|