@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 {cleanObject} from "@tsed/core";
2
+
3
+ import {registerJsonSchemaMapper} from "../../registries/JsonSchemaMapperContainer.js";
4
+ import type {JsonParameterOptions} from "./operationInParameterMapper.js";
5
+
6
+ export function operationInFilesMapper(parameter: any, {jsonSchema}: JsonParameterOptions) {
7
+ const schema = {
8
+ type: "string",
9
+ format: "binary",
10
+ oneOf: undefined
11
+ };
12
+
13
+ if (jsonSchema.type === "array") {
14
+ jsonSchema.items = cleanObject({
15
+ ...(jsonSchema.items as Object),
16
+ ...schema
17
+ });
18
+
19
+ parameter.schema = jsonSchema;
20
+
21
+ return parameter;
22
+ }
23
+
24
+ parameter.schema = cleanObject({
25
+ ...jsonSchema,
26
+ ...schema
27
+ });
28
+
29
+ return parameter;
30
+ }
31
+
32
+ registerJsonSchemaMapper("operationInFiles", operationInFilesMapper);
@@ -0,0 +1,56 @@
1
+ import {OS3Schema} from "@tsed/openspec";
2
+ import {camelCase} from "change-case";
3
+ import type {JSONSchema6} from "json-schema";
4
+
5
+ import {JsonParameter} from "../../domain/JsonParameter.js";
6
+ import {JsonParameterTypes} from "../../domain/JsonParameterTypes.js";
7
+ import {JsonSchemaOptions} from "../../interfaces/JsonSchemaOptions.js";
8
+ import {execMapper, hasMapper, registerJsonSchemaMapper} from "../../registries/JsonSchemaMapperContainer.js";
9
+ import {popGenerics} from "../../utils/generics.js";
10
+
11
+ export type JsonParameterOptions = JsonSchemaOptions & {
12
+ jsonParameter: JsonParameter;
13
+ jsonSchema: JSONSchema6;
14
+ oldSchemas: Record<string, OS3Schema>;
15
+ };
16
+
17
+ function mapOptions(parameter: JsonParameter, options: JsonSchemaOptions = {}) {
18
+ return {
19
+ ...options,
20
+ groups: parameter.groups,
21
+ groupsName: parameter.groupsName
22
+ };
23
+ }
24
+
25
+ export function operationInParameterMapper(jsonParameter: JsonParameter, opts?: JsonSchemaOptions) {
26
+ const options = mapOptions(jsonParameter, opts);
27
+ const schemas = {...(options.components?.schemas || {})};
28
+
29
+ const {type, schema, ...parameter} = execMapper("map", [jsonParameter], options);
30
+
31
+ const jsonSchema = execMapper("item", [jsonParameter.$schema], {
32
+ ...options,
33
+ ...popGenerics(jsonParameter)
34
+ });
35
+
36
+ parameter.required = parameter.required || jsonParameter.get("in") === JsonParameterTypes.PATH;
37
+
38
+ const paramOpts = {
39
+ ...options,
40
+ jsonSchema,
41
+ jsonParameter,
42
+ oldSchemas: schemas
43
+ };
44
+
45
+ const mapperName = camelCase(`operationIn ${jsonParameter.get("in")}`);
46
+
47
+ if (hasMapper(mapperName)) {
48
+ return execMapper(mapperName, [parameter], paramOpts);
49
+ }
50
+
51
+ parameter.schema = jsonSchema;
52
+
53
+ return parameter;
54
+ }
55
+
56
+ registerJsonSchemaMapper("operationInParameter", operationInParameterMapper);
@@ -0,0 +1,9 @@
1
+ import {JsonParameter} from "../../domain/JsonParameter.js";
2
+ import {JsonSchemaOptions} from "../../interfaces/JsonSchemaOptions.js";
3
+ import {execMapper, registerJsonSchemaMapper} from "../../registries/JsonSchemaMapperContainer.js";
4
+
5
+ export function operationInParametersMapper(parameters: JsonParameter[], options: JsonSchemaOptions) {
6
+ return parameters.flatMap((parameter) => execMapper("operationInParameter", [parameter], options)).filter(Boolean);
7
+ }
8
+
9
+ registerJsonSchemaMapper("operationInParameters", operationInParametersMapper);
@@ -0,0 +1,74 @@
1
+ import {cleanObject} from "@tsed/core";
2
+ import {OS3Example} from "@tsed/openspec";
3
+
4
+ import {JsonSchemaOptions} from "../../interfaces/JsonSchemaOptions.js";
5
+ import {registerJsonSchemaMapper} from "../../registries/JsonSchemaMapperContainer.js";
6
+ import {createRefName} from "../../utils/ref.js";
7
+ import type {JsonParameterOptions} from "./operationInParameterMapper.js";
8
+
9
+ function buildExamples(property: string, examples?: Record<string, OS3Example>) {
10
+ if (!examples) {
11
+ return undefined;
12
+ }
13
+
14
+ let hasKey = false;
15
+
16
+ const newExamples = Object.entries(examples).reduce((acc, [key, {value, description, ...props}]) => {
17
+ if (value[property] === undefined) {
18
+ return acc;
19
+ }
20
+
21
+ hasKey = true;
22
+
23
+ return {
24
+ ...acc,
25
+ [key]: {
26
+ ...props,
27
+ value: value[property],
28
+ description
29
+ }
30
+ };
31
+ }, {});
32
+
33
+ return hasKey ? newExamples : undefined;
34
+ }
35
+
36
+ function inlineReference(parameter: any, {jsonParameter, ...options}: JsonSchemaOptions) {
37
+ const name = createRefName(jsonParameter.$schema.getName(), options);
38
+ const schema = options.components?.schemas?.[name];
39
+
40
+ if (schema && !options.oldSchemas?.[name]) {
41
+ delete options.components!.schemas![jsonParameter.$schema.getName()];
42
+ }
43
+
44
+ return Object.entries(schema?.properties || {}).reduce((params, [key, {description, ...prop}]: [string, any]) => {
45
+ return [
46
+ ...params,
47
+ cleanObject({
48
+ ...parameter,
49
+ name: key,
50
+ required: (schema?.required || []).includes(key),
51
+ description,
52
+ schema: prop,
53
+ style: prop.$ref ? "deepObject" : undefined,
54
+ examples: buildExamples(key, parameter.examples)
55
+ })
56
+ ];
57
+ }, []);
58
+ }
59
+
60
+ export function operationInQueryMapper(parameter: any, {jsonSchema, jsonParameters, ...options}: JsonParameterOptions) {
61
+ if (jsonSchema.$ref) {
62
+ if (!parameter.name) {
63
+ return inlineReference(parameter, options);
64
+ }
65
+
66
+ parameter.style = "deepObject";
67
+ }
68
+
69
+ parameter.schema = jsonSchema;
70
+
71
+ return parameter;
72
+ }
73
+
74
+ registerJsonSchemaMapper("operationInQuery", operationInQueryMapper);
@@ -0,0 +1,65 @@
1
+ import {getStatusMessage} from "../../constants/httpStatusMessages.js";
2
+ import {JsonOperation} from "../../domain/JsonOperation.js";
3
+ import {JsonParameter} from "../../domain/JsonParameter.js";
4
+ import {isParameterType, JsonParameterTypes} from "../../domain/JsonParameterTypes.js";
5
+ import {JsonSchemaOptions} from "../../interfaces/JsonSchemaOptions.js";
6
+ import {execMapper, registerJsonSchemaMapper} from "../../registries/JsonSchemaMapperContainer.js";
7
+
8
+ function extractParameters(jsonOperation: JsonOperation, options: JsonSchemaOptions) {
9
+ return jsonOperation
10
+ .get("parameters")
11
+ .filter((parameter: JsonParameter) => isParameterType(parameter.get("in")))
12
+ .reduce(
13
+ (inputs: [any[], JsonParameter[]], parameter: JsonParameter) => {
14
+ const [parameters, bodyParameters] = inputs;
15
+
16
+ if ([JsonParameterTypes.BODY, JsonParameterTypes.FILES].includes(parameter.get("in"))) {
17
+ return [parameters, [...bodyParameters, parameter]];
18
+ }
19
+
20
+ return [[...parameters, parameter], bodyParameters];
21
+ },
22
+ [[], []]
23
+ );
24
+ }
25
+
26
+ export function operationMapper(jsonOperation: JsonOperation, {tags = [], defaultTags = [], ...options}: JsonSchemaOptions = {}) {
27
+ const {consumes, produces, ...operation} = execMapper("map", [jsonOperation], {...options, ignore: ["parameters"]});
28
+
29
+ if (operation.security) {
30
+ operation.security = [].concat(operation.security);
31
+ }
32
+
33
+ if (jsonOperation.get("responses").size === 0) {
34
+ operation.responses = {
35
+ "200": {
36
+ description: getStatusMessage(200)
37
+ }
38
+ };
39
+ }
40
+
41
+ const parametersOptions = {
42
+ ...options,
43
+ consumes: jsonOperation.get("consumes")?.length ? jsonOperation.get("consumes") : ["application/json"]
44
+ };
45
+
46
+ const [parameters, bodyParameters] = extractParameters(jsonOperation, parametersOptions);
47
+
48
+ operation.parameters = execMapper("operationInParameters", [parameters], options);
49
+
50
+ if (bodyParameters.length) {
51
+ operation.requestBody = execMapper("operationRequestBody", [bodyParameters], parametersOptions);
52
+ }
53
+
54
+ const operationTags = operation.tags?.length ? operation.tags : defaultTags;
55
+
56
+ if (operationTags.length) {
57
+ operation.tags = operationTags.map(({name}: any) => name);
58
+ }
59
+
60
+ tags.push(...operationTags);
61
+
62
+ return operation;
63
+ }
64
+
65
+ registerJsonSchemaMapper("operation", operationMapper);
@@ -0,0 +1,11 @@
1
+ import {JsonMedia} from "../../domain/JsonMedia.js";
2
+ import {JsonSchemaOptions} from "../../interfaces/JsonSchemaOptions.js";
3
+ import {execMapper, registerJsonSchemaMapper} from "../../registries/JsonSchemaMapperContainer.js";
4
+
5
+ export function operationMediaMapper(jsonMedia: JsonMedia, options: JsonSchemaOptions) {
6
+ let groups = [...(jsonMedia.groups || [])];
7
+
8
+ return execMapper("map", [jsonMedia], {...options, groups, groupsName: jsonMedia.groupsName});
9
+ }
10
+
11
+ registerJsonSchemaMapper("operationMedia", operationMediaMapper);
@@ -0,0 +1,82 @@
1
+ import {JsonParameter} from "../../domain/JsonParameter.js";
2
+ import {JsonRequestBody} from "../../domain/JsonRequestBody.js";
3
+ import {JsonSchema} from "../../domain/JsonSchema.js";
4
+ import {JsonSchemaOptions} from "../../interfaces/JsonSchemaOptions.js";
5
+ import {execMapper, registerJsonSchemaMapper} from "../../registries/JsonSchemaMapperContainer.js";
6
+
7
+ function buildSchemaFromBodyParameters(parameters: JsonParameter[], options: JsonSchemaOptions) {
8
+ let schema = new JsonSchema();
9
+ const props: any = {};
10
+ const refs: JsonSchema[] = [];
11
+ let propsLength = 0;
12
+
13
+ const hasFile = parameters.some((param) => param.get("in") === "files");
14
+
15
+ parameters.forEach((parameter) => {
16
+ const name = parameter.getName();
17
+
18
+ [...parameter.entries()]
19
+ .filter(([key]) => !["in", "name"].includes(key))
20
+ .forEach(([key, value]) => {
21
+ if (props[key] === undefined) {
22
+ props[key] = value;
23
+ }
24
+ });
25
+
26
+ const jsonParameter = execMapper("operationInParameter", [parameter], options);
27
+
28
+ if (name) {
29
+ const propSchema = {
30
+ ...(jsonParameter.schema || {
31
+ type: jsonParameter.type
32
+ })
33
+ };
34
+
35
+ if (hasFile && jsonParameter.description) {
36
+ propSchema.description = jsonParameter.description;
37
+ }
38
+
39
+ schema.addProperty(name, propSchema);
40
+
41
+ if (parameter.get("required")) {
42
+ schema.addRequired(name);
43
+ }
44
+
45
+ propsLength++;
46
+ } else {
47
+ refs.push(jsonParameter);
48
+ }
49
+ });
50
+
51
+ if (!propsLength) {
52
+ if (refs.length === 1) {
53
+ return refs[0];
54
+ }
55
+ }
56
+
57
+ schema.type("object");
58
+
59
+ if (props.description && hasFile) {
60
+ delete props.description;
61
+ }
62
+
63
+ return {
64
+ schema: schema.toJSON(options),
65
+ required: false,
66
+ ...props
67
+ };
68
+ }
69
+
70
+ export function operationRequestBodyMapper(bodyParameters: JsonParameter[], {consumes, ...options}: JsonSchemaOptions) {
71
+ const {schema, examples, in: _, ...props} = buildSchemaFromBodyParameters(bodyParameters, options);
72
+
73
+ const requestBody = new JsonRequestBody(props);
74
+
75
+ consumes.forEach((consume: string) => {
76
+ requestBody.addContent(consume, schema, examples);
77
+ });
78
+
79
+ return execMapper("map", [requestBody], options);
80
+ }
81
+
82
+ registerJsonSchemaMapper("operationRequestBody", operationRequestBodyMapper);
@@ -0,0 +1,26 @@
1
+ import {JsonResponse} from "../../domain/JsonResponse.js";
2
+ import {JsonSchemaOptions} from "../../interfaces/JsonSchemaOptions.js";
3
+ import {execMapper, registerJsonSchemaMapper} from "../../registries/JsonSchemaMapperContainer.js";
4
+
5
+ export function operationResponseMapper(jsonResponse: JsonResponse, options: JsonSchemaOptions = {}) {
6
+ const response = execMapper("map", [jsonResponse], options);
7
+
8
+ if (jsonResponse.status === 204) {
9
+ delete response.content;
10
+ }
11
+
12
+ if (response.headers) {
13
+ Object.entries(response.headers).forEach(([key, {type, ...props}]: [string, any]) => {
14
+ response.headers[key] = {
15
+ ...props,
16
+ schema: {
17
+ type
18
+ }
19
+ };
20
+ });
21
+ }
22
+
23
+ return response;
24
+ }
25
+
26
+ registerJsonSchemaMapper("operationResponse", operationResponseMapper);
@@ -0,0 +1,132 @@
1
+ import {OS3Operation, OS3Paths} from "@tsed/openspec";
2
+
3
+ import {OperationVerbs} from "../../constants/OperationVerbs.js";
4
+ import {JsonMethodStore} from "../../domain/JsonMethodStore.js";
5
+ import {JsonMethodPath} from "../../domain/JsonOperation.js";
6
+ import {JsonSchemaOptions} from "../../interfaces/JsonSchemaOptions.js";
7
+ import {execMapper, registerJsonSchemaMapper} from "../../registries/JsonSchemaMapperContainer.js";
8
+ import {buildPath} from "../../utils/buildPath.js";
9
+ import {concatParameters} from "../../utils/concatParameters.js";
10
+ import {getJsonEntityStore} from "../../utils/getJsonEntityStore.js";
11
+ import {getJsonPathParameters} from "../../utils/getJsonPathParameters.js";
12
+ import {getOperationsStores} from "../../utils/getOperationsStores.js";
13
+ import {getOperationId} from "../../utils/operationIdFormatter.js";
14
+ import {removeHiddenOperation} from "../../utils/removeHiddenOperation.js";
15
+
16
+ const ALLOWED_VERBS = [
17
+ OperationVerbs.ALL,
18
+ OperationVerbs.GET,
19
+ OperationVerbs.POST,
20
+ OperationVerbs.PUT,
21
+ OperationVerbs.PATCH,
22
+ OperationVerbs.HEAD,
23
+ OperationVerbs.OPTIONS,
24
+ OperationVerbs.DELETE,
25
+ OperationVerbs.TRACE
26
+ ];
27
+
28
+ function pushToPath(
29
+ paths: OS3Paths,
30
+ {
31
+ path,
32
+ method,
33
+ operation
34
+ }: {
35
+ method: string;
36
+ path: string;
37
+ operation: OS3Operation;
38
+ }
39
+ ) {
40
+ return {
41
+ ...paths,
42
+ [path]: {
43
+ ...(paths as any)[path],
44
+ [method.toLowerCase()]: operation
45
+ }
46
+ };
47
+ }
48
+
49
+ function mapOperationInPathParameters(options: JsonSchemaOptions) {
50
+ return ({
51
+ operationPath,
52
+ operation,
53
+ operationStore
54
+ }: {
55
+ operationPath: JsonMethodPath;
56
+ operation: OS3Operation;
57
+ operationStore: JsonMethodStore;
58
+ }) => {
59
+ const {path, method} = operationPath;
60
+
61
+ return getJsonPathParameters(options.ctrlRootPath, path).map(({path, parameters}) => {
62
+ path = path ? path : "/";
63
+
64
+ parameters = concatParameters(
65
+ parameters.map(({type, ...param}) => {
66
+ return {
67
+ ...param,
68
+ schema: {
69
+ type
70
+ }
71
+ };
72
+ }),
73
+ operation
74
+ );
75
+
76
+ return {
77
+ operation: {
78
+ ...operation,
79
+ parameters,
80
+ operationId:
81
+ operation.operationId ||
82
+ getOperationId(path, {
83
+ ...options,
84
+ store: operationStore
85
+ })
86
+ },
87
+ method,
88
+ path
89
+ };
90
+ });
91
+ };
92
+ }
93
+
94
+ function mapOperation(options: JsonSchemaOptions) {
95
+ return (operationStore: JsonMethodStore) => {
96
+ const operationPaths = operationStore.operation.getAllowedOperationPath(ALLOWED_VERBS);
97
+
98
+ if (operationPaths.length === 0) {
99
+ return [];
100
+ }
101
+
102
+ const operation = execMapper("operation", [operationStore.operation], options);
103
+
104
+ return operationPaths.map((operationPath) => {
105
+ return {
106
+ operationPath,
107
+ operation,
108
+ operationStore
109
+ };
110
+ });
111
+ };
112
+ }
113
+
114
+ export function pathsMapper(model: any, {paths, rootPath, ...options}: JsonSchemaOptions) {
115
+ const store = getJsonEntityStore(model);
116
+ const ctrlPath = store.path;
117
+ const ctrlRootPath = buildPath(rootPath + ctrlPath);
118
+
119
+ options = {
120
+ ...options,
121
+ ctrlRootPath
122
+ };
123
+
124
+ return [...getOperationsStores(model).values()]
125
+ .filter(removeHiddenOperation)
126
+ .filter((operationStore) => operationStore.operation.getAllowedOperationPath(ALLOWED_VERBS).length > 0)
127
+ .flatMap(mapOperation(options))
128
+ .flatMap(mapOperationInPathParameters(options))
129
+ .reduce(pushToPath, paths);
130
+ }
131
+
132
+ registerJsonSchemaMapper("paths", pathsMapper);
@@ -0,0 +1,29 @@
1
+ export enum OperationVerbs {
2
+ ALL = "ALL", // special key
3
+ GET = "GET",
4
+ POST = "POST",
5
+ PUT = "PUT",
6
+ PATCH = "PATCH",
7
+ HEAD = "HEAD",
8
+ DELETE = "DELETE",
9
+ OPTIONS = "OPTIONS",
10
+ TRACE = "TRACE",
11
+ PUBLISH = "PUBLISH",
12
+ SUBSCRIBE = "SUBSCRIBE",
13
+ CUSTOM = "CUSTOM"
14
+ }
15
+
16
+ export const OPERATION_HTTP_VERBS = [
17
+ OperationVerbs.ALL,
18
+ OperationVerbs.GET,
19
+ OperationVerbs.POST,
20
+ OperationVerbs.PUT,
21
+ OperationVerbs.PATCH,
22
+ OperationVerbs.HEAD,
23
+ OperationVerbs.DELETE,
24
+ OperationVerbs.OPTIONS,
25
+ OperationVerbs.TRACE,
26
+ OperationVerbs.CUSTOM
27
+ ];
28
+
29
+ export const OPERATION_WS_VERBS = [OperationVerbs.PUBLISH, OperationVerbs.SUBSCRIBE];
@@ -0,0 +1,21 @@
1
+ import {constantCase} from "change-case";
2
+ import statuses from "statuses";
3
+
4
+ export const HTTP_STATUS_MESSAGES = statuses.codes.reduce((map: Record<string, {label: string; code: string}>, code: number) => {
5
+ const message: string = String(statuses(code));
6
+ return {
7
+ ...map,
8
+ [String(code)]: {label: message, code: constantCase(message)}
9
+ };
10
+ }, {});
11
+
12
+ HTTP_STATUS_MESSAGES["200"].label = "Success";
13
+ HTTP_STATUS_MESSAGES["200"].code = "SUCCESS";
14
+
15
+ export function getStatusConstant(status: number | string) {
16
+ return (HTTP_STATUS_MESSAGES as any)[status]?.code;
17
+ }
18
+
19
+ export function getStatusMessage(status: number | string) {
20
+ return (HTTP_STATUS_MESSAGES as any)[status]?.label;
21
+ }
@@ -0,0 +1,17 @@
1
+ export const MANY_OF_PROPERTIES = ["oneOf", "allOf", "anyOf"];
2
+ export const STRING_PROPERTIES = ["minLength", "maxLength", "pattern", "format"];
3
+ export const BOOLEAN_PROPERTIES = [];
4
+ export const NUMBER_PROPERTIES = ["minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "multipleOf"];
5
+ export const ARRAY_PROPERTIES = ["maxItems", "minItems", "uniqueItems", "items", "contains", "maxContains", "minContains"];
6
+ export const OBJECT_PROPERTIES = [
7
+ "maxItems",
8
+ "minItems",
9
+ "uniqueItems",
10
+ "items",
11
+ "contains",
12
+ "maxContains",
13
+ "minContains",
14
+ "patternProperties",
15
+ "dependencies"
16
+ ];
17
+ export const COMMON_PROPERTIES = ["const", "enum"];
@@ -0,0 +1,22 @@
1
+ import {Store, Type} from "@tsed/core";
2
+
3
+ import {JsonEntityFn} from "../common/jsonEntityFn.js";
4
+
5
+ /**
6
+ * Add Children class to compose routes
7
+ *
8
+ * @decorator
9
+ * @swagger
10
+ * @schema
11
+ * @classDecorator
12
+ * @param children
13
+ */
14
+ export function Children(...children: Type<any>[]): ClassDecorator {
15
+ return JsonEntityFn((store) => {
16
+ store.store.set("childrenControllers", children);
17
+
18
+ children.forEach((childToken) => {
19
+ Store.from(childToken).set("parentController", store.token);
20
+ });
21
+ });
22
+ }
@@ -0,0 +1,53 @@
1
+ import {snakeCase} from "change-case";
2
+
3
+ import {JsonEntityFn} from "../common/jsonEntityFn.js";
4
+
5
+ /**
6
+ * Declare a Discriminator value on a child class.
7
+ *
8
+ * ```ts
9
+ * export class Event {
10
+ * @DiscriminatorKey() // declare this property a discriminator key
11
+ * type: string;
12
+ *
13
+ * @Property()
14
+ * value: string;
15
+ * }
16
+ *
17
+ * @DiscriminatorValue("page_view")
18
+ * export class PageView extends Event {
19
+ * @Required()
20
+ * url: string;
21
+ * }
22
+ *
23
+ * @DiscriminatorValue("action")
24
+ * export class Action extends Event {
25
+ * @Required()
26
+ * event: string;
27
+ * }
28
+ *
29
+ * @DiscriminatorValue()
30
+ * export class CustomAction extends Event {
31
+ * @Required()
32
+ * event: string;
33
+ *
34
+ * @Property()
35
+ * meta: string;
36
+ * }
37
+ * ```
38
+ *
39
+ * @decorator
40
+ * @swagger
41
+ * @schema
42
+ * @classDecorator
43
+ * @param value
44
+ * @param values
45
+ */
46
+ export function DiscriminatorValue(value?: string, ...values: string[]): ClassDecorator {
47
+ return JsonEntityFn((store) => {
48
+ value = value || snakeCase(store.targetName);
49
+ if (store.discriminatorAncestor) {
50
+ store.schema.discriminatorValue(value, ...values);
51
+ }
52
+ });
53
+ }
@@ -0,0 +1,25 @@
1
+ import {CollectionOf} from "./collectionOf.js";
2
+
3
+ /**
4
+ * Set the type of the item collection. The possible value is String, Boolean, Number, Date, Object, Class, etc...
5
+ *
6
+ * The array instance will be valid against "contains" if at least one of its elements is valid against the given schema.
7
+ *
8
+ * ```typescript
9
+ * class Model {
10
+ * @CollectionContains(String).MinLength(0).MaxLength(0)
11
+ * property: string[];
12
+ * }
13
+ * ```
14
+ *
15
+ * @param {Type<any>} type
16
+ * @decorator
17
+ * @validation
18
+ * @swagger
19
+ * @schema
20
+ * @input
21
+ * @collections
22
+ */
23
+ export function CollectionContains(type: any) {
24
+ return CollectionOf(type).Contains();
25
+ }