@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,69 @@
1
+ import "../components/index.js";
2
+
3
+ import {getValue, Type} from "@tsed/core";
4
+
5
+ import type {JsonEntityStore} from "../domain/JsonEntityStore.js";
6
+ import {SpecTypes} from "../domain/SpecTypes.js";
7
+ import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions.js";
8
+ import {execMapper} from "../registries/JsonSchemaMapperContainer.js";
9
+ import {getJsonEntityStore} from "./getJsonEntityStore.js";
10
+
11
+ /**
12
+ * @ignore
13
+ */
14
+ const CACHE_KEY = "$cache:schemes";
15
+
16
+ /**
17
+ * @ignore
18
+ */
19
+ function getKey(options: any) {
20
+ return JSON.stringify(options);
21
+ }
22
+
23
+ /**
24
+ * @ignore
25
+ */
26
+ function get(entity: JsonEntityStore, options: any) {
27
+ const cache: Map<string, any> = entity.store.get(CACHE_KEY) || new Map();
28
+ const key = getKey(options);
29
+
30
+ if (!cache.has(key)) {
31
+ const schema = execMapper("schema", [entity.schema], options);
32
+
33
+ if (Object.keys(getValue(options, "components.schemas", {})).length) {
34
+ schema.definitions = options.components.schemas;
35
+ }
36
+
37
+ cache.set(key, schema);
38
+ }
39
+
40
+ entity.store.set(CACHE_KEY, cache);
41
+
42
+ return cache.get(key);
43
+ }
44
+
45
+ export function getJsonSchema(model: Type<any> | any, options: JsonSchemaOptions = {}) {
46
+ const entity = getJsonEntityStore(model);
47
+ const specType = options.specType || SpecTypes.JSON;
48
+ options = {
49
+ endpoint: true,
50
+ groups: [],
51
+ inlineEnums: specType === SpecTypes.JSON,
52
+ ...options,
53
+ specType,
54
+ components: {
55
+ schemas: {}
56
+ }
57
+ };
58
+
59
+ if (entity.decoratorType === "parameter") {
60
+ options = {
61
+ ...options,
62
+ genericTypes: entity.nestedGenerics[0],
63
+ nestedGenerics: entity.nestedGenerics,
64
+ groups: entity.parameter?.groups
65
+ };
66
+ }
67
+
68
+ return get(entity, options);
69
+ }
@@ -0,0 +1,28 @@
1
+ import {getJsonType} from "./getJsonType.js";
2
+
3
+ describe("getJsonType", () => {
4
+ it("should return file", () => {
5
+ expect(getJsonType("file")).toBe("file");
6
+ });
7
+ it("should return generic", () => {
8
+ expect(getJsonType("test")).toBe("generic");
9
+ });
10
+ it("should return ['generic']", () => {
11
+ expect(getJsonType(["test"])).toEqual(["generic"]);
12
+ });
13
+ it("should return array", () => {
14
+ expect(getJsonType(Array)).toBe("array");
15
+ });
16
+ it("should return string", () => {
17
+ expect(getJsonType(new Date())).toBe("string");
18
+ });
19
+ it("should return object", () => {
20
+ expect(getJsonType({test: "test"})).toBe("object");
21
+ });
22
+ it("should return null", () => {
23
+ expect(getJsonType(null)).toBe("null");
24
+ });
25
+ it("should return number", () => {
26
+ expect(getJsonType(5)).toBe("number");
27
+ });
28
+ });
@@ -0,0 +1,46 @@
1
+ import {isArray, isBuffer, isDate, isPrimitiveOrPrimitiveClass, primitiveOf} from "@tsed/core";
2
+
3
+ /**
4
+ * @ignore
5
+ */
6
+ export const JSON_TYPES = ["string", "number", "integer", "boolean", "object", "array", "null", "any"];
7
+
8
+ export function getJsonType(value: any): string {
9
+ if (value === null) {
10
+ return "null";
11
+ }
12
+
13
+ if (isPrimitiveOrPrimitiveClass(value)) {
14
+ if (JSON_TYPES.indexOf(value as string) > -1) {
15
+ return value;
16
+ }
17
+
18
+ if (typeof value === "string") {
19
+ if (value === "file") {
20
+ return "file";
21
+ }
22
+
23
+ return "generic";
24
+ }
25
+
26
+ return primitiveOf(value);
27
+ }
28
+
29
+ if (value === Array) {
30
+ return "array";
31
+ }
32
+
33
+ if (isArray(value)) {
34
+ return value.map(getJsonType) as any;
35
+ }
36
+
37
+ if (value === Set) {
38
+ return "array";
39
+ }
40
+
41
+ if (isDate(value) || isBuffer(value)) {
42
+ return "string";
43
+ }
44
+
45
+ return "object";
46
+ }
@@ -0,0 +1,284 @@
1
+ import {StoreSet} from "@tsed/core";
2
+
3
+ import {Children} from "../decorators/class/children.js";
4
+ import {In} from "../decorators/operations/in.js";
5
+ import {Path} from "../decorators/operations/path.js";
6
+ import {All, Get} from "../decorators/operations/route.js";
7
+ import {JsonOperationRoute} from "../domain/JsonOperationRoute.js";
8
+ import {getOperationsRoutes} from "./getOperationsRoutes.js";
9
+
10
+ function getData(operationRoute: JsonOperationRoute) {
11
+ return {
12
+ token: operationRoute.token,
13
+ target: operationRoute.endpoint.token,
14
+ propertyKey: operationRoute.propertyKey,
15
+ path: operationRoute.path,
16
+ fullPath: operationRoute.fullPath,
17
+ method: operationRoute.method,
18
+ storeValue: operationRoute.store.get("test")
19
+ };
20
+ }
21
+
22
+ describe("getOperationsRoutes()", () => {
23
+ it("should return operation with his path and methods", () => {
24
+ // GIVEN
25
+ @Path("/test")
26
+ class Test2 {
27
+ @Get("/")
28
+ @StoreSet("test", "Test2")
29
+ method1(): any {}
30
+ }
31
+
32
+ @Path("/test")
33
+ class Test1 extends Test2 {
34
+ @Get("/")
35
+ @StoreSet("test", "Test1")
36
+ method(): any {}
37
+
38
+ @Get("/")
39
+ @StoreSet("test", "Test1")
40
+ method2(): any {}
41
+ }
42
+
43
+ @Path("/test")
44
+ class Test extends Test1 {
45
+ @Get("/")
46
+ @StoreSet("test", "Test")
47
+ method(): any {}
48
+
49
+ @Get("/")
50
+ @StoreSet("test", "Test")
51
+ method3() {}
52
+
53
+ @All("/all")
54
+ all() {}
55
+
56
+ @StoreSet("test", "test-ignore")
57
+ shouldBeIgnored(@In("any") ctx: any) {}
58
+ }
59
+
60
+ const operationsRoutes = getOperationsRoutes(Test);
61
+
62
+ expect(operationsRoutes.map(getData)).toEqual([
63
+ {
64
+ fullPath: "/test",
65
+ method: "GET",
66
+ path: "/",
67
+ propertyKey: "method",
68
+ storeValue: "Test",
69
+ target: Test,
70
+ token: Test
71
+ },
72
+ {
73
+ fullPath: "/test",
74
+ method: "GET",
75
+ path: "/",
76
+ propertyKey: "method3",
77
+ storeValue: "Test",
78
+ target: Test,
79
+ token: Test
80
+ },
81
+ {
82
+ fullPath: "/test/all",
83
+ method: "ALL",
84
+ path: "/all",
85
+ propertyKey: "all",
86
+ storeValue: undefined,
87
+ target: Test,
88
+ token: Test
89
+ },
90
+ {
91
+ fullPath: "/test",
92
+ method: "GET",
93
+ path: "/",
94
+ propertyKey: "method2",
95
+ storeValue: "Test1",
96
+ target: Test1,
97
+ token: Test
98
+ },
99
+ {
100
+ fullPath: "/test",
101
+ method: "GET",
102
+ path: "/",
103
+ propertyKey: "method1",
104
+ storeValue: "Test2",
105
+ target: Test2,
106
+ token: Test
107
+ }
108
+ ]);
109
+ });
110
+ it("should ignore method not decorated with the right decorator", () => {
111
+ // GIVEN
112
+ @Path("/test")
113
+ class Test {
114
+ @StoreSet("test", "test-ignore")
115
+ shouldBeIgnored(@In("any") ctx: any) {}
116
+ }
117
+
118
+ const operationsRoutes = getOperationsRoutes(Test);
119
+
120
+ expect(operationsRoutes.map(getData)).toEqual([]);
121
+ });
122
+ it("should return operations routes with children", () => {
123
+ @Path("/deep")
124
+ class TestChild2 {
125
+ @Get("/")
126
+ @StoreSet("test", "deep")
127
+ method(): any {}
128
+ }
129
+
130
+ @Path("/children")
131
+ @Children(TestChild2)
132
+ class TestChild {
133
+ @Get("/")
134
+ @StoreSet("test", "children")
135
+ method(): any {}
136
+ }
137
+
138
+ @Path("/test")
139
+ @Children(TestChild)
140
+ class Test {
141
+ @Get("/")
142
+ @StoreSet("test", "Test")
143
+ method(): any {}
144
+
145
+ @Get("/")
146
+ @StoreSet("test", "Test")
147
+ method3() {}
148
+
149
+ @All("/all")
150
+ all() {}
151
+ }
152
+
153
+ const operationsRoutes = getOperationsRoutes(Test, {withChildren: true});
154
+
155
+ expect(operationsRoutes.map(getData)).toEqual([
156
+ {
157
+ fullPath: "/test/children/deep",
158
+ method: "GET",
159
+ path: "/",
160
+ propertyKey: "method",
161
+ storeValue: "deep",
162
+ target: TestChild2,
163
+ token: TestChild2
164
+ },
165
+ {
166
+ fullPath: "/test/children",
167
+ method: "GET",
168
+ path: "/",
169
+ propertyKey: "method",
170
+ storeValue: "children",
171
+ target: TestChild,
172
+ token: TestChild
173
+ },
174
+ {
175
+ fullPath: "/test",
176
+ method: "GET",
177
+ path: "/",
178
+ propertyKey: "method",
179
+ storeValue: "Test",
180
+ target: Test,
181
+ token: Test
182
+ },
183
+ {
184
+ fullPath: "/test",
185
+ method: "GET",
186
+ path: "/",
187
+ propertyKey: "method3",
188
+ storeValue: "Test",
189
+ target: Test,
190
+ token: Test
191
+ },
192
+ {
193
+ fullPath: "/test/all",
194
+ method: "ALL",
195
+ path: "/all",
196
+ propertyKey: "all",
197
+ storeValue: undefined,
198
+ target: Test,
199
+ token: Test
200
+ }
201
+ ]);
202
+ });
203
+ it("should return operations routes with children and basePath", () => {
204
+ @Path("/deep")
205
+ class TestChild2 {
206
+ @Get("/")
207
+ @StoreSet("test", "deep")
208
+ method(): any {}
209
+ }
210
+
211
+ @Path("/children")
212
+ @Children(TestChild2)
213
+ class TestChild {
214
+ @Get("/")
215
+ @StoreSet("test", "children")
216
+ method(): any {}
217
+ }
218
+
219
+ @Path("/test")
220
+ @Children(TestChild)
221
+ class Test {
222
+ @Get("/")
223
+ @StoreSet("test", "Test")
224
+ method(): any {}
225
+
226
+ @Get("/")
227
+ @StoreSet("test", "Test")
228
+ method3() {}
229
+
230
+ @All("/all")
231
+ all() {}
232
+ }
233
+
234
+ const operationsRoutes = getOperationsRoutes(Test, {withChildren: true, basePath: "/rest"});
235
+
236
+ expect(operationsRoutes.map(getData)).toEqual([
237
+ {
238
+ fullPath: "/rest/test/children/deep",
239
+ method: "GET",
240
+ path: "/",
241
+ propertyKey: "method",
242
+ storeValue: "deep",
243
+ target: TestChild2,
244
+ token: TestChild2
245
+ },
246
+ {
247
+ fullPath: "/rest/test/children",
248
+ method: "GET",
249
+ path: "/",
250
+ propertyKey: "method",
251
+ storeValue: "children",
252
+ target: TestChild,
253
+ token: TestChild
254
+ },
255
+ {
256
+ fullPath: "/rest/test",
257
+ method: "GET",
258
+ path: "/",
259
+ propertyKey: "method",
260
+ storeValue: "Test",
261
+ target: Test,
262
+ token: Test
263
+ },
264
+ {
265
+ fullPath: "/rest/test",
266
+ method: "GET",
267
+ path: "/",
268
+ propertyKey: "method3",
269
+ storeValue: "Test",
270
+ target: Test,
271
+ token: Test
272
+ },
273
+ {
274
+ fullPath: "/rest/test/all",
275
+ method: "ALL",
276
+ path: "/all",
277
+ propertyKey: "all",
278
+ storeValue: undefined,
279
+ target: Test,
280
+ token: Test
281
+ }
282
+ ]);
283
+ });
284
+ });
@@ -0,0 +1,56 @@
1
+ import {Type} from "@tsed/core";
2
+
3
+ import {OperationVerbs} from "../constants/OperationVerbs.js";
4
+ import {JsonEntityStore} from "../domain/JsonEntityStore.js";
5
+ import {JsonMethodStore} from "../domain/JsonMethodStore.js";
6
+ import {JsonOperationRoute} from "../domain/JsonOperationRoute.js";
7
+ import {concatPath} from "./concatPath.js";
8
+ import {getJsonEntityStore} from "./getJsonEntityStore.js";
9
+ import {getOperationsStores} from "./getOperationsStores.js";
10
+
11
+ export interface GetOperationsRoutesOptions {
12
+ withChildren?: boolean;
13
+ basePath?: string;
14
+ allowedVerbs?: OperationVerbs[];
15
+ }
16
+
17
+ export function getOperationsRoutes<Entity extends JsonMethodStore = JsonMethodStore>(
18
+ token: Type<any> | any,
19
+ options: GetOperationsRoutesOptions = {}
20
+ ): JsonOperationRoute<Entity>[] {
21
+ const store: JsonEntityStore = token.isStore ? token : getJsonEntityStore(token);
22
+ const basePath = concatPath(options.basePath, store.path);
23
+ let operationsRoutes: JsonOperationRoute<Entity>[] = [];
24
+
25
+ if (options.withChildren) {
26
+ const children = store.get<Type[]>("childrenControllers", []);
27
+
28
+ operationsRoutes = children.reduce((operationsRoutes, token) => {
29
+ return operationsRoutes.concat(
30
+ getOperationsRoutes(token, {
31
+ ...options,
32
+ basePath
33
+ })
34
+ );
35
+ }, operationsRoutes);
36
+ }
37
+
38
+ return [...getOperationsStores(token).values()].reduce((routes, endpoint) => {
39
+ const {operation} = endpoint;
40
+
41
+ if (operation) {
42
+ operation.getAllowedOperationPath(options.allowedVerbs).forEach((operationPath) => {
43
+ routes.push(
44
+ new JsonOperationRoute<Entity>({
45
+ basePath,
46
+ token,
47
+ endpoint,
48
+ operationPath
49
+ })
50
+ );
51
+ });
52
+ }
53
+
54
+ return routes;
55
+ }, operationsRoutes);
56
+ }
@@ -0,0 +1,47 @@
1
+ import {StoreSet} from "@tsed/core";
2
+
3
+ import {getOperationsStores, OperationPath} from "../index.js";
4
+
5
+ describe("getOperationsStore", () => {
6
+ it("should return operation with right order", () => {
7
+ class Test2 {
8
+ @StoreSet("test", "Test2")
9
+ @OperationPath("GET")
10
+ method1(): any {}
11
+ }
12
+
13
+ class Test1 extends Test2 {
14
+ @StoreSet("test", "Test1")
15
+ @OperationPath("GET")
16
+ method(): any {}
17
+
18
+ @StoreSet("test", "Test1")
19
+ @OperationPath("GET")
20
+ method2(): any {}
21
+ }
22
+
23
+ class Test extends Test1 {
24
+ @StoreSet("test", "Test")
25
+ @OperationPath("GET")
26
+ method(): any {}
27
+
28
+ @StoreSet("test", "Test")
29
+ @OperationPath("GET")
30
+ method3() {}
31
+ }
32
+
33
+ const stores = [...getOperationsStores(Test).entries()];
34
+
35
+ expect(stores[0][0]).toBe("method");
36
+ expect(stores[0][1].store.get("test")).toBe("Test");
37
+
38
+ expect(stores[1][0]).toBe("method3");
39
+ expect(stores[1][1].store.get("test")).toBe("Test");
40
+
41
+ expect(stores[2][0]).toBe("method2");
42
+ expect(stores[2][1].store.get("test")).toBe("Test1");
43
+
44
+ expect(stores[3][0]).toBe("method1");
45
+ expect(stores[3][1].store.get("test")).toBe("Test2");
46
+ });
47
+ });
@@ -0,0 +1,37 @@
1
+ import {Type} from "@tsed/core";
2
+
3
+ import type {JsonClassStore} from "../domain/JsonClassStore.js";
4
+ import {JsonMethodStore} from "../domain/JsonMethodStore.js";
5
+ import {JsonOperationPathsMap} from "../domain/JsonOperationPathsMap.js";
6
+ import {getInheritedStores} from "./getInheritedStores.js";
7
+ import {getJsonEntityStore} from "./getJsonEntityStore.js";
8
+
9
+ /**
10
+ * @ignore
11
+ */
12
+ export function getOperationsStores<T extends JsonMethodStore = JsonMethodStore>(target: Type<any> | any): Map<string, T> {
13
+ const store: JsonClassStore = target.isStore ? target : getJsonEntityStore(target);
14
+
15
+ if (!store.$operations) {
16
+ const operationPaths = new JsonOperationPathsMap();
17
+ store.$operations = new Map<string, T>();
18
+
19
+ getInheritedStores(store).forEach((currentStore) => {
20
+ currentStore.children.forEach((propStore) => {
21
+ if (propStore instanceof JsonMethodStore && !store.$operations.has(propStore.propertyKey)) {
22
+ store.$operations.set(propStore.propertyKey, propStore);
23
+ }
24
+ });
25
+ });
26
+
27
+ store.$operations.forEach((store: JsonMethodStore) => {
28
+ store.operation.operationPaths.forEach((operationPath) => {
29
+ operationPaths.setOperationPath(operationPath);
30
+ });
31
+ });
32
+
33
+ operationPaths.clear();
34
+ }
35
+
36
+ return store.$operations;
37
+ }
@@ -0,0 +1,138 @@
1
+ import {Email} from "../decorators/common/format.js";
2
+ import {Ignore} from "../decorators/common/ignore.js";
3
+ import {Property} from "../decorators/common/property.js";
4
+ import {Required} from "../decorators/common/required.js";
5
+ import {getProperties, getPropertiesStores} from "./getPropertiesStores.js";
6
+
7
+ class Base {
8
+ @Property()
9
+ id: string;
10
+
11
+ @Email()
12
+ email: string;
13
+ }
14
+
15
+ class Child extends Base {
16
+ @Required()
17
+ declare id: string;
18
+
19
+ @Property()
20
+ name: string;
21
+ }
22
+
23
+ describe("getProperties()", () => {
24
+ it("should return properties", () => {
25
+ const properties = getPropertiesStores(Child);
26
+ expect(Array.from(properties.keys())).toEqual(["id", "name", "email"]);
27
+ const properties2 = getPropertiesStores(Child);
28
+ expect(Array.from(properties2.keys())).toEqual(["id", "name", "email"]);
29
+ });
30
+
31
+ describe("getProperties()", () => {
32
+ class Parent {
33
+ @Ignore()
34
+ _id: string;
35
+
36
+ @Property()
37
+ id: string;
38
+
39
+ @Property()
40
+ name: string;
41
+
42
+ @Property()
43
+ categoryId: string;
44
+ }
45
+
46
+ class Children extends Parent {
47
+ @Property()
48
+ declare id: string;
49
+
50
+ @Property()
51
+ test: string;
52
+
53
+ @Ignore()
54
+ declare categoryId: string;
55
+ }
56
+
57
+ class Children2 extends Parent {
58
+ @Property()
59
+ declare id: string;
60
+
61
+ @Property()
62
+ test: string;
63
+
64
+ @Property()
65
+ declare categoryId: string;
66
+ }
67
+
68
+ describe("when is the Children class", () => {
69
+ it("should have a property id metadata from Children class", () => {
70
+ const result = getProperties(Children);
71
+ expect(result.get("id")!.targetName).toBe("Children");
72
+ });
73
+
74
+ it("should have a property name metadata from Parent class", () => {
75
+ const result = getProperties(Children);
76
+ expect(result.get("name")!.targetName).toBe("Parent");
77
+ });
78
+
79
+ it("should have a property test metadata from Parent class", () => {
80
+ const result = getProperties(Children);
81
+ expect(result.get("test")!.targetName).toBe("Children");
82
+ });
83
+
84
+ it("should not have a property categoryId metadata from Parent class", () => {
85
+ const result = getProperties(Children);
86
+ expect(result.has("categoryId")).toEqual(false);
87
+ });
88
+ });
89
+
90
+ describe("when is the Children2 class", () => {
91
+ it("should have a property id metadata from Children class", () => {
92
+ const result = getProperties(Children2);
93
+ expect(result.get("id")!.targetName).toBe("Children2");
94
+ });
95
+
96
+ it("should have a property name metadata from Parent class", () => {
97
+ const result = getProperties(Children2);
98
+ expect(result.get("name")!.targetName).toBe("Parent");
99
+ });
100
+
101
+ it("should have a property test metadata from Parent class", () => {
102
+ const result = getProperties(Children2);
103
+ expect(result.get("test")!.targetName).toBe("Children2");
104
+ });
105
+
106
+ it("should have a property categoryId metadata from Parent class", () => {
107
+ const result = getProperties(Children2);
108
+ expect(result.get("categoryId")!.targetName).toBe("Children2");
109
+ });
110
+ });
111
+
112
+ describe("when is the Parent class", () => {
113
+ it("should have a property test metadata from Parent class", () => {
114
+ const result = getProperties(Parent);
115
+ expect(result.has("test")).toBe(false);
116
+ });
117
+
118
+ it("should have a property id metadata from Children class", () => {
119
+ const result = getProperties(Parent);
120
+ expect(result.get("id")!.targetName).toBe("Parent");
121
+ });
122
+
123
+ it("should have a property name metadata from Parent class", () => {
124
+ const result = getProperties(Parent);
125
+ expect(result.get("name")!.targetName).toBe("Parent");
126
+ });
127
+
128
+ it("should not have a property _id metadata from Parent class (because ignoreProperty is used)", () => {
129
+ const result = getProperties(Parent);
130
+ expect(result.has("_id")).toBe(false);
131
+ });
132
+ it("should not have a property categoryId metadata from Parent class", () => {
133
+ const result = getProperties(Parent);
134
+ expect(result.has("categoryId")).toBe(true);
135
+ });
136
+ });
137
+ });
138
+ });