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.
- package/.eslintrc.cjs +33 -0
- package/.prettierignore +5 -0
- package/.vscode/settings.json +10 -0
- package/demo/encrypted/src/Backend.ts +27 -0
- package/demo/encrypted/src/Configuration.ts +7 -0
- package/demo/encrypted/src/api/HttpError.ts +1 -0
- package/demo/encrypted/src/api/IConnection.ts +1 -0
- package/demo/encrypted/src/api/Primitive.ts +1 -0
- package/demo/encrypted/src/api/__internal/AesPkcs5.ts +1 -0
- package/demo/encrypted/src/api/__internal/Fetcher.ts +1 -0
- package/demo/encrypted/src/api/functional/index.ts +7 -0
- package/demo/encrypted/src/api/functional/sellers/authenticate/index.ts +136 -0
- package/demo/encrypted/src/api/functional/sellers/authenticate/password/index.ts +53 -0
- package/demo/encrypted/src/api/functional/sellers/index.ts +7 -0
- package/demo/encrypted/src/api/index.ts +9 -0
- package/demo/encrypted/src/api/module.ts +10 -0
- package/demo/encrypted/src/api/structures/ISeller.ts +56 -0
- package/demo/encrypted/src/controllers/SellerAuthenticateController.ts +70 -0
- package/demo/encrypted/src/test/features/test_seller_exit.ts +18 -0
- package/demo/encrypted/src/test/features/test_seller_join.ts +19 -0
- package/demo/encrypted/src/test/features/test_seller_login.ts +16 -0
- package/demo/encrypted/src/test/features/test_seller_password_change.ts +18 -0
- package/demo/encrypted/src/test/index.ts +24 -0
- package/demo/encrypted/src/test/internal/DynamicImportIterator.ts +109 -0
- package/demo/encrypted/src/test/internal/StopWatch.ts +15 -0
- package/demo/encrypted/swagger.json +257 -0
- package/demo/encrypted/tsconfig.json +8 -0
- package/demo/generic/nestia.config.ts +10 -0
- package/demo/generic/src/Backend.ts +27 -0
- package/demo/generic/src/Configuration.ts +7 -0
- package/demo/generic/src/api/HttpError.ts +1 -0
- package/demo/generic/src/api/IConnection.ts +1 -0
- package/demo/generic/src/api/Primitive.ts +1 -0
- package/demo/generic/src/api/__internal/AesPkcs5.ts +1 -0
- package/demo/generic/src/api/__internal/Fetcher.ts +1 -0
- package/demo/generic/src/api/functional/consumers/index.ts +7 -0
- package/demo/generic/src/api/functional/consumers/sales/index.ts +8 -0
- package/demo/generic/src/api/functional/consumers/sales/questions/index.ts +136 -0
- package/demo/generic/src/api/functional/consumers/sales/reviews/index.ts +136 -0
- package/demo/generic/src/api/functional/index.ts +7 -0
- package/demo/generic/src/api/index.ts +9 -0
- package/demo/generic/src/api/module.ts +10 -0
- package/demo/generic/src/api/structures/IAttachmentFile.ts +21 -0
- package/demo/generic/src/api/structures/ISaleArticle.ts +79 -0
- package/demo/generic/src/api/structures/ISaleInquiry.ts +34 -0
- package/demo/generic/src/api/structures/ISaleInquiryAnswer.ts +23 -0
- package/demo/generic/src/api/structures/ISaleQuestion.ts +22 -0
- package/demo/generic/src/api/structures/ISaleReview.ts +32 -0
- package/demo/generic/src/controllers/ConsumerSaleQuestionsController.ts +33 -0
- package/demo/generic/src/controllers/ConsumerSaleReviewsController.ts +34 -0
- package/demo/generic/src/controllers/SaleInquiriesController.ts +87 -0
- package/demo/generic/src/test/features/test_question_store.ts +21 -0
- package/demo/generic/src/test/features/test_question_update.ts +42 -0
- package/demo/generic/src/test/features/test_review_store.ts +22 -0
- package/demo/generic/src/test/features/test_review_update.ts +44 -0
- package/demo/generic/src/test/index.ts +24 -0
- package/demo/generic/src/test/internal/DynamicImportIterator.ts +109 -0
- package/demo/generic/src/test/internal/StopWatch.ts +15 -0
- package/demo/generic/swagger.json +736 -0
- package/demo/generic/tsconfig.json +9 -0
- package/demo/multiple-paths/src/Backend.ts +27 -0
- package/demo/multiple-paths/src/Configuration.ts +7 -0
- package/demo/multiple-paths/src/api/HttpError.ts +1 -0
- package/demo/multiple-paths/src/api/IConnection.ts +1 -0
- package/demo/multiple-paths/src/api/Primitive.ts +1 -0
- package/demo/multiple-paths/src/api/__internal/AesPkcs5.ts +1 -0
- package/demo/multiple-paths/src/api/__internal/Fetcher.ts +1 -0
- package/demo/multiple-paths/src/api/functional/consumers/index.ts +7 -0
- package/demo/multiple-paths/src/api/functional/consumers/sales/articles/comments/index.ts +65 -0
- package/demo/multiple-paths/src/api/functional/consumers/sales/articles/index.ts +7 -0
- package/demo/multiple-paths/src/api/functional/consumers/sales/index.ts +7 -0
- package/demo/multiple-paths/src/api/functional/health/alive/index.ts +42 -0
- package/demo/multiple-paths/src/api/functional/health/index.ts +44 -0
- package/demo/multiple-paths/src/api/functional/healthy/alive/index.ts +42 -0
- package/demo/multiple-paths/src/api/functional/healthy/index.ts +44 -0
- package/demo/multiple-paths/src/api/functional/index.ts +10 -0
- package/demo/multiple-paths/src/api/functional/sellers/index.ts +7 -0
- package/demo/multiple-paths/src/api/functional/sellers/sales/articles/comments/index.ts +65 -0
- package/demo/multiple-paths/src/api/functional/sellers/sales/articles/index.ts +7 -0
- package/demo/multiple-paths/src/api/functional/sellers/sales/index.ts +7 -0
- package/demo/multiple-paths/src/api/index.ts +9 -0
- package/demo/multiple-paths/src/api/module.ts +10 -0
- package/demo/multiple-paths/src/api/structures/ISaleArticleComment.ts +93 -0
- package/demo/multiple-paths/src/controllers/HealthController.ts +7 -0
- package/demo/multiple-paths/src/controllers/MultipleController.ts +56 -0
- package/demo/multiple-paths/src/test/features/test_consumer_sale_article_comment_store.ts +21 -0
- package/demo/multiple-paths/src/test/features/test_health_checks.ts +10 -0
- package/demo/multiple-paths/src/test/features/test_seller_sale_article_store.ts +21 -0
- package/demo/multiple-paths/src/test/index.ts +24 -0
- package/demo/multiple-paths/src/test/internal/DynamicImportIterator.ts +109 -0
- package/demo/multiple-paths/src/test/internal/StopWatch.ts +15 -0
- package/demo/multiple-paths/swagger.json +338 -0
- package/demo/multiple-paths/tsconfig.json +3 -0
- package/demo/recursive/src/Backend.ts +27 -0
- package/demo/recursive/src/Configuration.ts +7 -0
- package/demo/recursive/src/api/HttpError.ts +1 -0
- package/demo/recursive/src/api/IConnection.ts +1 -0
- package/demo/recursive/src/api/Primitive.ts +1 -0
- package/demo/recursive/src/api/__internal/AesPkcs5.ts +1 -0
- package/demo/recursive/src/api/__internal/Fetcher.ts +1 -0
- package/demo/recursive/src/api/functional/consumers/index.ts +7 -0
- package/demo/recursive/src/api/functional/consumers/systematic/categories/index.ts +117 -0
- package/demo/recursive/src/api/functional/consumers/systematic/index.ts +7 -0
- package/demo/recursive/src/api/functional/index.ts +7 -0
- package/demo/recursive/src/api/index.ts +9 -0
- package/demo/recursive/src/api/module.ts +10 -0
- package/demo/recursive/src/api/structures/ICategory.ts +49 -0
- package/demo/recursive/src/consumer.categories.controller.ts +59 -0
- package/demo/recursive/src/test/features/test_category_at.ts +11 -0
- package/demo/recursive/src/test/features/test_category_invert.ts +14 -0
- package/demo/recursive/src/test/features/test_category_top.ts +11 -0
- package/demo/recursive/src/test/index.ts +24 -0
- package/demo/recursive/src/test/internal/DynamicImportIterator.ts +109 -0
- package/demo/recursive/src/test/internal/StopWatch.ts +15 -0
- package/demo/recursive/swagger.json +216 -0
- package/demo/recursive/tsconfig.json +3 -0
- package/demo/safe/nestia.config.ts +13 -0
- package/demo/safe/src/Backend.ts +27 -0
- package/demo/safe/src/Configuration.ts +7 -0
- package/demo/safe/src/api/HttpError.ts +1 -0
- package/demo/safe/src/api/IConnection.ts +1 -0
- package/demo/safe/src/api/Primitive.ts +1 -0
- package/demo/safe/src/api/__internal/AesPkcs5.ts +1 -0
- package/demo/safe/src/api/__internal/Fetcher.ts +1 -0
- package/demo/safe/src/api/functional/consumers/index.ts +7 -0
- package/demo/safe/src/api/functional/consumers/sales/articles/comments/index.ts +69 -0
- package/demo/safe/src/api/functional/consumers/sales/articles/index.ts +7 -0
- package/demo/safe/src/api/functional/consumers/sales/index.ts +7 -0
- package/demo/safe/src/api/functional/index.ts +7 -0
- package/demo/safe/src/api/index.ts +9 -0
- package/demo/safe/src/api/module.ts +10 -0
- package/demo/safe/src/api/structures/ISaleArticleComment.ts +93 -0
- package/demo/safe/src/controllers/ConsumerSaleArticleCommentsController.ts +63 -0
- package/demo/safe/src/test/features/test_comment_store.ts +23 -0
- package/demo/safe/src/test/index.ts +24 -0
- package/demo/safe/src/test/internal/DynamicImportIterator.ts +109 -0
- package/demo/safe/src/test/internal/StopWatch.ts +15 -0
- package/demo/safe/swagger.json +217 -0
- package/demo/safe/tsconfig.json +3 -0
- package/demo/tsconfig.base.json +70 -0
- package/demo/union/nestia.config.ts +9 -0
- package/demo/union/src/Backend.ts +27 -0
- package/demo/union/src/Configuration.ts +7 -0
- package/demo/union/src/api/HttpError.ts +1 -0
- package/demo/union/src/api/IConnection.ts +1 -0
- package/demo/union/src/api/Primitive.ts +1 -0
- package/demo/union/src/api/__internal/AesPkcs5.ts +1 -0
- package/demo/union/src/api/__internal/Fetcher.ts +1 -0
- package/demo/union/src/api/functional/consumers/index.ts +7 -0
- package/demo/union/src/api/functional/consumers/sales/entire_articles/index.ts +121 -0
- package/demo/union/src/api/functional/consumers/sales/index.ts +9 -0
- package/demo/union/src/api/functional/consumers/sales/questions/index.ts +57 -0
- package/demo/union/src/api/functional/consumers/sales/reviews/index.ts +54 -0
- package/demo/union/src/api/functional/index.ts +7 -0
- package/demo/union/src/api/index.ts +9 -0
- package/demo/union/src/api/module.ts +10 -0
- package/demo/union/src/api/structures/IAttachmentFile.ts +26 -0
- package/demo/union/src/api/structures/IPage.ts +80 -0
- package/demo/union/src/api/structures/ISaleArticle.ts +107 -0
- package/demo/union/src/api/structures/ISaleEntireArticle.ts +22 -0
- package/demo/union/src/api/structures/ISaleInquiry.ts +56 -0
- package/demo/union/src/api/structures/ISaleInquiryAnswer.ts +23 -0
- package/demo/union/src/api/structures/ISaleQuestion.ts +27 -0
- package/demo/union/src/api/structures/ISaleReview.ts +42 -0
- package/demo/union/src/controllers/ConsumerSaleEntireArticlesController.ts +109 -0
- package/demo/union/src/controllers/ConsumerSaleQuestionsController.ts +45 -0
- package/demo/union/src/controllers/ConsumerSaleReviewsController.ts +44 -0
- package/demo/union/src/test/features/test_sale_entire_articles_at.ts +16 -0
- package/demo/union/src/test/features/test_sale_entire_articles_index.ts +27 -0
- package/demo/union/src/test/index.ts +24 -0
- package/demo/union/src/test/internal/DynamicImportIterator.ts +109 -0
- package/demo/union/src/test/internal/StopWatch.ts +15 -0
- package/demo/union/swagger.json +991 -0
- package/demo/union/tsconfig.json +3 -0
- package/lib/test/TestBuilder.d.ts +4 -0
- package/lib/test/TestBuilder.js +60 -0
- package/lib/test/TestBuilder.js.map +1 -0
- package/lib/test/index.d.ts +1 -0
- package/lib/test/index.js +61 -0
- package/lib/test/index.js.map +1 -0
- package/lib/test/test.builder.executor.d.ts +1 -0
- package/lib/test/test.builder.executor.js +24 -0
- package/lib/test/test.builder.executor.js.map +1 -0
- package/package.json +1 -1
- package/prettier.config.js +7 -0
- package/src/IConfiguration.ts +119 -0
- package/src/NestiaApplication.ts +185 -0
- package/src/analyses/ControllerAnalyzer.ts +204 -0
- package/src/analyses/GenericAnalyzer.ts +53 -0
- package/src/analyses/ImportAnalyzer.ts +144 -0
- package/src/analyses/PathAnalyzer.ts +58 -0
- package/src/analyses/ReflectAnalyzer.ts +280 -0
- package/src/analyses/SourceFinder.ts +59 -0
- package/src/executable/internal/CompilerOptions.ts +18 -0
- package/src/executable/internal/NestiaCommand.ts +174 -0
- package/src/executable/internal/NestiaConfig.ts +36 -0
- package/src/executable/internal/NestiaStarter.ts +45 -0
- package/src/executable/internal/nestia.config.getter.ts +11 -0
- package/src/executable/nestia.ts +55 -0
- package/src/generates/FileGenerator.ts +156 -0
- package/src/generates/FunctionGenerator.ts +287 -0
- package/src/generates/SdkGenerator.ts +49 -0
- package/src/generates/SwaggerGenerator.ts +381 -0
- package/src/index.ts +2 -0
- package/src/module.ts +2 -0
- package/src/structures/IController.ts +27 -0
- package/src/structures/IRoute.ts +28 -0
- package/src/structures/ISwagger.ts +55 -0
- package/src/structures/ITypeTuple.ts +6 -0
- package/src/structures/MethodType.ts +11 -0
- package/src/structures/ParamCategory.ts +1 -0
- package/src/structures/TypeEntry.ts +22 -0
- package/src/test/TestBuilder.ts +49 -0
- package/src/test/index.ts +59 -0
- package/src/test/test.builder.executor.ts +11 -0
- package/src/utils/ArrayUtil.ts +26 -0
- package/src/utils/DirectoryUtil.ts +44 -0
- package/src/utils/ImportDictionary.ts +57 -0
- package/src/utils/MapUtil.ts +14 -0
- package/src/utils/StripEnums.ts +10 -0
- package/template/.eslintrc.cjs +22 -0
- package/template/.prettierignore +6 -0
- package/template/prettier.config.js +18 -0
- package/template/tsconfig.json +118 -0
- 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
|
+
}
|