@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
@@ -13,47 +13,47 @@ import { HttpMethod } from '@e22m4u/js-trie-router';
|
|
13
13
|
import { ActionReflector } from './action-reflector.js';
|
14
14
|
describe('action', function () {
|
15
15
|
it('sets given options to the target metadata', function () {
|
16
|
-
const
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
const options = {
|
17
|
+
method: HttpMethod.GET,
|
18
|
+
path: 'myPath',
|
19
|
+
before: () => undefined,
|
20
|
+
after: () => undefined,
|
21
|
+
customOption: 'customOption',
|
22
|
+
};
|
21
23
|
class Target {
|
22
24
|
method() { }
|
23
25
|
}
|
24
26
|
__decorate([
|
25
|
-
action(
|
27
|
+
action(options),
|
26
28
|
__metadata("design:type", Function),
|
27
29
|
__metadata("design:paramtypes", []),
|
28
30
|
__metadata("design:returntype", void 0)
|
29
31
|
], Target.prototype, "method", null);
|
30
32
|
const res = ActionReflector.getMetadata(Target);
|
31
33
|
expect(res.get('method')).to.be.eql({
|
34
|
+
...options,
|
32
35
|
propertyKey: 'method',
|
33
|
-
method,
|
34
|
-
path,
|
35
|
-
before,
|
36
|
-
after,
|
37
|
-
customOption,
|
38
36
|
});
|
39
37
|
});
|
40
38
|
it('overrides a given "propertyKey" option by the target method name', function () {
|
41
|
-
const
|
42
|
-
|
39
|
+
const options = {
|
40
|
+
propertyKey: 'myMethod',
|
41
|
+
method: HttpMethod.GET,
|
42
|
+
path: 'myPath',
|
43
|
+
};
|
43
44
|
class Target {
|
44
45
|
method() { }
|
45
46
|
}
|
46
47
|
__decorate([
|
47
|
-
action(
|
48
|
+
action(options),
|
48
49
|
__metadata("design:type", Function),
|
49
50
|
__metadata("design:paramtypes", []),
|
50
51
|
__metadata("design:returntype", void 0)
|
51
52
|
], Target.prototype, "method", null);
|
52
53
|
const res = ActionReflector.getMetadata(Target);
|
53
54
|
expect(res.get('method')).to.be.eql({
|
55
|
+
...options,
|
54
56
|
propertyKey: 'method',
|
55
|
-
method,
|
56
|
-
path,
|
57
57
|
});
|
58
58
|
});
|
59
59
|
});
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { Prototype } from '../../types.js';
|
2
|
+
import { Constructor } from '../../types.js';
|
3
|
+
import { AfterMetadata } from './after-metadata.js';
|
4
|
+
/**
|
5
|
+
* After decorator.
|
6
|
+
*
|
7
|
+
* @param options
|
8
|
+
*/
|
9
|
+
export declare function after<T extends object>(middleware: AfterMetadata['middleware']): (target: Constructor<T> | Prototype<T>, propertyKey?: string, descriptor?: PropertyDescriptor) => void;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { AfterReflector } from './after-reflector.js';
|
2
|
+
import { DecoratorTargetType } from '@e22m4u/ts-reflector';
|
3
|
+
import { getDecoratorTargetType } from '@e22m4u/ts-reflector';
|
4
|
+
/**
|
5
|
+
* After decorator.
|
6
|
+
*
|
7
|
+
* @param options
|
8
|
+
*/
|
9
|
+
export function after(middleware) {
|
10
|
+
return function (target, propertyKey, descriptor) {
|
11
|
+
const decoratorType = getDecoratorTargetType(target, propertyKey, descriptor);
|
12
|
+
if (decoratorType === DecoratorTargetType.CONSTRUCTOR) {
|
13
|
+
AfterReflector.addMetadata({ middleware }, target);
|
14
|
+
}
|
15
|
+
else if (decoratorType === DecoratorTargetType.INSTANCE_METHOD) {
|
16
|
+
AfterReflector.addMetadata({ propertyKey, middleware }, target.constructor, propertyKey);
|
17
|
+
}
|
18
|
+
else {
|
19
|
+
throw new Error('@after decorator is only supported on a class or an instance method.');
|
20
|
+
}
|
21
|
+
};
|
22
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,115 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
9
|
+
};
|
10
|
+
/* eslint mocha/no-sibling-hooks: 0 */
|
11
|
+
import { expect } from 'chai';
|
12
|
+
import { after } from './after-decorator.js';
|
13
|
+
import { AfterReflector } from './after-reflector.js';
|
14
|
+
const MIDDLEWARE_1 = () => undefined;
|
15
|
+
const MIDDLEWARE_2 = () => undefined;
|
16
|
+
const MIDDLEWARE_3 = () => undefined;
|
17
|
+
describe('after', function () {
|
18
|
+
describe('class target', function () {
|
19
|
+
it('sets given middleware to the target metadata', function () {
|
20
|
+
let Target = class Target {
|
21
|
+
method() { }
|
22
|
+
};
|
23
|
+
Target = __decorate([
|
24
|
+
after(MIDDLEWARE_1)
|
25
|
+
], Target);
|
26
|
+
const res = AfterReflector.getMetadata(Target);
|
27
|
+
expect(res).to.be.eql([{ middleware: MIDDLEWARE_1 }]);
|
28
|
+
});
|
29
|
+
it('sets miltiple middlewares to the target metadata', function () {
|
30
|
+
let Target = class Target {
|
31
|
+
method() { }
|
32
|
+
};
|
33
|
+
Target = __decorate([
|
34
|
+
after([MIDDLEWARE_1, MIDDLEWARE_2])
|
35
|
+
], Target);
|
36
|
+
const res = AfterReflector.getMetadata(Target);
|
37
|
+
expect(res).to.be.eql([{ middleware: [MIDDLEWARE_1, MIDDLEWARE_2] }]);
|
38
|
+
});
|
39
|
+
it('allows to use the decorator multiple times', function () {
|
40
|
+
let Target = class Target {
|
41
|
+
method() { }
|
42
|
+
};
|
43
|
+
Target = __decorate([
|
44
|
+
after(MIDDLEWARE_1),
|
45
|
+
after([MIDDLEWARE_2, MIDDLEWARE_3])
|
46
|
+
], Target);
|
47
|
+
const res = AfterReflector.getMetadata(Target);
|
48
|
+
expect(res).to.be.eql([
|
49
|
+
{ middleware: MIDDLEWARE_1 },
|
50
|
+
{ middleware: [MIDDLEWARE_2, MIDDLEWARE_3] },
|
51
|
+
]);
|
52
|
+
});
|
53
|
+
});
|
54
|
+
describe('method target', function () {
|
55
|
+
it('sets given middleware to the target metadata', function () {
|
56
|
+
class Target {
|
57
|
+
method() { }
|
58
|
+
}
|
59
|
+
__decorate([
|
60
|
+
after(MIDDLEWARE_1),
|
61
|
+
__metadata("design:type", Function),
|
62
|
+
__metadata("design:paramtypes", []),
|
63
|
+
__metadata("design:returntype", void 0)
|
64
|
+
], Target.prototype, "method", null);
|
65
|
+
const res = AfterReflector.getMetadata(Target, 'method');
|
66
|
+
expect(res).to.be.eql([
|
67
|
+
{
|
68
|
+
propertyKey: 'method',
|
69
|
+
middleware: MIDDLEWARE_1,
|
70
|
+
},
|
71
|
+
]);
|
72
|
+
});
|
73
|
+
it('sets miltiple middlewares to the target metadata', function () {
|
74
|
+
class Target {
|
75
|
+
method() { }
|
76
|
+
}
|
77
|
+
__decorate([
|
78
|
+
after([MIDDLEWARE_1, MIDDLEWARE_2]),
|
79
|
+
__metadata("design:type", Function),
|
80
|
+
__metadata("design:paramtypes", []),
|
81
|
+
__metadata("design:returntype", void 0)
|
82
|
+
], Target.prototype, "method", null);
|
83
|
+
const res = AfterReflector.getMetadata(Target, 'method');
|
84
|
+
expect(res).to.be.eql([
|
85
|
+
{
|
86
|
+
propertyKey: 'method',
|
87
|
+
middleware: [MIDDLEWARE_1, MIDDLEWARE_2],
|
88
|
+
},
|
89
|
+
]);
|
90
|
+
});
|
91
|
+
it('allows to use the decorator multiple times', function () {
|
92
|
+
class Target {
|
93
|
+
method() { }
|
94
|
+
}
|
95
|
+
__decorate([
|
96
|
+
after(MIDDLEWARE_1),
|
97
|
+
after([MIDDLEWARE_2, MIDDLEWARE_3]),
|
98
|
+
__metadata("design:type", Function),
|
99
|
+
__metadata("design:paramtypes", []),
|
100
|
+
__metadata("design:returntype", void 0)
|
101
|
+
], Target.prototype, "method", null);
|
102
|
+
const res = AfterReflector.getMetadata(Target, 'method');
|
103
|
+
expect(res).to.be.eql([
|
104
|
+
{
|
105
|
+
propertyKey: 'method',
|
106
|
+
middleware: MIDDLEWARE_1,
|
107
|
+
},
|
108
|
+
{
|
109
|
+
propertyKey: 'method',
|
110
|
+
middleware: [MIDDLEWARE_2, MIDDLEWARE_3],
|
111
|
+
},
|
112
|
+
]);
|
113
|
+
});
|
114
|
+
});
|
115
|
+
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { MetadataKey } from '@e22m4u/ts-reflector';
|
2
|
+
import { RoutePostHandler } from '@e22m4u/js-trie-router';
|
3
|
+
/**
|
4
|
+
* After metadata.
|
5
|
+
*/
|
6
|
+
export type AfterMetadata = {
|
7
|
+
propertyKey?: string;
|
8
|
+
middleware: RoutePostHandler | RoutePostHandler[];
|
9
|
+
};
|
10
|
+
/**
|
11
|
+
* After metadata key.
|
12
|
+
*/
|
13
|
+
export declare const AFTER_METADATA_KEY: MetadataKey<AfterMetadata[]>;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { Constructor } from '../../types.js';
|
2
|
+
import { AfterMetadata } from './after-metadata.js';
|
3
|
+
/**
|
4
|
+
* After reflector.
|
5
|
+
*/
|
6
|
+
export declare class AfterReflector {
|
7
|
+
/**
|
8
|
+
* Set metadata.
|
9
|
+
*
|
10
|
+
* @param metadata
|
11
|
+
* @param target
|
12
|
+
* @param propertyKey
|
13
|
+
*/
|
14
|
+
static addMetadata(metadata: AfterMetadata, target: Constructor, propertyKey?: string): void;
|
15
|
+
/**
|
16
|
+
* Get metadata.
|
17
|
+
*
|
18
|
+
* @param target
|
19
|
+
* @param propertyKey
|
20
|
+
*/
|
21
|
+
static getMetadata(target: Constructor, propertyKey?: string): AfterMetadata[];
|
22
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { Reflector } from '@e22m4u/ts-reflector';
|
2
|
+
import { AFTER_METADATA_KEY } from './after-metadata.js';
|
3
|
+
/**
|
4
|
+
* After reflector.
|
5
|
+
*/
|
6
|
+
export class AfterReflector {
|
7
|
+
/**
|
8
|
+
* Set metadata.
|
9
|
+
*
|
10
|
+
* @param metadata
|
11
|
+
* @param target
|
12
|
+
* @param propertyKey
|
13
|
+
*/
|
14
|
+
static addMetadata(metadata, target, propertyKey) {
|
15
|
+
const oldArray = Reflector.getOwnMetadata(AFTER_METADATA_KEY, target, propertyKey) ?? [];
|
16
|
+
const newArray = [metadata, ...oldArray];
|
17
|
+
Reflector.defineMetadata(AFTER_METADATA_KEY, newArray, target, propertyKey);
|
18
|
+
}
|
19
|
+
/**
|
20
|
+
* Get metadata.
|
21
|
+
*
|
22
|
+
* @param target
|
23
|
+
* @param propertyKey
|
24
|
+
*/
|
25
|
+
static getMetadata(target, propertyKey) {
|
26
|
+
const metadata = Reflector.getOwnMetadata(AFTER_METADATA_KEY, target, propertyKey);
|
27
|
+
return metadata ?? [];
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import { expect } from 'chai';
|
2
|
+
import { describe } from 'mocha';
|
3
|
+
import { Reflector } from '@e22m4u/ts-reflector';
|
4
|
+
import { AfterReflector } from './after-reflector.js';
|
5
|
+
import { AFTER_METADATA_KEY } from './after-metadata.js';
|
6
|
+
const MIDDLEWARE_1 = () => undefined;
|
7
|
+
const MIDDLEWARE_2 = () => undefined;
|
8
|
+
const MIDDLEWARE_3 = () => undefined;
|
9
|
+
describe('AfterReflector', function () {
|
10
|
+
describe('class target', function () {
|
11
|
+
describe('addMetadata', function () {
|
12
|
+
it('adds a given value to the target metadata', function () {
|
13
|
+
class Target {
|
14
|
+
}
|
15
|
+
const md1 = { middleware: MIDDLEWARE_1 };
|
16
|
+
const md2 = { middleware: [MIDDLEWARE_2, MIDDLEWARE_3] };
|
17
|
+
AfterReflector.addMetadata(md1, Target);
|
18
|
+
AfterReflector.addMetadata(md2, Target);
|
19
|
+
const res = Reflector.getOwnMetadata(AFTER_METADATA_KEY, Target);
|
20
|
+
expect(res).to.be.eql([md2, md1]);
|
21
|
+
});
|
22
|
+
});
|
23
|
+
describe('getMetadata', function () {
|
24
|
+
it('returns an empty array if no metadata', function () {
|
25
|
+
class Target {
|
26
|
+
}
|
27
|
+
const res = AfterReflector.getMetadata(Target);
|
28
|
+
expect(res).to.be.eql([]);
|
29
|
+
});
|
30
|
+
it('returns existing metadata by the target', function () {
|
31
|
+
class Target {
|
32
|
+
}
|
33
|
+
const md1 = { middleware: MIDDLEWARE_1 };
|
34
|
+
const md2 = { middleware: [MIDDLEWARE_2, MIDDLEWARE_3] };
|
35
|
+
const mdArray = [md1, md2];
|
36
|
+
Reflector.defineMetadata(AFTER_METADATA_KEY, mdArray, Target);
|
37
|
+
const res = AfterReflector.getMetadata(Target);
|
38
|
+
expect(res).to.be.eql(mdArray);
|
39
|
+
});
|
40
|
+
});
|
41
|
+
});
|
42
|
+
describe('method target', function () {
|
43
|
+
describe('addMetadata', function () {
|
44
|
+
it('adds a given value to the target metadata', function () {
|
45
|
+
class Target {
|
46
|
+
}
|
47
|
+
const md1 = { middleware: MIDDLEWARE_1 };
|
48
|
+
const md2 = { middleware: [MIDDLEWARE_2, MIDDLEWARE_3] };
|
49
|
+
AfterReflector.addMetadata(md1, Target, 'prop');
|
50
|
+
AfterReflector.addMetadata(md2, Target, 'prop');
|
51
|
+
const res = Reflector.getOwnMetadata(AFTER_METADATA_KEY, Target, 'prop');
|
52
|
+
expect(res).to.be.eql([md2, md1]);
|
53
|
+
});
|
54
|
+
});
|
55
|
+
describe('getMetadata', function () {
|
56
|
+
it('returns an empty array if no metadata', function () {
|
57
|
+
class Target {
|
58
|
+
}
|
59
|
+
const res = AfterReflector.getMetadata(Target, 'prop');
|
60
|
+
expect(res).to.be.eql([]);
|
61
|
+
});
|
62
|
+
it('returns existing metadata by the target', function () {
|
63
|
+
class Target {
|
64
|
+
}
|
65
|
+
const md1 = { middleware: MIDDLEWARE_1 };
|
66
|
+
const md2 = { middleware: [MIDDLEWARE_2, MIDDLEWARE_3] };
|
67
|
+
const mdArray = [md1, md2];
|
68
|
+
Reflector.defineMetadata(AFTER_METADATA_KEY, mdArray, Target, 'prop');
|
69
|
+
const res = AfterReflector.getMetadata(Target, 'prop');
|
70
|
+
expect(res).to.be.eql(mdArray);
|
71
|
+
});
|
72
|
+
});
|
73
|
+
});
|
74
|
+
describe('addMetadata', function () {
|
75
|
+
it('can distinguish class and method metadata', function () {
|
76
|
+
class Target {
|
77
|
+
}
|
78
|
+
const md1 = { middleware: MIDDLEWARE_1 };
|
79
|
+
const md2 = { middleware: MIDDLEWARE_2 };
|
80
|
+
AfterReflector.addMetadata(md1, Target);
|
81
|
+
AfterReflector.addMetadata(md2, Target, 'prop');
|
82
|
+
const res1 = Reflector.getOwnMetadata(AFTER_METADATA_KEY, Target);
|
83
|
+
const res2 = Reflector.getOwnMetadata(AFTER_METADATA_KEY, Target, 'prop');
|
84
|
+
expect(res1).to.be.eql([md1]);
|
85
|
+
expect(res2).to.be.eql([md2]);
|
86
|
+
});
|
87
|
+
});
|
88
|
+
describe('getMetadata', function () {
|
89
|
+
it('can distinguish class and method metadata', function () {
|
90
|
+
class Target {
|
91
|
+
}
|
92
|
+
const md1 = { middleware: MIDDLEWARE_1 };
|
93
|
+
const md2 = { middleware: MIDDLEWARE_2 };
|
94
|
+
Reflector.defineMetadata(AFTER_METADATA_KEY, [md1], Target);
|
95
|
+
Reflector.defineMetadata(AFTER_METADATA_KEY, [md2], Target, 'prop');
|
96
|
+
const res1 = AfterReflector.getMetadata(Target);
|
97
|
+
const res2 = AfterReflector.getMetadata(Target, 'prop');
|
98
|
+
expect(res1).to.be.eql([md1]);
|
99
|
+
expect(res2).to.be.eql([md2]);
|
100
|
+
});
|
101
|
+
});
|
102
|
+
});
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { Prototype } from '../../types.js';
|
2
|
+
import { Constructor } from '../../types.js';
|
3
|
+
import { BeforeMetadata } from './before-metadata.js';
|
4
|
+
/**
|
5
|
+
* Before decorator.
|
6
|
+
*
|
7
|
+
* @param options
|
8
|
+
*/
|
9
|
+
export declare function before<T extends object>(middleware: BeforeMetadata['middleware']): (target: Constructor<T> | Prototype<T>, propertyKey?: string, descriptor?: PropertyDescriptor) => void;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { BeforeReflector } from './before-reflector.js';
|
2
|
+
import { DecoratorTargetType } from '@e22m4u/ts-reflector';
|
3
|
+
import { getDecoratorTargetType } from '@e22m4u/ts-reflector';
|
4
|
+
/**
|
5
|
+
* Before decorator.
|
6
|
+
*
|
7
|
+
* @param options
|
8
|
+
*/
|
9
|
+
export function before(middleware) {
|
10
|
+
return function (target, propertyKey, descriptor) {
|
11
|
+
const decoratorType = getDecoratorTargetType(target, propertyKey, descriptor);
|
12
|
+
if (decoratorType === DecoratorTargetType.CONSTRUCTOR) {
|
13
|
+
BeforeReflector.addMetadata({ middleware }, target);
|
14
|
+
}
|
15
|
+
else if (decoratorType === DecoratorTargetType.INSTANCE_METHOD) {
|
16
|
+
BeforeReflector.addMetadata({ propertyKey, middleware }, target.constructor, propertyKey);
|
17
|
+
}
|
18
|
+
else {
|
19
|
+
throw new Error('@before decorator is only supported on a class or an instance method.');
|
20
|
+
}
|
21
|
+
};
|
22
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,115 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
9
|
+
};
|
10
|
+
/* eslint mocha/no-sibling-hooks: 0 */
|
11
|
+
import { expect } from 'chai';
|
12
|
+
import { before } from './before-decorator.js';
|
13
|
+
import { BeforeReflector } from './before-reflector.js';
|
14
|
+
const MIDDLEWARE_1 = () => undefined;
|
15
|
+
const MIDDLEWARE_2 = () => undefined;
|
16
|
+
const MIDDLEWARE_3 = () => undefined;
|
17
|
+
describe('before', function () {
|
18
|
+
describe('class target', function () {
|
19
|
+
it('sets given middleware to the target metadata', function () {
|
20
|
+
let Target = class Target {
|
21
|
+
method() { }
|
22
|
+
};
|
23
|
+
Target = __decorate([
|
24
|
+
before(MIDDLEWARE_1)
|
25
|
+
], Target);
|
26
|
+
const res = BeforeReflector.getMetadata(Target);
|
27
|
+
expect(res).to.be.eql([{ middleware: MIDDLEWARE_1 }]);
|
28
|
+
});
|
29
|
+
it('sets miltiple middlewares to the target metadata', function () {
|
30
|
+
let Target = class Target {
|
31
|
+
method() { }
|
32
|
+
};
|
33
|
+
Target = __decorate([
|
34
|
+
before([MIDDLEWARE_1, MIDDLEWARE_2])
|
35
|
+
], Target);
|
36
|
+
const res = BeforeReflector.getMetadata(Target);
|
37
|
+
expect(res).to.be.eql([{ middleware: [MIDDLEWARE_1, MIDDLEWARE_2] }]);
|
38
|
+
});
|
39
|
+
it('allows to use the decorator multiple times', function () {
|
40
|
+
let Target = class Target {
|
41
|
+
method() { }
|
42
|
+
};
|
43
|
+
Target = __decorate([
|
44
|
+
before(MIDDLEWARE_1),
|
45
|
+
before([MIDDLEWARE_2, MIDDLEWARE_3])
|
46
|
+
], Target);
|
47
|
+
const res = BeforeReflector.getMetadata(Target);
|
48
|
+
expect(res).to.be.eql([
|
49
|
+
{ middleware: MIDDLEWARE_1 },
|
50
|
+
{ middleware: [MIDDLEWARE_2, MIDDLEWARE_3] },
|
51
|
+
]);
|
52
|
+
});
|
53
|
+
});
|
54
|
+
describe('method target', function () {
|
55
|
+
it('sets given middleware to the target metadata', function () {
|
56
|
+
class Target {
|
57
|
+
method() { }
|
58
|
+
}
|
59
|
+
__decorate([
|
60
|
+
before(MIDDLEWARE_1),
|
61
|
+
__metadata("design:type", Function),
|
62
|
+
__metadata("design:paramtypes", []),
|
63
|
+
__metadata("design:returntype", void 0)
|
64
|
+
], Target.prototype, "method", null);
|
65
|
+
const res = BeforeReflector.getMetadata(Target, 'method');
|
66
|
+
expect(res).to.be.eql([
|
67
|
+
{
|
68
|
+
propertyKey: 'method',
|
69
|
+
middleware: MIDDLEWARE_1,
|
70
|
+
},
|
71
|
+
]);
|
72
|
+
});
|
73
|
+
it('sets miltiple middlewares to the target metadata', function () {
|
74
|
+
class Target {
|
75
|
+
method() { }
|
76
|
+
}
|
77
|
+
__decorate([
|
78
|
+
before([MIDDLEWARE_1, MIDDLEWARE_2]),
|
79
|
+
__metadata("design:type", Function),
|
80
|
+
__metadata("design:paramtypes", []),
|
81
|
+
__metadata("design:returntype", void 0)
|
82
|
+
], Target.prototype, "method", null);
|
83
|
+
const res = BeforeReflector.getMetadata(Target, 'method');
|
84
|
+
expect(res).to.be.eql([
|
85
|
+
{
|
86
|
+
propertyKey: 'method',
|
87
|
+
middleware: [MIDDLEWARE_1, MIDDLEWARE_2],
|
88
|
+
},
|
89
|
+
]);
|
90
|
+
});
|
91
|
+
it('allows to use the decorator multiple times', function () {
|
92
|
+
class Target {
|
93
|
+
method() { }
|
94
|
+
}
|
95
|
+
__decorate([
|
96
|
+
before(MIDDLEWARE_1),
|
97
|
+
before([MIDDLEWARE_2, MIDDLEWARE_3]),
|
98
|
+
__metadata("design:type", Function),
|
99
|
+
__metadata("design:paramtypes", []),
|
100
|
+
__metadata("design:returntype", void 0)
|
101
|
+
], Target.prototype, "method", null);
|
102
|
+
const res = BeforeReflector.getMetadata(Target, 'method');
|
103
|
+
expect(res).to.be.eql([
|
104
|
+
{
|
105
|
+
propertyKey: 'method',
|
106
|
+
middleware: MIDDLEWARE_1,
|
107
|
+
},
|
108
|
+
{
|
109
|
+
propertyKey: 'method',
|
110
|
+
middleware: [MIDDLEWARE_2, MIDDLEWARE_3],
|
111
|
+
},
|
112
|
+
]);
|
113
|
+
});
|
114
|
+
});
|
115
|
+
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { MetadataKey } from '@e22m4u/ts-reflector';
|
2
|
+
import { RoutePreHandler } from '@e22m4u/js-trie-router';
|
3
|
+
/**
|
4
|
+
* Before metadata.
|
5
|
+
*/
|
6
|
+
export type BeforeMetadata = {
|
7
|
+
propertyKey?: string;
|
8
|
+
middleware: RoutePreHandler | RoutePreHandler[];
|
9
|
+
};
|
10
|
+
/**
|
11
|
+
* Before metadata key.
|
12
|
+
*/
|
13
|
+
export declare const BEFORE_METADATA_KEY: MetadataKey<BeforeMetadata[]>;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { Constructor } from '../../types.js';
|
2
|
+
import { BeforeMetadata } from './before-metadata.js';
|
3
|
+
/**
|
4
|
+
* Before reflector.
|
5
|
+
*/
|
6
|
+
export declare class BeforeReflector {
|
7
|
+
/**
|
8
|
+
* Set metadata.
|
9
|
+
*
|
10
|
+
* @param metadata
|
11
|
+
* @param target
|
12
|
+
* @param propertyKey
|
13
|
+
*/
|
14
|
+
static addMetadata(metadata: BeforeMetadata, target: Constructor, propertyKey?: string): void;
|
15
|
+
/**
|
16
|
+
* Get metadata.
|
17
|
+
*
|
18
|
+
* @param target
|
19
|
+
* @param propertyKey
|
20
|
+
*/
|
21
|
+
static getMetadata(target: Constructor, propertyKey?: string): BeforeMetadata[];
|
22
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { Reflector } from '@e22m4u/ts-reflector';
|
2
|
+
import { BEFORE_METADATA_KEY } from './before-metadata.js';
|
3
|
+
/**
|
4
|
+
* Before reflector.
|
5
|
+
*/
|
6
|
+
export class BeforeReflector {
|
7
|
+
/**
|
8
|
+
* Set metadata.
|
9
|
+
*
|
10
|
+
* @param metadata
|
11
|
+
* @param target
|
12
|
+
* @param propertyKey
|
13
|
+
*/
|
14
|
+
static addMetadata(metadata, target, propertyKey) {
|
15
|
+
const oldArray = Reflector.getOwnMetadata(BEFORE_METADATA_KEY, target, propertyKey) ?? [];
|
16
|
+
const newArray = [metadata, ...oldArray];
|
17
|
+
Reflector.defineMetadata(BEFORE_METADATA_KEY, newArray, target, propertyKey);
|
18
|
+
}
|
19
|
+
/**
|
20
|
+
* Get metadata.
|
21
|
+
*
|
22
|
+
* @param target
|
23
|
+
* @param propertyKey
|
24
|
+
*/
|
25
|
+
static getMetadata(target, propertyKey) {
|
26
|
+
const metadata = Reflector.getOwnMetadata(BEFORE_METADATA_KEY, target, propertyKey);
|
27
|
+
return metadata ?? [];
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|