@e22m4u/ts-rest-router 0.1.2 → 0.2.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.md +59 -57
- package/dist/cjs/index.cjs +346 -360
- package/dist/esm/controller-registry.js +28 -28
- package/dist/esm/debuggable-service.d.ts +10 -1
- package/dist/esm/debuggable-service.js +14 -3
- package/dist/esm/decorators/after-action/after-action-decorator.d.ts +9 -0
- package/dist/esm/decorators/{before/before-decorator.js → after-action/after-action-decorator.js} +7 -7
- package/dist/esm/decorators/{before/before-decorator.spec.js → after-action/after-action-decorator.spec.js} +19 -19
- package/dist/esm/decorators/{after/after-metadata.d.ts → after-action/after-action-metadata.d.ts} +4 -4
- package/dist/esm/decorators/after-action/after-action-metadata.js +5 -0
- package/dist/esm/decorators/{after/after-reflector.d.ts → after-action/after-action-reflector.d.ts} +5 -5
- package/dist/esm/decorators/{after/after-reflector.js → after-action/after-action-reflector.js} +6 -6
- package/dist/esm/decorators/{before/before-reflector.spec.js → after-action/after-action-reflector.spec.js} +23 -23
- package/dist/esm/decorators/after-action/index.d.ts +3 -0
- package/dist/esm/decorators/after-action/index.js +3 -0
- package/dist/esm/decorators/before-action/before-action-decorator.d.ts +9 -0
- package/dist/esm/decorators/{after/after-decorator.js → before-action/before-action-decorator.js} +7 -7
- package/dist/esm/decorators/{after/after-decorator.spec.js → before-action/before-action-decorator.spec.js} +19 -19
- package/dist/esm/decorators/{before/before-metadata.d.ts → before-action/before-action-metadata.d.ts} +4 -4
- package/dist/esm/decorators/before-action/before-action-metadata.js +5 -0
- package/dist/esm/decorators/{before/before-reflector.d.ts → before-action/before-action-reflector.d.ts} +5 -5
- package/dist/esm/decorators/{before/before-reflector.js → before-action/before-action-reflector.js} +6 -6
- package/dist/esm/decorators/{after/after-reflector.spec.js → before-action/before-action-reflector.spec.js} +23 -23
- package/dist/esm/decorators/before-action/index.d.ts +3 -0
- package/dist/esm/decorators/before-action/index.js +3 -0
- package/dist/esm/decorators/index.d.ts +4 -4
- package/dist/esm/decorators/index.js +4 -4
- package/dist/esm/decorators/request-context/request-context-decorator.d.ts +4 -4
- package/dist/esm/decorators/request-context/request-context-decorator.js +4 -4
- package/dist/esm/decorators/request-context/request-context-decorator.spec.js +6 -0
- package/dist/esm/decorators/request-data/request-data-decorator.d.ts +10 -10
- package/dist/esm/decorators/request-data/request-data-decorator.js +10 -10
- package/dist/esm/decorators/request-data/request-data-decorator.spec.js +44 -32
- package/dist/esm/decorators/request-data/request-data-metadata.d.ts +1 -1
- package/dist/esm/decorators/rest-action/index.d.ts +3 -0
- package/dist/esm/decorators/rest-action/index.js +3 -0
- package/dist/esm/decorators/rest-action/rest-action-decorator.d.ts +57 -0
- package/dist/esm/decorators/rest-action/rest-action-decorator.js +52 -0
- package/dist/esm/decorators/rest-action/rest-action-decorator.spec.js +401 -0
- package/dist/esm/decorators/{action/action-metadata.d.ts → rest-action/rest-action-metadata.d.ts} +6 -6
- package/dist/esm/decorators/rest-action/rest-action-metadata.js +5 -0
- package/dist/esm/decorators/rest-action/rest-action-reflector.d.ts +22 -0
- package/dist/esm/decorators/{action/action-reflector.js → rest-action/rest-action-reflector.js} +6 -6
- package/dist/esm/decorators/{action/action-reflector.spec.js → rest-action/rest-action-reflector.spec.js} +13 -13
- package/dist/esm/decorators/rest-controller/index.d.ts +3 -0
- package/dist/esm/decorators/rest-controller/index.js +3 -0
- package/dist/esm/decorators/rest-controller/rest-controller-decorator.d.ts +14 -0
- package/dist/esm/decorators/{controller/controller-decorator.js → rest-controller/rest-controller-decorator.js} +5 -5
- package/dist/esm/decorators/{controller/controller-decorator.spec.js → rest-controller/rest-controller-decorator.spec.js} +15 -15
- package/dist/esm/decorators/{controller/controller-metadata.d.ts → rest-controller/rest-controller-metadata.d.ts} +5 -5
- package/dist/esm/decorators/rest-controller/rest-controller-metadata.js +5 -0
- package/dist/esm/decorators/rest-controller/rest-controller-reflector.d.ts +20 -0
- package/dist/esm/decorators/rest-controller/rest-controller-reflector.js +24 -0
- package/dist/esm/decorators/{controller/controller-reflector.spec.js → rest-controller/rest-controller-reflector.spec.js} +12 -12
- package/dist/esm/errors/not-a-controller-error.js +1 -1
- package/dist/esm/types.d.ts +0 -10
- package/dist/esm/utils/index.d.ts +0 -1
- package/dist/esm/utils/index.js +0 -1
- package/package.json +2 -2
- package/src/controller-registry.spec.ts +122 -122
- package/src/controller-registry.ts +33 -35
- package/src/debuggable-service.ts +17 -4
- package/src/decorators/{before/before-decorator.spec.ts → after-action/after-action-decorator.spec.ts} +19 -19
- package/src/decorators/{before/before-decorator.ts → after-action/after-action-decorator.ts} +9 -9
- package/src/decorators/{after/after-metadata.ts → after-action/after-action-metadata.ts} +5 -5
- package/src/decorators/{before/before-reflector.spec.ts → after-action/after-action-reflector.spec.ts} +33 -23
- package/src/decorators/{before/before-reflector.ts → after-action/after-action-reflector.ts} +13 -9
- package/src/decorators/after-action/index.ts +3 -0
- package/src/decorators/{after/after-decorator.spec.ts → before-action/before-action-decorator.spec.ts} +19 -19
- package/src/decorators/{after/after-decorator.ts → before-action/before-action-decorator.ts} +9 -9
- package/src/decorators/before-action/before-action-metadata.ts +17 -0
- package/src/decorators/{after/after-reflector.spec.ts → before-action/before-action-reflector.spec.ts} +40 -23
- package/src/decorators/{after/after-reflector.ts → before-action/before-action-reflector.ts} +18 -9
- package/src/decorators/before-action/index.ts +3 -0
- package/src/decorators/index.ts +4 -4
- package/src/decorators/request-context/request-context-decorator.spec.ts +7 -0
- package/src/decorators/request-context/request-context-decorator.ts +4 -4
- package/src/decorators/request-data/request-data-decorator.spec.ts +45 -32
- package/src/decorators/request-data/request-data-decorator.ts +10 -10
- package/src/decorators/request-data/request-data-metadata.ts +1 -1
- package/src/decorators/rest-action/index.ts +3 -0
- package/src/decorators/rest-action/rest-action-decorator.spec.ts +325 -0
- package/src/decorators/rest-action/rest-action-decorator.ts +166 -0
- package/src/decorators/{action/action-metadata.ts → rest-action/rest-action-metadata.ts} +7 -7
- package/src/decorators/{action/action-reflector.spec.ts → rest-action/rest-action-reflector.spec.ts} +13 -13
- package/src/decorators/rest-action/rest-action-reflector.ts +41 -0
- package/src/decorators/rest-controller/index.ts +3 -0
- package/src/decorators/{controller/controller-decorator.spec.ts → rest-controller/rest-controller-decorator.spec.ts} +16 -16
- package/src/decorators/{controller/controller-decorator.ts → rest-controller/rest-controller-decorator.ts} +14 -10
- package/src/decorators/{controller/controller-metadata.ts → rest-controller/rest-controller-metadata.ts} +6 -7
- package/src/decorators/{controller/controller-reflector.spec.ts → rest-controller/rest-controller-reflector.spec.ts} +21 -12
- package/src/decorators/rest-controller/rest-controller-reflector.ts +32 -0
- package/src/errors/not-a-controller-error.ts +4 -1
- package/src/types.ts +0 -10
- package/src/utils/index.ts +0 -1
- package/dist/esm/decorators/action/action-decorator.d.ts +0 -52
- package/dist/esm/decorators/action/action-decorator.js +0 -62
- package/dist/esm/decorators/action/action-decorator.spec.js +0 -59
- package/dist/esm/decorators/action/action-metadata.js +0 -5
- package/dist/esm/decorators/action/action-reflector.d.ts +0 -22
- package/dist/esm/decorators/action/index.d.ts +0 -3
- package/dist/esm/decorators/action/index.js +0 -3
- package/dist/esm/decorators/after/after-decorator.d.ts +0 -9
- package/dist/esm/decorators/after/after-metadata.js +0 -5
- package/dist/esm/decorators/after/index.d.ts +0 -3
- package/dist/esm/decorators/after/index.js +0 -3
- package/dist/esm/decorators/before/before-decorator.d.ts +0 -9
- package/dist/esm/decorators/before/before-metadata.js +0 -5
- package/dist/esm/decorators/before/index.d.ts +0 -3
- package/dist/esm/decorators/before/index.js +0 -3
- package/dist/esm/decorators/controller/controller-decorator.d.ts +0 -14
- package/dist/esm/decorators/controller/controller-metadata.js +0 -5
- package/dist/esm/decorators/controller/controller-reflector.d.ts +0 -20
- package/dist/esm/decorators/controller/controller-reflector.js +0 -24
- package/dist/esm/decorators/controller/index.d.ts +0 -3
- package/dist/esm/decorators/controller/index.js +0 -3
- package/dist/esm/utils/create-debugger.d.ts +0 -44
- package/dist/esm/utils/create-debugger.js +0 -81
- package/dist/esm/utils/create-debugger.spec.d.ts +0 -1
- package/dist/esm/utils/create-debugger.spec.js +0 -8
- package/src/decorators/action/action-decorator.spec.ts +0 -42
- package/src/decorators/action/action-decorator.ts +0 -98
- package/src/decorators/action/action-reflector.ts +0 -38
- package/src/decorators/action/index.ts +0 -3
- package/src/decorators/after/index.ts +0 -3
- package/src/decorators/before/before-metadata.ts +0 -17
- package/src/decorators/before/index.ts +0 -3
- package/src/decorators/controller/controller-reflector.ts +0 -28
- package/src/decorators/controller/index.ts +0 -3
- package/src/utils/create-debugger.spec.ts +0 -9
- package/src/utils/create-debugger.ts +0 -98
- /package/dist/esm/decorators/{action/action-decorator.spec.d.ts → after-action/after-action-decorator.spec.d.ts} +0 -0
- /package/dist/esm/decorators/{action/action-reflector.spec.d.ts → after-action/after-action-reflector.spec.d.ts} +0 -0
- /package/dist/esm/decorators/{after/after-decorator.spec.d.ts → before-action/before-action-decorator.spec.d.ts} +0 -0
- /package/dist/esm/decorators/{after/after-reflector.spec.d.ts → before-action/before-action-reflector.spec.d.ts} +0 -0
- /package/dist/esm/decorators/{before/before-decorator.spec.d.ts → rest-action/rest-action-decorator.spec.d.ts} +0 -0
- /package/dist/esm/decorators/{before/before-reflector.spec.d.ts → rest-action/rest-action-reflector.spec.d.ts} +0 -0
- /package/dist/esm/decorators/{controller/controller-decorator.spec.d.ts → rest-controller/rest-controller-decorator.spec.d.ts} +0 -0
- /package/dist/esm/decorators/{controller/controller-reflector.spec.d.ts → rest-controller/rest-controller-reflector.spec.d.ts} +0 -0
@@ -85,31 +85,31 @@ function createRequestDataPropertyDecoratorWithSource(
|
|
85
85
|
/**
|
86
86
|
* Decorator aliases.
|
87
87
|
*/
|
88
|
-
export const
|
88
|
+
export const requestParams = createRequestDataDecoratorWithSource(
|
89
89
|
RequestDataSource.PARAMS,
|
90
90
|
);
|
91
|
-
export const
|
91
|
+
export const requestParam = createRequestDataPropertyDecoratorWithSource(
|
92
92
|
RequestDataSource.PARAMS,
|
93
93
|
);
|
94
|
-
export const
|
94
|
+
export const requestQueries = createRequestDataDecoratorWithSource(
|
95
95
|
RequestDataSource.QUERY,
|
96
96
|
);
|
97
|
-
export const
|
97
|
+
export const requestQuery = createRequestDataPropertyDecoratorWithSource(
|
98
98
|
RequestDataSource.QUERY,
|
99
99
|
);
|
100
|
-
export const
|
100
|
+
export const requestHeaders = createRequestDataDecoratorWithSource(
|
101
101
|
RequestDataSource.HEADERS,
|
102
102
|
);
|
103
|
-
export const
|
103
|
+
export const requestHeader = createRequestDataPropertyDecoratorWithSource(
|
104
104
|
RequestDataSource.HEADERS,
|
105
105
|
);
|
106
|
-
export const
|
106
|
+
export const requestCookies = createRequestDataDecoratorWithSource(
|
107
107
|
RequestDataSource.COOKIE,
|
108
108
|
);
|
109
|
-
export const
|
109
|
+
export const requestCookie = createRequestDataPropertyDecoratorWithSource(
|
110
110
|
RequestDataSource.COOKIE,
|
111
111
|
);
|
112
|
-
export const
|
112
|
+
export const requestField = createRequestDataPropertyDecoratorWithSource(
|
113
113
|
RequestDataSource.BODY,
|
114
114
|
);
|
115
115
|
|
@@ -118,7 +118,7 @@ export const field = createRequestDataPropertyDecoratorWithSource(
|
|
118
118
|
*
|
119
119
|
* @param schemaOrType
|
120
120
|
*/
|
121
|
-
export function
|
121
|
+
export function requestBody(schemaOrType?: DataSchema | DataType) {
|
122
122
|
let schema: DataSchema;
|
123
123
|
if (typeof schemaOrType === 'object') {
|
124
124
|
schema = schemaOrType;
|
@@ -0,0 +1,325 @@
|
|
1
|
+
import {expect} from 'chai';
|
2
|
+
import {HttpMethod} from '@e22m4u/js-trie-router';
|
3
|
+
import {getAction} from './rest-action-decorator.js';
|
4
|
+
import {putAction} from './rest-action-decorator.js';
|
5
|
+
import {restAction} from './rest-action-decorator.js';
|
6
|
+
import {postAction} from './rest-action-decorator.js';
|
7
|
+
import {patchAction} from './rest-action-decorator.js';
|
8
|
+
import {deleteAction} from './rest-action-decorator.js';
|
9
|
+
import {RestActionReflector} from './rest-action-reflector.js';
|
10
|
+
|
11
|
+
describe('restAction', function () {
|
12
|
+
it('hasAliases', function () {
|
13
|
+
expect(getAction).to.be.instanceOf(Function);
|
14
|
+
expect(postAction).to.be.instanceOf(Function);
|
15
|
+
expect(putAction).to.be.instanceOf(Function);
|
16
|
+
expect(patchAction).to.be.instanceOf(Function);
|
17
|
+
expect(deleteAction).to.be.instanceOf(Function);
|
18
|
+
});
|
19
|
+
|
20
|
+
it('sets given options to the target metadata', function () {
|
21
|
+
const options = {
|
22
|
+
method: HttpMethod.GET,
|
23
|
+
path: 'myPath',
|
24
|
+
before: () => undefined,
|
25
|
+
after: () => undefined,
|
26
|
+
customOption: 'customOption',
|
27
|
+
};
|
28
|
+
class Target {
|
29
|
+
@restAction(options)
|
30
|
+
method() {}
|
31
|
+
}
|
32
|
+
const res = RestActionReflector.getMetadata(Target);
|
33
|
+
expect(res.get('method')).to.be.eql({
|
34
|
+
...options,
|
35
|
+
propertyKey: 'method',
|
36
|
+
});
|
37
|
+
});
|
38
|
+
|
39
|
+
it('overrides a given "propertyKey" option by the target method name', function () {
|
40
|
+
const options = {
|
41
|
+
propertyKey: 'myMethod',
|
42
|
+
method: HttpMethod.GET,
|
43
|
+
path: 'myPath',
|
44
|
+
};
|
45
|
+
class Target {
|
46
|
+
@restAction(options)
|
47
|
+
method() {}
|
48
|
+
}
|
49
|
+
const res = RestActionReflector.getMetadata(Target);
|
50
|
+
expect(res.get('method')).to.be.eql({
|
51
|
+
...options,
|
52
|
+
propertyKey: 'method',
|
53
|
+
});
|
54
|
+
});
|
55
|
+
|
56
|
+
describe('getAction', function () {
|
57
|
+
it('allows no arguments', function () {
|
58
|
+
class Target {
|
59
|
+
@getAction()
|
60
|
+
method() {}
|
61
|
+
}
|
62
|
+
const res = RestActionReflector.getMetadata(Target);
|
63
|
+
expect(res.get('method')).to.be.eql({
|
64
|
+
propertyKey: 'method',
|
65
|
+
method: HttpMethod.GET,
|
66
|
+
path: '',
|
67
|
+
});
|
68
|
+
});
|
69
|
+
|
70
|
+
it('allows options as first argument', function () {
|
71
|
+
const options = {
|
72
|
+
path: 'myPath',
|
73
|
+
before: () => undefined,
|
74
|
+
after: () => undefined,
|
75
|
+
customOption: 'customOption',
|
76
|
+
};
|
77
|
+
class Target {
|
78
|
+
@getAction(options)
|
79
|
+
method() {}
|
80
|
+
}
|
81
|
+
const res = RestActionReflector.getMetadata(Target);
|
82
|
+
expect(res.get('method')).to.be.eql({
|
83
|
+
...options,
|
84
|
+
propertyKey: 'method',
|
85
|
+
method: HttpMethod.GET,
|
86
|
+
});
|
87
|
+
});
|
88
|
+
|
89
|
+
it('allows path and options arguments', function () {
|
90
|
+
const options = {
|
91
|
+
path: 'myPath2',
|
92
|
+
before: () => undefined,
|
93
|
+
after: () => undefined,
|
94
|
+
customOption: 'customOption',
|
95
|
+
};
|
96
|
+
class Target {
|
97
|
+
@getAction('myPath1', options)
|
98
|
+
method() {}
|
99
|
+
}
|
100
|
+
const res = RestActionReflector.getMetadata(Target);
|
101
|
+
expect(res.get('method')).to.be.eql({
|
102
|
+
...options,
|
103
|
+
propertyKey: 'method',
|
104
|
+
method: HttpMethod.GET,
|
105
|
+
path: 'myPath1',
|
106
|
+
});
|
107
|
+
});
|
108
|
+
});
|
109
|
+
|
110
|
+
describe('postAction', function () {
|
111
|
+
it('allows no arguments', function () {
|
112
|
+
class Target {
|
113
|
+
@postAction()
|
114
|
+
method() {}
|
115
|
+
}
|
116
|
+
const res = RestActionReflector.getMetadata(Target);
|
117
|
+
expect(res.get('method')).to.be.eql({
|
118
|
+
propertyKey: 'method',
|
119
|
+
method: HttpMethod.POST,
|
120
|
+
path: '',
|
121
|
+
});
|
122
|
+
});
|
123
|
+
|
124
|
+
it('allows options as first argument', function () {
|
125
|
+
const options = {
|
126
|
+
path: 'myPath',
|
127
|
+
before: () => undefined,
|
128
|
+
after: () => undefined,
|
129
|
+
customOption: 'customOption',
|
130
|
+
};
|
131
|
+
class Target {
|
132
|
+
@postAction(options)
|
133
|
+
method() {}
|
134
|
+
}
|
135
|
+
const res = RestActionReflector.getMetadata(Target);
|
136
|
+
expect(res.get('method')).to.be.eql({
|
137
|
+
...options,
|
138
|
+
propertyKey: 'method',
|
139
|
+
method: HttpMethod.POST,
|
140
|
+
});
|
141
|
+
});
|
142
|
+
|
143
|
+
it('allows path and options arguments', function () {
|
144
|
+
const options = {
|
145
|
+
path: 'myPath2',
|
146
|
+
before: () => undefined,
|
147
|
+
after: () => undefined,
|
148
|
+
customOption: 'customOption',
|
149
|
+
};
|
150
|
+
class Target {
|
151
|
+
@postAction('myPath1', options)
|
152
|
+
method() {}
|
153
|
+
}
|
154
|
+
const res = RestActionReflector.getMetadata(Target);
|
155
|
+
expect(res.get('method')).to.be.eql({
|
156
|
+
...options,
|
157
|
+
propertyKey: 'method',
|
158
|
+
method: HttpMethod.POST,
|
159
|
+
path: 'myPath1',
|
160
|
+
});
|
161
|
+
});
|
162
|
+
});
|
163
|
+
|
164
|
+
describe('putAction', function () {
|
165
|
+
it('allows no arguments', function () {
|
166
|
+
class Target {
|
167
|
+
@putAction()
|
168
|
+
method() {}
|
169
|
+
}
|
170
|
+
const res = RestActionReflector.getMetadata(Target);
|
171
|
+
expect(res.get('method')).to.be.eql({
|
172
|
+
propertyKey: 'method',
|
173
|
+
method: HttpMethod.PUT,
|
174
|
+
path: '',
|
175
|
+
});
|
176
|
+
});
|
177
|
+
|
178
|
+
it('allows options as first argument', function () {
|
179
|
+
const options = {
|
180
|
+
path: 'myPath',
|
181
|
+
before: () => undefined,
|
182
|
+
after: () => undefined,
|
183
|
+
customOption: 'customOption',
|
184
|
+
};
|
185
|
+
class Target {
|
186
|
+
@putAction(options)
|
187
|
+
method() {}
|
188
|
+
}
|
189
|
+
const res = RestActionReflector.getMetadata(Target);
|
190
|
+
expect(res.get('method')).to.be.eql({
|
191
|
+
...options,
|
192
|
+
propertyKey: 'method',
|
193
|
+
method: HttpMethod.PUT,
|
194
|
+
});
|
195
|
+
});
|
196
|
+
|
197
|
+
it('allows path and options arguments', function () {
|
198
|
+
const options = {
|
199
|
+
path: 'myPath2',
|
200
|
+
before: () => undefined,
|
201
|
+
after: () => undefined,
|
202
|
+
customOption: 'customOption',
|
203
|
+
};
|
204
|
+
class Target {
|
205
|
+
@putAction('myPath1', options)
|
206
|
+
method() {}
|
207
|
+
}
|
208
|
+
const res = RestActionReflector.getMetadata(Target);
|
209
|
+
expect(res.get('method')).to.be.eql({
|
210
|
+
...options,
|
211
|
+
propertyKey: 'method',
|
212
|
+
method: HttpMethod.PUT,
|
213
|
+
path: 'myPath1',
|
214
|
+
});
|
215
|
+
});
|
216
|
+
});
|
217
|
+
|
218
|
+
describe('patchAction', function () {
|
219
|
+
it('allows no arguments', function () {
|
220
|
+
class Target {
|
221
|
+
@patchAction()
|
222
|
+
method() {}
|
223
|
+
}
|
224
|
+
const res = RestActionReflector.getMetadata(Target);
|
225
|
+
expect(res.get('method')).to.be.eql({
|
226
|
+
propertyKey: 'method',
|
227
|
+
method: HttpMethod.PATCH,
|
228
|
+
path: '',
|
229
|
+
});
|
230
|
+
});
|
231
|
+
|
232
|
+
it('allows options as first argument', function () {
|
233
|
+
const options = {
|
234
|
+
path: 'myPath',
|
235
|
+
before: () => undefined,
|
236
|
+
after: () => undefined,
|
237
|
+
customOption: 'customOption',
|
238
|
+
};
|
239
|
+
class Target {
|
240
|
+
@patchAction(options)
|
241
|
+
method() {}
|
242
|
+
}
|
243
|
+
const res = RestActionReflector.getMetadata(Target);
|
244
|
+
expect(res.get('method')).to.be.eql({
|
245
|
+
...options,
|
246
|
+
propertyKey: 'method',
|
247
|
+
method: HttpMethod.PATCH,
|
248
|
+
});
|
249
|
+
});
|
250
|
+
|
251
|
+
it('allows path and options arguments', function () {
|
252
|
+
const options = {
|
253
|
+
path: 'myPath2',
|
254
|
+
before: () => undefined,
|
255
|
+
after: () => undefined,
|
256
|
+
customOption: 'customOption',
|
257
|
+
};
|
258
|
+
class Target {
|
259
|
+
@patchAction('myPath1', options)
|
260
|
+
method() {}
|
261
|
+
}
|
262
|
+
const res = RestActionReflector.getMetadata(Target);
|
263
|
+
expect(res.get('method')).to.be.eql({
|
264
|
+
...options,
|
265
|
+
propertyKey: 'method',
|
266
|
+
method: HttpMethod.PATCH,
|
267
|
+
path: 'myPath1',
|
268
|
+
});
|
269
|
+
});
|
270
|
+
});
|
271
|
+
|
272
|
+
describe('deleteAction', function () {
|
273
|
+
it('allows no arguments', function () {
|
274
|
+
class Target {
|
275
|
+
@deleteAction()
|
276
|
+
method() {}
|
277
|
+
}
|
278
|
+
const res = RestActionReflector.getMetadata(Target);
|
279
|
+
expect(res.get('method')).to.be.eql({
|
280
|
+
propertyKey: 'method',
|
281
|
+
method: HttpMethod.DELETE,
|
282
|
+
path: '',
|
283
|
+
});
|
284
|
+
});
|
285
|
+
|
286
|
+
it('allows options as first argument', function () {
|
287
|
+
const options = {
|
288
|
+
path: 'myPath',
|
289
|
+
before: () => undefined,
|
290
|
+
after: () => undefined,
|
291
|
+
customOption: 'customOption',
|
292
|
+
};
|
293
|
+
class Target {
|
294
|
+
@deleteAction(options)
|
295
|
+
method() {}
|
296
|
+
}
|
297
|
+
const res = RestActionReflector.getMetadata(Target);
|
298
|
+
expect(res.get('method')).to.be.eql({
|
299
|
+
...options,
|
300
|
+
propertyKey: 'method',
|
301
|
+
method: HttpMethod.DELETE,
|
302
|
+
});
|
303
|
+
});
|
304
|
+
|
305
|
+
it('allows path and options arguments', function () {
|
306
|
+
const options = {
|
307
|
+
path: 'myPath2',
|
308
|
+
before: () => undefined,
|
309
|
+
after: () => undefined,
|
310
|
+
customOption: 'customOption',
|
311
|
+
};
|
312
|
+
class Target {
|
313
|
+
@deleteAction('myPath1', options)
|
314
|
+
method() {}
|
315
|
+
}
|
316
|
+
const res = RestActionReflector.getMetadata(Target);
|
317
|
+
expect(res.get('method')).to.be.eql({
|
318
|
+
...options,
|
319
|
+
propertyKey: 'method',
|
320
|
+
method: HttpMethod.DELETE,
|
321
|
+
path: 'myPath1',
|
322
|
+
});
|
323
|
+
});
|
324
|
+
});
|
325
|
+
});
|
@@ -0,0 +1,166 @@
|
|
1
|
+
import {Flatten, PartialBy} from '../../types.js';
|
2
|
+
import {Prototype} from '../../types.js';
|
3
|
+
import {Constructor} from '../../types.js';
|
4
|
+
import {HttpMethod} from '@e22m4u/js-trie-router';
|
5
|
+
import {DecoratorTargetType} from '@e22m4u/ts-reflector';
|
6
|
+
import {getDecoratorTargetType} from '@e22m4u/ts-reflector';
|
7
|
+
import {RestActionMetadata} from './rest-action-metadata.js';
|
8
|
+
import {RestActionReflector} from './rest-action-reflector.js';
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Rest action options.
|
12
|
+
*/
|
13
|
+
export type RestActionOptions = Flatten<
|
14
|
+
Omit<RestActionMetadata, 'propertyKey'>
|
15
|
+
>;
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Rest action decorator.
|
19
|
+
*/
|
20
|
+
type RestActionDecorator = ReturnType<typeof restAction>;
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Rest action decorator factory.
|
24
|
+
*
|
25
|
+
* @param options
|
26
|
+
*/
|
27
|
+
export function restAction<T extends object>(options: RestActionOptions) {
|
28
|
+
return function (
|
29
|
+
target: Prototype<T>,
|
30
|
+
propertyKey: string,
|
31
|
+
descriptor: PropertyDescriptor,
|
32
|
+
) {
|
33
|
+
const decoratorType = getDecoratorTargetType(
|
34
|
+
target,
|
35
|
+
propertyKey,
|
36
|
+
descriptor,
|
37
|
+
);
|
38
|
+
if (decoratorType !== DecoratorTargetType.INSTANCE_METHOD)
|
39
|
+
throw new Error(
|
40
|
+
'@restAction decorator is only supported on an instance method.',
|
41
|
+
);
|
42
|
+
RestActionReflector.setMetadata(
|
43
|
+
{...options, propertyKey},
|
44
|
+
target.constructor as Constructor<T>,
|
45
|
+
propertyKey,
|
46
|
+
);
|
47
|
+
};
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Rest action method options.
|
52
|
+
*/
|
53
|
+
export type RestActionAliasOptions = Flatten<
|
54
|
+
PartialBy<Omit<RestActionOptions, 'method'>, 'path'>
|
55
|
+
>;
|
56
|
+
|
57
|
+
/**
|
58
|
+
* Get action decorator.
|
59
|
+
*/
|
60
|
+
export function getAction(): RestActionDecorator;
|
61
|
+
export function getAction(path: string): RestActionDecorator;
|
62
|
+
export function getAction(options: RestActionAliasOptions): RestActionDecorator;
|
63
|
+
export function getAction(
|
64
|
+
path: string,
|
65
|
+
options: RestActionAliasOptions,
|
66
|
+
): RestActionDecorator;
|
67
|
+
export function getAction(
|
68
|
+
pathOrOptions?: string | RestActionAliasOptions,
|
69
|
+
options?: RestActionAliasOptions,
|
70
|
+
) {
|
71
|
+
let path = typeof pathOrOptions === 'string' ? pathOrOptions : '';
|
72
|
+
options = typeof pathOrOptions === 'object' ? pathOrOptions : options;
|
73
|
+
if (typeof options === 'object' && !path && options.path != null)
|
74
|
+
path = options.path;
|
75
|
+
return restAction({...options, path, method: HttpMethod.GET});
|
76
|
+
}
|
77
|
+
|
78
|
+
/**
|
79
|
+
* Post action decorator.
|
80
|
+
*/
|
81
|
+
export function postAction(): RestActionDecorator;
|
82
|
+
export function postAction(path: string): RestActionDecorator;
|
83
|
+
export function postAction(
|
84
|
+
options: RestActionAliasOptions,
|
85
|
+
): RestActionDecorator;
|
86
|
+
export function postAction(
|
87
|
+
path: string,
|
88
|
+
options: RestActionAliasOptions,
|
89
|
+
): RestActionDecorator;
|
90
|
+
export function postAction(
|
91
|
+
pathOrOptions?: string | RestActionAliasOptions,
|
92
|
+
options?: RestActionAliasOptions,
|
93
|
+
) {
|
94
|
+
let path = typeof pathOrOptions === 'string' ? pathOrOptions : '';
|
95
|
+
options = typeof pathOrOptions === 'object' ? pathOrOptions : options;
|
96
|
+
if (typeof options === 'object' && !path && options.path != null)
|
97
|
+
path = options.path;
|
98
|
+
return restAction({...options, path, method: HttpMethod.POST});
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Put action decorator.
|
103
|
+
*/
|
104
|
+
export function putAction(): RestActionDecorator;
|
105
|
+
export function putAction(path: string): RestActionDecorator;
|
106
|
+
export function putAction(options: RestActionAliasOptions): RestActionDecorator;
|
107
|
+
export function putAction(
|
108
|
+
path: string,
|
109
|
+
options: RestActionAliasOptions,
|
110
|
+
): RestActionDecorator;
|
111
|
+
export function putAction(
|
112
|
+
pathOrOptions?: string | RestActionAliasOptions,
|
113
|
+
options?: RestActionAliasOptions,
|
114
|
+
) {
|
115
|
+
let path = typeof pathOrOptions === 'string' ? pathOrOptions : '';
|
116
|
+
options = typeof pathOrOptions === 'object' ? pathOrOptions : options;
|
117
|
+
if (typeof options === 'object' && !path && options.path != null)
|
118
|
+
path = options.path;
|
119
|
+
return restAction({...options, path, method: HttpMethod.PUT});
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Patch action decorator.
|
124
|
+
*/
|
125
|
+
export function patchAction(): RestActionDecorator;
|
126
|
+
export function patchAction(path: string): RestActionDecorator;
|
127
|
+
export function patchAction(
|
128
|
+
options: RestActionAliasOptions,
|
129
|
+
): RestActionDecorator;
|
130
|
+
export function patchAction(
|
131
|
+
path: string,
|
132
|
+
options: RestActionAliasOptions,
|
133
|
+
): RestActionDecorator;
|
134
|
+
export function patchAction(
|
135
|
+
pathOrOptions?: string | RestActionAliasOptions,
|
136
|
+
options?: RestActionAliasOptions,
|
137
|
+
) {
|
138
|
+
let path = typeof pathOrOptions === 'string' ? pathOrOptions : '';
|
139
|
+
options = typeof pathOrOptions === 'object' ? pathOrOptions : options;
|
140
|
+
if (typeof options === 'object' && !path && options.path != null)
|
141
|
+
path = options.path;
|
142
|
+
return restAction({...options, path, method: HttpMethod.PATCH});
|
143
|
+
}
|
144
|
+
|
145
|
+
/**
|
146
|
+
* Delete action decorator.
|
147
|
+
*/
|
148
|
+
export function deleteAction(): RestActionDecorator;
|
149
|
+
export function deleteAction(path: string): RestActionDecorator;
|
150
|
+
export function deleteAction(
|
151
|
+
options: RestActionAliasOptions,
|
152
|
+
): RestActionDecorator;
|
153
|
+
export function deleteAction(
|
154
|
+
path: string,
|
155
|
+
options: RestActionAliasOptions,
|
156
|
+
): RestActionDecorator;
|
157
|
+
export function deleteAction(
|
158
|
+
pathOrOptions?: string | RestActionAliasOptions,
|
159
|
+
options?: RestActionAliasOptions,
|
160
|
+
) {
|
161
|
+
let path = typeof pathOrOptions === 'string' ? pathOrOptions : '';
|
162
|
+
options = typeof pathOrOptions === 'object' ? pathOrOptions : options;
|
163
|
+
if (typeof options === 'object' && !path && options.path != null)
|
164
|
+
path = options.path;
|
165
|
+
return restAction({...options, path, method: HttpMethod.DELETE});
|
166
|
+
}
|
@@ -4,9 +4,9 @@ import {RoutePreHandler} from '@e22m4u/js-trie-router';
|
|
4
4
|
import {RoutePostHandler} from '@e22m4u/js-trie-router';
|
5
5
|
|
6
6
|
/**
|
7
|
-
*
|
7
|
+
* Rest action metadata.
|
8
8
|
*/
|
9
|
-
export type
|
9
|
+
export type RestActionMetadata = {
|
10
10
|
propertyKey: string;
|
11
11
|
method: HttpMethod;
|
12
12
|
path: string;
|
@@ -15,13 +15,13 @@ export type ActionMetadata = {
|
|
15
15
|
};
|
16
16
|
|
17
17
|
/**
|
18
|
-
*
|
18
|
+
* Rest action metadata map.
|
19
19
|
*/
|
20
|
-
export type
|
20
|
+
export type RestActionMetadataMap = Map<string, RestActionMetadata>;
|
21
21
|
|
22
22
|
/**
|
23
|
-
*
|
23
|
+
* Rest actions metadata key.
|
24
24
|
*/
|
25
|
-
export const
|
26
|
-
'
|
25
|
+
export const REST_ACTIONS_METADATA_KEY = new MetadataKey<RestActionMetadataMap>(
|
26
|
+
'restActionsMetadataKey',
|
27
27
|
);
|
package/src/decorators/{action/action-reflector.spec.ts → rest-action/rest-action-reflector.spec.ts}
RENAMED
@@ -2,10 +2,10 @@ import {expect} from 'chai';
|
|
2
2
|
import {describe} from 'mocha';
|
3
3
|
import {Reflector} from '@e22m4u/ts-reflector';
|
4
4
|
import {HttpMethod} from '@e22m4u/js-trie-router';
|
5
|
-
import {
|
6
|
-
import {
|
5
|
+
import {RestActionReflector} from './rest-action-reflector.js';
|
6
|
+
import {REST_ACTIONS_METADATA_KEY} from './rest-action-metadata.js';
|
7
7
|
|
8
|
-
describe('
|
8
|
+
describe('RestActionReflector', function () {
|
9
9
|
describe('setMetadata', function () {
|
10
10
|
it('sets a given value as target metadata', function () {
|
11
11
|
class Target {}
|
@@ -19,9 +19,9 @@ describe('ActionReflector', function () {
|
|
19
19
|
method: HttpMethod.GET,
|
20
20
|
path: '/bar',
|
21
21
|
};
|
22
|
-
|
23
|
-
|
24
|
-
const res = Reflector.getOwnMetadata(
|
22
|
+
RestActionReflector.setMetadata(md1, Target, 'propertyKey1');
|
23
|
+
RestActionReflector.setMetadata(md2, Target, 'propertyKey2');
|
24
|
+
const res = Reflector.getOwnMetadata(REST_ACTIONS_METADATA_KEY, Target);
|
25
25
|
expect(res).to.be.instanceof(Map);
|
26
26
|
expect(res!.get('propertyKey1')).to.be.eq(md1);
|
27
27
|
expect(res!.get('propertyKey2')).to.be.eq(md2);
|
@@ -39,12 +39,12 @@ describe('ActionReflector', function () {
|
|
39
39
|
method: HttpMethod.POST,
|
40
40
|
path: '/bar',
|
41
41
|
};
|
42
|
-
|
43
|
-
const res1 = Reflector.getOwnMetadata(
|
42
|
+
RestActionReflector.setMetadata(md1, Target, 'propertyKey');
|
43
|
+
const res1 = Reflector.getOwnMetadata(REST_ACTIONS_METADATA_KEY, Target);
|
44
44
|
expect(res1).to.be.instanceof(Map);
|
45
45
|
expect(res1!.get('propertyKey')).to.be.eq(md1);
|
46
|
-
|
47
|
-
const res2 = Reflector.getOwnMetadata(
|
46
|
+
RestActionReflector.setMetadata(md2, Target, 'propertyKey');
|
47
|
+
const res2 = Reflector.getOwnMetadata(REST_ACTIONS_METADATA_KEY, Target);
|
48
48
|
expect(res2).to.be.instanceof(Map);
|
49
49
|
expect(res2!.get('propertyKey')).to.be.eq(md2);
|
50
50
|
});
|
@@ -67,8 +67,8 @@ describe('ActionReflector', function () {
|
|
67
67
|
['propertyKey1', md1],
|
68
68
|
['propertyKey2', md2],
|
69
69
|
]);
|
70
|
-
Reflector.defineMetadata(
|
71
|
-
const res =
|
70
|
+
Reflector.defineMetadata(REST_ACTIONS_METADATA_KEY, mdMap, Target);
|
71
|
+
const res = RestActionReflector.getMetadata(Target);
|
72
72
|
expect(res).to.be.instanceof(Map);
|
73
73
|
expect(res!.get('propertyKey1')).to.be.eq(md1);
|
74
74
|
expect(res!.get('propertyKey2')).to.be.eq(md2);
|
@@ -76,7 +76,7 @@ describe('ActionReflector', function () {
|
|
76
76
|
|
77
77
|
it('returns an empty map if no metadata', function () {
|
78
78
|
class Target {}
|
79
|
-
const res =
|
79
|
+
const res = RestActionReflector.getMetadata(Target);
|
80
80
|
expect(res).to.be.instanceof(Map);
|
81
81
|
expect(res).to.be.empty;
|
82
82
|
});
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import {Constructor} from '../../types.js';
|
2
|
+
import {Reflector} from '@e22m4u/ts-reflector';
|
3
|
+
import {RestActionMetadata} from './rest-action-metadata.js';
|
4
|
+
import {RestActionMetadataMap} from './rest-action-metadata.js';
|
5
|
+
import {REST_ACTIONS_METADATA_KEY} from './rest-action-metadata.js';
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Rest action reflector.
|
9
|
+
*/
|
10
|
+
export class RestActionReflector {
|
11
|
+
/**
|
12
|
+
* Set metadata.
|
13
|
+
*
|
14
|
+
* @param metadata
|
15
|
+
* @param target
|
16
|
+
* @param propertyKey
|
17
|
+
*/
|
18
|
+
static setMetadata(
|
19
|
+
metadata: RestActionMetadata,
|
20
|
+
target: Constructor,
|
21
|
+
propertyKey: string,
|
22
|
+
) {
|
23
|
+
const oldMap = Reflector.getOwnMetadata(REST_ACTIONS_METADATA_KEY, target);
|
24
|
+
const newMap = new Map(oldMap);
|
25
|
+
newMap.set(propertyKey, metadata);
|
26
|
+
Reflector.defineMetadata(REST_ACTIONS_METADATA_KEY, newMap, target);
|
27
|
+
}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Get metadata.
|
31
|
+
*
|
32
|
+
* @param target
|
33
|
+
*/
|
34
|
+
static getMetadata(target: Constructor): RestActionMetadataMap {
|
35
|
+
const metadata = Reflector.getOwnMetadata(
|
36
|
+
REST_ACTIONS_METADATA_KEY,
|
37
|
+
target,
|
38
|
+
);
|
39
|
+
return metadata ?? new Map();
|
40
|
+
}
|
41
|
+
}
|