@e22m4u/ts-rest-router 0.0.6 → 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 +227 -0
- package/README.md +227 -0
- package/dist/cjs/index.cjs +448 -153
- 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/action/action-decorator.d.ts +7 -8
- package/dist/esm/decorators/action/action-decorator.js +1 -5
- package/dist/esm/decorators/action/action-decorator.spec.js +16 -16
- package/dist/esm/decorators/action/action-metadata.d.ts +0 -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 +27 -6
- package/dist/esm/decorators/controller/controller-decorator.spec.js +37 -15
- package/dist/esm/decorators/controller/controller-metadata.d.ts +0 -1
- package/dist/esm/decorators/index.d.ts +2 -0
- package/dist/esm/decorators/index.js +2 -0
- package/dist/esm/decorators/request-context/request-context-decorator.d.ts +2 -3
- package/dist/esm/decorators/request-context/request-context-decorator.js +3 -6
- package/dist/esm/decorators/request-context/request-context-decorator.spec.js +2 -17
- package/dist/esm/decorators/request-context/request-context-metadata.d.ts +0 -1
- package/dist/esm/decorators/request-data/request-data-decorator.d.ts +7 -3
- package/dist/esm/decorators/request-data/request-data-decorator.js +16 -16
- package/dist/esm/decorators/request-data/request-data-decorator.spec.js +12 -10
- package/dist/esm/decorators/request-data/request-data-metadata.d.ts +0 -1
- package/dist/esm/utils/create-debugger.d.ts +35 -2
- package/dist/esm/utils/create-debugger.js +71 -5
- package/package.json +17 -17
- 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/action/action-decorator.spec.ts +16 -16
- package/src/decorators/action/action-decorator.ts +10 -12
- package/src/decorators/action/action-metadata.ts +0 -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 +33 -16
- package/src/decorators/controller/controller-decorator.ts +33 -6
- package/src/decorators/controller/controller-metadata.ts +0 -1
- package/src/decorators/index.ts +2 -0
- package/src/decorators/request-context/request-context-decorator.spec.ts +2 -15
- package/src/decorators/request-context/request-context-decorator.ts +3 -8
- package/src/decorators/request-context/request-context-metadata.ts +0 -1
- package/src/decorators/request-data/request-data-decorator.spec.ts +12 -11
- package/src/decorators/request-data/request-data-decorator.ts +41 -16
- package/src/decorators/request-data/request-data-metadata.ts +0 -1
- package/src/utils/create-debugger.ts +84 -7
@@ -0,0 +1,50 @@
|
|
1
|
+
import {Constructor} from '../../types.js';
|
2
|
+
import {Reflector} from '@e22m4u/ts-reflector';
|
3
|
+
import {BeforeMetadata} from './before-metadata.js';
|
4
|
+
import {BEFORE_METADATA_KEY} from './before-metadata.js';
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Before reflector.
|
8
|
+
*/
|
9
|
+
export class BeforeReflector {
|
10
|
+
/**
|
11
|
+
* Set metadata.
|
12
|
+
*
|
13
|
+
* @param metadata
|
14
|
+
* @param target
|
15
|
+
* @param propertyKey
|
16
|
+
*/
|
17
|
+
static addMetadata(
|
18
|
+
metadata: BeforeMetadata,
|
19
|
+
target: Constructor,
|
20
|
+
propertyKey?: string,
|
21
|
+
) {
|
22
|
+
const oldArray =
|
23
|
+
Reflector.getOwnMetadata(BEFORE_METADATA_KEY, target, propertyKey) ?? [];
|
24
|
+
const newArray = [metadata, ...oldArray];
|
25
|
+
Reflector.defineMetadata(
|
26
|
+
BEFORE_METADATA_KEY,
|
27
|
+
newArray,
|
28
|
+
target,
|
29
|
+
propertyKey,
|
30
|
+
);
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Get metadata.
|
35
|
+
*
|
36
|
+
* @param target
|
37
|
+
* @param propertyKey
|
38
|
+
*/
|
39
|
+
static getMetadata(
|
40
|
+
target: Constructor,
|
41
|
+
propertyKey?: string,
|
42
|
+
): BeforeMetadata[] {
|
43
|
+
const metadata = Reflector.getOwnMetadata(
|
44
|
+
BEFORE_METADATA_KEY,
|
45
|
+
target,
|
46
|
+
propertyKey,
|
47
|
+
);
|
48
|
+
return metadata ?? [];
|
49
|
+
}
|
50
|
+
}
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import {expect} from 'chai';
|
2
2
|
import {controller} from './controller-decorator.js';
|
3
|
+
import {ControllerOptions} from './controller-decorator.js';
|
3
4
|
import {ControllerReflector} from './controller-reflector.js';
|
4
5
|
|
5
6
|
describe('controller', function () {
|
6
|
-
it('does not
|
7
|
+
it('does not require options', function () {
|
7
8
|
@controller()
|
8
9
|
class Target {}
|
9
10
|
const res = ControllerReflector.getMetadata(Target);
|
@@ -11,31 +12,47 @@ describe('controller', function () {
|
|
11
12
|
});
|
12
13
|
|
13
14
|
it('sets given options to the target metadata', function () {
|
14
|
-
const
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
after,
|
22
|
-
extraOption,
|
23
|
-
})
|
15
|
+
const options = {
|
16
|
+
path: 'myPath',
|
17
|
+
before: () => undefined,
|
18
|
+
after: () => undefined,
|
19
|
+
extraOption: 'extraOption',
|
20
|
+
};
|
21
|
+
@controller(options)
|
24
22
|
class Target {}
|
25
23
|
const res = ControllerReflector.getMetadata(Target);
|
26
24
|
expect(res).to.be.eql({
|
25
|
+
...options,
|
27
26
|
className: 'Target',
|
28
|
-
path,
|
29
|
-
before,
|
30
|
-
after,
|
31
|
-
extraOption,
|
32
27
|
});
|
33
28
|
});
|
34
29
|
|
35
30
|
it('overrides given "className" option by the target class name', function () {
|
36
|
-
@controller({className: 'myClassName'})
|
31
|
+
@controller({className: 'myClassName'} as ControllerOptions)
|
37
32
|
class Target {}
|
38
33
|
const res = ControllerReflector.getMetadata(Target);
|
39
34
|
expect(res).to.be.eql({className: 'Target'});
|
40
35
|
});
|
36
|
+
|
37
|
+
it('allows to pass the path option to the first parameter', function () {
|
38
|
+
@controller('myPath')
|
39
|
+
class Target {}
|
40
|
+
const res = ControllerReflector.getMetadata(Target);
|
41
|
+
expect(res).to.be.eql({className: 'Target', path: 'myPath'});
|
42
|
+
});
|
43
|
+
|
44
|
+
it('merges two given arguments in the target metadata', function () {
|
45
|
+
const before = () => undefined;
|
46
|
+
@controller('myPath', {before})
|
47
|
+
class Target {}
|
48
|
+
const res = ControllerReflector.getMetadata(Target);
|
49
|
+
expect(res).to.be.eql({className: 'Target', path: 'myPath', before});
|
50
|
+
});
|
51
|
+
|
52
|
+
it('overrides the path option by the first argument', function () {
|
53
|
+
@controller('myPath1', {path: 'myPath2'})
|
54
|
+
class Target {}
|
55
|
+
const res = ControllerReflector.getMetadata(Target);
|
56
|
+
expect(res).to.be.eql({className: 'Target', path: 'myPath1'});
|
57
|
+
});
|
41
58
|
});
|
@@ -13,17 +13,44 @@ export type ControllerOptions = Flatten<Omit<ControllerMetadata, 'className'>>;
|
|
13
13
|
/**
|
14
14
|
* Controller decorator.
|
15
15
|
*
|
16
|
+
* @param pathOrOptions
|
16
17
|
* @param options
|
17
18
|
*/
|
18
|
-
export function controller<T extends object>(
|
19
|
+
export function controller<T extends object>(
|
20
|
+
pathOrOptions?: string | ControllerOptions,
|
21
|
+
options?: ControllerOptions,
|
22
|
+
) {
|
19
23
|
return function (target: Constructor<T>) {
|
20
24
|
const decoratorType = getDecoratorTargetType(target);
|
21
25
|
if (decoratorType !== DecoratorTargetType.CONSTRUCTOR)
|
22
26
|
throw new Error('@controller decorator is only supported on a class.');
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
// если первый аргумент является строкой,
|
28
|
+
// то значение используется в качестве
|
29
|
+
// базового пути контроллера
|
30
|
+
if (typeof pathOrOptions === 'string') {
|
31
|
+
// если второй аргумент не определен,
|
32
|
+
// то создается новый объект опций,
|
33
|
+
// который включает базовый путь
|
34
|
+
if (!options) {
|
35
|
+
options = {path: pathOrOptions};
|
36
|
+
}
|
37
|
+
// если второй аргумент определен,
|
38
|
+
// то базовый путь из первого аргумента
|
39
|
+
// передается в объект опций декоратора
|
40
|
+
else {
|
41
|
+
options.path = pathOrOptions;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
// если первый аргумент является объектом,
|
45
|
+
// то его значение используется в качестве
|
46
|
+
// объекта опций декоратора, а второй
|
47
|
+
// аргумент игнорируется
|
48
|
+
else if (typeof pathOrOptions === 'object') {
|
49
|
+
options = pathOrOptions;
|
50
|
+
}
|
51
|
+
ControllerReflector.setMetadata(
|
52
|
+
{...options, className: target.name},
|
53
|
+
target,
|
54
|
+
);
|
28
55
|
};
|
29
56
|
}
|
package/src/decorators/index.ts
CHANGED
@@ -4,7 +4,7 @@ import {requestContext} from './request-context-decorator.js';
|
|
4
4
|
import {RequestContextReflector} from './request-context-reflector.js';
|
5
5
|
|
6
6
|
describe('requestContext', function () {
|
7
|
-
it('does not
|
7
|
+
it('does not require options', function () {
|
8
8
|
class Target {
|
9
9
|
method(
|
10
10
|
@requestContext()
|
@@ -15,7 +15,7 @@ describe('requestContext', function () {
|
|
15
15
|
expect(res.get(0)).to.be.eql({property: undefined});
|
16
16
|
});
|
17
17
|
|
18
|
-
it('sets a given
|
18
|
+
it('sets a given property to the target metadata', function () {
|
19
19
|
class Target {
|
20
20
|
method(
|
21
21
|
@requestContext('res')
|
@@ -25,17 +25,4 @@ describe('requestContext', function () {
|
|
25
25
|
const res = RequestContextReflector.getMetadata(Target, 'method');
|
26
26
|
expect(res.get(0)).to.be.eql({property: 'res'});
|
27
27
|
});
|
28
|
-
|
29
|
-
it('sets a given RequestContextMetadata as the target metadata', function () {
|
30
|
-
const property = 'res';
|
31
|
-
const customOption = 'customOption';
|
32
|
-
class Target {
|
33
|
-
method(
|
34
|
-
@requestContext({property, customOption})
|
35
|
-
prop: unknown,
|
36
|
-
) {}
|
37
|
-
}
|
38
|
-
const res = RequestContextReflector.getMetadata(Target, 'method');
|
39
|
-
expect(res.get(0)).to.be.eql({property, customOption});
|
40
|
-
});
|
41
28
|
});
|
@@ -4,15 +4,14 @@ import {RequestContext} from '@e22m4u/js-trie-router';
|
|
4
4
|
import {DecoratorTargetType} from '@e22m4u/ts-reflector';
|
5
5
|
import {getDecoratorTargetType} from '@e22m4u/ts-reflector';
|
6
6
|
import {RequestContextReflector} from './request-context-reflector.js';
|
7
|
-
import {RequestContextMetadata} from './request-context-metadata.js';
|
8
7
|
|
9
8
|
/**
|
10
9
|
* Request context decorator.
|
11
10
|
*
|
12
|
-
* @param
|
11
|
+
* @param propertyName
|
13
12
|
*/
|
14
13
|
export function requestContext<T extends object>(
|
15
|
-
|
14
|
+
propertyName?: keyof RequestContext,
|
16
15
|
) {
|
17
16
|
return function (
|
18
17
|
target: Prototype<T>,
|
@@ -29,12 +28,8 @@ export function requestContext<T extends object>(
|
|
29
28
|
'@requestContext decorator is only supported ' +
|
30
29
|
'on an instance method parameter.',
|
31
30
|
);
|
32
|
-
const metadata =
|
33
|
-
typeof propertyOrMetadata !== 'object'
|
34
|
-
? {property: propertyOrMetadata}
|
35
|
-
: propertyOrMetadata;
|
36
31
|
RequestContextReflector.setMetadata(
|
37
|
-
|
32
|
+
{property: propertyName},
|
38
33
|
target.constructor as Constructor<T>,
|
39
34
|
indexOrDescriptor,
|
40
35
|
propertyKey,
|
@@ -10,26 +10,27 @@ import {params} from './request-data-decorator.js';
|
|
10
10
|
import {queries} from './request-data-decorator.js';
|
11
11
|
import {cookies} from './request-data-decorator.js';
|
12
12
|
import {headers} from './request-data-decorator.js';
|
13
|
-
import {
|
13
|
+
import {bodyProp} from './request-data-decorator.js';
|
14
14
|
import {requestData} from './request-data-decorator.js';
|
15
15
|
import {RequestDataSource} from './request-data-metadata.js';
|
16
|
-
import {RequestDataMetadata} from './request-data-metadata.js';
|
17
16
|
import {RequestDataReflector} from './request-data-reflector.js';
|
18
17
|
|
19
18
|
describe('requestData', function () {
|
20
|
-
it('sets
|
21
|
-
const
|
22
|
-
source: RequestDataSource.
|
19
|
+
it('sets given options to the target metadata', function () {
|
20
|
+
const options = {
|
21
|
+
source: RequestDataSource.BODY,
|
22
|
+
schema: {type: DataType.STRING},
|
23
|
+
property: 'prop',
|
23
24
|
customOption: 'myOption',
|
24
25
|
};
|
25
26
|
class Target {
|
26
27
|
myMethod(
|
27
|
-
@requestData(
|
28
|
+
@requestData(options)
|
28
29
|
prop: unknown,
|
29
30
|
) {}
|
30
31
|
}
|
31
32
|
const res = RequestDataReflector.getMetadata(Target, 'myMethod');
|
32
|
-
expect(res.get(0)).to.be.eql(
|
33
|
+
expect(res.get(0)).to.be.eql(options);
|
33
34
|
});
|
34
35
|
|
35
36
|
describe('request data by a given source', function () {
|
@@ -408,11 +409,11 @@ describe('requestData', function () {
|
|
408
409
|
});
|
409
410
|
});
|
410
411
|
|
411
|
-
describe('
|
412
|
+
describe('bodyProp', function () {
|
412
413
|
it('sets a given "propertyKey" to the target metadata', function () {
|
413
414
|
class Target {
|
414
415
|
myMethod(
|
415
|
-
@
|
416
|
+
@bodyProp('myPropertyKey')
|
416
417
|
prop: unknown,
|
417
418
|
) {}
|
418
419
|
}
|
@@ -429,7 +430,7 @@ describe('requestData', function () {
|
|
429
430
|
const propertyType = DataType.STRING;
|
430
431
|
class Target {
|
431
432
|
myMethod(
|
432
|
-
@
|
433
|
+
@bodyProp(propertyKey, propertyType)
|
433
434
|
prop: unknown,
|
434
435
|
) {}
|
435
436
|
}
|
@@ -456,7 +457,7 @@ describe('requestData', function () {
|
|
456
457
|
const propertyKey = 'myPropertyKey';
|
457
458
|
class Target {
|
458
459
|
myMethod(
|
459
|
-
@
|
460
|
+
@bodyProp(propertyKey, schema)
|
460
461
|
prop: unknown,
|
461
462
|
) {}
|
462
463
|
}
|
@@ -9,12 +9,17 @@ import {RequestDataSource} from './request-data-metadata.js';
|
|
9
9
|
import {RequestDataMetadata} from './request-data-metadata.js';
|
10
10
|
import {RequestDataReflector} from './request-data-reflector.js';
|
11
11
|
|
12
|
+
/**
|
13
|
+
* Request data options.
|
14
|
+
*/
|
15
|
+
export type RequestDataOptions = RequestDataMetadata;
|
16
|
+
|
12
17
|
/**
|
13
18
|
* Request data decorator.
|
14
19
|
*
|
15
|
-
* @param
|
20
|
+
* @param options
|
16
21
|
*/
|
17
|
-
export function requestData<T extends object>(
|
22
|
+
export function requestData<T extends object>(options: RequestDataOptions) {
|
18
23
|
return function (
|
19
24
|
target: Prototype<T>,
|
20
25
|
propertyKey: string,
|
@@ -31,7 +36,7 @@ export function requestData<T extends object>(metadata: RequestDataMetadata) {
|
|
31
36
|
'on an instance method parameter.',
|
32
37
|
);
|
33
38
|
RequestDataReflector.setMetadata(
|
34
|
-
|
39
|
+
options,
|
35
40
|
target.constructor as Constructor<T>,
|
36
41
|
indexOrDescriptor,
|
37
42
|
propertyKey,
|
@@ -40,11 +45,11 @@ export function requestData<T extends object>(metadata: RequestDataMetadata) {
|
|
40
45
|
}
|
41
46
|
|
42
47
|
/**
|
43
|
-
* Create data decorator.
|
48
|
+
* Create request data decorator with source.
|
44
49
|
*
|
45
50
|
* @param source
|
46
51
|
*/
|
47
|
-
function
|
52
|
+
function createRequestDataDecoratorWithSource(source: RequestDataSource) {
|
48
53
|
return function () {
|
49
54
|
const schema = {type: DataType.OBJECT};
|
50
55
|
return requestData({schema, source});
|
@@ -52,11 +57,13 @@ function createDataDecorator(source: RequestDataSource) {
|
|
52
57
|
}
|
53
58
|
|
54
59
|
/**
|
55
|
-
* Create property decorator.
|
60
|
+
* Create request data property decorator with source.
|
56
61
|
*
|
57
62
|
* @param source
|
58
63
|
*/
|
59
|
-
function
|
64
|
+
function createRequestDataPropertyDecoratorWithSource(
|
65
|
+
source: RequestDataSource,
|
66
|
+
) {
|
60
67
|
return function (propertyKey: string, schemaOrType?: DataSchema | DataType) {
|
61
68
|
const properties = {} as NoUndef<DataSchema['properties']>;
|
62
69
|
const rootSchema: DataSchema = {type: DataType.OBJECT};
|
@@ -78,15 +85,33 @@ function createPropertyDecorator(source: RequestDataSource) {
|
|
78
85
|
/**
|
79
86
|
* Decorator aliases.
|
80
87
|
*/
|
81
|
-
export const params =
|
82
|
-
|
83
|
-
|
84
|
-
export const
|
85
|
-
|
86
|
-
|
87
|
-
export const
|
88
|
-
|
89
|
-
|
88
|
+
export const params = createRequestDataDecoratorWithSource(
|
89
|
+
RequestDataSource.PARAMS,
|
90
|
+
);
|
91
|
+
export const param = createRequestDataPropertyDecoratorWithSource(
|
92
|
+
RequestDataSource.PARAMS,
|
93
|
+
);
|
94
|
+
export const queries = createRequestDataDecoratorWithSource(
|
95
|
+
RequestDataSource.QUERY,
|
96
|
+
);
|
97
|
+
export const query = createRequestDataPropertyDecoratorWithSource(
|
98
|
+
RequestDataSource.QUERY,
|
99
|
+
);
|
100
|
+
export const headers = createRequestDataDecoratorWithSource(
|
101
|
+
RequestDataSource.HEADERS,
|
102
|
+
);
|
103
|
+
export const header = createRequestDataPropertyDecoratorWithSource(
|
104
|
+
RequestDataSource.HEADERS,
|
105
|
+
);
|
106
|
+
export const cookies = createRequestDataDecoratorWithSource(
|
107
|
+
RequestDataSource.COOKIE,
|
108
|
+
);
|
109
|
+
export const cookie = createRequestDataPropertyDecoratorWithSource(
|
110
|
+
RequestDataSource.COOKIE,
|
111
|
+
);
|
112
|
+
export const bodyProp = createRequestDataPropertyDecoratorWithSource(
|
113
|
+
RequestDataSource.BODY,
|
114
|
+
);
|
90
115
|
|
91
116
|
/**
|
92
117
|
* Request body decorator.
|
@@ -1,21 +1,98 @@
|
|
1
|
-
import
|
1
|
+
import {inspect} from 'util';
|
2
|
+
import DebugModule from 'debug';
|
3
|
+
import {AnyObject} from '../types.js';
|
2
4
|
import {format} from '@e22m4u/js-format';
|
3
5
|
|
4
6
|
/**
|
5
7
|
* Debugger.
|
6
8
|
*/
|
7
|
-
export type Debugger = (
|
9
|
+
export type Debugger = (
|
10
|
+
messageOrData: string | unknown,
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
12
|
+
...args: any[]
|
13
|
+
) => void;
|
14
|
+
|
15
|
+
/**
|
16
|
+
* Colorize string.
|
17
|
+
*
|
18
|
+
* @param input
|
19
|
+
*/
|
20
|
+
function colorizeString(input: string): string {
|
21
|
+
const c = Number(DebugModule['selectColor'](input));
|
22
|
+
const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
|
23
|
+
return `${colorCode};1m${input}\u001B[0m`;
|
24
|
+
}
|
8
25
|
|
9
26
|
/**
|
10
27
|
* Create debugger.
|
11
28
|
*
|
29
|
+
* Base usage:
|
30
|
+
* ```ts
|
31
|
+
* const debug = createDebugger('myService');
|
32
|
+
* debug('Service created.');
|
33
|
+
* // ujut:myService Service created.
|
34
|
+
* ```
|
35
|
+
*
|
36
|
+
* Nested namespaces:
|
37
|
+
* ```ts
|
38
|
+
* const debug1 = debug.bind('namespace1');
|
39
|
+
* const debug2 = debug.bind('namespace2');
|
40
|
+
* debug1('Application started'); // ujut:myService [namespace1] Application started
|
41
|
+
* debug2('Connection established'); // ujut:myService [namespace2] Connection established
|
42
|
+
* ```
|
43
|
+
*
|
44
|
+
* Value inspection:
|
45
|
+
* ```ts
|
46
|
+
* debug({foo: 'lorem', bar: 'ipsum'})
|
47
|
+
* // ujut:myService {
|
48
|
+
* // ujut:myService "foo": "lorem",
|
49
|
+
* // ujut:myService "bar": "ipsum"
|
50
|
+
* // ujut:myService }
|
51
|
+
* ```
|
52
|
+
*
|
53
|
+
* Titled inspection output:
|
54
|
+
* ```ts
|
55
|
+
* debug({foo: 'lorem', bar: 'ipsum'}, 'My awesome output:')
|
56
|
+
* // ujut:myService My awesome output:
|
57
|
+
* // ujut:myService {
|
58
|
+
* // ujut:myService "foo": "lorem",
|
59
|
+
* // ujut:myService "bar": "ipsum"
|
60
|
+
* // ujut:myService }
|
61
|
+
* ```
|
62
|
+
*
|
12
63
|
* @param name
|
13
64
|
*/
|
14
65
|
export function createDebugger(name: string): Debugger {
|
15
|
-
const
|
16
|
-
//
|
17
|
-
|
18
|
-
|
19
|
-
|
66
|
+
const debuggerName = `tsRestRouter:${name}`;
|
67
|
+
// включить вывод логов можно принудительно
|
68
|
+
// if (!process.env.DEBUG) DebugModule.enable('ujut*');
|
69
|
+
const debug = DebugModule(debuggerName);
|
70
|
+
return function (
|
71
|
+
this: unknown,
|
72
|
+
messageOrData: string | unknown,
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
74
|
+
...args: any[]
|
75
|
+
) {
|
76
|
+
let prefix = '';
|
77
|
+
if (typeof this === 'string') {
|
78
|
+
const isDebugUsesColors = (debug as AnyObject).useColors;
|
79
|
+
prefix = isDebugUsesColors ? colorizeString(`[${this}] `) : `[${this}] `;
|
80
|
+
}
|
81
|
+
if (typeof messageOrData === 'string') {
|
82
|
+
const interpolatedMessage = format(messageOrData, ...args);
|
83
|
+
return debug(prefix + interpolatedMessage);
|
84
|
+
}
|
85
|
+
const inspectOptions = {
|
86
|
+
showHidden: false,
|
87
|
+
depth: null,
|
88
|
+
colors: true,
|
89
|
+
compact: false,
|
90
|
+
};
|
91
|
+
const multiString = inspect(messageOrData, inspectOptions);
|
92
|
+
const rows = multiString.split('\n');
|
93
|
+
const colorizedDebuggerName = colorizeString(debuggerName);
|
94
|
+
[...args, ...rows].forEach(v =>
|
95
|
+
console.log(` ${colorizedDebuggerName} ${prefix}${v}`),
|
96
|
+
);
|
20
97
|
};
|
21
98
|
}
|