@tsed/schema 8.0.1 → 8.0.2

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 (291) hide show
  1. package/package.json +11 -10
  2. package/src/components/async-api/channelsMapper.ts +81 -0
  3. package/src/components/async-api/generate.ts +24 -0
  4. package/src/components/async-api/messageMapper.ts +62 -0
  5. package/src/components/async-api/payloadMapper.ts +61 -0
  6. package/src/components/async-api/responseMapper.ts +70 -0
  7. package/src/components/default/anyMapper.spec.ts +7 -0
  8. package/src/components/default/anyMapper.ts +33 -0
  9. package/src/components/default/classMapper.ts +55 -0
  10. package/src/components/default/discriminatorMappingMapper.ts +36 -0
  11. package/src/components/default/enumsMapper.spec.ts +64 -0
  12. package/src/components/default/enumsMapper.ts +17 -0
  13. package/src/components/default/genericsMapper.ts +70 -0
  14. package/src/components/default/inheritedClassMapper.ts +24 -0
  15. package/src/components/default/itemMapper.ts +8 -0
  16. package/src/components/default/lazyRefMapper.ts +21 -0
  17. package/src/components/default/mapMapper.ts +25 -0
  18. package/src/components/default/nullableMapper.ts +55 -0
  19. package/src/components/default/objectMapper.ts +36 -0
  20. package/src/components/default/ofMapper.ts +16 -0
  21. package/src/components/default/propertiesMapper.ts +25 -0
  22. package/src/components/default/requiredMapper.ts +69 -0
  23. package/src/components/default/schemaMapper.ts +151 -0
  24. package/src/components/index.ts +36 -0
  25. package/src/components/open-spec/discriminatorMappingMapper.ts +7 -0
  26. package/src/components/open-spec/enumsMapper.ts +20 -0
  27. package/src/components/open-spec/generate.ts +29 -0
  28. package/src/components/open-spec/nullableMapper.ts +51 -0
  29. package/src/components/open-spec/operationInFilesMapper.ts +32 -0
  30. package/src/components/open-spec/operationInParameterMapper.ts +56 -0
  31. package/src/components/open-spec/operationInParametersMapper.ts +9 -0
  32. package/src/components/open-spec/operationInQueryMapper.ts +74 -0
  33. package/src/components/open-spec/operationMapper.ts +65 -0
  34. package/src/components/open-spec/operationMediaMapper.ts +11 -0
  35. package/src/components/open-spec/operationRequestBodyMapper.ts +82 -0
  36. package/src/components/open-spec/operationResponseMapper.ts +26 -0
  37. package/src/components/open-spec/pathsMapper.ts +132 -0
  38. package/src/constants/OperationVerbs.ts +29 -0
  39. package/src/constants/httpStatusMessages.ts +21 -0
  40. package/src/constants/jsonSchemaProperties.ts +17 -0
  41. package/src/decorators/class/children.ts +22 -0
  42. package/src/decorators/class/discriminatorValue.ts +53 -0
  43. package/src/decorators/collections/collectionContains.ts +25 -0
  44. package/src/decorators/collections/collectionOf.spec.ts +327 -0
  45. package/src/decorators/collections/collectionOf.ts +182 -0
  46. package/src/decorators/collections/maxItems.spec.ts +40 -0
  47. package/src/decorators/collections/maxItems.ts +59 -0
  48. package/src/decorators/collections/maxProperties.spec.ts +109 -0
  49. package/src/decorators/collections/maxProperties.ts +82 -0
  50. package/src/decorators/collections/minItems.spec.ts +40 -0
  51. package/src/decorators/collections/minItems.ts +63 -0
  52. package/src/decorators/collections/minProperties.spec.ts +109 -0
  53. package/src/decorators/collections/minProperties.ts +81 -0
  54. package/src/decorators/collections/uniqueItems.spec.ts +28 -0
  55. package/src/decorators/collections/uniqueItems.ts +59 -0
  56. package/src/decorators/common/__snapshots__/groups.spec.ts.snap +321 -0
  57. package/src/decorators/common/additionalProperties.spec.ts +133 -0
  58. package/src/decorators/common/additionalProperties.ts +17 -0
  59. package/src/decorators/common/allOf.spec.ts +276 -0
  60. package/src/decorators/common/allOf.ts +19 -0
  61. package/src/decorators/common/allow.spec.ts +130 -0
  62. package/src/decorators/common/allow.ts +50 -0
  63. package/src/decorators/common/any.spec.ts +109 -0
  64. package/src/decorators/common/any.ts +45 -0
  65. package/src/decorators/common/anyOf.spec.ts +270 -0
  66. package/src/decorators/common/anyOf.ts +23 -0
  67. package/src/decorators/common/const.spec.ts +98 -0
  68. package/src/decorators/common/const.ts +68 -0
  69. package/src/decorators/common/customKey.spec.ts +105 -0
  70. package/src/decorators/common/customKey.ts +39 -0
  71. package/src/decorators/common/default.spec.ts +25 -0
  72. package/src/decorators/common/default.ts +47 -0
  73. package/src/decorators/common/defaultMsg.spec.ts +22 -0
  74. package/src/decorators/common/defaultMsg.ts +38 -0
  75. package/src/decorators/common/description.spec.ts +166 -0
  76. package/src/decorators/common/description.ts +77 -0
  77. package/src/decorators/common/discriminatorKey.ts +14 -0
  78. package/src/decorators/common/enum.spec.ts +305 -0
  79. package/src/decorators/common/enum.ts +111 -0
  80. package/src/decorators/common/errorMsg.spec.ts +57 -0
  81. package/src/decorators/common/errorMsg.ts +14 -0
  82. package/src/decorators/common/example.spec.ts +93 -0
  83. package/src/decorators/common/example.ts +18 -0
  84. package/src/decorators/common/examples.spec.ts +101 -0
  85. package/src/decorators/common/examples.ts +20 -0
  86. package/src/decorators/common/exclusiveMaximum.spec.ts +47 -0
  87. package/src/decorators/common/exclusiveMaximum.ts +75 -0
  88. package/src/decorators/common/exclusiveMinimum.spec.ts +47 -0
  89. package/src/decorators/common/exclusiveMinimum.ts +75 -0
  90. package/src/decorators/common/format.spec.ts +149 -0
  91. package/src/decorators/common/format.ts +486 -0
  92. package/src/decorators/common/forwardGroups.spec.ts +270 -0
  93. package/src/decorators/common/forwardGroups.ts +16 -0
  94. package/src/decorators/common/groups.spec.ts +968 -0
  95. package/src/decorators/common/groups.ts +66 -0
  96. package/src/decorators/common/hidden.spec.ts +52 -0
  97. package/src/decorators/common/hidden.ts +36 -0
  98. package/src/decorators/common/ignore.spec.ts +88 -0
  99. package/src/decorators/common/ignore.ts +66 -0
  100. package/src/decorators/common/integer.spec.ts +110 -0
  101. package/src/decorators/common/integer.ts +69 -0
  102. package/src/decorators/common/jsonEntityFn.spec.ts +16 -0
  103. package/src/decorators/common/jsonEntityFn.ts +33 -0
  104. package/src/decorators/common/maxLength.spec.ts +61 -0
  105. package/src/decorators/common/maxLength.ts +88 -0
  106. package/src/decorators/common/maximum.spec.ts +73 -0
  107. package/src/decorators/common/maximum.ts +146 -0
  108. package/src/decorators/common/minLength.spec.ts +186 -0
  109. package/src/decorators/common/minLength.ts +89 -0
  110. package/src/decorators/common/minimum.spec.ts +74 -0
  111. package/src/decorators/common/minimum.ts +145 -0
  112. package/src/decorators/common/multipleOf.spec.ts +33 -0
  113. package/src/decorators/common/multipleOf.ts +80 -0
  114. package/src/decorators/common/name.spec.ts +56 -0
  115. package/src/decorators/common/name.ts +50 -0
  116. package/src/decorators/common/nullable.spec.ts +818 -0
  117. package/src/decorators/common/nullable.ts +32 -0
  118. package/src/decorators/common/oneOf.spec.ts +301 -0
  119. package/src/decorators/common/oneOf.ts +24 -0
  120. package/src/decorators/common/optional.spec.ts +43 -0
  121. package/src/decorators/common/optional.ts +26 -0
  122. package/src/decorators/common/pattern.spec.ts +27 -0
  123. package/src/decorators/common/pattern.ts +102 -0
  124. package/src/decorators/common/property.ts +24 -0
  125. package/src/decorators/common/readOnly.spec.ts +135 -0
  126. package/src/decorators/common/readOnly.ts +17 -0
  127. package/src/decorators/common/recordOf.spec.ts +41 -0
  128. package/src/decorators/common/recordOf.ts +59 -0
  129. package/src/decorators/common/required.spec.ts +188 -0
  130. package/src/decorators/common/required.ts +50 -0
  131. package/src/decorators/common/requiredGroups.spec.ts +127 -0
  132. package/src/decorators/common/requiredGroups.ts +23 -0
  133. package/src/decorators/common/schema.spec.ts +23 -0
  134. package/src/decorators/common/schema.ts +64 -0
  135. package/src/decorators/common/title.spec.ts +20 -0
  136. package/src/decorators/common/title.ts +45 -0
  137. package/src/decorators/common/typeError.spec.ts +22 -0
  138. package/src/decorators/common/typeError.ts +15 -0
  139. package/src/decorators/common/writeOnly.spec.ts +105 -0
  140. package/src/decorators/common/writeOnly.ts +17 -0
  141. package/src/decorators/config/jsonEntityComponent.ts +16 -0
  142. package/src/decorators/generics/genericOf.spec.ts +246 -0
  143. package/src/decorators/generics/genericOf.ts +112 -0
  144. package/src/decorators/generics/generics.ts +22 -0
  145. package/src/decorators/operations/acceptMime.spec.ts +39 -0
  146. package/src/decorators/operations/acceptMime.ts +25 -0
  147. package/src/decorators/operations/consumes.spec.ts +89 -0
  148. package/src/decorators/operations/consumes.ts +37 -0
  149. package/src/decorators/operations/contentType.spec.ts +40 -0
  150. package/src/decorators/operations/contentType.ts +24 -0
  151. package/src/decorators/operations/deprecated.spec.ts +223 -0
  152. package/src/decorators/operations/deprecated.ts +49 -0
  153. package/src/decorators/operations/header.spec.ts +214 -0
  154. package/src/decorators/operations/header.ts +62 -0
  155. package/src/decorators/operations/in.spec.ts +321 -0
  156. package/src/decorators/operations/in.ts +141 -0
  157. package/src/decorators/operations/inFile.spec.ts +209 -0
  158. package/src/decorators/operations/inFile.ts +55 -0
  159. package/src/decorators/operations/location.spec.ts +51 -0
  160. package/src/decorators/operations/location.ts +26 -0
  161. package/src/decorators/operations/operation.ts +119 -0
  162. package/src/decorators/operations/operationId.spec.ts +43 -0
  163. package/src/decorators/operations/operationId.ts +22 -0
  164. package/src/decorators/operations/operationPath.spec.ts +42 -0
  165. package/src/decorators/operations/operationPath.ts +33 -0
  166. package/src/decorators/operations/partial.spec.ts +249 -0
  167. package/src/decorators/operations/partial.ts +14 -0
  168. package/src/decorators/operations/path.spec.ts +47 -0
  169. package/src/decorators/operations/path.ts +27 -0
  170. package/src/decorators/operations/produces.spec.ts +89 -0
  171. package/src/decorators/operations/produces.ts +44 -0
  172. package/src/decorators/operations/publish.spec.ts +26 -0
  173. package/src/decorators/operations/publish.ts +6 -0
  174. package/src/decorators/operations/redirect.spec.ts +146 -0
  175. package/src/decorators/operations/redirect.ts +82 -0
  176. package/src/decorators/operations/returns.spec.ts +1393 -0
  177. package/src/decorators/operations/returns.ts +662 -0
  178. package/src/decorators/operations/route.spec.ts +211 -0
  179. package/src/decorators/operations/route.ts +154 -0
  180. package/src/decorators/operations/security.spec.ts +162 -0
  181. package/src/decorators/operations/security.ts +83 -0
  182. package/src/decorators/operations/status.spec.ts +582 -0
  183. package/src/decorators/operations/status.ts +130 -0
  184. package/src/decorators/operations/subscribe.spec.ts +32 -0
  185. package/src/decorators/operations/subscribe.ts +6 -0
  186. package/src/decorators/operations/summary.spec.ts +45 -0
  187. package/src/decorators/operations/summary.ts +32 -0
  188. package/src/decorators/operations/tags.spec.ts +113 -0
  189. package/src/decorators/operations/tags.ts +53 -0
  190. package/src/decorators/operations/view.spec.ts +16 -0
  191. package/src/decorators/operations/view.ts +27 -0
  192. package/src/domain/DecoratorContext.ts +116 -0
  193. package/src/domain/JsonAliasMap.ts +19 -0
  194. package/src/domain/JsonClassStore.ts +35 -0
  195. package/src/domain/JsonDiscriminator.spec.ts +65 -0
  196. package/src/domain/JsonDiscriminator.ts +52 -0
  197. package/src/domain/JsonEntityStore.spec.ts +277 -0
  198. package/src/domain/JsonEntityStore.ts +284 -0
  199. package/src/domain/JsonFormatTypes.ts +17 -0
  200. package/src/domain/JsonLazyRef.ts +21 -0
  201. package/src/domain/JsonMap.spec.ts +15 -0
  202. package/src/domain/JsonMap.ts +33 -0
  203. package/src/domain/JsonMedia.ts +24 -0
  204. package/src/domain/JsonMethodStore.spec.ts +301 -0
  205. package/src/domain/JsonMethodStore.ts +212 -0
  206. package/src/domain/JsonOperation.spec.ts +126 -0
  207. package/src/domain/JsonOperation.ts +219 -0
  208. package/src/domain/JsonOperationPathsMap.ts +16 -0
  209. package/src/domain/JsonOperationRoute.spec.ts +109 -0
  210. package/src/domain/JsonOperationRoute.ts +75 -0
  211. package/src/domain/JsonParameter.ts +70 -0
  212. package/src/domain/JsonParameterStore.spec.ts +212 -0
  213. package/src/domain/JsonParameterStore.ts +138 -0
  214. package/src/domain/JsonParameterTypes.spec.ts +12 -0
  215. package/src/domain/JsonParameterTypes.ts +20 -0
  216. package/src/domain/JsonPropertyStore.spec.ts +177 -0
  217. package/src/domain/JsonPropertyStore.ts +92 -0
  218. package/src/domain/JsonRequestBody.ts +47 -0
  219. package/src/domain/JsonResponse.spec.ts +33 -0
  220. package/src/domain/JsonResponse.ts +64 -0
  221. package/src/domain/JsonSchema.spec.ts +1470 -0
  222. package/src/domain/JsonSchema.ts +1049 -0
  223. package/src/domain/SpecTypes.ts +6 -0
  224. package/src/hooks/alterIgnore.ts +25 -0
  225. package/src/hooks/alterOneOf.ts +67 -0
  226. package/src/hooks/alterRequiredGroups.ts +12 -0
  227. package/src/index.ts +185 -0
  228. package/src/interfaces/IgnoreCallback.ts +5 -0
  229. package/src/interfaces/JsonHookContext.ts +18 -0
  230. package/src/interfaces/JsonOpenSpec.ts +7 -0
  231. package/src/interfaces/JsonSchemaOptions.ts +35 -0
  232. package/src/registries/JsonSchemaMapperContainer.ts +52 -0
  233. package/src/registries/enumRegistries.ts +3 -0
  234. package/src/utils/__snapshots__/generateSpec.spec.ts.snap +109 -0
  235. package/src/utils/buildPath.ts +8 -0
  236. package/src/utils/concatParameters.ts +12 -0
  237. package/src/utils/concatPath.spec.ts +23 -0
  238. package/src/utils/concatPath.ts +24 -0
  239. package/src/utils/defineStatusModel.ts +11 -0
  240. package/src/utils/from.spec.ts +243 -0
  241. package/src/utils/from.ts +281 -0
  242. package/src/utils/generateSpec.spec.ts +1262 -0
  243. package/src/utils/generateSpec.ts +54 -0
  244. package/src/utils/generics.ts +83 -0
  245. package/src/utils/getComputedType.spec.ts +45 -0
  246. package/src/utils/getComputedType.ts +39 -0
  247. package/src/utils/getInheritedStores.spec.ts +47 -0
  248. package/src/utils/getInheritedStores.ts +23 -0
  249. package/src/utils/getJsonEntityStore.ts +36 -0
  250. package/src/utils/getJsonPathParameters.spec.ts +126 -0
  251. package/src/utils/getJsonPathParameters.ts +97 -0
  252. package/src/utils/getJsonSchema.spec.ts +695 -0
  253. package/src/utils/getJsonSchema.ts +69 -0
  254. package/src/utils/getJsonType.spec.ts +28 -0
  255. package/src/utils/getJsonType.ts +46 -0
  256. package/src/utils/getOperationsRoutes.spec.ts +284 -0
  257. package/src/utils/getOperationsRoutes.ts +56 -0
  258. package/src/utils/getOperationsStore.spec.ts +47 -0
  259. package/src/utils/getOperationsStores.ts +37 -0
  260. package/src/utils/getPropertiesStores.spec.ts +138 -0
  261. package/src/utils/getPropertiesStores.ts +66 -0
  262. package/src/utils/getSpec.spec.ts +610 -0
  263. package/src/utils/getSpec.ts +117 -0
  264. package/src/utils/getSpecType.spec.ts +16 -0
  265. package/src/utils/getSpecType.ts +19 -0
  266. package/src/utils/isSuccessStatus.spec.ts +22 -0
  267. package/src/utils/isSuccessStatus.ts +2 -0
  268. package/src/utils/mapHeaders.spec.ts +57 -0
  269. package/src/utils/mapHeaders.ts +33 -0
  270. package/src/utils/mapOpenSpec.ts +44 -0
  271. package/src/utils/mapOpenSpec2.ts +50 -0
  272. package/src/utils/mapOpenSpec3.ts +25 -0
  273. package/src/utils/mapOpenSpecInfo.ts +19 -0
  274. package/src/utils/mapOperationOptions.ts +34 -0
  275. package/src/utils/matchGroups.spec.ts +85 -0
  276. package/src/utils/matchGroups.ts +64 -0
  277. package/src/utils/mergeSpec.spec.ts +533 -0
  278. package/src/utils/mergeSpec.ts +54 -0
  279. package/src/utils/operationIdFormatter.spec.ts +11 -0
  280. package/src/utils/operationIdFormatter.ts +49 -0
  281. package/src/utils/ref.ts +65 -0
  282. package/src/utils/removeHiddenOperation.ts +5 -0
  283. package/src/utils/serializeEnumValues.ts +27 -0
  284. package/src/utils/somethingOf.ts +11 -0
  285. package/src/utils/toJsonMapCollection.spec.ts +18 -0
  286. package/src/utils/toJsonMapCollection.ts +12 -0
  287. package/src/utils/toJsonRegex.ts +7 -0
  288. package/src/utils/transformToOS2.spec.ts +177 -0
  289. package/src/utils/transformToOS2.ts +607 -0
  290. package/src/utils/withErrorMsg.spec.ts +16 -0
  291. package/src/utils/withErrorMsg.ts +56 -0
