nestia 3.1.1 → 3.1.2-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 (54) hide show
  1. package/README.md +133 -17
  2. package/lib/executable/internal/NestiaStarter.js +10 -26
  3. package/lib/executable/internal/NestiaStarter.js.map +1 -1
  4. package/package.json +2 -2
  5. package/template/.eslintrc.cjs +0 -22
  6. package/template/.github/workflows/build.yml +0 -18
  7. package/template/.prettierignore +0 -6
  8. package/template/.vscode/launch.json +0 -19
  9. package/template/.vscode/settings.json +0 -10
  10. package/template/LICENSE +0 -21
  11. package/template/README.md +0 -131
  12. package/template/bundle/gitignore +0 -6
  13. package/template/bundle/npmignore +0 -6
  14. package/template/nestia.config.ts +0 -12
  15. package/template/package.json +0 -62
  16. package/template/packages/api/LICENSE +0 -21
  17. package/template/packages/api/README.md +0 -66
  18. package/template/packages/api/package.json +0 -21
  19. package/template/prettier.config.js +0 -18
  20. package/template/src/Backend.ts +0 -65
  21. package/template/src/Configuration.ts +0 -11
  22. package/template/src/api/HttpError.ts +0 -1
  23. package/template/src/api/IConnection.ts +0 -1
  24. package/template/src/api/Primitive.ts +0 -1
  25. package/template/src/api/__internal/AesPkcs5.ts +0 -1
  26. package/template/src/api/__internal/Fetcher.ts +0 -1
  27. package/template/src/api/functional/bbs/articles/index.ts +0 -166
  28. package/template/src/api/functional/bbs/index.ts +0 -7
  29. package/template/src/api/functional/index.ts +0 -7
  30. package/template/src/api/index.ts +0 -4
  31. package/template/src/api/module.ts +0 -5
  32. package/template/src/api/structures/bbs/IBbsArticle.ts +0 -142
  33. package/template/src/api/structures/common/IAttachmentFile.ts +0 -5
  34. package/template/src/api/structures/common/IPage.ts +0 -75
  35. package/template/src/controllers/BbsArticlesController.ts +0 -46
  36. package/template/src/providers/bbs/BbsArticleProvider.ts +0 -217
  37. package/template/src/test/features/api/bbs/test_api_bbs_article_at.ts +0 -52
  38. package/template/src/test/features/api/bbs/test_api_bbs_article_index_search.ts +0 -82
  39. package/template/src/test/features/api/bbs/test_api_bbs_article_index_sort.ts +0 -49
  40. package/template/src/test/features/api/bbs/test_api_bbs_article_store.ts +0 -44
  41. package/template/src/test/features/api/bbs/test_api_bbs_article_update.ts +0 -66
  42. package/template/src/test/index.ts +0 -45
  43. package/template/src/test/internal/DynamicImportIterator.ts +0 -119
  44. package/template/src/test/internal/GaffComparator.ts +0 -48
  45. package/template/src/test/internal/IPointer.ts +0 -3
  46. package/template/src/test/internal/RandomGenerator.ts +0 -72
  47. package/template/src/test/internal/StopWatch.ts +0 -16
  48. package/template/src/test/internal/exception_must_be_thrown.ts +0 -11
  49. package/template/src/test/internal/validate_index.ts +0 -29
  50. package/template/src/test/internal/validate_index_sort.ts +0 -39
  51. package/template/src/utils/ArrayUtil.ts +0 -86
  52. package/template/src/utils/MapUtil.ts +0 -14
  53. package/template/tsconfig.api.json +0 -15
  54. package/template/tsconfig.json +0 -118
