nestia 3.1.0 → 3.1.1-dev.20221016

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 (225) hide show
  1. package/.eslintrc.cjs +33 -0
  2. package/.prettierignore +5 -0
  3. package/.vscode/settings.json +10 -0
  4. package/demo/encrypted/src/Backend.ts +27 -0
  5. package/demo/encrypted/src/Configuration.ts +7 -0
  6. package/demo/encrypted/src/api/HttpError.ts +1 -0
  7. package/demo/encrypted/src/api/IConnection.ts +1 -0
  8. package/demo/encrypted/src/api/Primitive.ts +1 -0
  9. package/demo/encrypted/src/api/__internal/AesPkcs5.ts +1 -0
  10. package/demo/encrypted/src/api/__internal/Fetcher.ts +1 -0
  11. package/demo/encrypted/src/api/functional/index.ts +7 -0
  12. package/demo/encrypted/src/api/functional/sellers/authenticate/index.ts +136 -0
  13. package/demo/encrypted/src/api/functional/sellers/authenticate/password/index.ts +53 -0
  14. package/demo/encrypted/src/api/functional/sellers/index.ts +7 -0
  15. package/demo/encrypted/src/api/index.ts +9 -0
  16. package/demo/encrypted/src/api/module.ts +10 -0
  17. package/demo/encrypted/src/api/structures/ISeller.ts +56 -0
  18. package/demo/encrypted/src/controllers/SellerAuthenticateController.ts +70 -0
  19. package/demo/encrypted/src/test/features/test_seller_exit.ts +18 -0
  20. package/demo/encrypted/src/test/features/test_seller_join.ts +19 -0
  21. package/demo/encrypted/src/test/features/test_seller_login.ts +16 -0
  22. package/demo/encrypted/src/test/features/test_seller_password_change.ts +18 -0
  23. package/demo/encrypted/src/test/index.ts +24 -0
  24. package/demo/encrypted/src/test/internal/DynamicImportIterator.ts +109 -0
  25. package/demo/encrypted/src/test/internal/StopWatch.ts +15 -0
  26. package/demo/encrypted/swagger.json +257 -0
  27. package/demo/encrypted/tsconfig.json +8 -0
  28. package/demo/generic/nestia.config.ts +10 -0
  29. package/demo/generic/src/Backend.ts +27 -0
  30. package/demo/generic/src/Configuration.ts +7 -0
  31. package/demo/generic/src/api/HttpError.ts +1 -0
  32. package/demo/generic/src/api/IConnection.ts +1 -0
  33. package/demo/generic/src/api/Primitive.ts +1 -0
  34. package/demo/generic/src/api/__internal/AesPkcs5.ts +1 -0
  35. package/demo/generic/src/api/__internal/Fetcher.ts +1 -0
  36. package/demo/generic/src/api/functional/consumers/index.ts +7 -0
  37. package/demo/generic/src/api/functional/consumers/sales/index.ts +8 -0
  38. package/demo/generic/src/api/functional/consumers/sales/questions/index.ts +136 -0
  39. package/demo/generic/src/api/functional/consumers/sales/reviews/index.ts +136 -0
  40. package/demo/generic/src/api/functional/index.ts +7 -0
  41. package/demo/generic/src/api/index.ts +9 -0
  42. package/demo/generic/src/api/module.ts +10 -0
  43. package/demo/generic/src/api/structures/IAttachmentFile.ts +21 -0
  44. package/demo/generic/src/api/structures/ISaleArticle.ts +79 -0
  45. package/demo/generic/src/api/structures/ISaleInquiry.ts +34 -0
  46. package/demo/generic/src/api/structures/ISaleInquiryAnswer.ts +23 -0
  47. package/demo/generic/src/api/structures/ISaleQuestion.ts +22 -0
  48. package/demo/generic/src/api/structures/ISaleReview.ts +32 -0
  49. package/demo/generic/src/controllers/ConsumerSaleQuestionsController.ts +33 -0
  50. package/demo/generic/src/controllers/ConsumerSaleReviewsController.ts +34 -0
  51. package/demo/generic/src/controllers/SaleInquiriesController.ts +87 -0
  52. package/demo/generic/src/test/features/test_question_store.ts +21 -0
  53. package/demo/generic/src/test/features/test_question_update.ts +42 -0
  54. package/demo/generic/src/test/features/test_review_store.ts +22 -0
  55. package/demo/generic/src/test/features/test_review_update.ts +44 -0
  56. package/demo/generic/src/test/index.ts +24 -0
  57. package/demo/generic/src/test/internal/DynamicImportIterator.ts +109 -0
  58. package/demo/generic/src/test/internal/StopWatch.ts +15 -0
  59. package/demo/generic/swagger.json +736 -0
  60. package/demo/generic/tsconfig.json +9 -0
  61. package/demo/multiple-paths/src/Backend.ts +27 -0
  62. package/demo/multiple-paths/src/Configuration.ts +7 -0
  63. package/demo/multiple-paths/src/api/HttpError.ts +1 -0
  64. package/demo/multiple-paths/src/api/IConnection.ts +1 -0
  65. package/demo/multiple-paths/src/api/Primitive.ts +1 -0
  66. package/demo/multiple-paths/src/api/__internal/AesPkcs5.ts +1 -0
  67. package/demo/multiple-paths/src/api/__internal/Fetcher.ts +1 -0
  68. package/demo/multiple-paths/src/api/functional/consumers/index.ts +7 -0
  69. package/demo/multiple-paths/src/api/functional/consumers/sales/articles/comments/index.ts +65 -0
  70. package/demo/multiple-paths/src/api/functional/consumers/sales/articles/index.ts +7 -0
  71. package/demo/multiple-paths/src/api/functional/consumers/sales/index.ts +7 -0
  72. package/demo/multiple-paths/src/api/functional/health/alive/index.ts +42 -0
  73. package/demo/multiple-paths/src/api/functional/health/index.ts +44 -0
  74. package/demo/multiple-paths/src/api/functional/healthy/alive/index.ts +42 -0
  75. package/demo/multiple-paths/src/api/functional/healthy/index.ts +44 -0
  76. package/demo/multiple-paths/src/api/functional/index.ts +10 -0
  77. package/demo/multiple-paths/src/api/functional/sellers/index.ts +7 -0
  78. package/demo/multiple-paths/src/api/functional/sellers/sales/articles/comments/index.ts +65 -0
  79. package/demo/multiple-paths/src/api/functional/sellers/sales/articles/index.ts +7 -0
  80. package/demo/multiple-paths/src/api/functional/sellers/sales/index.ts +7 -0
  81. package/demo/multiple-paths/src/api/index.ts +9 -0
  82. package/demo/multiple-paths/src/api/module.ts +10 -0
  83. package/demo/multiple-paths/src/api/structures/ISaleArticleComment.ts +93 -0
  84. package/demo/multiple-paths/src/controllers/HealthController.ts +7 -0
  85. package/demo/multiple-paths/src/controllers/MultipleController.ts +56 -0
  86. package/demo/multiple-paths/src/test/features/test_consumer_sale_article_comment_store.ts +21 -0
  87. package/demo/multiple-paths/src/test/features/test_health_checks.ts +10 -0
  88. package/demo/multiple-paths/src/test/features/test_seller_sale_article_store.ts +21 -0
  89. package/demo/multiple-paths/src/test/index.ts +24 -0
  90. package/demo/multiple-paths/src/test/internal/DynamicImportIterator.ts +109 -0
  91. package/demo/multiple-paths/src/test/internal/StopWatch.ts +15 -0
  92. package/demo/multiple-paths/swagger.json +338 -0
  93. package/demo/multiple-paths/tsconfig.json +3 -0
  94. package/demo/recursive/src/Backend.ts +27 -0
  95. package/demo/recursive/src/Configuration.ts +7 -0
  96. package/demo/recursive/src/api/HttpError.ts +1 -0
  97. package/demo/recursive/src/api/IConnection.ts +1 -0
  98. package/demo/recursive/src/api/Primitive.ts +1 -0
  99. package/demo/recursive/src/api/__internal/AesPkcs5.ts +1 -0
  100. package/demo/recursive/src/api/__internal/Fetcher.ts +1 -0
  101. package/demo/recursive/src/api/functional/consumers/index.ts +7 -0
  102. package/demo/recursive/src/api/functional/consumers/systematic/categories/index.ts +117 -0
  103. package/demo/recursive/src/api/functional/consumers/systematic/index.ts +7 -0
  104. package/demo/recursive/src/api/functional/index.ts +7 -0
  105. package/demo/recursive/src/api/index.ts +9 -0
  106. package/demo/recursive/src/api/module.ts +10 -0
  107. package/demo/recursive/src/api/structures/ICategory.ts +49 -0
  108. package/demo/recursive/src/consumer.categories.controller.ts +59 -0
  109. package/demo/recursive/src/test/features/test_category_at.ts +11 -0
  110. package/demo/recursive/src/test/features/test_category_invert.ts +14 -0
  111. package/demo/recursive/src/test/features/test_category_top.ts +11 -0
  112. package/demo/recursive/src/test/index.ts +24 -0
  113. package/demo/recursive/src/test/internal/DynamicImportIterator.ts +109 -0
  114. package/demo/recursive/src/test/internal/StopWatch.ts +15 -0
  115. package/demo/recursive/swagger.json +216 -0
  116. package/demo/recursive/tsconfig.json +3 -0
  117. package/demo/safe/nestia.config.ts +13 -0
  118. package/demo/safe/src/Backend.ts +27 -0
  119. package/demo/safe/src/Configuration.ts +7 -0
  120. package/demo/safe/src/api/HttpError.ts +1 -0
  121. package/demo/safe/src/api/IConnection.ts +1 -0
  122. package/demo/safe/src/api/Primitive.ts +1 -0
  123. package/demo/safe/src/api/__internal/AesPkcs5.ts +1 -0
  124. package/demo/safe/src/api/__internal/Fetcher.ts +1 -0
  125. package/demo/safe/src/api/functional/consumers/index.ts +7 -0
  126. package/demo/safe/src/api/functional/consumers/sales/articles/comments/index.ts +69 -0
  127. package/demo/safe/src/api/functional/consumers/sales/articles/index.ts +7 -0
  128. package/demo/safe/src/api/functional/consumers/sales/index.ts +7 -0
  129. package/demo/safe/src/api/functional/index.ts +7 -0
  130. package/demo/safe/src/api/index.ts +9 -0
  131. package/demo/safe/src/api/module.ts +10 -0
  132. package/demo/safe/src/api/structures/ISaleArticleComment.ts +93 -0
  133. package/demo/safe/src/controllers/ConsumerSaleArticleCommentsController.ts +63 -0
  134. package/demo/safe/src/test/features/test_comment_store.ts +23 -0
  135. package/demo/safe/src/test/index.ts +24 -0
  136. package/demo/safe/src/test/internal/DynamicImportIterator.ts +109 -0
  137. package/demo/safe/src/test/internal/StopWatch.ts +15 -0
  138. package/demo/safe/swagger.json +217 -0
  139. package/demo/safe/tsconfig.json +3 -0
  140. package/demo/tsconfig.base.json +70 -0
  141. package/demo/union/nestia.config.ts +9 -0
  142. package/demo/union/src/Backend.ts +27 -0
  143. package/demo/union/src/Configuration.ts +7 -0
  144. package/demo/union/src/api/HttpError.ts +1 -0
  145. package/demo/union/src/api/IConnection.ts +1 -0
  146. package/demo/union/src/api/Primitive.ts +1 -0
  147. package/demo/union/src/api/__internal/AesPkcs5.ts +1 -0
  148. package/demo/union/src/api/__internal/Fetcher.ts +1 -0
  149. package/demo/union/src/api/functional/consumers/index.ts +7 -0
  150. package/demo/union/src/api/functional/consumers/sales/entire_articles/index.ts +121 -0
  151. package/demo/union/src/api/functional/consumers/sales/index.ts +9 -0
  152. package/demo/union/src/api/functional/consumers/sales/questions/index.ts +57 -0
  153. package/demo/union/src/api/functional/consumers/sales/reviews/index.ts +54 -0
  154. package/demo/union/src/api/functional/index.ts +7 -0
  155. package/demo/union/src/api/index.ts +9 -0
  156. package/demo/union/src/api/module.ts +10 -0
  157. package/demo/union/src/api/structures/IAttachmentFile.ts +26 -0
  158. package/demo/union/src/api/structures/IPage.ts +80 -0
  159. package/demo/union/src/api/structures/ISaleArticle.ts +107 -0
  160. package/demo/union/src/api/structures/ISaleEntireArticle.ts +22 -0
  161. package/demo/union/src/api/structures/ISaleInquiry.ts +56 -0
  162. package/demo/union/src/api/structures/ISaleInquiryAnswer.ts +23 -0
  163. package/demo/union/src/api/structures/ISaleQuestion.ts +27 -0
  164. package/demo/union/src/api/structures/ISaleReview.ts +42 -0
  165. package/demo/union/src/controllers/ConsumerSaleEntireArticlesController.ts +109 -0
  166. package/demo/union/src/controllers/ConsumerSaleQuestionsController.ts +45 -0
  167. package/demo/union/src/controllers/ConsumerSaleReviewsController.ts +44 -0
  168. package/demo/union/src/test/features/test_sale_entire_articles_at.ts +16 -0
  169. package/demo/union/src/test/features/test_sale_entire_articles_index.ts +27 -0
  170. package/demo/union/src/test/index.ts +24 -0
  171. package/demo/union/src/test/internal/DynamicImportIterator.ts +109 -0
  172. package/demo/union/src/test/internal/StopWatch.ts +15 -0
  173. package/demo/union/swagger.json +991 -0
  174. package/demo/union/tsconfig.json +3 -0
  175. package/lib/test/TestBuilder.d.ts +4 -0
  176. package/lib/test/TestBuilder.js +60 -0
  177. package/lib/test/TestBuilder.js.map +1 -0
  178. package/lib/test/index.d.ts +1 -0
  179. package/lib/test/index.js +61 -0
  180. package/lib/test/index.js.map +1 -0
  181. package/lib/test/test.builder.executor.d.ts +1 -0
  182. package/lib/test/test.builder.executor.js +24 -0
  183. package/lib/test/test.builder.executor.js.map +1 -0
  184. package/package.json +1 -1
  185. package/prettier.config.js +7 -0
  186. package/src/IConfiguration.ts +119 -0
  187. package/src/NestiaApplication.ts +185 -0
  188. package/src/analyses/ControllerAnalyzer.ts +204 -0
  189. package/src/analyses/GenericAnalyzer.ts +53 -0
  190. package/src/analyses/ImportAnalyzer.ts +144 -0
  191. package/src/analyses/PathAnalyzer.ts +58 -0
  192. package/src/analyses/ReflectAnalyzer.ts +280 -0
  193. package/src/analyses/SourceFinder.ts +59 -0
  194. package/src/executable/internal/CompilerOptions.ts +18 -0
  195. package/src/executable/internal/NestiaCommand.ts +174 -0
  196. package/src/executable/internal/NestiaConfig.ts +36 -0
  197. package/src/executable/internal/NestiaStarter.ts +45 -0
  198. package/src/executable/internal/nestia.config.getter.ts +11 -0
  199. package/src/executable/nestia.ts +55 -0
  200. package/src/generates/FileGenerator.ts +156 -0
  201. package/src/generates/FunctionGenerator.ts +287 -0
  202. package/src/generates/SdkGenerator.ts +49 -0
  203. package/src/generates/SwaggerGenerator.ts +381 -0
  204. package/src/index.ts +2 -0
  205. package/src/module.ts +2 -0
  206. package/src/structures/IController.ts +27 -0
  207. package/src/structures/IRoute.ts +28 -0
  208. package/src/structures/ISwagger.ts +55 -0
  209. package/src/structures/ITypeTuple.ts +6 -0
  210. package/src/structures/MethodType.ts +11 -0
  211. package/src/structures/ParamCategory.ts +1 -0
  212. package/src/structures/TypeEntry.ts +22 -0
  213. package/src/test/TestBuilder.ts +49 -0
  214. package/src/test/index.ts +59 -0
  215. package/src/test/test.builder.executor.ts +11 -0
  216. package/src/utils/ArrayUtil.ts +26 -0
  217. package/src/utils/DirectoryUtil.ts +44 -0
  218. package/src/utils/ImportDictionary.ts +57 -0
  219. package/src/utils/MapUtil.ts +14 -0
  220. package/src/utils/StripEnums.ts +10 -0
  221. package/template/.eslintrc.cjs +22 -0
  222. package/template/.prettierignore +6 -0
  223. package/template/prettier.config.js +18 -0
  224. package/template/tsconfig.json +118 -0
  225. package/tsconfig.json +82 -0
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Attachemd (physical) file info.
3
+ *
4
+ * @author Jeongho Nam - https://github.com/samchon
5
+ */
6
+ export interface IAttachmentFile {
7
+ /**
8
+ * Name of the file.
9
+ */
10
+ name: string;
11
+
12
+ /**
13
+ * Extension of the file, but ommitable.
14
+ */
15
+ extension: string | null;
16
+
17
+ /**
18
+ * Full URL path of the file.
19
+ */
20
+ url: string;
21
+ }
@@ -0,0 +1,79 @@
1
+ import { IAttachmentFile } from "./IAttachmentFile";
2
+
3
+ /**
4
+ * Article about a sale.
5
+ *
6
+ * The `ISaleArticle` is a super type interface. Many sub-type articles would be
7
+ * designed by extending this super type interface `ISaleArticle`.
8
+ *
9
+ * @template Content Content type.
10
+ * @author Jeongho Nam - https://github.com/samchon
11
+ */
12
+ export interface ISaleArticle<Content extends ISaleArticle.IContent> {
13
+ /**
14
+ * Primary Key.
15
+ */
16
+ id: number;
17
+
18
+ /**
19
+ * Hit count.
20
+ *
21
+ * How many consumers had read.
22
+ */
23
+ hit: number;
24
+
25
+ /**
26
+ * List of contents.
27
+ *
28
+ * When the article writer tries to modify content, it would not modify the article
29
+ * content but would be accumulated. Therefore, all of the people can read how
30
+ * the content has been changed.
31
+ */
32
+ contents: Content[];
33
+
34
+ /**
35
+ * Creation time.
36
+ */
37
+ created_at: string;
38
+ }
39
+ export namespace ISaleArticle {
40
+ /**
41
+ * Content info.
42
+ */
43
+ export interface IContent extends IStore {
44
+ /**
45
+ * Primary Key
46
+ */
47
+ id: string;
48
+
49
+ /**
50
+ * Creation time.
51
+ */
52
+ created_at: string;
53
+ }
54
+
55
+ /**
56
+ * Store info.
57
+ */
58
+ export interface IStore {
59
+ /**
60
+ * Title of the content.
61
+ */
62
+ title: string;
63
+
64
+ /**
65
+ * Body of the content.
66
+ */
67
+ body: string;
68
+
69
+ /**
70
+ * Extension, content type (format).
71
+ */
72
+ extension: "html" | "md" | "txt";
73
+
74
+ /**
75
+ * Attached files.
76
+ */
77
+ files: IAttachmentFile[];
78
+ }
79
+ }
@@ -0,0 +1,34 @@
1
+ import { ISaleArticle } from "./ISaleArticle";
2
+ import { ISaleInquiryAnswer } from "./ISaleInquiryAnswer";
3
+
4
+ /**
5
+ * Inquiry article.
6
+ *
7
+ * Sub-type of article and super-type of question and answer.
8
+ *
9
+ * @template Content Content type
10
+ * @author Jeongho Nam - https://github.com/samchon
11
+ */
12
+ export interface ISaleInquiry<Content extends ISaleInquiry.IContent>
13
+ extends ISaleArticle<Content> {
14
+ /**
15
+ * Name of the writer.
16
+ */
17
+ writer: string;
18
+
19
+ /**
20
+ * Formal answer from the seller.
21
+ */
22
+ answer: ISaleInquiryAnswer | null;
23
+ }
24
+ export namespace ISaleInquiry {
25
+ /**
26
+ * Content type of the inquiry article.
27
+ */
28
+ export type IContent = ISaleArticle.IContent;
29
+
30
+ /**
31
+ * Store info of the inquiry article.
32
+ */
33
+ export type IStore = ISaleArticle.IStore;
34
+ }
@@ -0,0 +1,23 @@
1
+ import { ISaleArticle } from "./ISaleArticle";
2
+
3
+ /**
4
+ * Formal answer from the seller.
5
+ *
6
+ * When a consumer writes an inquiry about a sale, the seller can write a formal
7
+ * answer article. This `ISaleInquiryAnswer` has been designed to represent such
8
+ * formal answer article from the seller.
9
+ *
10
+ * @author Jeongho Nam - https://github.com/samchon
11
+ */
12
+ export type ISaleInquiryAnswer = ISaleArticle<ISaleInquiryAnswer.IContent>;
13
+ export namespace ISaleInquiryAnswer {
14
+ /**
15
+ * Content type of the answer.
16
+ */
17
+ export type IContent = ISaleArticle.IContent;
18
+
19
+ /**
20
+ * Store info of the answer.
21
+ */
22
+ export type IStore = ISaleArticle.IContent;
23
+ }
@@ -0,0 +1,22 @@
1
+ import { ISaleInquiry } from "./ISaleInquiry";
2
+
3
+ /**
4
+ * Question article.
5
+ *
6
+ * The `ISaleQuestion` is a type of question article wrriten by a consumer
7
+ * who has something to ask about the sale.
8
+ *
9
+ * @author Jeongho Nam - https://github.com/samchon
10
+ */
11
+ export type ISaleQuestion = ISaleInquiry<ISaleQuestion.IContent>;
12
+ export namespace ISaleQuestion {
13
+ /**
14
+ * Content info of the question.
15
+ */
16
+ export type IContent = ISaleInquiry.IContent;
17
+
18
+ /**
19
+ * Store info of the question.
20
+ */
21
+ export type IStore = ISaleInquiry.IStore;
22
+ }
@@ -0,0 +1,32 @@
1
+ import { ISaleInquiry } from "./ISaleInquiry";
2
+
3
+ /**
4
+ * Review article.
5
+ *
6
+ * The `ISaleReview` is a type of review article written by a consumer who've bought
7
+ * the sale good with the estimation score.
8
+ *
9
+ * @author Jeongho Nam - https://github.com/samchon
10
+ */
11
+ export type ISaleReview = ISaleInquiry<ISaleReview.IContent>;
12
+ export namespace ISaleReview {
13
+ /**
14
+ * Content info of the review.
15
+ */
16
+ export interface IContent extends ISaleInquiry.IContent {
17
+ /**
18
+ * Estimation score.
19
+ */
20
+ score: number;
21
+ }
22
+
23
+ /**
24
+ * Store info of the review.
25
+ */
26
+ export interface IStore extends ISaleInquiry.IStore {
27
+ /**
28
+ * Estimation score.
29
+ */
30
+ score: number;
31
+ }
32
+ }
@@ -0,0 +1,33 @@
1
+ import TSON from "typescript-json";
2
+ import * as nest from "@nestjs/common";
3
+
4
+ import { ISaleQuestion } from "@api/structures/ISaleQuestion";
5
+
6
+ import { SaleInquiriesController } from "./SaleInquiriesController";
7
+
8
+ @nest.Controller("consumers/:section/sales/:saleId/questions")
9
+ export class ConsumerSaleQuestionsController extends SaleInquiriesController<
10
+ ISaleQuestion.IContent,
11
+ ISaleQuestion.IStore,
12
+ ISaleQuestion
13
+ >({
14
+ assert: (input) => TSON.assertType(input),
15
+ stringify: (input) => TSON.stringify(input),
16
+ convert: (input) => ({
17
+ id: 0,
18
+ hit: 0,
19
+ writer: "someone",
20
+ answer: null,
21
+ created_at: new Date().toString(),
22
+ contents: [
23
+ {
24
+ id: "some-content-id",
25
+ title: input.title,
26
+ body: input.body,
27
+ extension: input.extension,
28
+ files: input.files,
29
+ created_at: new Date().toString(),
30
+ },
31
+ ],
32
+ }),
33
+ }) {}
@@ -0,0 +1,34 @@
1
+ import * as nest from "@nestjs/common";
2
+
3
+ import { ISaleReview } from "@api/structures/ISaleReview";
4
+
5
+ import { SaleInquiriesController } from "./SaleInquiriesController";
6
+ import TSON from "typescript-json";
7
+
8
+ @nest.Controller("consumers/:section/sales/:saleId/reviews")
9
+ export class ConsumerSaleReviewsController extends SaleInquiriesController<
10
+ ISaleReview.IContent,
11
+ ISaleReview.IStore,
12
+ ISaleReview
13
+ >({
14
+ assert: (input) => TSON.assertType(input),
15
+ stringify: (input) => TSON.stringify(input),
16
+ convert: (input) => ({
17
+ id: 0,
18
+ hit: 0,
19
+ writer: "someone",
20
+ answer: null,
21
+ created_at: new Date().toString(),
22
+ contents: [
23
+ {
24
+ id: "some-content-id",
25
+ title: input.title,
26
+ body: input.body,
27
+ extension: input.extension,
28
+ files: input.files,
29
+ created_at: new Date().toString(),
30
+ score: 100,
31
+ },
32
+ ],
33
+ }),
34
+ }) {}
@@ -0,0 +1,87 @@
1
+ import * as express from "express";
2
+ import * as nest from "@nestjs/common";
3
+ import helper from "nestia-helper";
4
+
5
+ import { ISaleInquiry } from "@api/structures/ISaleInquiry";
6
+
7
+ export function SaleInquiriesController<
8
+ Content extends ISaleInquiry.IContent,
9
+ Store extends ISaleInquiry.IStore,
10
+ Json extends ISaleInquiry<Content>,
11
+ >(trait: SaleInquiriesController.ITrait<Content, Store, Json>) {
12
+ abstract class SaleInquiriesController {
13
+ /**
14
+ * Store a new inquiry.
15
+ *
16
+ * Write a new article inquirying about a sale.
17
+ *
18
+ * @param request Instance of the Express.Request
19
+ * @param section Code of the target section
20
+ * @param saleId ID of the target sale
21
+ * @param input Content to archive
22
+ * @return Newly archived inquiry
23
+ *
24
+ * @throw 400 bad request error when type of the input data is not valid
25
+ * @throw 401 unauthorized error when you've not logged in yet
26
+ */
27
+ @helper.TypedRoute.Post(trait.stringify)
28
+ public async store(
29
+ @nest.Request() request: express.Request,
30
+ @helper.TypedParam("section", "string") section: string,
31
+ @helper.TypedParam("saleId", "string") saleId: string,
32
+ @helper.TypedBody(trait.assert) input: Store,
33
+ ): Promise<Json> {
34
+ request;
35
+ section;
36
+ saleId;
37
+
38
+ return trait.convert(input);
39
+ }
40
+
41
+ /**
42
+ * Update an inquiry.
43
+ *
44
+ * Update ordinary inquiry article. However, it would not modify the content reocrd
45
+ * {@link ISaleInquiry.IContent}, but be accumulated into the {@link ISaleInquiry.contents}.
46
+ * Therefore, all of the poeple can read how the content has been changed.
47
+ *
48
+ * @param request Instance of the Express.Request
49
+ * @param section Code of the target section
50
+ * @param saleId ID of the target sale
51
+ * @param id ID of the target article to be updated
52
+ * @param input New content to be overwritten
53
+ * @return The newly created content record
54
+ *
55
+ * @throw 400 bad request error when type of the input data is not valid
56
+ * @throw 401 unauthorized error when you've not logged in yet
57
+ * @throw 403 forbidden error when the article is not yours
58
+ */
59
+ @helper.TypedRoute.Put(":id", trait.stringify)
60
+ public async update(
61
+ @nest.Request() request: express.Request,
62
+ @helper.TypedParam("section", "string") section: string,
63
+ @helper.TypedParam("saleId", "string") saleId: string,
64
+ @helper.TypedParam("id", "number") id: number,
65
+ @helper.TypedBody(trait.assert) input: Store,
66
+ ): Promise<Json> {
67
+ request;
68
+ section;
69
+ saleId;
70
+ id;
71
+
72
+ return trait.convert(input);
73
+ }
74
+ }
75
+ return SaleInquiriesController;
76
+ }
77
+ export namespace SaleInquiriesController {
78
+ export interface ITrait<
79
+ Content extends ISaleInquiry.IContent,
80
+ Store extends ISaleInquiry.IStore,
81
+ Json extends ISaleInquiry<Content>,
82
+ > {
83
+ stringify(json: Json): string;
84
+ assert(input: Store): Store;
85
+ convert(input: Store): Json;
86
+ }
87
+ }
@@ -0,0 +1,21 @@
1
+ import api from "@api";
2
+ import { ISaleQuestion } from "@api/structures/ISaleQuestion";
3
+ import TSON from "typescript-json";
4
+
5
+ export async function test_question_store(
6
+ connection: api.IConnection,
7
+ ): Promise<void> {
8
+ const question: ISaleQuestion =
9
+ await api.functional.consumers.sales.questions.store(
10
+ connection,
11
+ "general",
12
+ "some-sale-id",
13
+ {
14
+ title: "some-title",
15
+ body: "some-body-content",
16
+ files: [],
17
+ extension: "html",
18
+ },
19
+ );
20
+ TSON.assertType(question);
21
+ }
@@ -0,0 +1,42 @@
1
+ import api from "@api";
2
+ import { ISaleQuestion } from "@api/structures/ISaleQuestion";
3
+ import TSON from "typescript-json";
4
+
5
+ export async function test_question_update(
6
+ connection: api.IConnection,
7
+ ): Promise<void> {
8
+ const question: ISaleQuestion =
9
+ await api.functional.consumers.sales.questions.store(
10
+ connection,
11
+ "general",
12
+ "some-sale-id",
13
+ {
14
+ title: "some-title",
15
+ body: "some-body-content",
16
+ files: [],
17
+ extension: "html",
18
+ },
19
+ );
20
+ TSON.assertType(question);
21
+
22
+ const updated: ISaleQuestion =
23
+ await api.functional.consumers.sales.questions.update(
24
+ connection,
25
+ "general",
26
+ "some-sale-id",
27
+ question.id,
28
+ {
29
+ title: "new-title",
30
+ body: "new-content-body",
31
+ files: [
32
+ {
33
+ name: "typescript-json",
34
+ extension: "lnk",
35
+ url: "https://github.com/samchon/typescript-json",
36
+ },
37
+ ],
38
+ extension: "html",
39
+ },
40
+ );
41
+ TSON.assertType(updated);
42
+ }
@@ -0,0 +1,22 @@
1
+ import api from "@api";
2
+ import { ISaleReview } from "@api/structures/ISaleReview";
3
+ import TSON from "typescript-json";
4
+
5
+ export async function test_review_store(
6
+ connection: api.IConnection,
7
+ ): Promise<void> {
8
+ const question: ISaleReview =
9
+ await api.functional.consumers.sales.reviews.store(
10
+ connection,
11
+ "general",
12
+ "some-sale-id",
13
+ {
14
+ title: "some-title",
15
+ body: "some-body-content",
16
+ files: [],
17
+ extension: "html",
18
+ score: 100,
19
+ },
20
+ );
21
+ TSON.assertType(question);
22
+ }
@@ -0,0 +1,44 @@
1
+ import api from "@api";
2
+ import { ISaleReview } from "@api/structures/ISaleReview";
3
+ import TSON from "typescript-json";
4
+
5
+ export async function test_review_update(
6
+ connection: api.IConnection,
7
+ ): Promise<void> {
8
+ const question: ISaleReview =
9
+ await api.functional.consumers.sales.reviews.store(
10
+ connection,
11
+ "general",
12
+ "some-sale-id",
13
+ {
14
+ title: "some-title",
15
+ body: "some-body-content",
16
+ files: [],
17
+ extension: "html",
18
+ score: 100,
19
+ },
20
+ );
21
+ TSON.assertType(question);
22
+
23
+ const updated: ISaleReview =
24
+ await api.functional.consumers.sales.reviews.update(
25
+ connection,
26
+ "general",
27
+ "some-sale-id",
28
+ question.id,
29
+ {
30
+ title: "new-title",
31
+ body: "new-content-body",
32
+ files: [
33
+ {
34
+ name: "typescript-json",
35
+ extension: "lnk",
36
+ url: "https://github.com/samchon/typescript-json",
37
+ },
38
+ ],
39
+ extension: "html",
40
+ score: 90,
41
+ },
42
+ );
43
+ TSON.assertType(updated);
44
+ }
@@ -0,0 +1,24 @@
1
+ import api from "../api";
2
+ import { Backend } from "../Backend";
3
+ import { Configuration } from "../Configuration";
4
+ import { DynamicImportIterator } from "./internal/DynamicImportIterator";
5
+
6
+ async function main(): Promise<void> {
7
+ const server: Backend = new Backend();
8
+ await server.open();
9
+
10
+ const connection: api.IConnection = {
11
+ host: `http://127.0.0.1:${Configuration.PORT}`,
12
+ encryption: Configuration.ENCRYPTION_PASSWORD,
13
+ };
14
+ await DynamicImportIterator.main(__dirname, {
15
+ prefix: "test",
16
+ parameters: () => [connection],
17
+ });
18
+
19
+ await server.close();
20
+ }
21
+ main().catch((exp) => {
22
+ console.log(exp);
23
+ process.exit(-1);
24
+ });
@@ -0,0 +1,109 @@
1
+ const EXTENSION = __filename.substr(-2);
2
+
3
+ import cli from "cli";
4
+ import fs from "fs";
5
+ import { IPointer } from "tstl/functional/IPointer";
6
+
7
+ import { StopWatch } from "./StopWatch";
8
+
9
+ interface ICommand {
10
+ include?: string;
11
+ exclude?: string;
12
+ }
13
+
14
+ export namespace DynamicImportIterator {
15
+ export type Closure<Arguments extends any[]> = (
16
+ ...args: Arguments
17
+ ) => Promise<any>;
18
+ type Module<Arguments extends any[]> = {
19
+ [key: string]: Closure<Arguments>;
20
+ };
21
+
22
+ export interface IOptions<Parameters extends any[]> {
23
+ prefix: string;
24
+ parameters: () => Parameters;
25
+ wrapper?: (name: string, output: any) => Promise<any>;
26
+ counter?: IPointer<number>;
27
+ showElapsedTime?: boolean;
28
+ }
29
+
30
+ export async function main<Arguments extends any[]>(
31
+ path: string,
32
+ options: IOptions<Arguments>,
33
+ ): Promise<void> {
34
+ const command: ICommand = cli.parse();
35
+ await iterate(options, command, path);
36
+ }
37
+
38
+ export async function force<Arguments extends any[]>(
39
+ path: string,
40
+ options: IOptions<Arguments>,
41
+ ): Promise<Error[]> {
42
+ const command: ICommand = cli.parse();
43
+ const exceptions: Error[] = [];
44
+
45
+ await iterate(options, command, path, exceptions);
46
+ return exceptions;
47
+ }
48
+
49
+ async function iterate<Arguments extends any[]>(
50
+ options: IOptions<Arguments>,
51
+ command: ICommand,
52
+ path: string,
53
+ exceptions?: Error[],
54
+ ): Promise<void> {
55
+ const directory: string[] = await fs.promises.readdir(path);
56
+ for (const file of directory) {
57
+ const current: string = `${path}/${file}`;
58
+ const stats: fs.Stats = await fs.promises.lstat(current);
59
+
60
+ if (stats.isDirectory() === true) {
61
+ await iterate(options, command, current, exceptions);
62
+ continue;
63
+ } else if (file.substr(-3) !== `.${EXTENSION}`) continue;
64
+
65
+ const external: Module<Arguments> = await import(current);
66
+ await execute(options, command, external, exceptions);
67
+ }
68
+ }
69
+
70
+ async function execute<Arguments extends any[]>(
71
+ options: IOptions<Arguments>,
72
+ command: ICommand,
73
+ external: Module<Arguments>,
74
+ exceptions?: Error[],
75
+ ): Promise<void> {
76
+ for (const key in external) {
77
+ if (command.exclude && key.indexOf(command.exclude) !== -1)
78
+ continue;
79
+ else if (command.include && key.indexOf(command.include) === -1)
80
+ continue;
81
+ else if (key.substr(0, options.prefix.length) !== options.prefix)
82
+ continue;
83
+ else if (external[key] instanceof Function) {
84
+ const closure: Closure<Arguments> = external[key];
85
+ const func = async () => {
86
+ const output = await closure(...options.parameters());
87
+ if (options.wrapper) await options.wrapper(key, output);
88
+ };
89
+
90
+ try {
91
+ if (options.counter) ++options.counter.value;
92
+ if (options.showElapsedTime === false) {
93
+ await func();
94
+ console.log(` - ${key}`);
95
+ } else {
96
+ const time: number = await StopWatch.measure(func);
97
+ console.log(` - ${key}: ${time.toLocaleString()} ms`);
98
+ }
99
+ } catch (exp) {
100
+ if (!(exp instanceof Error)) return;
101
+
102
+ console.log(` - ${key} -> ${exp.name}`);
103
+ if (exceptions !== undefined) exceptions.push(exp);
104
+ else throw exp;
105
+ }
106
+ }
107
+ }
108
+ }
109
+ }
@@ -0,0 +1,15 @@
1
+ export namespace StopWatch {
2
+ export type Task = () => Promise<void>;
3
+
4
+ export async function measure(task: Task): Promise<number> {
5
+ const time: number = Date.now();
6
+ await task();
7
+ return Date.now() - time;
8
+ }
9
+
10
+ export async function trace(title: string, task: Task): Promise<void> {
11
+ process.stdout.write(title);
12
+ const time: number = await measure(task);
13
+ console.log(`: ${time.toLocaleString()} ms`);
14
+ }
15
+ }