@@ -0,0 +1,211 @@
1
+ import {JsonEntityStore, OperationVerbs} from "../../index.js";
2
+ import {All, Delete, Get, Head, Options, Patch, Post, Put} from "./route.js";
3
+
4
+ describe("Route decorators", () => {
5
+ describe("All", () => {
6
+ it("should register route and middleware (1)", () => {
7
+ // WHEN
8
+ class Test {
9
+ @All("/")
10
+ test() {}
11
+ }
12
+
13
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
14
+
15
+ // THEN
16
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
17
+ {
18
+ method: OperationVerbs.ALL,
19
+ path: "/"
20
+ }
21
+ ]);
22
+ expect(endpoint.propertyKey).toBe("test");
23
+ });
24
+ });
25
+
26
+ describe("Get", () => {
27
+ it("should register route and middleware (1)", () => {
28
+ // WHEN
29
+ class Test {
30
+ @Get("/")
31
+ test() {}
32
+ }
33
+
34
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
35
+
36
+ // THEN
37
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
38
+ {
39
+ method: OperationVerbs.GET,
40
+ path: "/"
41
+ }
42
+ ]);
43
+ expect(endpoint.propertyKey).toBe("test");
44
+ });
45
+ it("should register route and middleware (2)", () => {
46
+ const middleware = () => {};
47
+
48
+ // WHEN
49
+ class Test {
50
+ @Get("/", middleware)
51
+ test() {}
52
+ }
53
+
54
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
55
+
56
+ // THEN
57
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
58
+ {
59
+ method: OperationVerbs.GET,
60
+ path: "/"
61
+ }
62
+ ]);
63
+ expect(endpoint.propertyKey).toBe("test");
64
+ });
65
+ it("should register route and middleware (with handler)", () => {
66
+ const middleware = () => {};
67
+ const beforeMiddleware = () => {};
68
+ const afterMiddleware = () => {};
69
+
70
+ // WHEN
71
+ class Test {
72
+ @(Get("/").UseBefore(beforeMiddleware).Use(middleware).UseAfter(afterMiddleware))
73
+ test() {}
74
+ }
75
+
76
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
77
+ expect(endpoint.middlewares).toEqual([middleware]);
78
+ expect(endpoint.afterMiddlewares).toEqual([afterMiddleware]);
79
+ expect(endpoint.beforeMiddlewares).toEqual([beforeMiddleware]);
80
+ });
81
+ });
82
+
83
+ describe("Post", () => {
84
+ it("should register route and middleware", () => {
85
+ // WHEN
86
+ class Test {
87
+ @Post("/")
88
+ test() {}
89
+ }
90
+
91
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
92
+
93
+ // THEN
94
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
95
+ {
96
+ method: OperationVerbs.POST,
97
+ path: "/"
98
+ }
99
+ ]);
100
+ expect(endpoint.propertyKey).toBe("test");
101
+ });
102
+ });
103
+
104
+ describe("Put", () => {
105
+ it("should register route and middleware", () => {
106
+ // WHEN
107
+ class Test {
108
+ @(Put("/").Id("operationId").Summary("Summary").Description("Description"))
109
+ test() {}
110
+ }
111
+
112
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
113
+
114
+ // THEN
115
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
116
+ {
117
+ method: OperationVerbs.PUT,
118
+ path: "/"
119
+ }
120
+ ]);
121
+ expect(endpoint.propertyKey).toBe("test");
122
+ expect(endpoint.operation!.get("description")).toBe("Description");
123
+ expect(endpoint.operation!.get("summary")).toBe("Summary");
124
+ expect(endpoint.operation!.get("operationId")).toBe("operationId");
125
+ });
126
+ });
127
+
128
+ describe("Delete", () => {
129
+ it("should register route and middleware", () => {
130
+ // WHEN
131
+ class Test {
132
+ @Delete("/")
133
+ test() {}
134
+ }
135
+
136
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
137
+
138
+ // THEN
139
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
140
+ {
141
+ method: OperationVerbs.DELETE,
142
+ path: "/"
143
+ }
144
+ ]);
145
+ expect(endpoint.propertyKey).toBe("test");
146
+ });
147
+ });
148
+
149
+ describe("Head", () => {
150
+ it("should register route and middleware", () => {
151
+ // WHEN
152
+ class Test {
153
+ @Head("/")
154
+ test() {}
155
+ }
156
+
157
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
158
+
159
+ // THEN
160
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
161
+ {
162
+ method: OperationVerbs.HEAD,
163
+ path: "/"
164
+ }
165
+ ]);
166
+ expect(endpoint.propertyKey).toBe("test");
167
+ });
168
+ });
169
+
170
+ describe("Patch", () => {
171
+ it("should register route and middleware", () => {
172
+ // WHEN
173
+ class Test {
174
+ @Patch("/")
175
+ test() {}
176
+ }
177
+
178
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
179
+
180
+ // THEN
181
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
182
+ {
183
+ method: OperationVerbs.PATCH,
184
+ path: "/"
185
+ }
186
+ ]);
187
+ expect(endpoint.propertyKey).toBe("test");
188
+ });
189
+ });
190
+
191
+ describe("Options", () => {
192
+ it("should register route and middleware", () => {
193
+ // WHEN
194
+ class Test {
195
+ @Options("/")
196
+ test() {}
197
+ }
198
+
199
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
200
+
201
+ // THEN
202
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
203
+ {
204
+ method: OperationVerbs.OPTIONS,
205
+ path: "/"
206
+ }
207
+ ]);
208
+ expect(endpoint.propertyKey).toBe("test");
209
+ });
210
+ });
211
+ });
@@ -0,0 +1,154 @@
1
+ import {OperationVerbs} from "../../constants/OperationVerbs.js";
2
+ import {Operation} from "./operation.js";
3
+
4
+ /**
5
+ * This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
6
+ *
7
+ * This method is extremely useful for mapping “global” logic for specific path prefixes or arbitrary matches.
8
+ * For example, if you placed the following route at the top of all other route definitions, it would require that
9
+ * all routes from that point on would require authentication, and automatically load a user.
10
+ * Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then call next()
11
+ * to continue matching subsequent routes.
12
+ * @param path
13
+ * @param args
14
+ * @returns {Function}
15
+ * @decorator
16
+ * @operation
17
+ * @httpMethod
18
+ */
19
+ export function All(path: string | RegExp | unknown = "/", ...args: unknown[]) {
20
+ return Operation(...[OperationVerbs.ALL, path].concat(args));
21
+ }
22
+
23
+ /**
24
+ * This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
25
+ *
26
+ * This method is extremely useful for mapping “global” logic for specific path prefixes or arbitrary matches.
27
+ * For example, if you placed the following route at the top of all other route definitions, it would require that
28
+ * all routes from that point on would require authentication, and automatically load a user.
29
+ * Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then call next()
30
+ * to continue matching subsequent routes.
31
+ * @param path
32
+ * @param args
33
+ * @returns {Function}
34
+ * @decorator
35
+ * @operation
36
+ * @httpMethod
37
+ */
38
+ export function Get(path: string | RegExp | unknown = "/", ...args: unknown[]) {
39
+ return Operation(...[OperationVerbs.GET, path].concat(args));
40
+ }
41
+
42
+ /**
43
+ * This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
44
+ *
45
+ * This method is extremely useful for mapping “global” logic for specific path prefixes or arbitrary matches.
46
+ * For example, if you placed the following route at the top of all other route definitions, it would require that
47
+ * all routes from that point on would require authentication, and automatically load a user.
48
+ * Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then call next()
49
+ * to continue matching subsequent routes.
50
+ * @param path
51
+ * @param args
52
+ * @returns {Function}
53
+ * @decorator
54
+ * @operation
55
+ * @httpMethod
56
+ */
57
+ export function Post(path: string | RegExp | unknown = "/", ...args: unknown[]) {
58
+ return Operation(...[OperationVerbs.POST, path].concat(args));
59
+ }
60
+
61
+ /**
62
+ * This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
63
+ *
64
+ * This method is extremely useful for mapping “global” logic for specific path prefixes or arbitrary matches.
65
+ * For example, if you placed the following route at the top of all other route definitions, it would require that
66
+ * all routes from that point on would require authentication, and automatically load a user.
67
+ * Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then call next()
68
+ * to continue matching subsequent routes.
69
+ * @param path
70
+ * @param args
71
+ * @returns {Function}
72
+ * @decorator
73
+ * @operation
74
+ * @httpMethod
75
+ */
76
+ export function Put(path: string | RegExp | unknown = "/", ...args: unknown[]) {
77
+ return Operation(...[OperationVerbs.PUT, path].concat(args));
78
+ }
79
+
80
+ /**
81
+ * This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
82
+ *
83
+ * This method is extremely useful for mapping “global” logic for specific path prefixes or arbitrary matches.
84
+ * For example, if you placed the following route at the top of all other route definitions, it would require that
85
+ * all routes from that point on would require authentication, and automatically load a user.
86
+ * Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then call next()
87
+ * to continue matching subsequent routes.
88
+ * @param path
89
+ * @param args
90
+ * @returns {Function}
91
+ * @decorator
92
+ * @operation
93
+ * @httpMethod
94
+ */
95
+ export function Delete(path: string | RegExp | unknown = "/", ...args: unknown[]) {
96
+ return Operation(...[OperationVerbs.DELETE, path].concat(args));
97
+ }
98
+
99
+ /**
100
+ * This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
101
+ *
102
+ * This method is extremely useful for mapping “global” logic for specific path prefixes or arbitrary matches.
103
+ * For example, if you placed the following route at the top of all other route definitions, it would require that
104
+ * all routes from that point on would require authentication, and automatically load a user.
105
+ * Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then call next()
106
+ * to continue matching subsequent routes.
107
+ * @param path
108
+ * @param args
109
+ * @returns {Function}
110
+ * @decorator
111
+ * @operation
112
+ * @httpMethod
113
+ */
114
+ export function Head(path: string | RegExp | unknown = "/", ...args: unknown[]) {
115
+ return Operation(...[OperationVerbs.HEAD, path].concat(args));
116
+ }
117
+
118
+ /**
119
+ * This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
120
+ *
121
+ * This method is extremely useful for mapping “global” logic for specific path prefixes or arbitrary matches.
122
+ * For example, if you placed the following route at the top of all other route definitions, it would require that
123
+ * all routes from that point on would require authentication, and automatically load a user.
124
+ * Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then call next()
125
+ * to continue matching subsequent routes.
126
+ * @param path
127
+ * @param args
128
+ * @returns {Function}
129
+ * @decorator
130
+ * @operation
131
+ * @httpMethod
132
+ */
133
+ export function Patch(path: string | RegExp | any = "/", ...args: any[]) {
134
+ return Operation(...[OperationVerbs.PATCH, path].concat(args));
135
+ }
136
+
137
+ /**
138
+ * This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
139
+ *
140
+ * This method is extremely useful for mapping “global” logic for specific path prefixes or arbitrary matches.
141
+ * For example, if you placed the following route at the top of all other route definitions, it would require that
142
+ * all routes from that point on would require authentication, and automatically load a user.
143
+ * Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then call next()
144
+ * to continue matching subsequent routes.
145
+ * @param path
146
+ * @param args
147
+ * @returns {Function}
148
+ * @decorator
149
+ * @operation
150
+ * @httpMethod
151
+ */
152
+ export function Options(path: string | RegExp | unknown = "/", ...args: unknown[]) {
153
+ return Operation(...[OperationVerbs.OPTIONS, path].concat(args));
154
+ }
@@ -0,0 +1,162 @@
1
+ import {getSpec, OperationPath, SpecTypes} from "../../index.js";
2
+ import {Security} from "./security.js";
3
+
4
+ describe("Security", () => {
5
+ it("should store metadata (method)", () => {
6
+ class MyController {
7
+ @OperationPath("POST", "/")
8
+ @Security("oauth", "user")
9
+ get() {}
10
+ }
11
+
12
+ expect(getSpec(MyController)).toEqual({
13
+ tags: [
14
+ {
15
+ name: "MyController"
16
+ }
17
+ ],
18
+ paths: {
19
+ "/": {
20
+ post: {
21
+ operationId: "myControllerGet",
22
+ parameters: [],
23
+ responses: {
24
+ "200": {
25
+ description: "Success"
26
+ }
27
+ },
28
+ security: [{oauth: ["user"]}],
29
+ tags: ["MyController"]
30
+ }
31
+ }
32
+ }
33
+ });
34
+ expect(getSpec(MyController, {specType: SpecTypes.OPENAPI})).toEqual({
35
+ tags: [
36
+ {
37
+ name: "MyController"
38
+ }
39
+ ],
40
+ paths: {
41
+ "/": {
42
+ post: {
43
+ operationId: "myControllerGet",
44
+ parameters: [],
45
+ responses: {
46
+ "200": {
47
+ description: "Success"
48
+ }
49
+ },
50
+ security: [{oauth: ["user"]}],
51
+ tags: ["MyController"]
52
+ }
53
+ }
54
+ }
55
+ });
56
+ });
57
+ it("should store multiple security schemes (method)", () => {
58
+ class MyController {
59
+ @OperationPath("POST", "/")
60
+ @Security([{A: ["scope-1"]}, {B: [], C: ["scope-2", "scope-3"]}])
61
+ post() {}
62
+ }
63
+
64
+ expect(getSpec(MyController)).toEqual({
65
+ tags: [
66
+ {
67
+ name: "MyController"
68
+ }
69
+ ],
70
+ paths: {
71
+ "/": {
72
+ post: {
73
+ operationId: "myControllerPost",
74
+ parameters: [],
75
+ responses: {
76
+ "200": {
77
+ description: "Success"
78
+ }
79
+ },
80
+ security: [
81
+ {
82
+ A: ["scope-1"]
83
+ },
84
+ {
85
+ B: [],
86
+ C: ["scope-2", "scope-3"]
87
+ }
88
+ ],
89
+ tags: ["MyController"]
90
+ }
91
+ }
92
+ }
93
+ });
94
+ });
95
+ it("should store metadata (class)", () => {
96
+ @Security("oauth", "user")
97
+ class MyController {
98
+ @OperationPath("GET", "/")
99
+ get() {}
100
+
101
+ @OperationPath("POST", "/")
102
+ @Security("oauth", "admin")
103
+ post() {}
104
+ }
105
+
106
+ expect(getSpec(MyController)).toEqual({
107
+ tags: [
108
+ {
109
+ name: "MyController"
110
+ }
111
+ ],
112
+ paths: {
113
+ "/": {
114
+ get: {
115
+ operationId: "myControllerGet",
116
+ parameters: [],
117
+ responses: {
118
+ "200": {
119
+ description: "Success"
120
+ }
121
+ },
122
+ security: [
123
+ {
124
+ oauth: ["user"]
125
+ }
126
+ ],
127
+ tags: ["MyController"]
128
+ },
129
+ post: {
130
+ operationId: "myControllerPost",
131
+ parameters: [],
132
+ responses: {
133
+ "200": {
134
+ description: "Success"
135
+ }
136
+ },
137
+ security: [
138
+ {
139
+ oauth: ["admin", "user"]
140
+ }
141
+ ],
142
+ tags: ["MyController"]
143
+ }
144
+ }
145
+ }
146
+ });
147
+ });
148
+ it("should throw error for unsupported usage", () => {
149
+ class Test {
150
+ test() {}
151
+ }
152
+
153
+ let actualError: any;
154
+ try {
155
+ Security("POST", "/")(Test.prototype, "test", 0);
156
+ } catch (er) {
157
+ actualError = er;
158
+ }
159
+
160
+ expect(actualError.message).toEqual("Security cannot be used as parameter decorator on Test.test.[0]");
161
+ });
162
+ });
@@ -0,0 +1,83 @@
1
+ import {decorateMethodsOf, DecoratorTypes, UnsupportedDecoratorType} from "@tsed/core";
2
+ import {OpenSpecSecurity} from "@tsed/openspec";
3
+
4
+ import {JsonEntityFn} from "../common/jsonEntityFn.js";
5
+
6
+ /**
7
+ * Add security metadata on the decorated method.
8
+ *
9
+ * ## Examples
10
+ * ### On method
11
+ *
12
+ * ```typescript
13
+ * @Controller("/")
14
+ * class ModelCtrl {
15
+ * @Security("write:calendars")
16
+ * async method() {}
17
+ * }
18
+ * ```
19
+ *
20
+ * @param name
21
+ * @param scopes
22
+ * @decorator
23
+ * @swagger
24
+ * @schema
25
+ * @classDecorator
26
+ * @operation
27
+ */
28
+ export function Security(name: string, ...scopes: string[]): Function;
29
+ /**
30
+ * Add security metadata on the decorated method.
31
+ *
32
+ * You can use it to add multiple authentication types.
33
+ * See <https://swagger.io/docs/specification/authentication/#multiple>.
34
+ *
35
+ * ## Examples
36
+ * ### On method
37
+ *
38
+ * ```typescript
39
+ * @Controller("/")
40
+ * class ModelCtrl {
41
+ * @Security([{ "A": ["scope-1"] }, { "B": [], "C": ["scope-2", "scope-3"]}])
42
+ * async method() {}
43
+ * }
44
+ * ```
45
+ * this will add the following security metadata
46
+ * ```yaml
47
+ * security: # A OR (B AND C)
48
+ * - A: ["scope-1"]
49
+ * - B: []
50
+ * C: ["scope-2", "scope-3"]
51
+ * ```
52
+ *
53
+ * @param security
54
+ * @decorator
55
+ * @swagger
56
+ * @schema
57
+ * @classDecorator
58
+ * @operation
59
+ */
60
+ export function Security(security: OpenSpecSecurity): Function;
61
+ export function Security(nameOrSecurity: string | OpenSpecSecurity, ...scopes: string[]): Function {
62
+ return JsonEntityFn((store, args) => {
63
+ switch (store.decoratorType) {
64
+ case DecoratorTypes.METHOD:
65
+ if (Array.isArray(nameOrSecurity)) {
66
+ store.operation!.security(nameOrSecurity);
67
+ } else {
68
+ store.operation!.addSecurityScopes(nameOrSecurity, scopes);
69
+ }
70
+ break;
71
+ case DecoratorTypes.CLASS:
72
+ if (Array.isArray(nameOrSecurity)) {
73
+ decorateMethodsOf(args[0], Security(nameOrSecurity));
74
+ } else {
75
+ decorateMethodsOf(args[0], Security(nameOrSecurity, ...scopes));
76
+ }
77
+ break;
78
+
79
+ default:
80
+ throw new UnsupportedDecoratorType(Security, args);
81
+ }
82
+ });
83
+ }