@tsed/schema 8.0.1 → 8.0.3

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 (292) hide show
  1. package/package.json +11 -10
  2. package/readme.md +6 -6
  3. package/src/components/async-api/channelsMapper.ts +81 -0
  4. package/src/components/async-api/generate.ts +24 -0
  5. package/src/components/async-api/messageMapper.ts +62 -0
  6. package/src/components/async-api/payloadMapper.ts +61 -0
  7. package/src/components/async-api/responseMapper.ts +70 -0
  8. package/src/components/default/anyMapper.spec.ts +7 -0
  9. package/src/components/default/anyMapper.ts +33 -0
  10. package/src/components/default/classMapper.ts +55 -0
  11. package/src/components/default/discriminatorMappingMapper.ts +36 -0
  12. package/src/components/default/enumsMapper.spec.ts +64 -0
  13. package/src/components/default/enumsMapper.ts +17 -0
  14. package/src/components/default/genericsMapper.ts +70 -0
  15. package/src/components/default/inheritedClassMapper.ts +24 -0
  16. package/src/components/default/itemMapper.ts +8 -0
  17. package/src/components/default/lazyRefMapper.ts +21 -0
  18. package/src/components/default/mapMapper.ts +25 -0
  19. package/src/components/default/nullableMapper.ts +55 -0
  20. package/src/components/default/objectMapper.ts +36 -0
  21. package/src/components/default/ofMapper.ts +16 -0
  22. package/src/components/default/propertiesMapper.ts +25 -0
  23. package/src/components/default/requiredMapper.ts +69 -0
  24. package/src/components/default/schemaMapper.ts +151 -0
  25. package/src/components/index.ts +36 -0
  26. package/src/components/open-spec/discriminatorMappingMapper.ts +7 -0
  27. package/src/components/open-spec/enumsMapper.ts +20 -0
  28. package/src/components/open-spec/generate.ts +29 -0
  29. package/src/components/open-spec/nullableMapper.ts +51 -0
  30. package/src/components/open-spec/operationInFilesMapper.ts +32 -0
  31. package/src/components/open-spec/operationInParameterMapper.ts +56 -0
  32. package/src/components/open-spec/operationInParametersMapper.ts +9 -0
  33. package/src/components/open-spec/operationInQueryMapper.ts +74 -0
  34. package/src/components/open-spec/operationMapper.ts +65 -0
  35. package/src/components/open-spec/operationMediaMapper.ts +11 -0
  36. package/src/components/open-spec/operationRequestBodyMapper.ts +82 -0
  37. package/src/components/open-spec/operationResponseMapper.ts +26 -0
  38. package/src/components/open-spec/pathsMapper.ts +132 -0
  39. package/src/constants/OperationVerbs.ts +29 -0
  40. package/src/constants/httpStatusMessages.ts +21 -0
  41. package/src/constants/jsonSchemaProperties.ts +17 -0
  42. package/src/decorators/class/children.ts +22 -0
  43. package/src/decorators/class/discriminatorValue.ts +53 -0
  44. package/src/decorators/collections/collectionContains.ts +25 -0
  45. package/src/decorators/collections/collectionOf.spec.ts +327 -0
  46. package/src/decorators/collections/collectionOf.ts +182 -0
  47. package/src/decorators/collections/maxItems.spec.ts +40 -0
  48. package/src/decorators/collections/maxItems.ts +59 -0
  49. package/src/decorators/collections/maxProperties.spec.ts +109 -0
  50. package/src/decorators/collections/maxProperties.ts +82 -0
  51. package/src/decorators/collections/minItems.spec.ts +40 -0
  52. package/src/decorators/collections/minItems.ts +63 -0
  53. package/src/decorators/collections/minProperties.spec.ts +109 -0
  54. package/src/decorators/collections/minProperties.ts +81 -0
  55. package/src/decorators/collections/uniqueItems.spec.ts +28 -0
  56. package/src/decorators/collections/uniqueItems.ts +59 -0
  57. package/src/decorators/common/__snapshots__/groups.spec.ts.snap +321 -0
  58. package/src/decorators/common/additionalProperties.spec.ts +133 -0
  59. package/src/decorators/common/additionalProperties.ts +17 -0
  60. package/src/decorators/common/allOf.spec.ts +276 -0
  61. package/src/decorators/common/allOf.ts +19 -0
  62. package/src/decorators/common/allow.spec.ts +130 -0
  63. package/src/decorators/common/allow.ts +50 -0
  64. package/src/decorators/common/any.spec.ts +109 -0
  65. package/src/decorators/common/any.ts +45 -0
  66. package/src/decorators/common/anyOf.spec.ts +270 -0
  67. package/src/decorators/common/anyOf.ts +23 -0
  68. package/src/decorators/common/const.spec.ts +98 -0
  69. package/src/decorators/common/const.ts +68 -0
  70. package/src/decorators/common/customKey.spec.ts +105 -0
  71. package/src/decorators/common/customKey.ts +39 -0
  72. package/src/decorators/common/default.spec.ts +25 -0
  73. package/src/decorators/common/default.ts +47 -0
  74. package/src/decorators/common/defaultMsg.spec.ts +22 -0
  75. package/src/decorators/common/defaultMsg.ts +38 -0
  76. package/src/decorators/common/description.spec.ts +166 -0
  77. package/src/decorators/common/description.ts +77 -0
  78. package/src/decorators/common/discriminatorKey.ts +14 -0
  79. package/src/decorators/common/enum.spec.ts +305 -0
  80. package/src/decorators/common/enum.ts +111 -0
  81. package/src/decorators/common/errorMsg.spec.ts +57 -0
  82. package/src/decorators/common/errorMsg.ts +14 -0
  83. package/src/decorators/common/example.spec.ts +93 -0
  84. package/src/decorators/common/example.ts +18 -0
  85. package/src/decorators/common/examples.spec.ts +101 -0
  86. package/src/decorators/common/examples.ts +20 -0
  87. package/src/decorators/common/exclusiveMaximum.spec.ts +47 -0
  88. package/src/decorators/common/exclusiveMaximum.ts +75 -0
  89. package/src/decorators/common/exclusiveMinimum.spec.ts +47 -0
  90. package/src/decorators/common/exclusiveMinimum.ts +75 -0
  91. package/src/decorators/common/format.spec.ts +149 -0
  92. package/src/decorators/common/format.ts +486 -0
  93. package/src/decorators/common/forwardGroups.spec.ts +270 -0
  94. package/src/decorators/common/forwardGroups.ts +16 -0
  95. package/src/decorators/common/groups.spec.ts +968 -0
  96. package/src/decorators/common/groups.ts +66 -0
  97. package/src/decorators/common/hidden.spec.ts +52 -0
  98. package/src/decorators/common/hidden.ts +36 -0
  99. package/src/decorators/common/ignore.spec.ts +88 -0
  100. package/src/decorators/common/ignore.ts +66 -0
  101. package/src/decorators/common/integer.spec.ts +110 -0
  102. package/src/decorators/common/integer.ts +69 -0
  103. package/src/decorators/common/jsonEntityFn.spec.ts +16 -0
  104. package/src/decorators/common/jsonEntityFn.ts +33 -0
  105. package/src/decorators/common/maxLength.spec.ts +61 -0
  106. package/src/decorators/common/maxLength.ts +88 -0
  107. package/src/decorators/common/maximum.spec.ts +73 -0
  108. package/src/decorators/common/maximum.ts +146 -0
  109. package/src/decorators/common/minLength.spec.ts +186 -0
  110. package/src/decorators/common/minLength.ts +89 -0
  111. package/src/decorators/common/minimum.spec.ts +74 -0
  112. package/src/decorators/common/minimum.ts +145 -0
  113. package/src/decorators/common/multipleOf.spec.ts +33 -0
  114. package/src/decorators/common/multipleOf.ts +80 -0
  115. package/src/decorators/common/name.spec.ts +56 -0
  116. package/src/decorators/common/name.ts +50 -0
  117. package/src/decorators/common/nullable.spec.ts +818 -0
  118. package/src/decorators/common/nullable.ts +32 -0
  119. package/src/decorators/common/oneOf.spec.ts +301 -0
  120. package/src/decorators/common/oneOf.ts +24 -0
  121. package/src/decorators/common/optional.spec.ts +43 -0
  122. package/src/decorators/common/optional.ts +26 -0
  123. package/src/decorators/common/pattern.spec.ts +27 -0
  124. package/src/decorators/common/pattern.ts +102 -0
  125. package/src/decorators/common/property.ts +24 -0
  126. package/src/decorators/common/readOnly.spec.ts +135 -0
  127. package/src/decorators/common/readOnly.ts +17 -0
  128. package/src/decorators/common/recordOf.spec.ts +41 -0
  129. package/src/decorators/common/recordOf.ts +59 -0
  130. package/src/decorators/common/required.spec.ts +188 -0
  131. package/src/decorators/common/required.ts +50 -0
  132. package/src/decorators/common/requiredGroups.spec.ts +127 -0
  133. package/src/decorators/common/requiredGroups.ts +23 -0
  134. package/src/decorators/common/schema.spec.ts +23 -0
  135. package/src/decorators/common/schema.ts +64 -0
  136. package/src/decorators/common/title.spec.ts +20 -0
  137. package/src/decorators/common/title.ts +45 -0
  138. package/src/decorators/common/typeError.spec.ts +22 -0
  139. package/src/decorators/common/typeError.ts +15 -0
  140. package/src/decorators/common/writeOnly.spec.ts +105 -0
  141. package/src/decorators/common/writeOnly.ts +17 -0
  142. package/src/decorators/config/jsonEntityComponent.ts +16 -0
  143. package/src/decorators/generics/genericOf.spec.ts +246 -0
  144. package/src/decorators/generics/genericOf.ts +112 -0
  145. package/src/decorators/generics/generics.ts +22 -0
  146. package/src/decorators/operations/acceptMime.spec.ts +39 -0
  147. package/src/decorators/operations/acceptMime.ts +25 -0
  148. package/src/decorators/operations/consumes.spec.ts +89 -0
  149. package/src/decorators/operations/consumes.ts +37 -0
  150. package/src/decorators/operations/contentType.spec.ts +40 -0
  151. package/src/decorators/operations/contentType.ts +24 -0
  152. package/src/decorators/operations/deprecated.spec.ts +223 -0
  153. package/src/decorators/operations/deprecated.ts +49 -0
  154. package/src/decorators/operations/header.spec.ts +214 -0
  155. package/src/decorators/operations/header.ts +62 -0
  156. package/src/decorators/operations/in.spec.ts +321 -0
  157. package/src/decorators/operations/in.ts +141 -0
  158. package/src/decorators/operations/inFile.spec.ts +209 -0
  159. package/src/decorators/operations/inFile.ts +55 -0
  160. package/src/decorators/operations/location.spec.ts +51 -0
  161. package/src/decorators/operations/location.ts +26 -0
  162. package/src/decorators/operations/operation.ts +119 -0
  163. package/src/decorators/operations/operationId.spec.ts +43 -0
  164. package/src/decorators/operations/operationId.ts +22 -0
  165. package/src/decorators/operations/operationPath.spec.ts +42 -0
  166. package/src/decorators/operations/operationPath.ts +33 -0
  167. package/src/decorators/operations/partial.spec.ts +249 -0
  168. package/src/decorators/operations/partial.ts +14 -0
  169. package/src/decorators/operations/path.spec.ts +47 -0
  170. package/src/decorators/operations/path.ts +27 -0
  171. package/src/decorators/operations/produces.spec.ts +89 -0
  172. package/src/decorators/operations/produces.ts +44 -0
  173. package/src/decorators/operations/publish.spec.ts +26 -0
  174. package/src/decorators/operations/publish.ts +6 -0
  175. package/src/decorators/operations/redirect.spec.ts +146 -0
  176. package/src/decorators/operations/redirect.ts +82 -0
  177. package/src/decorators/operations/returns.spec.ts +1393 -0
  178. package/src/decorators/operations/returns.ts +662 -0
  179. package/src/decorators/operations/route.spec.ts +211 -0
  180. package/src/decorators/operations/route.ts +154 -0
  181. package/src/decorators/operations/security.spec.ts +162 -0
  182. package/src/decorators/operations/security.ts +83 -0
  183. package/src/decorators/operations/status.spec.ts +582 -0
  184. package/src/decorators/operations/status.ts +130 -0
  185. package/src/decorators/operations/subscribe.spec.ts +32 -0
  186. package/src/decorators/operations/subscribe.ts +6 -0
  187. package/src/decorators/operations/summary.spec.ts +45 -0
  188. package/src/decorators/operations/summary.ts +32 -0
  189. package/src/decorators/operations/tags.spec.ts +113 -0
  190. package/src/decorators/operations/tags.ts +53 -0
  191. package/src/decorators/operations/view.spec.ts +16 -0
  192. package/src/decorators/operations/view.ts +27 -0
  193. package/src/domain/DecoratorContext.ts +116 -0
  194. package/src/domain/JsonAliasMap.ts +19 -0
  195. package/src/domain/JsonClassStore.ts +35 -0
  196. package/src/domain/JsonDiscriminator.spec.ts +65 -0
  197. package/src/domain/JsonDiscriminator.ts +52 -0
  198. package/src/domain/JsonEntityStore.spec.ts +277 -0
  199. package/src/domain/JsonEntityStore.ts +284 -0
  200. package/src/domain/JsonFormatTypes.ts +17 -0
  201. package/src/domain/JsonLazyRef.ts +21 -0
  202. package/src/domain/JsonMap.spec.ts +15 -0
  203. package/src/domain/JsonMap.ts +33 -0
  204. package/src/domain/JsonMedia.ts +24 -0
  205. package/src/domain/JsonMethodStore.spec.ts +301 -0
  206. package/src/domain/JsonMethodStore.ts +212 -0
  207. package/src/domain/JsonOperation.spec.ts +126 -0
  208. package/src/domain/JsonOperation.ts +219 -0
  209. package/src/domain/JsonOperationPathsMap.ts +16 -0
  210. package/src/domain/JsonOperationRoute.spec.ts +109 -0
  211. package/src/domain/JsonOperationRoute.ts +75 -0
  212. package/src/domain/JsonParameter.ts +70 -0
  213. package/src/domain/JsonParameterStore.spec.ts +212 -0
  214. package/src/domain/JsonParameterStore.ts +138 -0
  215. package/src/domain/JsonParameterTypes.spec.ts +12 -0
  216. package/src/domain/JsonParameterTypes.ts +20 -0
  217. package/src/domain/JsonPropertyStore.spec.ts +177 -0
  218. package/src/domain/JsonPropertyStore.ts +92 -0
  219. package/src/domain/JsonRequestBody.ts +47 -0
  220. package/src/domain/JsonResponse.spec.ts +33 -0
  221. package/src/domain/JsonResponse.ts +64 -0
  222. package/src/domain/JsonSchema.spec.ts +1470 -0
  223. package/src/domain/JsonSchema.ts +1049 -0
  224. package/src/domain/SpecTypes.ts +6 -0
  225. package/src/hooks/alterIgnore.ts +25 -0
  226. package/src/hooks/alterOneOf.ts +67 -0
  227. package/src/hooks/alterRequiredGroups.ts +12 -0
  228. package/src/index.ts +185 -0
  229. package/src/interfaces/IgnoreCallback.ts +5 -0
  230. package/src/interfaces/JsonHookContext.ts +18 -0
  231. package/src/interfaces/JsonOpenSpec.ts +7 -0
  232. package/src/interfaces/JsonSchemaOptions.ts +35 -0
  233. package/src/registries/JsonSchemaMapperContainer.ts +52 -0
  234. package/src/registries/enumRegistries.ts +3 -0
  235. package/src/utils/__snapshots__/generateSpec.spec.ts.snap +109 -0
  236. package/src/utils/buildPath.ts +8 -0
  237. package/src/utils/concatParameters.ts +12 -0
  238. package/src/utils/concatPath.spec.ts +23 -0
  239. package/src/utils/concatPath.ts +24 -0
  240. package/src/utils/defineStatusModel.ts +11 -0
  241. package/src/utils/from.spec.ts +243 -0
  242. package/src/utils/from.ts +281 -0
  243. package/src/utils/generateSpec.spec.ts +1262 -0
  244. package/src/utils/generateSpec.ts +54 -0
  245. package/src/utils/generics.ts +83 -0
  246. package/src/utils/getComputedType.spec.ts +45 -0
  247. package/src/utils/getComputedType.ts +39 -0
  248. package/src/utils/getInheritedStores.spec.ts +47 -0
  249. package/src/utils/getInheritedStores.ts +23 -0
  250. package/src/utils/getJsonEntityStore.ts +36 -0
  251. package/src/utils/getJsonPathParameters.spec.ts +126 -0
  252. package/src/utils/getJsonPathParameters.ts +97 -0
  253. package/src/utils/getJsonSchema.spec.ts +695 -0
  254. package/src/utils/getJsonSchema.ts +69 -0
  255. package/src/utils/getJsonType.spec.ts +28 -0
  256. package/src/utils/getJsonType.ts +46 -0
  257. package/src/utils/getOperationsRoutes.spec.ts +284 -0
  258. package/src/utils/getOperationsRoutes.ts +56 -0
  259. package/src/utils/getOperationsStore.spec.ts +47 -0
  260. package/src/utils/getOperationsStores.ts +37 -0
  261. package/src/utils/getPropertiesStores.spec.ts +138 -0
  262. package/src/utils/getPropertiesStores.ts +66 -0
  263. package/src/utils/getSpec.spec.ts +610 -0
  264. package/src/utils/getSpec.ts +117 -0
  265. package/src/utils/getSpecType.spec.ts +16 -0
  266. package/src/utils/getSpecType.ts +19 -0
  267. package/src/utils/isSuccessStatus.spec.ts +22 -0
  268. package/src/utils/isSuccessStatus.ts +2 -0
  269. package/src/utils/mapHeaders.spec.ts +57 -0
  270. package/src/utils/mapHeaders.ts +33 -0
  271. package/src/utils/mapOpenSpec.ts +44 -0
  272. package/src/utils/mapOpenSpec2.ts +50 -0
  273. package/src/utils/mapOpenSpec3.ts +25 -0
  274. package/src/utils/mapOpenSpecInfo.ts +19 -0
  275. package/src/utils/mapOperationOptions.ts +34 -0
  276. package/src/utils/matchGroups.spec.ts +85 -0
  277. package/src/utils/matchGroups.ts +64 -0
  278. package/src/utils/mergeSpec.spec.ts +533 -0
  279. package/src/utils/mergeSpec.ts +54 -0
  280. package/src/utils/operationIdFormatter.spec.ts +11 -0
  281. package/src/utils/operationIdFormatter.ts +49 -0
  282. package/src/utils/ref.ts +65 -0
  283. package/src/utils/removeHiddenOperation.ts +5 -0
  284. package/src/utils/serializeEnumValues.ts +27 -0
  285. package/src/utils/somethingOf.ts +11 -0
  286. package/src/utils/toJsonMapCollection.spec.ts +18 -0
  287. package/src/utils/toJsonMapCollection.ts +12 -0
  288. package/src/utils/toJsonRegex.ts +7 -0
  289. package/src/utils/transformToOS2.spec.ts +177 -0
  290. package/src/utils/transformToOS2.ts +607 -0
  291. package/src/utils/withErrorMsg.spec.ts +16 -0
  292. package/src/utils/withErrorMsg.ts +56 -0