@@ -1,217 +0,0 @@
1
- import { ForbiddenException, NotFoundException } from "@nestjs/common";
2
- import { v4 } from "uuid";
3
-
4
- import { IBbsArticle } from "@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle";
5
- import { IPage } from "@ORGANIZATION/PROJECT-api/lib/structures/common/IPage";
6
-
7
- import { MapUtil } from "../../utils/MapUtil";
8
-
9
- /**
10
- * This is a fake provider.
11
- *
12
- * Remove it or change it to be stored on the real DB.
13
- */
14
- export namespace BbsArticleProvider {
15
- export async function index(
16
- section: string,
17
- input: IBbsArticle.IRequest,
18
- ): Promise<IPage<IBbsArticle.ISummary>> {
19
- // GET ENTIRE ARTICLES
20
- const dict = storage.get(section);
21
- if (dict === undefined)
22
- throw new NotFoundException(
23
- `Error on BbsArticleProvider.index(): unable to find the matched section "${section}".`,
24
- );
25
-
26
- /* disable-eslint */
27
- let articles: IBbsArticle[] = Array.from(dict.values()).map(
28
- (rec) => rec.article,
29
- );
30
-
31
- // SEARCH
32
- if (input.search !== undefined) {
33
- if (input.search.writer)
34
- articles = articles.filter(
35
- (x) => x.writer.indexOf(input.search!.writer!) !== -1,
36
- );
37
- if (input.search.title)
38
- articles = articles.filter(
39
- (x) =>
40
- x.contents
41
- .at(-1)!
42
- .title.indexOf(input.search!.title!) !== -1,
43
- );
44
- if (input.search.body)
45
- articles = articles.filter(
46
- (x) =>
47
- x.contents.at(-1)!.body.indexOf(input.search!.body!) !==
48
- -1,
49
- );
50
- }
51
-
52
- // SORT
53
- if (input.sort?.length) {
54
- for (const comp of input.sort.reverse())
55
- articles = articles.sort((x, y) => {
56
- const sign = comp[0];
57
- const column = comp.substring(1);
58
- const closure = () => {
59
- if (column === "created_at")
60
- return (
61
- new Date(x.created_at).getTime() -
62
- new Date(y.created_at).getTime()
63
- );
64
- else if (column === "updated_at")
65
- return (
66
- new Date(
67
- x.contents.at(-1)!.created_at,
68
- ).getTime() -
69
- new Date(
70
- y.contents.at(-1)!.created_at,
71
- ).getTime()
72
- );
73
- else if (column === "writer")
74
- return x.writer.localeCompare(y.writer);
75
- else
76
- return x.contents
77
- .at(-1)!
78
- .title.localeCompare(y.contents.at(-1)!.title);
79
- };
80
- return sign === "+" ? closure() : -closure();
81
- });
82
- } else {
83
- articles.sort(
84
- (a, b) =>
85
- new Date(b.created_at).getTime() -
86
- new Date(a.created_at).getTime(),
87
- );
88
- }
89
-
90
- // PAGINATION
91
- const limit: number = input.limit || 100;
92
- const start: number = ((input.page || 1) - 1) * limit;
93
- return {
94
- pagination: {
95
- page: input.page || 1,
96
- limit: limit,
97
- total_count: articles.length,
98
- total_pages: Math.ceil(articles.length / limit),
99
- },
100
- data: articles.slice(start, start + limit).map((article) => ({
101
- id: article.id,
102
- section: article.section,
103
- writer: article.writer,
104
- title: article.contents.at(-1)!.title,
105
- created_at: article.created_at,
106
- updated_at: article.contents.at(-1)!.created_at,
107
- })),
108
- };
109
- }
110
-
111
- export async function find(
112
- section: string,
113
- id: string,
114
- password?: string,
115
- ): Promise<IBbsArticle> {
116
- const dict = storage.get(section);
117
- if (dict === undefined)
118
- throw new NotFoundException(
119
- `Error on BbsArticleProvider.find(): unable to find the matched section "${section}".`,
120
- );
121
-
122
- const record = dict.get(id);
123
- if (record === undefined)
124
- throw new NotFoundException(
125
- `Error on BbsArticleProvider.find(): unable to find the matched article "${id}".`,
126
- );
127
- else if (password !== undefined && password !== record.password)
128
- throw new ForbiddenException(
129
- `Error on BbsArticleProvider.find(): different password.`,
130
- );
131
- return record.article;
132
- }
133
-
134
- export async function store(
135
- section: string,
136
- input: IBbsArticle.IStore,
137
- ): Promise<IBbsArticle> {
138
- const now: string = datetime_to_string(new Date());
139
- const article: IBbsArticle = {
140
- id: v4(),
141
- section,
142
- writer: input.writer,
143
- contents: [
144
- {
145
- ...{
146
- ...input,
147
- password: undefined,
148
- },
149
- id: v4(),
150
- created_at: now,
151
- },
152
- ],
153
- created_at: now,
154
- };
155
-
156
- const dict: Map<string, IRecord> = MapUtil.take(
157
- storage,
158
- section,
159
- () => new Map(),
160
- );
161
- dict.set(article.id, {
162
- article,
163
- password: input.password,
164
- });
165
-
166
- return article;
167
- }
168
-
169
- export async function update(
170
- section: string,
171
- id: string,
172
- input: IBbsArticle.IUpdate,
173
- ): Promise<IBbsArticle.IContent> {
174
- const article: IBbsArticle = await find(section, id, input.password);
175
- const content: IBbsArticle.IContent = {
176
- ...{
177
- ...input,
178
- password: undefined,
179
- },
180
- id: v4(),
181
- created_at: datetime_to_string(new Date()),
182
- };
183
- article.contents.push(content);
184
- return content;
185
- }
186
- }
187
-
188
- interface IRecord {
189
- article: IBbsArticle;
190
- password: string;
191
- }
192
- const storage: Map<string, Map<string, IRecord>> = new Map();
193
-
194
- function datetime_to_string(date: Date): string {
195
- return (
196
- cipher(4)(date.getFullYear()) +
197
- "-" +
198
- ([
199
- [date.getMonth() + 1, date.getDate()].map(cipher(2)).join("-"),
200
- [date.getHours(), date.getMinutes(), date.getSeconds()]
201
- .map(cipher(2))
202
- .join(":"),
203
- ].join(" ") +
204
- "." +
205
- precision(date.getMilliseconds()))
206
- );
207
- }
208
-
209
- const cipher = (digit: number) => (value: number) => {
210
- const str: string = String(value);
211
- return "0".repeat(digit - str.length) + str;
212
- };
213
-
214
- const precision = (value: number) => {
215
- const str: string = String(value);
216
- return str + "0".repeat(3 - str.length);
217
- };
@@ -1,52 +0,0 @@
1
- import TSON from "typescript-json";
2
- import { v4 } from "uuid";
3
-
4
- import api from "@ORGANIZATION/PROJECT-api/lib/index";
5
- import { IBbsArticle } from "@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle";
6
-
7
- import { exception_must_be_thrown } from "../../../internal/exception_must_be_thrown";
8
-
9
- export async function test_api_bbs_article_at(
10
- connection: api.IConnection,
11
- ): Promise<void> {
12
- // STORE A NEW ARTICLE
13
- const stored: IBbsArticle = await api.functional.bbs.articles.store(
14
- connection,
15
- "general",
16
- {
17
- writer: "Robot",
18
- title: "Hello, world!",
19
- body: "Hello, I'm test automation robot",
20
- format: "txt",
21
- files: [
22
- {
23
- name: "logo",
24
- extension: "png",
25
- url: "https://somewhere.com/logo.png",
26
- },
27
- ],
28
- password: "1234",
29
- },
30
- );
31
- TSON.assertEquals(stored);
32
-
33
- // READ IT
34
- const read: IBbsArticle = await api.functional.bbs.articles.at(
35
- connection,
36
- stored.section,
37
- stored.id,
38
- );
39
- TSON.assertEquals(read);
40
-
41
- // CHECK EQUALITY
42
- if (api.Primitive.equal_to(stored, read) === false)
43
- throw new Error("Bug on BbsArticleProvider.at(): different data.");
44
-
45
- // TRY 404 ERRORS
46
- await exception_must_be_thrown("wrong section", () =>
47
- api.functional.bbs.articles.at(connection, v4(), stored.id),
48
- );
49
- await exception_must_be_thrown("wrong id", () =>
50
- api.functional.bbs.articles.at(connection, stored.section, v4()),
51
- );
52
- }
@@ -1,82 +0,0 @@
1
- import TSON from "typescript-json";
2
-
3
- import api from "@ORGANIZATION/PROJECT-api/lib/index";
4
- import { IBbsArticle } from "@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle";
5
- import { IPage } from "@ORGANIZATION/PROJECT-api/lib/structures/common/IPage";
6
-
7
- import { ArrayUtil } from "../../../../utils/ArrayUtil";
8
- import { RandomGenerator } from "../../../internal/RandomGenerator";
9
- import { validate_index } from "../../../internal/validate_index";
10
-
11
- export async function test_api_bbs_article_index_search(
12
- connection: api.IConnection,
13
- ): Promise<void> {
14
- // GENERATE 100 ARTICLES
15
- const section: string = "general";
16
- const articles: IBbsArticle[] = await ArrayUtil.asyncRepeat(100, () =>
17
- api.functional.bbs.articles.store(connection, section, {
18
- writer: RandomGenerator.name(),
19
- title: RandomGenerator.paragraph(),
20
- body: RandomGenerator.content(),
21
- format: "txt",
22
- files: [],
23
- password: RandomGenerator.alphabets(8),
24
- }),
25
- );
26
- TSON.assertEquals(articles);
27
-
28
- // DO SEARCH
29
- const validator = search(connection, articles);
30
- await validator(
31
- "writer",
32
- (x) => x.writer,
33
- (elem, word) => elem.writer.indexOf(word) !== -1,
34
- );
35
- await validator(
36
- "title",
37
- (x) => x.contents.at(-1)!.title,
38
- (elem, word) => elem.contents.at(-1)!.title.indexOf(word) !== -1,
39
- );
40
- await validator(
41
- "body",
42
- (x) => x.contents.at(-1)!.body,
43
- (elem, word) => elem.contents.at(-1)!.body.indexOf(word) !== -1,
44
- );
45
- }
46
-
47
- const search =
48
- (connection: api.IConnection, total: IBbsArticle[]) =>
49
- async (
50
- field: string,
51
- getter: (
52
- record: IBbsArticle,
53
- input: IBbsArticle.IRequest.ISearch,
54
- ) => string,
55
- filter: (record: IBbsArticle, word: string) => boolean,
56
- ): Promise<void> => {
57
- const input: IBbsArticle.IRequest = {
58
- limit: total.length,
59
- search: {},
60
- };
61
- const value: string = getter(
62
- RandomGenerator.pick(total),
63
- input.search!,
64
- );
65
- const matched: IBbsArticle[] = total.filter((elem) =>
66
- filter(elem, value),
67
- );
68
-
69
- const page: IPage<IBbsArticle.ISummary> =
70
- await api.functional.bbs.articles.index(
71
- connection,
72
- "general",
73
- input,
74
- );
75
- TSON.assertEquals(page);
76
-
77
- validate_index(
78
- `BbsArticleProvider.index() with ${field} searching`,
79
- matched,
80
- page.data,
81
- );
82
- };
@@ -1,49 +0,0 @@
1
- import TSON from "typescript-json";
2
-
3
- import api from "@ORGANIZATION/PROJECT-api/lib/index";
4
- import { IBbsArticle } from "@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle";
5
-
6
- import { ArrayUtil } from "../../../../utils/ArrayUtil";
7
- import { GaffComparator } from "../../../internal/GaffComparator";
8
- import { RandomGenerator } from "../../../internal/RandomGenerator";
9
- import { validate_index_sort } from "../../../internal/validate_index_sort";
10
-
11
- export async function test_api_bbs_article_index_sort(
12
- connection: api.IConnection,
13
- ): Promise<void> {
14
- // GENERATE 100 ARTICLES
15
- const section: string = "general";
16
- const articles: IBbsArticle[] = await ArrayUtil.asyncRepeat(100, () =>
17
- api.functional.bbs.articles.store(connection, section, {
18
- writer: RandomGenerator.name(),
19
- title: RandomGenerator.paragraph(),
20
- body: RandomGenerator.content(),
21
- format: "txt",
22
- files: [],
23
- password: RandomGenerator.alphabets(8),
24
- }),
25
- );
26
- TSON.assertEquals(articles);
27
-
28
- // PREPARE VALIDATOR
29
- const validator = validate_index_sort("BbsArticleProvider.idex()")(
30
- (input: IBbsArticle.IRequest) =>
31
- api.functional.bbs.articles.index(connection, section, input),
32
- );
33
-
34
- // DO VALIDATE
35
- const components = [
36
- validator("created_at")(GaffComparator.dates((x) => x.created_at)),
37
- validator("updated_at")(GaffComparator.dates((x) => x.updated_at)),
38
- validator("title")(GaffComparator.strings((x) => x.title)),
39
- validator("writer")(GaffComparator.strings((x) => x.writer)),
40
- validator(
41
- "writer",
42
- "title",
43
- )(GaffComparator.strings((x) => [x.writer, x.title])),
44
- ];
45
- for (const comp of components) {
46
- await comp("+");
47
- await comp("-");
48
- }
49
- }
@@ -1,44 +0,0 @@
1
- import TSON from "typescript-json";
2
- import { v4 } from "uuid";
3
-
4
- import api from "@ORGANIZATION/PROJECT-api/lib/index";
5
- import { IBbsArticle } from "@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle";
6
-
7
- import { RandomGenerator } from "../../../internal/RandomGenerator";
8
-
9
- export async function test_api_bbs_article_store(
10
- connection: api.IConnection,
11
- ): Promise<void> {
12
- // STORE A NEW ARTICLE
13
- const stored: IBbsArticle = await api.functional.bbs.articles.store(
14
- connection,
15
- "general",
16
- {
17
- writer: RandomGenerator.name(),
18
- title: RandomGenerator.paragraph(),
19
- body: RandomGenerator.content(),
20
- format: "txt",
21
- files: [
22
- {
23
- name: "logo",
24
- extension: "png",
25
- url: "https://somewhere.com/logo.png",
26
- },
27
- ],
28
- password: v4(),
29
- },
30
- );
31
- TSON.assertEquals(stored);
32
-
33
- // READ THE DATA AGAIN
34
- const read: IBbsArticle = await api.functional.bbs.articles.at(
35
- connection,
36
- stored.section,
37
- stored.id,
38
- );
39
- TSON.assertEquals(read);
40
-
41
- // CHECK EXISTENCE
42
- if (read.id !== stored.id)
43
- throw new Error("Bug on BbsArticleProvider.store(): failed to store.");
44
- }
@@ -1,66 +0,0 @@
1
- import TSON from "typescript-json";
2
- import { v4 } from "uuid";
3
-
4
- import api from "@ORGANIZATION/PROJECT-api/lib/index";
5
- import { IBbsArticle } from "@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle";
6
-
7
- import { RandomGenerator } from "../../../internal/RandomGenerator";
8
- import { exception_must_be_thrown } from "../../../internal/exception_must_be_thrown";
9
-
10
- export async function test_api_bbs_article_update(
11
- connection: api.IConnection,
12
- ): Promise<void> {
13
- // STORE A NEW ARTICLE
14
- const password: string = v4();
15
- const article: IBbsArticle = await api.functional.bbs.articles.store(
16
- connection,
17
- "general",
18
- {
19
- writer: RandomGenerator.name(),
20
- title: RandomGenerator.paragraph(),
21
- body: RandomGenerator.content(),
22
- format: "txt",
23
- files: [
24
- {
25
- name: "logo",
26
- extension: "png",
27
- url: "https://somewhere.com/logo.png",
28
- },
29
- ],
30
- password,
31
- },
32
- );
33
- TSON.assertEquals(article);
34
-
35
- // UPDATE WITH EXACT PASSWORD
36
- const content: IBbsArticle.IContent =
37
- await api.functional.bbs.articles.update(
38
- connection,
39
- article.section,
40
- article.id,
41
- {
42
- title: RandomGenerator.paragraph(),
43
- body: RandomGenerator.content(),
44
- format: "txt",
45
- files: [],
46
- password,
47
- },
48
- );
49
- article.contents.push(TSON.assertEquals(content));
50
-
51
- // TRY UPDATE WITH WRONG PASSWORD
52
- await exception_must_be_thrown("update with wrong password", () =>
53
- api.functional.bbs.articles.update(
54
- connection,
55
- article.section,
56
- article.id,
57
- {
58
- title: RandomGenerator.paragraph(),
59
- body: RandomGenerator.content(),
60
- format: "txt",
61
- files: [],
62
- password: v4(),
63
- },
64
- ),
65
- );
66
- }
@@ -1,45 +0,0 @@
1
- import { sleep_for } from "tstl/thread/global";
2
-
3
- import api from "@ORGANIZATION/PROJECT-api";
4
-
5
- import { Backend } from "../Backend";
6
- import { Configuration } from "../Configuration";
7
- import { DynamicImportIterator } from "./internal/DynamicImportIterator";
8
-
9
- async function main(): Promise<void> {
10
- // BACKEND SERVER
11
- const backend: Backend = new Backend();
12
- await backend.open();
13
-
14
- //----
15
- // CLINET CONNECTOR
16
- //----
17
- // DO TEST
18
- const connection: api.IConnection = {
19
- host: `http://127.0.0.1:${await Configuration.API_PORT()}`,
20
- encryption: await Configuration.ENCRYPTION_PASSWORD(),
21
- };
22
- const exceptions: Error[] = await DynamicImportIterator.force(
23
- __dirname + "/features",
24
- {
25
- prefix: "test",
26
- parameters: () => [connection],
27
- },
28
- );
29
-
30
- // WAIT FOR A WHILE FOR THE EVENTS
31
- await sleep_for(2500);
32
-
33
- // TERMINATE
34
- await backend.close();
35
-
36
- if (exceptions.length === 0) console.log("Success");
37
- else {
38
- for (const exp of exceptions) console.log(exp);
39
- process.exit(-1);
40
- }
41
- }
42
- main().catch((exp) => {
43
- console.log(exp);
44
- process.exit(-1);
45
- });
@@ -1,119 +0,0 @@
1
- import chalk from "chalk";
2
- import cli from "cli";
3
- import fs from "fs";
4
-
5
- import { IPointer } from "./IPointer";
6
- import { StopWatch } from "./StopWatch";
7
-
8
- const EXTENSION = __filename.substr(-2);
9
- if (EXTENSION === "js") require("source-map-support/register");
10
-
11
- interface ICommand {
12
- include?: string;
13
- exclude?: string;
14
- }
15
-
16
- export namespace DynamicImportIterator {
17
- export type Closure<Arguments extends any[], Ret = any> = (
18
- ...args: Arguments
19
- ) => Promise<Ret>;
20
- type Module<Arguments extends any[]> = {
21
- [key: string]: Closure<Arguments>;
22
- };
23
-
24
- export interface IOptions<Parameters extends any[], Ret = any> {
25
- prefix: string;
26
- parameters: (name: string) => Parameters;
27
- wrapper?: (
28
- name: string,
29
- closure: Closure<Parameters, Ret>,
30
- ) => Promise<any>;
31
- counter?: IPointer<number>;
32
- showElapsedTime?: boolean;
33
- }
34
-
35
- export async function main<Arguments extends any[]>(
36
- path: string,
37
- options: IOptions<Arguments>,
38
- ): Promise<void> {
39
- const command: ICommand = cli.parse();
40
- await iterate(options, command, path);
41
- }
42
-
43
- export async function force<Arguments extends any[]>(
44
- path: string,
45
- options: IOptions<Arguments>,
46
- ): Promise<Error[]> {
47
- const command: ICommand = cli.parse();
48
- const exceptions: Error[] = [];
49
-
50
- await iterate(options, command, path, exceptions);
51
- return exceptions;
52
- }
53
-
54
- async function iterate<Arguments extends any[]>(
55
- options: IOptions<Arguments>,
56
- command: ICommand,
57
- path: string,
58
- exceptions?: Error[],
59
- ): Promise<void> {
60
- const directory: string[] = await fs.promises.readdir(path);
61
- for (const file of directory) {
62
- const current: string = `${path}/${file}`;
63
- const stats: fs.Stats = await fs.promises.lstat(current);
64
-
65
- if (stats.isDirectory() === true) {
66
- await iterate(options, command, current, exceptions);
67
- continue;
68
- } else if (file.substr(-3) !== `.${EXTENSION}`) continue;
69
-
70
- const external: Module<Arguments> = await import(current);
71
- await execute(options, command, external, exceptions);
72
- }
73
- }
74
-
75
- async function execute<Arguments extends any[]>(
76
- options: IOptions<Arguments>,
77
- command: ICommand,
78
- external: Module<Arguments>,
79
- exceptions?: Error[],
80
- ): Promise<void> {
81
- for (const key in external) {
82
- if (command.exclude && key.indexOf(command.exclude) !== -1)
83
- continue;
84
- else if (command.include && key.indexOf(command.include) === -1)
85
- continue;
86
- else if (key.substr(0, options.prefix.length) !== options.prefix)
87
- continue;
88
- else if (!(external[key] instanceof Function)) continue;
89
-
90
- const closure: Closure<Arguments> = external[key];
91
- const func = async () => {
92
- if (options.wrapper !== undefined)
93
- await options.wrapper(key, closure);
94
- else await closure(...options.parameters(key));
95
- };
96
- const label: string = chalk.greenBright(key);
97
- try {
98
- if (options.counter) ++options.counter.value;
99
- if (options.showElapsedTime === false) {
100
- await func();
101
- console.log(` - ${label}`);
102
- } else {
103
- const time: number = await StopWatch.measure(func);
104
- console.log(
105
- ` - ${label}: ${chalk.yellowBright(
106
- time.toLocaleString(),
107
- )} ms`,
108
- );
109
- }
110
- } catch (exp) {
111
- if (!(exp instanceof Error)) return;
112
-
113
- console.log(` - ${label} -> ${chalk.redBright(exp.name)}`);
114
- if (exceptions !== undefined) exceptions.push(exp);
115
- else throw exp;
116
- }
117
- }
118
- }
119
- }