@e22m4u/ts-rest-router 0.1.1 → 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.
Files changed (140) hide show
  1. package/README.md +118 -118
  2. package/dist/cjs/index.cjs +346 -360
  3. package/dist/esm/controller-registry.js +28 -28
  4. package/dist/esm/debuggable-service.d.ts +10 -1
  5. package/dist/esm/debuggable-service.js +14 -3
  6. package/dist/esm/decorators/after-action/after-action-decorator.d.ts +9 -0
  7. package/dist/esm/decorators/{after/after-decorator.js → after-action/after-action-decorator.js} +7 -7
  8. package/dist/esm/decorators/{before/before-decorator.spec.js → after-action/after-action-decorator.spec.js} +19 -19
  9. package/dist/esm/decorators/{after/after-metadata.d.ts → after-action/after-action-metadata.d.ts} +4 -4
  10. package/dist/esm/decorators/after-action/after-action-metadata.js +5 -0
  11. package/dist/esm/decorators/{after/after-reflector.d.ts → after-action/after-action-reflector.d.ts} +5 -5
  12. package/dist/esm/decorators/{before/before-reflector.js → after-action/after-action-reflector.js} +6 -6
  13. package/dist/esm/decorators/{before/before-reflector.spec.js → after-action/after-action-reflector.spec.js} +23 -23
  14. package/dist/esm/decorators/after-action/index.d.ts +3 -0
  15. package/dist/esm/decorators/after-action/index.js +3 -0
  16. package/dist/esm/decorators/before-action/before-action-decorator.d.ts +9 -0
  17. package/dist/esm/decorators/{before/before-decorator.js → before-action/before-action-decorator.js} +7 -7
  18. package/dist/esm/decorators/{after/after-decorator.spec.js → before-action/before-action-decorator.spec.js} +19 -19
  19. package/dist/esm/decorators/{before/before-metadata.d.ts → before-action/before-action-metadata.d.ts} +4 -4
  20. package/dist/esm/decorators/before-action/before-action-metadata.js +5 -0
  21. package/dist/esm/decorators/{before/before-reflector.d.ts → before-action/before-action-reflector.d.ts} +5 -5
  22. package/dist/esm/decorators/{after/after-reflector.js → before-action/before-action-reflector.js} +6 -6
  23. package/dist/esm/decorators/{after/after-reflector.spec.js → before-action/before-action-reflector.spec.js} +23 -23
  24. package/dist/esm/decorators/before-action/index.d.ts +3 -0
  25. package/dist/esm/decorators/before-action/index.js +3 -0
  26. package/dist/esm/decorators/index.d.ts +4 -4
  27. package/dist/esm/decorators/index.js +4 -4
  28. package/dist/esm/decorators/request-context/request-context-decorator.d.ts +4 -4
  29. package/dist/esm/decorators/request-context/request-context-decorator.js +4 -4
  30. package/dist/esm/decorators/request-context/request-context-decorator.spec.js +6 -0
  31. package/dist/esm/decorators/request-data/request-data-decorator.d.ts +10 -10
  32. package/dist/esm/decorators/request-data/request-data-decorator.js +10 -10
  33. package/dist/esm/decorators/request-data/request-data-decorator.spec.js +44 -32
  34. package/dist/esm/decorators/request-data/request-data-metadata.d.ts +1 -1
  35. package/dist/esm/decorators/rest-action/index.d.ts +3 -0
  36. package/dist/esm/decorators/rest-action/index.js +3 -0
  37. package/dist/esm/decorators/rest-action/rest-action-decorator.d.ts +57 -0
  38. package/dist/esm/decorators/rest-action/rest-action-decorator.js +52 -0
  39. package/dist/esm/decorators/rest-action/rest-action-decorator.spec.js +401 -0
  40. package/dist/esm/decorators/{action/action-metadata.d.ts → rest-action/rest-action-metadata.d.ts} +6 -6
  41. package/dist/esm/decorators/rest-action/rest-action-metadata.js +5 -0
  42. package/dist/esm/decorators/rest-action/rest-action-reflector.d.ts +22 -0
  43. package/dist/esm/decorators/{action/action-reflector.js → rest-action/rest-action-reflector.js} +6 -6
  44. package/dist/esm/decorators/{action/action-reflector.spec.js → rest-action/rest-action-reflector.spec.js} +13 -13
  45. package/dist/esm/decorators/rest-controller/index.d.ts +3 -0
  46. package/dist/esm/decorators/rest-controller/index.js +3 -0
  47. package/dist/esm/decorators/rest-controller/rest-controller-decorator.d.ts +14 -0
  48. package/dist/esm/decorators/{controller/controller-decorator.js → rest-controller/rest-controller-decorator.js} +5 -5
  49. package/dist/esm/decorators/{controller/controller-decorator.spec.js → rest-controller/rest-controller-decorator.spec.js} +15 -15
  50. package/dist/esm/decorators/{controller/controller-metadata.d.ts → rest-controller/rest-controller-metadata.d.ts} +5 -5
  51. package/dist/esm/decorators/rest-controller/rest-controller-metadata.js +5 -0
  52. package/dist/esm/decorators/rest-controller/rest-controller-reflector.d.ts +20 -0
  53. package/dist/esm/decorators/rest-controller/rest-controller-reflector.js +24 -0
  54. package/dist/esm/decorators/{controller/controller-reflector.spec.js → rest-controller/rest-controller-reflector.spec.js} +12 -12
  55. package/dist/esm/errors/not-a-controller-error.js +1 -1
  56. package/dist/esm/types.d.ts +0 -10
  57. package/dist/esm/utils/index.d.ts +0 -1
  58. package/dist/esm/utils/index.js +0 -1
  59. package/package.json +19 -19
  60. package/src/controller-registry.spec.ts +122 -122
  61. package/src/controller-registry.ts +33 -35
  62. package/src/debuggable-service.ts +17 -4
  63. package/src/decorators/{after/after-decorator.spec.ts → after-action/after-action-decorator.spec.ts} +19 -19
  64. package/src/decorators/{before/before-decorator.ts → after-action/after-action-decorator.ts} +9 -9
  65. package/src/decorators/{after/after-metadata.ts → after-action/after-action-metadata.ts} +5 -5
  66. package/src/decorators/{before/before-reflector.spec.ts → after-action/after-action-reflector.spec.ts} +33 -23
  67. package/src/decorators/{before/before-reflector.ts → after-action/after-action-reflector.ts} +13 -9
  68. package/src/decorators/after-action/index.ts +3 -0
  69. package/src/decorators/{before/before-decorator.spec.ts → before-action/before-action-decorator.spec.ts} +19 -19
  70. package/src/decorators/{after/after-decorator.ts → before-action/before-action-decorator.ts} +9 -9
  71. package/src/decorators/before-action/before-action-metadata.ts +17 -0
  72. package/src/decorators/{after/after-reflector.spec.ts → before-action/before-action-reflector.spec.ts} +40 -23
  73. package/src/decorators/{after/after-reflector.ts → before-action/before-action-reflector.ts} +18 -9
  74. package/src/decorators/before-action/index.ts +3 -0
  75. package/src/decorators/index.ts +4 -4
  76. package/src/decorators/request-context/request-context-decorator.spec.ts +7 -0
  77. package/src/decorators/request-context/request-context-decorator.ts +4 -4
  78. package/src/decorators/request-data/request-data-decorator.spec.ts +45 -32
  79. package/src/decorators/request-data/request-data-decorator.ts +10 -10
  80. package/src/decorators/request-data/request-data-metadata.ts +1 -1
  81. package/src/decorators/rest-action/index.ts +3 -0
  82. package/src/decorators/rest-action/rest-action-decorator.spec.ts +325 -0
  83. package/src/decorators/rest-action/rest-action-decorator.ts +166 -0
  84. package/src/decorators/{action/action-metadata.ts → rest-action/rest-action-metadata.ts} +7 -7
  85. package/src/decorators/{action/action-reflector.spec.ts → rest-action/rest-action-reflector.spec.ts} +13 -13
  86. package/src/decorators/rest-action/rest-action-reflector.ts +41 -0
  87. package/src/decorators/rest-controller/index.ts +3 -0
  88. package/src/decorators/{controller/controller-decorator.spec.ts → rest-controller/rest-controller-decorator.spec.ts} +16 -16
  89. package/src/decorators/{controller/controller-decorator.ts → rest-controller/rest-controller-decorator.ts} +14 -10
  90. package/src/decorators/{controller/controller-metadata.ts → rest-controller/rest-controller-metadata.ts} +6 -7
  91. package/src/decorators/{controller/controller-reflector.spec.ts → rest-controller/rest-controller-reflector.spec.ts} +21 -12
  92. package/src/decorators/rest-controller/rest-controller-reflector.ts +32 -0
  93. package/src/errors/not-a-controller-error.ts +4 -1
  94. package/src/types.ts +0 -10
  95. package/src/utils/index.ts +0 -1
  96. package/README-ru.md +0 -268
  97. package/dist/esm/decorators/action/action-decorator.d.ts +0 -52
  98. package/dist/esm/decorators/action/action-decorator.js +0 -62
  99. package/dist/esm/decorators/action/action-decorator.spec.js +0 -59
  100. package/dist/esm/decorators/action/action-metadata.js +0 -5
  101. package/dist/esm/decorators/action/action-reflector.d.ts +0 -22
  102. package/dist/esm/decorators/action/index.d.ts +0 -3
  103. package/dist/esm/decorators/action/index.js +0 -3
  104. package/dist/esm/decorators/after/after-decorator.d.ts +0 -9
  105. package/dist/esm/decorators/after/after-metadata.js +0 -5
  106. package/dist/esm/decorators/after/index.d.ts +0 -3
  107. package/dist/esm/decorators/after/index.js +0 -3
  108. package/dist/esm/decorators/before/before-decorator.d.ts +0 -9
  109. package/dist/esm/decorators/before/before-metadata.js +0 -5
  110. package/dist/esm/decorators/before/index.d.ts +0 -3
  111. package/dist/esm/decorators/before/index.js +0 -3
  112. package/dist/esm/decorators/controller/controller-decorator.d.ts +0 -14
  113. package/dist/esm/decorators/controller/controller-metadata.js +0 -5
  114. package/dist/esm/decorators/controller/controller-reflector.d.ts +0 -20
  115. package/dist/esm/decorators/controller/controller-reflector.js +0 -24
  116. package/dist/esm/decorators/controller/index.d.ts +0 -3
  117. package/dist/esm/decorators/controller/index.js +0 -3
  118. package/dist/esm/utils/create-debugger.d.ts +0 -44
  119. package/dist/esm/utils/create-debugger.js +0 -81
  120. package/dist/esm/utils/create-debugger.spec.d.ts +0 -1
  121. package/dist/esm/utils/create-debugger.spec.js +0 -8
  122. package/src/decorators/action/action-decorator.spec.ts +0 -42
  123. package/src/decorators/action/action-decorator.ts +0 -98
  124. package/src/decorators/action/action-reflector.ts +0 -38
  125. package/src/decorators/action/index.ts +0 -3
  126. package/src/decorators/after/index.ts +0 -3
  127. package/src/decorators/before/before-metadata.ts +0 -17
  128. package/src/decorators/before/index.ts +0 -3
  129. package/src/decorators/controller/controller-reflector.ts +0 -28
  130. package/src/decorators/controller/index.ts +0 -3
  131. package/src/utils/create-debugger.spec.ts +0 -9
  132. package/src/utils/create-debugger.ts +0 -98
  133. /package/dist/esm/decorators/{action/action-decorator.spec.d.ts → after-action/after-action-decorator.spec.d.ts} +0 -0
  134. /package/dist/esm/decorators/{action/action-reflector.spec.d.ts → after-action/after-action-reflector.spec.d.ts} +0 -0
  135. /package/dist/esm/decorators/{after/after-decorator.spec.d.ts → before-action/before-action-decorator.spec.d.ts} +0 -0
  136. /package/dist/esm/decorators/{after/after-reflector.spec.d.ts → before-action/before-action-reflector.spec.d.ts} +0 -0
  137. /package/dist/esm/decorators/{before/before-decorator.spec.d.ts → rest-action/rest-action-decorator.spec.d.ts} +0 -0
  138. /package/dist/esm/decorators/{before/before-reflector.spec.d.ts → rest-action/rest-action-reflector.spec.d.ts} +0 -0
  139. /package/dist/esm/decorators/{controller/controller-decorator.spec.d.ts → rest-controller/rest-controller-decorator.spec.d.ts} +0 -0
  140. /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 params = createRequestDataDecoratorWithSource(
88
+ export const requestParams = createRequestDataDecoratorWithSource(
89
89
  RequestDataSource.PARAMS,
90
90
  );
91
- export const param = createRequestDataPropertyDecoratorWithSource(
91
+ export const requestParam = createRequestDataPropertyDecoratorWithSource(
92
92
  RequestDataSource.PARAMS,
93
93
  );
94
- export const queries = createRequestDataDecoratorWithSource(
94
+ export const requestQueries = createRequestDataDecoratorWithSource(
95
95
  RequestDataSource.QUERY,
96
96
  );
97
- export const query = createRequestDataPropertyDecoratorWithSource(
97
+ export const requestQuery = createRequestDataPropertyDecoratorWithSource(
98
98
  RequestDataSource.QUERY,
99
99
  );
100
- export const headers = createRequestDataDecoratorWithSource(
100
+ export const requestHeaders = createRequestDataDecoratorWithSource(
101
101
  RequestDataSource.HEADERS,
102
102
  );
103
- export const header = createRequestDataPropertyDecoratorWithSource(
103
+ export const requestHeader = createRequestDataPropertyDecoratorWithSource(
104
104
  RequestDataSource.HEADERS,
105
105
  );
106
- export const cookies = createRequestDataDecoratorWithSource(
106
+ export const requestCookies = createRequestDataDecoratorWithSource(
107
107
  RequestDataSource.COOKIE,
108
108
  );
109
- export const cookie = createRequestDataPropertyDecoratorWithSource(
109
+ export const requestCookie = createRequestDataPropertyDecoratorWithSource(
110
110
  RequestDataSource.COOKIE,
111
111
  );
112
- export const field = createRequestDataPropertyDecoratorWithSource(
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 body(schemaOrType?: DataSchema | DataType) {
121
+ export function requestBody(schemaOrType?: DataSchema | DataType) {
122
122
  let schema: DataSchema;
123
123
  if (typeof schemaOrType === 'object') {
124
124
  schema = schemaOrType;
@@ -1,5 +1,5 @@
1
- import {DataSchema} from '@e22m4u/ts-data-schema';
2
1
  import {MetadataKey} from '@e22m4u/ts-reflector';
2
+ import {DataSchema} from '@e22m4u/ts-data-schema';
3
3
 
4
4
  /**
5
5
  * Request data source.
@@ -0,0 +1,3 @@
1
+ export * from './rest-action-metadata.js';
2
+ export * from './rest-action-reflector.js';
3
+ export * from './rest-action-decorator.js';
@@ -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
- * Action metadata.
7
+ * Rest action metadata.
8
8
  */
9
- export type ActionMetadata = {
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
- * Action metadata map.
18
+ * Rest action metadata map.
19
19
  */
20
- export type ActionMetadataMap = Map<string, ActionMetadata>;
20
+ export type RestActionMetadataMap = Map<string, RestActionMetadata>;
21
21
 
22
22
  /**
23
- * Actions metadata key.
23
+ * Rest actions metadata key.
24
24
  */
25
- export const ACTIONS_METADATA_KEY = new MetadataKey<ActionMetadataMap>(
26
- 'actionsMetadataKey',
25
+ export const REST_ACTIONS_METADATA_KEY = new MetadataKey<RestActionMetadataMap>(
26
+ 'restActionsMetadataKey',
27
27
  );
@@ -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 {ActionReflector} from './action-reflector.js';
6
- import {ACTIONS_METADATA_KEY} from './action-metadata.js';
5
+ import {RestActionReflector} from './rest-action-reflector.js';
6
+ import {REST_ACTIONS_METADATA_KEY} from './rest-action-metadata.js';
7
7
 
8
- describe('ActionReflector', function () {
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
- ActionReflector.setMetadata(md1, Target, 'propertyKey1');
23
- ActionReflector.setMetadata(md2, Target, 'propertyKey2');
24
- const res = Reflector.getOwnMetadata(ACTIONS_METADATA_KEY, Target);
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
- ActionReflector.setMetadata(md1, Target, 'propertyKey');
43
- const res1 = Reflector.getOwnMetadata(ACTIONS_METADATA_KEY, Target);
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
- ActionReflector.setMetadata(md2, Target, 'propertyKey');
47
- const res2 = Reflector.getOwnMetadata(ACTIONS_METADATA_KEY, Target);
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(ACTIONS_METADATA_KEY, mdMap, Target);
71
- const res = ActionReflector.getMetadata(Target);
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 = ActionReflector.getMetadata(Target);
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
+ }
@@ -0,0 +1,3 @@
1
+ export * from './rest-controller-metadata.js';
2
+ export * from './rest-controller-decorator.js';
3
+ export * from './rest-controller-reflector.js';