@@ -0,0 +1,32 @@
1
+ import {Type, useDecorators} from "@tsed/core";
2
+ import type {JSONSchema6TypeName} from "json-schema";
3
+
4
+ import {Any} from "./any.js";
5
+ import {Property} from "./property.js";
6
+
7
+ /**
8
+ * Set field as nullable.
9
+ *
10
+ * ## Example
11
+ *
12
+ * ```typescript
13
+ * class Model {
14
+ * @Nullable(Date)
15
+ * property: Date | null;
16
+ *
17
+ * @Nullable(String, Number, Boolean)
18
+ * property: string | number | boolean | null;
19
+ * }
20
+ * ```
21
+ *
22
+ * @returns {Function}
23
+ * @decorator
24
+ * @validation
25
+ * @swagger
26
+ * @schema
27
+ * @input
28
+ */
29
+ export function Nullable(type: JSONSchema6TypeName | Type<any> | any, ...types: (JSONSchema6TypeName | Type<any> | any)[]) {
30
+ types = [type, ...types];
31
+ return useDecorators(types.length === 1 && Property(types[0]), Any(null, ...types));
32
+ }
@@ -0,0 +1,301 @@
1
+ import {AllOf, getJsonSchema, getSpec, In, OneOf, OperationPath, Path, Property, SpecTypes} from "../../index.js";
2
+ import {number, string} from "../../utils/from.js";
3
+
4
+ describe("@OneOf", () => {
5
+ it("should declare return schema", () => {
6
+ // WHEN
7
+ class Model {
8
+ @OneOf(string(), number())
9
+ num: string;
10
+ }
11
+
12
+ // THEN
13
+ const schema = getJsonSchema(Model);
14
+
15
+ expect(schema).toEqual({
16
+ properties: {
17
+ num: {
18
+ oneOf: [
19
+ {
20
+ type: "string"
21
+ },
22
+ {
23
+ type: "number"
24
+ }
25
+ ]
26
+ }
27
+ },
28
+ type: "object"
29
+ });
30
+ });
31
+ it("should declare return schema for only one model", () => {
32
+ // WHEN
33
+ class Nested {
34
+ @Property()
35
+ id: string;
36
+ }
37
+ class Model {
38
+ @OneOf(Nested)
39
+ num: string;
40
+ }
41
+
42
+ // THEN
43
+ const schema = getJsonSchema(Model);
44
+
45
+ expect(schema).toEqual({
46
+ definitions: {
47
+ Nested: {
48
+ properties: {
49
+ id: {
50
+ type: "string"
51
+ }
52
+ },
53
+ type: "object"
54
+ }
55
+ },
56
+ properties: {
57
+ num: {
58
+ $ref: "#/definitions/Nested"
59
+ }
60
+ },
61
+ type: "object"
62
+ });
63
+ });
64
+ it("should declare two models", () => {
65
+ class One1 {
66
+ @Property()
67
+ id: string;
68
+ }
69
+
70
+ class One2 {
71
+ @Property()
72
+ id: string;
73
+ }
74
+
75
+ class Model {
76
+ @OneOf(One1, One2)
77
+ test: One1 | One2;
78
+ }
79
+
80
+ const schema = getJsonSchema(Model);
81
+
82
+ expect(schema).toEqual({
83
+ definitions: {
84
+ One1: {
85
+ type: "object",
86
+ properties: {
87
+ id: {
88
+ type: "string"
89
+ }
90
+ }
91
+ },
92
+ One2: {
93
+ type: "object",
94
+ properties: {
95
+ id: {
96
+ type: "string"
97
+ }
98
+ }
99
+ }
100
+ },
101
+ properties: {
102
+ test: {
103
+ oneOf: [
104
+ {
105
+ $ref: "#/definitions/One1"
106
+ },
107
+ {
108
+ $ref: "#/definitions/One2"
109
+ }
110
+ ]
111
+ }
112
+ },
113
+ type: "object"
114
+ });
115
+ });
116
+ it("should declare two models - OS3", () => {
117
+ class One1 {
118
+ @Property()
119
+ id: string;
120
+ }
121
+
122
+ class One2 {
123
+ @Property()
124
+ id: string;
125
+ }
126
+
127
+ class Model {
128
+ @OneOf(One1, One2)
129
+ test: One1 | One2;
130
+ }
131
+
132
+ @Path("/")
133
+ class MyController {
134
+ @OperationPath("POST", "/")
135
+ get(@In("body") payload: Model) {}
136
+ }
137
+
138
+ const spec = getSpec(MyController, {specType: SpecTypes.OPENAPI});
139
+
140
+ expect(spec).toEqual({
141
+ components: {
142
+ schemas: {
143
+ Model: {
144
+ properties: {
145
+ test: {
146
+ oneOf: [
147
+ {
148
+ $ref: "#/components/schemas/One1"
149
+ },
150
+ {
151
+ $ref: "#/components/schemas/One2"
152
+ }
153
+ ]
154
+ }
155
+ },
156
+ type: "object"
157
+ },
158
+ One1: {
159
+ properties: {
160
+ id: {
161
+ type: "string"
162
+ }
163
+ },
164
+ type: "object"
165
+ },
166
+ One2: {
167
+ properties: {
168
+ id: {
169
+ type: "string"
170
+ }
171
+ },
172
+ type: "object"
173
+ }
174
+ }
175
+ },
176
+ paths: {
177
+ "/": {
178
+ post: {
179
+ operationId: "myControllerGet",
180
+ parameters: [],
181
+ requestBody: {
182
+ content: {
183
+ "application/json": {
184
+ schema: {
185
+ $ref: "#/components/schemas/Model"
186
+ }
187
+ }
188
+ },
189
+ required: false
190
+ },
191
+ responses: {
192
+ "200": {
193
+ description: "Success"
194
+ }
195
+ },
196
+ tags: ["MyController"]
197
+ }
198
+ }
199
+ },
200
+ tags: [
201
+ {
202
+ name: "MyController"
203
+ }
204
+ ]
205
+ });
206
+ });
207
+ it("should declare two models (array) - OS3", () => {
208
+ class One1 {
209
+ @Property()
210
+ id: string;
211
+ }
212
+
213
+ class One2 {
214
+ @Property()
215
+ id: string;
216
+ }
217
+
218
+ class Model {
219
+ @OneOf(One1, One2)
220
+ list: (One1 | One2)[];
221
+ }
222
+
223
+ @Path("/")
224
+ class MyController {
225
+ @OperationPath("POST", "/")
226
+ get(@In("body") payload: Model) {}
227
+ }
228
+
229
+ const spec = getSpec(MyController, {specType: SpecTypes.OPENAPI});
230
+
231
+ expect(spec).toEqual({
232
+ components: {
233
+ schemas: {
234
+ Model: {
235
+ properties: {
236
+ list: {
237
+ type: "array",
238
+ items: {
239
+ oneOf: [
240
+ {
241
+ $ref: "#/components/schemas/One1"
242
+ },
243
+ {
244
+ $ref: "#/components/schemas/One2"
245
+ }
246
+ ]
247
+ }
248
+ }
249
+ },
250
+ type: "object"
251
+ },
252
+ One1: {
253
+ properties: {
254
+ id: {
255
+ type: "string"
256
+ }
257
+ },
258
+ type: "object"
259
+ },
260
+ One2: {
261
+ properties: {
262
+ id: {
263
+ type: "string"
264
+ }
265
+ },
266
+ type: "object"
267
+ }
268
+ }
269
+ },
270
+ paths: {
271
+ "/": {
272
+ post: {
273
+ operationId: "myControllerGet",
274
+ parameters: [],
275
+ requestBody: {
276
+ content: {
277
+ "application/json": {
278
+ schema: {
279
+ $ref: "#/components/schemas/Model"
280
+ }
281
+ }
282
+ },
283
+ required: false
284
+ },
285
+ responses: {
286
+ "200": {
287
+ description: "Success"
288
+ }
289
+ },
290
+ tags: ["MyController"]
291
+ }
292
+ }
293
+ },
294
+ tags: [
295
+ {
296
+ name: "MyController"
297
+ }
298
+ ]
299
+ });
300
+ });
301
+ });
@@ -0,0 +1,24 @@
1
+ import {AnyJsonSchema} from "../../domain/JsonSchema.js";
2
+ import {JsonEntityFn} from "./jsonEntityFn.js";
3
+
4
+ /**
5
+ * See https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.28
6
+ *
7
+ * ::: warning
8
+ * OneOf isn't supported by OS2
9
+ * :::
10
+ *
11
+ * @decorator
12
+ * @validation
13
+ * @swagger
14
+ * @schema
15
+ * @classDecorator
16
+ * @input
17
+ * @param oneOf
18
+ */
19
+ export function OneOf(...oneOf: AnyJsonSchema[]) {
20
+ return JsonEntityFn((entity) => {
21
+ entity.itemSchema.oneOf(oneOf);
22
+ entity.type = Object;
23
+ });
24
+ }
@@ -0,0 +1,43 @@
1
+ import {getSpec, In, Name, OperationPath, Optional, SpecTypes} from "../../index.js";
2
+ import {Path} from "../operations/path.js";
3
+
4
+ describe("Optional", () => {
5
+ it("should set metadata when optional is used on param", () => {
6
+ @Path("/")
7
+ class MyController {
8
+ @OperationPath("GET", "/")
9
+ method(@In("query") @Name("q") @Optional() q: string) {}
10
+ }
11
+
12
+ expect(getSpec(MyController, {specType: SpecTypes.OPENAPI})).toEqual({
13
+ paths: {
14
+ "/": {
15
+ get: {
16
+ operationId: "myControllerMethod",
17
+ parameters: [
18
+ {
19
+ in: "query",
20
+ name: "q",
21
+ required: false,
22
+ schema: {
23
+ type: "string"
24
+ }
25
+ }
26
+ ],
27
+ responses: {
28
+ "200": {
29
+ description: "Success"
30
+ }
31
+ },
32
+ tags: ["MyController"]
33
+ }
34
+ }
35
+ },
36
+ tags: [
37
+ {
38
+ name: "MyController"
39
+ }
40
+ ]
41
+ });
42
+ });
43
+ });
@@ -0,0 +1,26 @@
1
+ import {DecoratorTypes, UnsupportedDecoratorType} from "@tsed/core";
2
+
3
+ import type {JsonParameterStore} from "../../domain/JsonParameterStore.js";
4
+ import {JsonEntityFn} from "./jsonEntityFn.js";
5
+
6
+ /**
7
+ * Add optional annotation on Property or Parameter.
8
+ *
9
+ * @decorator
10
+ * @validation
11
+ * @swagger
12
+ * @schema
13
+ * @input
14
+ */
15
+ export function Optional() {
16
+ return JsonEntityFn((store) => {
17
+ switch (store.decoratorType) {
18
+ case DecoratorTypes.PARAM:
19
+ (store as JsonParameterStore).required = false;
20
+ break;
21
+ case DecoratorTypes.PROP:
22
+ store.parentSchema.removeRequired(store.propertyName);
23
+ break;
24
+ }
25
+ });
26
+ }
@@ -0,0 +1,27 @@
1
+ import "../../index.js";
2
+
3
+ import {JsonEntityStore} from "../../domain/JsonEntityStore.js";
4
+ import {Pattern} from "./pattern.js";
5
+
6
+ describe("@Pattern", () => {
7
+ it("should declare pattern value", () => {
8
+ // WHEN
9
+ class Model {
10
+ @Pattern(/(a|b)/)
11
+ num: string;
12
+ }
13
+
14
+ // THEN
15
+ const classSchema = JsonEntityStore.from(Model);
16
+
17
+ expect(classSchema.schema.toJSON()).toEqual({
18
+ properties: {
19
+ num: {
20
+ pattern: "(a|b)",
21
+ type: "string"
22
+ }
23
+ },
24
+ type: "object"
25
+ });
26
+ });
27
+ });
@@ -0,0 +1,102 @@
1
+ import {JsonEntityStore} from "../../domain/JsonEntityStore.js";
2
+ import {withErrorMsg} from "../../utils/withErrorMsg.js";
3
+ import {JsonEntityFn} from "./jsonEntityFn.js";
4
+
5
+ /**
6
+ * The pattern and Pattern Properties keywords use regular expressions to express constraints.
7
+ * The regular expression syntax used is from JavaScript (ECMA 262, specifically). However, that complete syntax is not widely supported, therefore it is recommended that you stick to the subset of that syntax described below.
8
+ *
9
+ * ::: warning
10
+ * For v6 user, use @@Pattern@@ from @tsed/schema instead of @tsed/platform-http.
11
+ * :::
12
+ *
13
+ * A single unicode character (other than the special characters below) matches itself.
14
+ *
15
+ * * `^`: Matches only at the beginning of the string.
16
+ * * `$`: Matches only at the end of the string.
17
+ * * `(...)`: Group a series of regular expressions into a single regular expression.
18
+ * * `|`: Matches either the regular expression preceding or following the | symbol.
19
+ * * `[abc]`: Matches any of the characters inside the square brackets.
20
+ * * `[a-z]`: Matches the range of characters.
21
+ * * `[^abc]`: Matches any character not listed.
22
+ * * `[^a-z]`: Matches any character outside of the range.
23
+ * * `+`: Matches one or more repetitions of the preceding regular expression.
24
+ * * `*`: Matches zero or more repetitions of the preceding regular expression.
25
+ * * `?`: Matches zero or one repetitions of the preceding regular expression.
26
+ * * `+?`, *?`, ??`: The `*`, `+`, and `?` qualifiers are all greedy; they match as much text as possible. Sometimes this behavior isn’t desired and you want to match as few characters as possible.
27
+ * * `{x}`: Match exactly x occurrences of the preceding regular expression.
28
+ * * `{x,y}`: Match at least x and at most y occurrences of the preceding regular expression.
29
+ * * `{x,}`: Match x occurrences or more of the preceding regular expression.
30
+ * * `{x}?`, {x,y}?, {x,}?`: Lazy versions of the above expressions.
31
+ *
32
+ * ## Example
33
+ *
34
+ * ```typescript
35
+ * class Model {
36
+ * @Pattern("^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$")
37
+ * @Pattern(/^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$/)
38
+ * property: string;
39
+ * }
40
+ * ```
41
+ *
42
+ * ### With primitive type
43
+ *
44
+ * ```typescript
45
+ * class Model {
46
+ * @Pattern(/^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$/)
47
+ * property: string;
48
+ * }
49
+ * ```
50
+ *
51
+ * ```json
52
+ * {
53
+ * "type": "object",
54
+ * "properties": {
55
+ * "property": {
56
+ * "type": "string",
57
+ * "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
58
+ * }
59
+ * }
60
+ * }
61
+ * ```
62
+ *
63
+ * ### With array type
64
+ *
65
+ * ```typescript
66
+ * class Model {
67
+ * @CollectionOf(string)
68
+ * @Pattern(/^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$/)
69
+ * property: string[];
70
+ * }
71
+ * ```
72
+ *
73
+ * Will produce:
74
+ *
75
+ * ```json
76
+ * {
77
+ * "type": "object",
78
+ * "properties": {
79
+ * "property": {
80
+ * "type": "array",
81
+ * "items": {
82
+ * "type": "string",
83
+ * "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
84
+ * }
85
+ * }
86
+ * }
87
+ * }
88
+ * ```
89
+ *
90
+ * @param {string} pattern
91
+ * @decorator
92
+ * @validation
93
+ * @swagger
94
+ * @schema
95
+ * @input
96
+ * @ajv-errors
97
+ */
98
+ export const Pattern = withErrorMsg("pattern", (pattern: string | RegExp) => {
99
+ return JsonEntityFn((store: JsonEntityStore) => {
100
+ store.itemSchema.pattern(pattern);
101
+ });
102
+ });
@@ -0,0 +1,24 @@
1
+ import {isArrowFn, isClass} from "@tsed/core";
2
+
3
+ import {JsonEntityFn} from "./jsonEntityFn.js";
4
+
5
+ /**
6
+ * Declare a new property on a model.
7
+ *
8
+ * @param type
9
+ * @decorator
10
+ * @validation
11
+ * @swagger
12
+ * @schema
13
+ * @input
14
+ */
15
+ export function Property(type?: any) {
16
+ return JsonEntityFn((store) => {
17
+ if (type) {
18
+ if (isClass(type) || isArrowFn(type)) {
19
+ store.type = type;
20
+ }
21
+ store.itemSchema.type(type);
22
+ }
23
+ });
24
+ }
@@ -0,0 +1,135 @@
1
+ import {Format, getJsonSchema, getSpec, In, Path, Post, Property, Returns, SpecTypes} from "../../index.js";
2
+ import {ReadOnly} from "./readOnly.js";
3
+
4
+ describe("@ReadOnly", () => {
5
+ it("should declare readOnly field", () => {
6
+ // WHEN
7
+ class Model {
8
+ @ReadOnly(true)
9
+ num: string;
10
+ }
11
+
12
+ // THEN
13
+ const schema = getJsonSchema(Model);
14
+
15
+ expect(schema).toEqual({
16
+ properties: {
17
+ num: {
18
+ readOnly: true,
19
+ type: "string"
20
+ }
21
+ },
22
+ type: "object"
23
+ });
24
+ });
25
+
26
+ it("should declare property as readonly (OS3)", () => {
27
+ class TestPerson {
28
+ @Property()
29
+ name: string;
30
+
31
+ @Property()
32
+ band: string;
33
+ }
34
+
35
+ // WHEN
36
+ class TestBand {
37
+ @Format("date-time")
38
+ @ReadOnly()
39
+ createdAt: number = Date.now();
40
+
41
+ @Format("date-time")
42
+ @ReadOnly()
43
+ updatedAt: number = Date.now();
44
+
45
+ @ReadOnly()
46
+ @Property(TestPerson)
47
+ members: TestPerson;
48
+ }
49
+
50
+ @Path("/")
51
+ class MyCtrl {
52
+ @Post("/")
53
+ @Returns(200, TestBand)
54
+ post(@In("body") model: TestBand) {}
55
+ }
56
+
57
+ // THEN
58
+ expect(getSpec(MyCtrl, {specType: SpecTypes.OPENAPI})).toEqual({
59
+ components: {
60
+ schemas: {
61
+ TestBand: {
62
+ properties: {
63
+ createdAt: {
64
+ format: "date-time",
65
+ readOnly: true,
66
+ type: "number"
67
+ },
68
+ members: {
69
+ anyOf: [
70
+ {
71
+ $ref: "#/components/schemas/TestPerson"
72
+ }
73
+ ],
74
+ readOnly: true
75
+ },
76
+ updatedAt: {
77
+ format: "date-time",
78
+ readOnly: true,
79
+ type: "number"
80
+ }
81
+ },
82
+ type: "object"
83
+ },
84
+ TestPerson: {
85
+ properties: {
86
+ band: {
87
+ type: "string"
88
+ },
89
+ name: {
90
+ type: "string"
91
+ }
92
+ },
93
+ type: "object"
94
+ }
95
+ }
96
+ },
97
+ paths: {
98
+ "/": {
99
+ post: {
100
+ operationId: "myCtrlPost",
101
+ parameters: [],
102
+ requestBody: {
103
+ content: {
104
+ "application/json": {
105
+ schema: {
106
+ $ref: "#/components/schemas/TestBand"
107
+ }
108
+ }
109
+ },
110
+ required: false
111
+ },
112
+ responses: {
113
+ "200": {
114
+ content: {
115
+ "application/json": {
116
+ schema: {
117
+ $ref: "#/components/schemas/TestBand"
118
+ }
119
+ }
120
+ },
121
+ description: "Success"
122
+ }
123
+ },
124
+ tags: ["MyCtrl"]
125
+ }
126
+ }
127
+ },
128
+ tags: [
129
+ {
130
+ name: "MyCtrl"
131
+ }
132
+ ]
133
+ });
134
+ });
135
+ });