@tsed/schema 8.0.0 → 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,32 @@
1
+ import "../../index.js";
2
+
3
+ import {OperationVerbs} from "../../constants/OperationVerbs.js";
4
+ import {JsonEntityStore} from "../../domain/JsonEntityStore.js";
5
+ import {Publish} from "./publish.js";
6
+ import {Subscribe} from "./subscribe.js";
7
+
8
+ describe("Subscribe", () => {
9
+ it("should register operation with Subscribe verb", () => {
10
+ // WHEN
11
+ class Test {
12
+ @Publish("event")
13
+ @Subscribe("event")
14
+ test() {}
15
+ }
16
+
17
+ const endpoint = JsonEntityStore.fromMethod(Test, "test");
18
+
19
+ // THEN
20
+ expect([...endpoint.operation!.operationPaths.values()]).toEqual([
21
+ {
22
+ method: OperationVerbs.SUBSCRIBE,
23
+ path: "event"
24
+ },
25
+ {
26
+ method: OperationVerbs.PUBLISH,
27
+ path: "event"
28
+ }
29
+ ]);
30
+ expect(endpoint.propertyKey).toBe("test");
31
+ });
32
+ });
@@ -0,0 +1,6 @@
1
+ import {OperationVerbs} from "../../constants/OperationVerbs.js";
2
+ import {Operation} from "./operation.js";
3
+
4
+ export function Subscribe(event: string) {
5
+ return Operation(OperationVerbs.SUBSCRIBE, event);
6
+ }
@@ -0,0 +1,45 @@
1
+ import {getSpec, OperationPath} from "../../index.js";
2
+ import {Summary} from "./summary.js";
3
+
4
+ describe("Summary", () => {
5
+ it("should store metadata", () => {
6
+ class MyController {
7
+ @OperationPath("POST", "/")
8
+ @Summary("summary")
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
+ summary: "summary",
29
+ tags: ["MyController"]
30
+ }
31
+ }
32
+ }
33
+ });
34
+ });
35
+ it("should throw error for unsupported usage", () => {
36
+ let actualError: any;
37
+ try {
38
+ Summary("summary")(class Test {});
39
+ } catch (er) {
40
+ actualError = er;
41
+ }
42
+
43
+ expect(actualError.message).toEqual("Summary cannot be used as class decorator on Test");
44
+ });
45
+ });
@@ -0,0 +1,32 @@
1
+ import {DecoratorTypes, UnsupportedDecoratorType} from "@tsed/core";
2
+
3
+ import {JsonEntityFn} from "../common/jsonEntityFn.js";
4
+
5
+ /**
6
+ * Add summary metadata on the decorated element.
7
+ *
8
+ * ## Examples
9
+ * ### On method
10
+ *
11
+ * ```typescript
12
+ * class Model {
13
+ * @Summary("summary")
14
+ * id: string;
15
+ * }
16
+ * ```
17
+ *
18
+ * @param summary
19
+ * @decorator
20
+ * @swagger
21
+ * @schema
22
+ * @operation
23
+ */
24
+ export function Summary(summary: string) {
25
+ return JsonEntityFn((store, args) => {
26
+ if (store.decoratorType !== DecoratorTypes.METHOD) {
27
+ throw new UnsupportedDecoratorType(Summary, args);
28
+ }
29
+
30
+ store.operation!.summary(summary);
31
+ });
32
+ }
@@ -0,0 +1,113 @@
1
+ import {getSpec, OperationPath} from "../../index.js";
2
+ import {Tags} from "./tags.js";
3
+
4
+ describe("Tags", () => {
5
+ it("should store metadata (method)", () => {
6
+ class MyController {
7
+ @OperationPath("POST", "/")
8
+ @Tags("api")
9
+ get() {}
10
+ }
11
+
12
+ expect(getSpec(MyController)).toEqual({
13
+ tags: [{name: "api"}],
14
+ paths: {
15
+ "/": {
16
+ post: {
17
+ operationId: "myControllerGet",
18
+ parameters: [],
19
+ responses: {
20
+ "200": {
21
+ description: "Success"
22
+ }
23
+ },
24
+ tags: ["api"]
25
+ }
26
+ }
27
+ }
28
+ });
29
+ });
30
+ it("should store metadata (method - map)", () => {
31
+ class MyController {
32
+ @OperationPath("POST", "/")
33
+ @Tags({name: "api", description: "description"})
34
+ get() {}
35
+ }
36
+
37
+ expect(getSpec(MyController)).toEqual({
38
+ tags: [
39
+ {
40
+ name: "api",
41
+ description: "description"
42
+ }
43
+ ],
44
+ paths: {
45
+ "/": {
46
+ post: {
47
+ operationId: "myControllerGet",
48
+ parameters: [],
49
+ responses: {
50
+ "200": {
51
+ description: "Success"
52
+ }
53
+ },
54
+ tags: ["api"]
55
+ }
56
+ }
57
+ }
58
+ });
59
+ });
60
+ it("should store metadata (class)", () => {
61
+ @Tags("api")
62
+ class MyController {
63
+ @OperationPath("GET", "/")
64
+ get() {}
65
+
66
+ @OperationPath("POST", "/")
67
+ @Tags("allow")
68
+ post() {}
69
+ }
70
+
71
+ expect(getSpec(MyController)).toEqual({
72
+ tags: [{name: "api"}, {name: "allow"}],
73
+ paths: {
74
+ "/": {
75
+ get: {
76
+ operationId: "myControllerGet",
77
+ parameters: [],
78
+ responses: {
79
+ "200": {
80
+ description: "Success"
81
+ }
82
+ },
83
+ tags: ["api"]
84
+ },
85
+ post: {
86
+ operationId: "myControllerPost",
87
+ parameters: [],
88
+ responses: {
89
+ "200": {
90
+ description: "Success"
91
+ }
92
+ },
93
+ tags: ["allow", "api"]
94
+ }
95
+ }
96
+ }
97
+ });
98
+ });
99
+ it("should throw error for unsupported usage", () => {
100
+ class Test {
101
+ test() {}
102
+ }
103
+
104
+ let actualError: any;
105
+ try {
106
+ Tags("tags")(Test.prototype, "test", 0);
107
+ } catch (er) {
108
+ actualError = er;
109
+ }
110
+
111
+ expect(actualError.message).toEqual("Tags cannot be used as parameter decorator on Test.test.[0]");
112
+ });
113
+ });
@@ -0,0 +1,53 @@
1
+ import {decorateMethodsOf, DecoratorTypes, UnsupportedDecoratorType} from "@tsed/core";
2
+ import {OpenSpecTag} from "@tsed/openspec";
3
+
4
+ import {JsonEntityFn} from "../common/jsonEntityFn.js";
5
+
6
+ function mapTags(tags: (string | OpenSpecTag)[]) {
7
+ return tags.map((tag) => {
8
+ if (typeof tag === "string") {
9
+ return {
10
+ name: tag
11
+ };
12
+ }
13
+
14
+ return tag;
15
+ });
16
+ }
17
+
18
+ /**
19
+ * Add tags metadata on the decorated element.
20
+ *
21
+ * ## Examples
22
+ * ### On method
23
+ *
24
+ * ```typescript
25
+ * @Controller("/")
26
+ * class MyController {
27
+ * @Tags("api")
28
+ * get() {}
29
+ * }
30
+ * ```
31
+ *
32
+ * @param tags
33
+ * @decorator
34
+ * @swagger
35
+ * @schema
36
+ * @classDecorator
37
+ * @operation
38
+ */
39
+ export function Tags(...tags: (string | OpenSpecTag)[]) {
40
+ return JsonEntityFn((store, args) => {
41
+ switch (store.decoratorType) {
42
+ case DecoratorTypes.METHOD:
43
+ store.operation!.addTags(mapTags(tags));
44
+ break;
45
+ case DecoratorTypes.CLASS:
46
+ decorateMethodsOf(args[0], Tags(...tags));
47
+ break;
48
+
49
+ default:
50
+ throw new UnsupportedDecoratorType(Tags, args);
51
+ }
52
+ });
53
+ }
@@ -0,0 +1,16 @@
1
+ import {JsonMethodStore, View} from "../../index.js";
2
+
3
+ describe("@View", () => {
4
+ it("should set metadata", () => {
5
+ class Test {
6
+ @View("page", {test: "test"})
7
+ test() {}
8
+ }
9
+
10
+ const endpoint = JsonMethodStore.get(Test, "test");
11
+ expect(endpoint.view).toEqual({
12
+ path: "page",
13
+ options: {test: "test"}
14
+ });
15
+ });
16
+ });
@@ -0,0 +1,27 @@
1
+ import {StoreSet} from "@tsed/core";
2
+
3
+ /**
4
+ * Use a view and sends the rendered HTML string to the client. Optional parameter:
5
+ *
6
+ * * viewOptions, an object whose properties define local variables for the view.
7
+ *
8
+ * The view argument is a string that is the file path of the view file to render.
9
+ * This can be an absolute path, or a path relative to the views setting.
10
+ * If the path does not contain a file extension, then the view engine setting determines the file extension.
11
+ * If the path does contain a file extension, then Express will load the module for the specified template engine (via require())
12
+ * and render it using the loaded module’s __express function.
13
+ *
14
+ * For more information, see [Using template engines with Express](http://expressjs.com/guide/using-template-engines.html).
15
+ *
16
+ * > NOTE: The view argument performs file system operations like reading a file from disk and evaluating Node.js modules,
17
+ * and as so for security reasons should not contain input from the end-user.
18
+ *
19
+ * @param path Relative path to the view file.
20
+ * @param options Additional options
21
+ * @decorator
22
+ * @operation
23
+ * @response
24
+ */
25
+ export function View(path: string, options?: Object): MethodDecorator {
26
+ return StoreSet("view", {path, options}) as any;
27
+ }
@@ -0,0 +1,116 @@
1
+ import {DecoratorParameters, DecoratorTypes} from "@tsed/core";
2
+ import {pascalCase} from "change-case";
3
+
4
+ import {JsonEntityStore} from "./JsonEntityStore.js";
5
+
6
+ /**
7
+ * @ignore
8
+ */
9
+ export interface DecoratorActionHandler {
10
+ (ctx: Map<string, any>): void;
11
+ }
12
+
13
+ /**
14
+ * @ignore
15
+ */
16
+ export abstract class DecoratorContext<T = any> extends Map<string, any> {
17
+ readonly methods: string[];
18
+ protected decoratorType: DecoratorTypes;
19
+ protected entity: JsonEntityStore;
20
+ protected actions: DecoratorActionHandler[] = [];
21
+
22
+ constructor(opts: any = {}) {
23
+ super();
24
+
25
+ Object.entries(opts).forEach(([key, value]) => {
26
+ this.set(key, value);
27
+ });
28
+ }
29
+
30
+ addAction(cb: DecoratorActionHandler) {
31
+ this.actions.push(cb);
32
+ return this;
33
+ }
34
+
35
+ build(): T {
36
+ const decorator: any = (...args: DecoratorParameters) => this.bind(args, decorator);
37
+
38
+ const wrap = (cb: any) => {
39
+ return (...args: any[]) => {
40
+ cb(...args);
41
+ return decorator;
42
+ };
43
+ };
44
+
45
+ const wrapKey = (key: string) => {
46
+ return wrap((...values: any[]) => {
47
+ key in this ? (this as any)[key](...values) : this.set(key, values[0]);
48
+ });
49
+ };
50
+
51
+ this.methods.forEach((name) => {
52
+ decorator[pascalCase(name)] = wrapKey(name);
53
+ });
54
+
55
+ return decorator as unknown as T;
56
+ }
57
+
58
+ toObject(): any {
59
+ return [...this.entries()].reduce((obj, [key, value]) => {
60
+ return {
61
+ ...obj,
62
+ [key]: value
63
+ };
64
+ }, {});
65
+ }
66
+
67
+ getMergedKey(key: string, defaultValue: any) {
68
+ let value = this.get(key) || defaultValue;
69
+
70
+ if (!value) {
71
+ return;
72
+ }
73
+
74
+ if (this.decoratorType === DecoratorTypes.CLASS) {
75
+ value = {
76
+ ...value,
77
+ ...(defaultValue || {})
78
+ };
79
+ }
80
+
81
+ return {
82
+ ...(defaultValue || {}),
83
+ ...value
84
+ };
85
+ }
86
+
87
+ protected bind(args: DecoratorParameters, decorator: any) {
88
+ this.entity = JsonEntityStore.from(...args);
89
+
90
+ this.beforeInit();
91
+ this.onInit(args, decorator);
92
+ this.afterInit();
93
+ }
94
+
95
+ protected onInit(args: DecoratorParameters, decorator: any): void {
96
+ this.forEach((value, key) => {
97
+ this.onMapKey(key, value);
98
+ });
99
+ }
100
+
101
+ protected onMapKey(key: string, value: any): void {
102
+ this.entity.set(key, value);
103
+ }
104
+
105
+ protected runActions() {
106
+ this.actions.forEach((action: any) => {
107
+ action(this);
108
+ });
109
+
110
+ return this;
111
+ }
112
+
113
+ protected beforeInit() {}
114
+
115
+ protected afterInit() {}
116
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @ignore
3
+ */
4
+ export type AliasType = string | number | symbol;
5
+ /**
6
+ * @ignore
7
+ */
8
+ export type AliasMap = Map<AliasType, AliasType>;
9
+ /**
10
+ * @ignore
11
+ */
12
+ export function mapAliasedProperties(value: any, alias: AliasMap) {
13
+ return Object.entries(value).reduce<any>((properties, [key, value]) => {
14
+ key = (alias.get(key) as string) || key;
15
+ properties[key] = value;
16
+
17
+ return properties;
18
+ }, {});
19
+ }
@@ -0,0 +1,35 @@
1
+ import {DecoratorTypes} from "@tsed/core";
2
+
3
+ import {JsonEntityComponent} from "../decorators/config/jsonEntityComponent.js";
4
+ import {JsonEntityStore, JsonEntityStoreOptions} from "./JsonEntityStore.js";
5
+ import type {JsonMethodStore} from "./JsonMethodStore.js";
6
+ import type {JsonPropertyStore} from "./JsonPropertyStore.js";
7
+ import {JsonSchema} from "./JsonSchema.js";
8
+
9
+ @JsonEntityComponent(DecoratorTypes.CLASS)
10
+ export class JsonClassStore extends JsonEntityStore {
11
+ /**
12
+ * List of children JsonEntityStore (properties or methods or params)
13
+ */
14
+ readonly children: Map<string | number, JsonMethodStore | JsonPropertyStore> = new Map();
15
+
16
+ get path() {
17
+ return this.store.get("path", "/");
18
+ }
19
+
20
+ set path(path: string) {
21
+ this.store.set("path", path);
22
+ }
23
+
24
+ protected build() {
25
+ if (!this._type) {
26
+ this.buildType(this.target);
27
+ }
28
+
29
+ this._type = this._type || Object;
30
+
31
+ this._schema = JsonSchema.from({
32
+ type: this.type
33
+ });
34
+ }
35
+ }
@@ -0,0 +1,65 @@
1
+ import {DiscriminatorValue} from "../decorators/class/discriminatorValue.js";
2
+ import {DiscriminatorKey} from "../decorators/common/discriminatorKey.js";
3
+ import {Property} from "../decorators/common/property.js";
4
+ import {Required} from "../decorators/common/required.js";
5
+ import {JsonEntityStore} from "./JsonEntityStore.js";
6
+
7
+ class Event {
8
+ @DiscriminatorKey() // declare this property a discriminator key
9
+ type: string;
10
+
11
+ @Property()
12
+ value: string;
13
+ }
14
+
15
+ @DiscriminatorValue("page_view") // or @DiscriminatorValue() value can be inferred by the class name
16
+ class PageView extends Event {
17
+ @Required()
18
+ url: string;
19
+ }
20
+
21
+ @DiscriminatorValue("action", "click_action")
22
+ class Action extends Event {
23
+ @Required()
24
+ event: string;
25
+ }
26
+
27
+ @DiscriminatorValue()
28
+ class CustomAction extends Event {
29
+ @Required()
30
+ event: string;
31
+
32
+ @Property()
33
+ meta: string;
34
+ }
35
+
36
+ describe("Discriminator", () => {
37
+ describe("getType()", () => {
38
+ it("should return the expected type", () => {
39
+ const discriminator = JsonEntityStore.from(Event).schema.discriminator();
40
+
41
+ expect(discriminator.getType("custom_action")).toEqual(CustomAction);
42
+ expect(discriminator.getType("")).toEqual(Event);
43
+ });
44
+ });
45
+
46
+ describe("getValues()", () => {
47
+ it("should return the expected values", () => {
48
+ const discriminator = JsonEntityStore.from(Event).schema.discriminator();
49
+
50
+ expect(discriminator.getValues(CustomAction)).toEqual(["custom_action"]);
51
+ expect(discriminator.getValues(Event)).toEqual(undefined);
52
+ expect(discriminator.getValues(Action)).toEqual(["action", "click_action"]);
53
+ });
54
+ });
55
+
56
+ describe("getDefaultValue()", () => {
57
+ it("should return the expected value", () => {
58
+ const discriminator = JsonEntityStore.from(Event).schema.discriminator();
59
+
60
+ expect(discriminator.getDefaultValue(CustomAction)).toEqual("custom_action");
61
+ expect(discriminator.getDefaultValue(Event)).toEqual(undefined);
62
+ expect(discriminator.getDefaultValue(Action)).toEqual("action");
63
+ });
64
+ });
65
+ });
@@ -0,0 +1,52 @@
1
+ import {cleanObject, Type} from "@tsed/core";
2
+
3
+ export class Discriminator {
4
+ propertyName: string;
5
+ base: Type<any>;
6
+ values: Map<string, Type> = new Map();
7
+ types: Map<Type, string[]> = new Map();
8
+
9
+ constructor({
10
+ base,
11
+ propertyName,
12
+ types,
13
+ values
14
+ }: Partial<{base: Type<any>; propertyName: string; values: Map<string, Type<any>>; types: Map<Type, string[]>}> = {}) {
15
+ Object.assign(
16
+ this,
17
+ cleanObject({
18
+ base,
19
+ propertyName,
20
+ types: types ? new Map(types) : undefined,
21
+ values: values ? new Map(values) : undefined
22
+ })
23
+ );
24
+ }
25
+
26
+ add(type: Type<string>, values: string[]) {
27
+ values.forEach((value) => {
28
+ this.values.set(value, type);
29
+ });
30
+
31
+ this.types.set(type, values);
32
+
33
+ return this;
34
+ }
35
+
36
+ getType(discriminatorValue: string): Type<any> {
37
+ return this.values.get(discriminatorValue) || this.base;
38
+ }
39
+
40
+ getValues(type: Type) {
41
+ return this.types.get(type);
42
+ }
43
+
44
+ getDefaultValue(type: Type<any>) {
45
+ const values = this.types.get(type);
46
+ return values ? values[0] : undefined;
47
+ }
48
+
49
+ children() {
50
+ return [...new Set([...this.types.keys()])];
51
+ }
52
+ }