@e22m4u/ts-rest-router 0.0.7 → 0.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/README-ru.md +114 -91
- package/README.md +106 -85
- package/dist/cjs/index.cjs +427 -123
- package/dist/esm/controller-registry.d.ts +53 -11
- package/dist/esm/controller-registry.js +242 -104
- package/dist/esm/debuggable-service.js +1 -1
- package/dist/esm/decorators/after/after-decorator.d.ts +9 -0
- package/dist/esm/decorators/after/after-decorator.js +22 -0
- package/dist/esm/decorators/after/after-decorator.spec.d.ts +1 -0
- package/dist/esm/decorators/after/after-decorator.spec.js +115 -0
- package/dist/esm/decorators/after/after-metadata.d.ts +13 -0
- package/dist/esm/decorators/after/after-metadata.js +5 -0
- package/dist/esm/decorators/after/after-reflector.d.ts +22 -0
- package/dist/esm/decorators/after/after-reflector.js +29 -0
- package/dist/esm/decorators/after/after-reflector.spec.d.ts +1 -0
- package/dist/esm/decorators/after/after-reflector.spec.js +102 -0
- package/dist/esm/decorators/after/index.d.ts +3 -0
- package/dist/esm/decorators/after/index.js +3 -0
- package/dist/esm/decorators/before/before-decorator.d.ts +9 -0
- package/dist/esm/decorators/before/before-decorator.js +22 -0
- package/dist/esm/decorators/before/before-decorator.spec.d.ts +1 -0
- package/dist/esm/decorators/before/before-decorator.spec.js +115 -0
- package/dist/esm/decorators/before/before-metadata.d.ts +13 -0
- package/dist/esm/decorators/before/before-metadata.js +5 -0
- package/dist/esm/decorators/before/before-reflector.d.ts +22 -0
- package/dist/esm/decorators/before/before-reflector.js +29 -0
- package/dist/esm/decorators/before/before-reflector.spec.d.ts +1 -0
- package/dist/esm/decorators/before/before-reflector.spec.js +102 -0
- package/dist/esm/decorators/before/index.d.ts +3 -0
- package/dist/esm/decorators/before/index.js +3 -0
- package/dist/esm/decorators/controller/controller-decorator.d.ts +2 -1
- package/dist/esm/decorators/controller/controller-decorator.js +26 -1
- package/dist/esm/decorators/controller/controller-decorator.spec.js +28 -0
- package/dist/esm/decorators/index.d.ts +2 -0
- package/dist/esm/decorators/index.js +2 -0
- package/dist/esm/decorators/request-data/request-data-decorator.d.ts +1 -1
- package/dist/esm/decorators/request-data/request-data-decorator.js +1 -1
- package/dist/esm/decorators/request-data/request-data-decorator.spec.js +5 -5
- package/dist/esm/utils/create-debugger.d.ts +35 -2
- package/dist/esm/utils/create-debugger.js +71 -5
- package/package.json +1 -1
- package/src/controller-registry.spec.ts +601 -275
- package/src/controller-registry.ts +263 -128
- package/src/debuggable-service.ts +1 -1
- package/src/decorators/after/after-decorator.spec.ts +92 -0
- package/src/decorators/after/after-decorator.ts +40 -0
- package/src/decorators/after/after-metadata.ts +17 -0
- package/src/decorators/after/after-reflector.spec.ts +107 -0
- package/src/decorators/after/after-reflector.ts +45 -0
- package/src/decorators/after/index.ts +3 -0
- package/src/decorators/before/before-decorator.spec.ts +92 -0
- package/src/decorators/before/before-decorator.ts +40 -0
- package/src/decorators/before/before-metadata.ts +17 -0
- package/src/decorators/before/before-reflector.spec.ts +111 -0
- package/src/decorators/before/before-reflector.ts +50 -0
- package/src/decorators/before/index.ts +3 -0
- package/src/decorators/controller/controller-decorator.spec.ts +22 -0
- package/src/decorators/controller/controller-decorator.ts +29 -1
- package/src/decorators/index.ts +2 -0
- package/src/decorators/request-data/request-data-decorator.spec.ts +5 -5
- package/src/decorators/request-data/request-data-decorator.ts +1 -1
- package/src/utils/create-debugger.ts +84 -7
@@ -4,13 +4,38 @@ import { ControllerReflector } from './controller-reflector.js';
|
|
4
4
|
/**
|
5
5
|
* Controller decorator.
|
6
6
|
*
|
7
|
+
* @param pathOrOptions
|
7
8
|
* @param options
|
8
9
|
*/
|
9
|
-
export function controller(options) {
|
10
|
+
export function controller(pathOrOptions, options) {
|
10
11
|
return function (target) {
|
11
12
|
const decoratorType = getDecoratorTargetType(target);
|
12
13
|
if (decoratorType !== DecoratorTargetType.CONSTRUCTOR)
|
13
14
|
throw new Error('@controller decorator is only supported on a class.');
|
15
|
+
// если первый аргумент является строкой,
|
16
|
+
// то значение используется в качестве
|
17
|
+
// базового пути контроллера
|
18
|
+
if (typeof pathOrOptions === 'string') {
|
19
|
+
// если второй аргумент не определен,
|
20
|
+
// то создается новый объект опций,
|
21
|
+
// который включает базовый путь
|
22
|
+
if (!options) {
|
23
|
+
options = { path: pathOrOptions };
|
24
|
+
}
|
25
|
+
// если второй аргумент определен,
|
26
|
+
// то базовый путь из первого аргумента
|
27
|
+
// передается в объект опций декоратора
|
28
|
+
else {
|
29
|
+
options.path = pathOrOptions;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
// если первый аргумент является объектом,
|
33
|
+
// то его значение используется в качестве
|
34
|
+
// объекта опций декоратора, а второй
|
35
|
+
// аргумент игнорируется
|
36
|
+
else if (typeof pathOrOptions === 'object') {
|
37
|
+
options = pathOrOptions;
|
38
|
+
}
|
14
39
|
ControllerReflector.setMetadata({ ...options, className: target.name }, target);
|
15
40
|
};
|
16
41
|
}
|
@@ -44,4 +44,32 @@ describe('controller', function () {
|
|
44
44
|
const res = ControllerReflector.getMetadata(Target);
|
45
45
|
expect(res).to.be.eql({ className: 'Target' });
|
46
46
|
});
|
47
|
+
it('allows to pass the path option to the first parameter', function () {
|
48
|
+
let Target = class Target {
|
49
|
+
};
|
50
|
+
Target = __decorate([
|
51
|
+
controller('myPath')
|
52
|
+
], Target);
|
53
|
+
const res = ControllerReflector.getMetadata(Target);
|
54
|
+
expect(res).to.be.eql({ className: 'Target', path: 'myPath' });
|
55
|
+
});
|
56
|
+
it('merges two given arguments in the target metadata', function () {
|
57
|
+
const before = () => undefined;
|
58
|
+
let Target = class Target {
|
59
|
+
};
|
60
|
+
Target = __decorate([
|
61
|
+
controller('myPath', { before })
|
62
|
+
], Target);
|
63
|
+
const res = ControllerReflector.getMetadata(Target);
|
64
|
+
expect(res).to.be.eql({ className: 'Target', path: 'myPath', before });
|
65
|
+
});
|
66
|
+
it('overrides the path option by the first argument', function () {
|
67
|
+
let Target = class Target {
|
68
|
+
};
|
69
|
+
Target = __decorate([
|
70
|
+
controller('myPath1', { path: 'myPath2' })
|
71
|
+
], Target);
|
72
|
+
const res = ControllerReflector.getMetadata(Target);
|
73
|
+
expect(res).to.be.eql({ className: 'Target', path: 'myPath1' });
|
74
|
+
});
|
47
75
|
});
|
@@ -23,7 +23,7 @@ export declare const headers: () => (target: Prototype<object>, propertyKey: str
|
|
23
23
|
export declare const header: (propertyKey: string, schemaOrType?: DataSchema | DataType) => (target: Prototype<object>, propertyKey: string, indexOrDescriptor: number) => void;
|
24
24
|
export declare const cookies: () => (target: Prototype<object>, propertyKey: string, indexOrDescriptor: number) => void;
|
25
25
|
export declare const cookie: (propertyKey: string, schemaOrType?: DataSchema | DataType) => (target: Prototype<object>, propertyKey: string, indexOrDescriptor: number) => void;
|
26
|
-
export declare const
|
26
|
+
export declare const bodyProp: (propertyKey: string, schemaOrType?: DataSchema | DataType) => (target: Prototype<object>, propertyKey: string, indexOrDescriptor: number) => void;
|
27
27
|
/**
|
28
28
|
* Request body decorator.
|
29
29
|
*
|
@@ -63,7 +63,7 @@ export const headers = createRequestDataDecoratorWithSource(RequestDataSource.HE
|
|
63
63
|
export const header = createRequestDataPropertyDecoratorWithSource(RequestDataSource.HEADERS);
|
64
64
|
export const cookies = createRequestDataDecoratorWithSource(RequestDataSource.COOKIE);
|
65
65
|
export const cookie = createRequestDataPropertyDecoratorWithSource(RequestDataSource.COOKIE);
|
66
|
-
export const
|
66
|
+
export const bodyProp = createRequestDataPropertyDecoratorWithSource(RequestDataSource.BODY);
|
67
67
|
/**
|
68
68
|
* Request body decorator.
|
69
69
|
*
|
@@ -22,7 +22,7 @@ import { params } from './request-data-decorator.js';
|
|
22
22
|
import { queries } from './request-data-decorator.js';
|
23
23
|
import { cookies } from './request-data-decorator.js';
|
24
24
|
import { headers } from './request-data-decorator.js';
|
25
|
-
import {
|
25
|
+
import { bodyProp } from './request-data-decorator.js';
|
26
26
|
import { requestData } from './request-data-decorator.js';
|
27
27
|
import { RequestDataSource } from './request-data-metadata.js';
|
28
28
|
import { RequestDataReflector } from './request-data-reflector.js';
|
@@ -460,13 +460,13 @@ describe('requestData', function () {
|
|
460
460
|
});
|
461
461
|
});
|
462
462
|
});
|
463
|
-
describe('
|
463
|
+
describe('bodyProp', function () {
|
464
464
|
it('sets a given "propertyKey" to the target metadata', function () {
|
465
465
|
class Target {
|
466
466
|
myMethod(prop) { }
|
467
467
|
}
|
468
468
|
__decorate([
|
469
|
-
__param(0,
|
469
|
+
__param(0, bodyProp('myPropertyKey')),
|
470
470
|
__metadata("design:type", Function),
|
471
471
|
__metadata("design:paramtypes", [Object]),
|
472
472
|
__metadata("design:returntype", void 0)
|
@@ -485,7 +485,7 @@ describe('requestData', function () {
|
|
485
485
|
myMethod(prop) { }
|
486
486
|
}
|
487
487
|
__decorate([
|
488
|
-
__param(0,
|
488
|
+
__param(0, bodyProp(propertyKey, propertyType)),
|
489
489
|
__metadata("design:type", Function),
|
490
490
|
__metadata("design:paramtypes", [Object]),
|
491
491
|
__metadata("design:returntype", void 0)
|
@@ -514,7 +514,7 @@ describe('requestData', function () {
|
|
514
514
|
myMethod(prop) { }
|
515
515
|
}
|
516
516
|
__decorate([
|
517
|
-
__param(0,
|
517
|
+
__param(0, bodyProp(propertyKey, schema)),
|
518
518
|
__metadata("design:type", Function),
|
519
519
|
__metadata("design:paramtypes", [Object]),
|
520
520
|
__metadata("design:returntype", void 0)
|
@@ -1,11 +1,44 @@
|
|
1
|
-
import { format } from '@e22m4u/js-format';
|
2
1
|
/**
|
3
2
|
* Debugger.
|
4
3
|
*/
|
5
|
-
export type Debugger = (...args:
|
4
|
+
export type Debugger = (messageOrData: string | unknown, ...args: any[]) => void;
|
6
5
|
/**
|
7
6
|
* Create debugger.
|
8
7
|
*
|
8
|
+
* Base usage:
|
9
|
+
* ```ts
|
10
|
+
* const debug = createDebugger('myService');
|
11
|
+
* debug('Service created.');
|
12
|
+
* // ujut:myService Service created.
|
13
|
+
* ```
|
14
|
+
*
|
15
|
+
* Nested namespaces:
|
16
|
+
* ```ts
|
17
|
+
* const debug1 = debug.bind('namespace1');
|
18
|
+
* const debug2 = debug.bind('namespace2');
|
19
|
+
* debug1('Application started'); // ujut:myService [namespace1] Application started
|
20
|
+
* debug2('Connection established'); // ujut:myService [namespace2] Connection established
|
21
|
+
* ```
|
22
|
+
*
|
23
|
+
* Value inspection:
|
24
|
+
* ```ts
|
25
|
+
* debug({foo: 'lorem', bar: 'ipsum'})
|
26
|
+
* // ujut:myService {
|
27
|
+
* // ujut:myService "foo": "lorem",
|
28
|
+
* // ujut:myService "bar": "ipsum"
|
29
|
+
* // ujut:myService }
|
30
|
+
* ```
|
31
|
+
*
|
32
|
+
* Titled inspection output:
|
33
|
+
* ```ts
|
34
|
+
* debug({foo: 'lorem', bar: 'ipsum'}, 'My awesome output:')
|
35
|
+
* // ujut:myService My awesome output:
|
36
|
+
* // ujut:myService {
|
37
|
+
* // ujut:myService "foo": "lorem",
|
38
|
+
* // ujut:myService "bar": "ipsum"
|
39
|
+
* // ujut:myService }
|
40
|
+
* ```
|
41
|
+
*
|
9
42
|
* @param name
|
10
43
|
*/
|
11
44
|
export declare function createDebugger(name: string): Debugger;
|
@@ -1,15 +1,81 @@
|
|
1
|
-
import
|
1
|
+
import { inspect } from 'util';
|
2
|
+
import DebugModule from 'debug';
|
2
3
|
import { format } from '@e22m4u/js-format';
|
4
|
+
/**
|
5
|
+
* Colorize string.
|
6
|
+
*
|
7
|
+
* @param input
|
8
|
+
*/
|
9
|
+
function colorizeString(input) {
|
10
|
+
const c = Number(DebugModule['selectColor'](input));
|
11
|
+
const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
|
12
|
+
return `${colorCode};1m${input}\u001B[0m`;
|
13
|
+
}
|
3
14
|
/**
|
4
15
|
* Create debugger.
|
5
16
|
*
|
17
|
+
* Base usage:
|
18
|
+
* ```ts
|
19
|
+
* const debug = createDebugger('myService');
|
20
|
+
* debug('Service created.');
|
21
|
+
* // ujut:myService Service created.
|
22
|
+
* ```
|
23
|
+
*
|
24
|
+
* Nested namespaces:
|
25
|
+
* ```ts
|
26
|
+
* const debug1 = debug.bind('namespace1');
|
27
|
+
* const debug2 = debug.bind('namespace2');
|
28
|
+
* debug1('Application started'); // ujut:myService [namespace1] Application started
|
29
|
+
* debug2('Connection established'); // ujut:myService [namespace2] Connection established
|
30
|
+
* ```
|
31
|
+
*
|
32
|
+
* Value inspection:
|
33
|
+
* ```ts
|
34
|
+
* debug({foo: 'lorem', bar: 'ipsum'})
|
35
|
+
* // ujut:myService {
|
36
|
+
* // ujut:myService "foo": "lorem",
|
37
|
+
* // ujut:myService "bar": "ipsum"
|
38
|
+
* // ujut:myService }
|
39
|
+
* ```
|
40
|
+
*
|
41
|
+
* Titled inspection output:
|
42
|
+
* ```ts
|
43
|
+
* debug({foo: 'lorem', bar: 'ipsum'}, 'My awesome output:')
|
44
|
+
* // ujut:myService My awesome output:
|
45
|
+
* // ujut:myService {
|
46
|
+
* // ujut:myService "foo": "lorem",
|
47
|
+
* // ujut:myService "bar": "ipsum"
|
48
|
+
* // ujut:myService }
|
49
|
+
* ```
|
50
|
+
*
|
6
51
|
* @param name
|
7
52
|
*/
|
8
53
|
export function createDebugger(name) {
|
9
|
-
const
|
54
|
+
const debuggerName = `tsRestRouter:${name}`;
|
55
|
+
// включить вывод логов можно принудительно
|
56
|
+
// if (!process.env.DEBUG) DebugModule.enable('ujut*');
|
57
|
+
const debug = DebugModule(debuggerName);
|
58
|
+
return function (messageOrData,
|
10
59
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
11
|
-
|
12
|
-
|
13
|
-
|
60
|
+
...args) {
|
61
|
+
let prefix = '';
|
62
|
+
if (typeof this === 'string') {
|
63
|
+
const isDebugUsesColors = debug.useColors;
|
64
|
+
prefix = isDebugUsesColors ? colorizeString(`[${this}] `) : `[${this}] `;
|
65
|
+
}
|
66
|
+
if (typeof messageOrData === 'string') {
|
67
|
+
const interpolatedMessage = format(messageOrData, ...args);
|
68
|
+
return debug(prefix + interpolatedMessage);
|
69
|
+
}
|
70
|
+
const inspectOptions = {
|
71
|
+
showHidden: false,
|
72
|
+
depth: null,
|
73
|
+
colors: true,
|
74
|
+
compact: false,
|
75
|
+
};
|
76
|
+
const multiString = inspect(messageOrData, inspectOptions);
|
77
|
+
const rows = multiString.split('\n');
|
78
|
+
const colorizedDebuggerName = colorizeString(debuggerName);
|
79
|
+
[...args, ...rows].forEach(v => console.log(` ${colorizedDebuggerName} ${prefix}${v}`));
|
14
80
|
};
|
15
81
|
}
|