@nestia/sdk 1.1.0 → 1.2.0-dev.20230504
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/assets/bundle/api/index.ts +4 -0
- package/assets/bundle/api/module.ts +5 -0
- package/assets/bundle/e2e/index.ts +41 -0
- package/lib/INestiaConfig.d.ts +6 -0
- package/lib/NestiaSdkApplication.d.ts +1 -0
- package/lib/NestiaSdkApplication.js +35 -14
- package/lib/NestiaSdkApplication.js.map +1 -1
- package/lib/analyses/ControllerAnalyzer.js +1 -0
- package/lib/analyses/ControllerAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectAnalyzer.js +14 -2
- package/lib/analyses/ReflectAnalyzer.js.map +1 -1
- package/lib/executable/internal/NestiaSdkCommand.d.ts +3 -2
- package/lib/executable/internal/NestiaSdkCommand.js +53 -57
- package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
- package/lib/executable/internal/NestiaSdkConfig.js +23 -50
- package/lib/executable/internal/NestiaSdkConfig.js.map +1 -1
- package/lib/executable/sdk.js +5 -8
- package/lib/executable/sdk.js.map +1 -1
- package/lib/generates/E2eGenerator.d.ts +5 -0
- package/lib/generates/E2eGenerator.js +52 -0
- package/lib/generates/E2eGenerator.js.map +1 -0
- package/lib/generates/SdkGenerator.d.ts +1 -2
- package/lib/generates/SdkGenerator.js +20 -22
- package/lib/generates/SdkGenerator.js.map +1 -1
- package/lib/generates/SwaggerGenerator.d.ts +1 -1
- package/lib/generates/SwaggerGenerator.js +40 -43
- package/lib/generates/SwaggerGenerator.js.map +1 -1
- package/lib/generates/internal/E2eFileProgrammer.d.ts +8 -0
- package/lib/generates/internal/E2eFileProgrammer.js +101 -0
- package/lib/generates/internal/E2eFileProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkFileProgrammer.d.ts +5 -0
- package/lib/generates/internal/SdkFileProgrammer.js +121 -0
- package/lib/generates/internal/SdkFileProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkFunctionProgrammer.d.ts +5 -0
- package/lib/generates/{FunctionGenerator.js → internal/SdkFunctionProgrammer.js} +58 -57
- package/lib/generates/internal/SdkFunctionProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkRouteDirectory.d.ts +10 -0
- package/lib/generates/internal/SdkRouteDirectory.js +18 -0
- package/lib/generates/internal/SdkRouteDirectory.js.map +1 -0
- package/lib/structures/IController.d.ts +4 -0
- package/lib/structures/IRoute.d.ts +4 -0
- package/lib/utils/NestiaConfigUtil.d.ts +4 -0
- package/lib/utils/NestiaConfigUtil.js +24 -0
- package/lib/utils/NestiaConfigUtil.js.map +1 -0
- package/lib/utils/SourceFinder.d.ts +9 -0
- package/lib/utils/SourceFinder.js +60 -0
- package/lib/utils/SourceFinder.js.map +1 -0
- package/package.json +6 -10
- package/src/INestiaConfig.ts +7 -0
- package/src/NestiaSdkApplication.ts +54 -17
- package/src/analyses/ControllerAnalyzer.ts +1 -0
- package/src/analyses/ReflectAnalyzer.ts +14 -2
- package/src/executable/internal/NestiaSdkCommand.ts +87 -105
- package/src/executable/sdk.ts +4 -8
- package/src/generates/E2eGenerator.ts +65 -0
- package/src/generates/SdkGenerator.ts +29 -30
- package/src/generates/SwaggerGenerator.ts +66 -64
- package/src/generates/internal/E2eFileProgrammer.ts +119 -0
- package/src/generates/internal/SdkFileProgrammer.ts +144 -0
- package/src/generates/internal/SdkFunctionProgrammer.ts +371 -0
- package/src/generates/internal/SdkRouteDirectory.ts +21 -0
- package/src/structures/IController.ts +4 -0
- package/src/structures/IRoute.ts +4 -0
- package/src/utils/NestiaConfigUtil.ts +21 -0
- package/src/utils/SourceFinder.ts +60 -0
- package/lib/analyses/SourceFinder.d.ts +0 -4
- package/lib/analyses/SourceFinder.js +0 -71
- package/lib/analyses/SourceFinder.js.map +0 -1
- package/lib/generates/FileGenerator.d.ts +0 -5
- package/lib/generates/FileGenerator.js +0 -138
- package/lib/generates/FileGenerator.js.map +0 -1
- package/lib/generates/FunctionGenerator.d.ts +0 -5
- package/lib/generates/FunctionGenerator.js.map +0 -1
- package/src/analyses/SourceFinder.ts +0 -59
- package/src/generates/FileGenerator.ts +0 -156
- package/src/generates/FunctionGenerator.ts +0 -348
- /package/assets/bundle/{HttpError.ts → api/HttpError.ts} +0 -0
- /package/assets/bundle/{IConnection.ts → api/IConnection.ts} +0 -0
- /package/assets/bundle/{Primitive.ts → api/Primitive.ts} +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.SourceFinder = void 0;
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const glob_1 = __importDefault(require("glob"));
|
|
18
|
+
const path_1 = __importDefault(require("path"));
|
|
19
|
+
var SourceFinder;
|
|
20
|
+
(function (SourceFinder) {
|
|
21
|
+
SourceFinder.find = (props) => __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
var _a;
|
|
23
|
+
const dict = new Set();
|
|
24
|
+
yield emplace(props.filter)(props.include)((str) => dict.add(str));
|
|
25
|
+
if ((_a = props.exclude) === null || _a === void 0 ? void 0 : _a.length)
|
|
26
|
+
yield emplace(props.filter)(props.exclude)((str) => dict.delete(str));
|
|
27
|
+
return [...dict];
|
|
28
|
+
});
|
|
29
|
+
const emplace = (filter) => (input) => (closure) => __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
for (const pattern of input) {
|
|
31
|
+
for (const file of yield _Glob(path_1.default.resolve(pattern))) {
|
|
32
|
+
const stats = yield fs_1.default.promises.stat(file);
|
|
33
|
+
if (stats.isDirectory() === true)
|
|
34
|
+
yield iterate(filter)(closure)(file);
|
|
35
|
+
else if (stats.isFile() && filter(file))
|
|
36
|
+
closure(file);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const iterate = (filter) => (closure) => (location) => __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
const directory = yield fs_1.default.promises.readdir(location);
|
|
42
|
+
for (const file of directory) {
|
|
43
|
+
const next = path_1.default.resolve(`${location}/${file}`);
|
|
44
|
+
const stats = yield fs_1.default.promises.stat(next);
|
|
45
|
+
if (stats.isDirectory() === true)
|
|
46
|
+
yield iterate(filter)(closure)(next);
|
|
47
|
+
else if (stats.isFile() && filter(next))
|
|
48
|
+
closure(next);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
const _Glob = (pattern) => new Promise((resolve, reject) => {
|
|
52
|
+
(0, glob_1.default)(pattern, (err, matches) => {
|
|
53
|
+
if (err)
|
|
54
|
+
reject(err);
|
|
55
|
+
else
|
|
56
|
+
resolve(matches.map((str) => path_1.default.resolve(str)));
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
})(SourceFinder = exports.SourceFinder || (exports.SourceFinder = {}));
|
|
60
|
+
//# sourceMappingURL=SourceFinder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SourceFinder.js","sourceRoot":"","sources":["../../src/utils/SourceFinder.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestia/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-dev.20230504",
|
|
4
4
|
"description": "Nestia SDK and Swagger generator",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -11,11 +11,10 @@
|
|
|
11
11
|
"build": "rimraf lib && tsc",
|
|
12
12
|
"dev": "rimraf lib && tsc --watch",
|
|
13
13
|
"eslint": "eslint ./**/*.ts",
|
|
14
|
-
"package:latest": "npm run build && npm
|
|
14
|
+
"package:latest": "npm run build && npm publish --access public",
|
|
15
15
|
"package:next": "npm run package:latest -- --tag next",
|
|
16
16
|
"prepare": "ts-patch install",
|
|
17
|
-
"prettier": "prettier --write ./**/*.ts"
|
|
18
|
-
"test": "node lib/test"
|
|
17
|
+
"prettier": "prettier --write ./**/*.ts"
|
|
19
18
|
},
|
|
20
19
|
"repository": {
|
|
21
20
|
"type": "git",
|
|
@@ -43,7 +42,7 @@
|
|
|
43
42
|
"tsconfck": "^2.0.1",
|
|
44
43
|
"tsconfig-paths": "^4.1.1",
|
|
45
44
|
"tstl": "^2.5.13",
|
|
46
|
-
"typia": "^3.8.
|
|
45
|
+
"typia": "^3.8.4"
|
|
47
46
|
},
|
|
48
47
|
"peerDependencies": {
|
|
49
48
|
"@nestjs/common": ">= 7.0.1",
|
|
@@ -53,7 +52,6 @@
|
|
|
53
52
|
"typescript": ">= 4.5.2"
|
|
54
53
|
},
|
|
55
54
|
"devDependencies": {
|
|
56
|
-
"@nestia/core": "^1.1.0",
|
|
57
55
|
"@nestia/fetcher": "^1.1.2",
|
|
58
56
|
"@trivago/prettier-plugin-sort-imports": "^4.0.0",
|
|
59
57
|
"@types/cli": "^0.11.21",
|
|
@@ -69,8 +67,8 @@
|
|
|
69
67
|
"prettier": "^2.8.1",
|
|
70
68
|
"rimraf": "^3.0.2",
|
|
71
69
|
"ts-node": "^10.9.1",
|
|
72
|
-
"ts-patch": "
|
|
73
|
-
"typescript": "^
|
|
70
|
+
"ts-patch": "v2.1.0",
|
|
71
|
+
"typescript": "^4.9.5",
|
|
74
72
|
"typescript-transform-paths": "^3.4.4",
|
|
75
73
|
"uuid": "^9.0.0"
|
|
76
74
|
},
|
|
@@ -78,8 +76,6 @@
|
|
|
78
76
|
"assets",
|
|
79
77
|
"lib",
|
|
80
78
|
"src",
|
|
81
|
-
"!lib/test",
|
|
82
|
-
"!src/test",
|
|
83
79
|
"README.md",
|
|
84
80
|
"LICENSE",
|
|
85
81
|
"package.json"
|
package/src/INestiaConfig.ts
CHANGED
|
@@ -21,6 +21,13 @@ export interface INestiaConfig {
|
|
|
21
21
|
*/
|
|
22
22
|
output?: string;
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Otput directory that e2e test codes would be placed in.
|
|
26
|
+
*
|
|
27
|
+
* If not configured, you can't generate e2e test functions.
|
|
28
|
+
*/
|
|
29
|
+
e2e?: string;
|
|
30
|
+
|
|
24
31
|
/**
|
|
25
32
|
* Compiler options for the TypeScript.
|
|
26
33
|
*
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import * as runner from "ts-node";
|
|
4
|
-
import { Singleton } from "tstl
|
|
5
|
-
import { Pair } from "tstl/utility/Pair";
|
|
4
|
+
import { Pair, Singleton } from "tstl";
|
|
6
5
|
import ts from "typescript";
|
|
7
6
|
|
|
8
7
|
import { INestiaConfig } from "./INestiaConfig";
|
|
9
8
|
import { ControllerAnalyzer } from "./analyses/ControllerAnalyzer";
|
|
10
9
|
import { ReflectAnalyzer } from "./analyses/ReflectAnalyzer";
|
|
11
|
-
import { SourceFinder } from "./analyses/SourceFinder";
|
|
12
10
|
import { NestiaConfigCompilerOptions } from "./executable/internal/NestiaConfigCompilerOptions";
|
|
11
|
+
import { E2eGenerator } from "./generates/E2eGenerator";
|
|
13
12
|
import { SdkGenerator } from "./generates/SdkGenerator";
|
|
14
13
|
import { SwaggerGenerator } from "./generates/SwaggerGenerator";
|
|
15
14
|
import { IController } from "./structures/IController";
|
|
16
15
|
import { IRoute } from "./structures/IRoute";
|
|
17
16
|
import { ArrayUtil } from "./utils/ArrayUtil";
|
|
17
|
+
import { NestiaConfigUtil } from "./utils/NestiaConfigUtil";
|
|
18
|
+
import { SourceFinder } from "./utils/SourceFinder";
|
|
18
19
|
|
|
19
20
|
export class NestiaSdkApplication {
|
|
20
21
|
private readonly config_: INestiaConfig;
|
|
@@ -57,6 +58,39 @@ export class NestiaSdkApplication {
|
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
public async e2e(): Promise<void> {
|
|
62
|
+
if (!this.config_.output)
|
|
63
|
+
throw new Error(
|
|
64
|
+
"Error on NestiaApplication.e2e(): output path of SDK is not specified.",
|
|
65
|
+
);
|
|
66
|
+
else if (!this.config_.e2e)
|
|
67
|
+
throw new Error(
|
|
68
|
+
"Error on NestiaApplication.e2e(): output path of e2e test files is not specified.",
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const validate =
|
|
72
|
+
(title: string) =>
|
|
73
|
+
async (location: string): Promise<void> => {
|
|
74
|
+
const parent: string = path.resolve(location + "/..");
|
|
75
|
+
const stats: fs.Stats = await fs.promises.lstat(parent);
|
|
76
|
+
if (stats.isDirectory() === false)
|
|
77
|
+
throw new Error(
|
|
78
|
+
`Error on NestiaApplication.e2e(): output directory of ${title} does not exists.`,
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
await validate("sdk")(this.config_.output);
|
|
82
|
+
await validate("e2e")(this.config_.e2e);
|
|
83
|
+
|
|
84
|
+
await this.generate(
|
|
85
|
+
(config) => config,
|
|
86
|
+
() => SdkGenerator.generate,
|
|
87
|
+
);
|
|
88
|
+
await this.generate(
|
|
89
|
+
(config) => config,
|
|
90
|
+
() => E2eGenerator.generate,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
60
94
|
public async sdk(): Promise<void> {
|
|
61
95
|
if (!this.config_.output)
|
|
62
96
|
throw new Error(
|
|
@@ -69,12 +103,14 @@ export class NestiaSdkApplication {
|
|
|
69
103
|
throw new Error(
|
|
70
104
|
"Error on NestiaApplication.sdk(): output directory does not exists.",
|
|
71
105
|
);
|
|
72
|
-
|
|
73
|
-
|
|
106
|
+
await this.generate(
|
|
107
|
+
(config) => config,
|
|
108
|
+
() => SdkGenerator.generate,
|
|
109
|
+
);
|
|
74
110
|
}
|
|
75
111
|
|
|
76
112
|
public async swagger(): Promise<void> {
|
|
77
|
-
if (!this.config_.swagger
|
|
113
|
+
if (!this.config_.swagger?.output)
|
|
78
114
|
throw new Error(
|
|
79
115
|
`Error on NestiaApplication.swagger(): output path of the "swagger.json" is not specified.`,
|
|
80
116
|
);
|
|
@@ -99,22 +135,23 @@ export class NestiaSdkApplication {
|
|
|
99
135
|
config: (entire: INestiaConfig) => Config,
|
|
100
136
|
archiver: (
|
|
101
137
|
checker: ts.TypeChecker,
|
|
102
|
-
|
|
103
|
-
routes: IRoute[],
|
|
104
|
-
) => Promise<void>,
|
|
138
|
+
) => (config: Config) => (routes: IRoute[]) => Promise<void>,
|
|
105
139
|
): Promise<void> {
|
|
106
140
|
// MOUNT TS-NODE
|
|
107
141
|
this.prepare();
|
|
108
142
|
|
|
109
143
|
// LOAD CONTROLLER FILES
|
|
110
|
-
const input: INestiaConfig.IInput =
|
|
111
|
-
this.config_.input
|
|
112
|
-
|
|
113
|
-
: typeof this.config_.input === "string"
|
|
114
|
-
? { include: [this.config_.input] }
|
|
115
|
-
: this.config_.input;
|
|
144
|
+
const input: INestiaConfig.IInput = NestiaConfigUtil.input(
|
|
145
|
+
this.config_.input,
|
|
146
|
+
);
|
|
116
147
|
const fileList: string[] = await ArrayUtil.asyncFilter(
|
|
117
|
-
await SourceFinder.find(
|
|
148
|
+
await SourceFinder.find({
|
|
149
|
+
include: input.include,
|
|
150
|
+
exclude: input.exclude,
|
|
151
|
+
filter: (file) =>
|
|
152
|
+
file.substring(file.length - 3) === ".ts" &&
|
|
153
|
+
file.substring(file.length - 5) !== ".d.ts",
|
|
154
|
+
}),
|
|
118
155
|
(file) => this.is_not_excluded(file),
|
|
119
156
|
);
|
|
120
157
|
|
|
@@ -147,7 +184,7 @@ export class NestiaSdkApplication {
|
|
|
147
184
|
}
|
|
148
185
|
|
|
149
186
|
// DO GENERATE
|
|
150
|
-
await archiver(checker
|
|
187
|
+
await archiver(checker)(config(this.config_))(routeList);
|
|
151
188
|
}
|
|
152
189
|
|
|
153
190
|
private prepare(): void {
|
|
@@ -6,6 +6,8 @@ import { ParamCategory } from "../structures/ParamCategory";
|
|
|
6
6
|
import { ArrayUtil } from "../utils/ArrayUtil";
|
|
7
7
|
import { PathAnalyzer } from "./PathAnalyzer";
|
|
8
8
|
|
|
9
|
+
declare const Reflect: any;
|
|
10
|
+
|
|
9
11
|
type IModule = {
|
|
10
12
|
[key: string]: any;
|
|
11
13
|
};
|
|
@@ -248,15 +250,25 @@ export namespace ReflectAnalyzer {
|
|
|
248
250
|
field: param.data,
|
|
249
251
|
encrypted: param.factory.name === "EncryptedBody",
|
|
250
252
|
};
|
|
251
|
-
} else if (param.factory.name === "TypedParam")
|
|
253
|
+
} else if (param.factory.name === "TypedParam") {
|
|
252
254
|
return {
|
|
253
255
|
name: param.name,
|
|
254
256
|
category: "param",
|
|
255
257
|
index: param.index,
|
|
256
258
|
field: param.data,
|
|
257
259
|
encrypted: false,
|
|
260
|
+
meta: (() => {
|
|
261
|
+
const type = (param.factory as any).type;
|
|
262
|
+
const nullable = (param.factory as any).nullable;
|
|
263
|
+
if (type !== undefined && nullable !== undefined)
|
|
264
|
+
return {
|
|
265
|
+
type,
|
|
266
|
+
nullable,
|
|
267
|
+
};
|
|
268
|
+
return undefined;
|
|
269
|
+
})(),
|
|
258
270
|
};
|
|
259
|
-
else if (param.factory.name === "TypedQuery")
|
|
271
|
+
} else if (param.factory.name === "TypedQuery")
|
|
260
272
|
return {
|
|
261
273
|
name: param.name,
|
|
262
274
|
category: "query",
|
|
@@ -11,99 +11,83 @@ import { NestiaSdkConfig } from "./NestiaSdkConfig";
|
|
|
11
11
|
interface ICommand {
|
|
12
12
|
exclude: string | null;
|
|
13
13
|
out: string | null;
|
|
14
|
+
e2e: string | null;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
interface
|
|
17
|
+
interface IProps {
|
|
17
18
|
assign: (config: INestiaConfig, output: string) => void;
|
|
18
19
|
validate: (config: INestiaConfig) => boolean;
|
|
19
20
|
location: (config: INestiaConfig) => string;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export namespace NestiaSdkCommand {
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
export const sdk = (argv: string[]) =>
|
|
25
|
+
main({
|
|
26
|
+
assign: (config, output) => (config.output = output),
|
|
27
|
+
validate: (config) => !!config.output,
|
|
28
|
+
location: (config) => config.output!,
|
|
29
|
+
})(argv)((app) => app.sdk());
|
|
30
|
+
|
|
31
|
+
export const swagger = (argv: string[]) =>
|
|
32
|
+
main({
|
|
33
|
+
assign: (config, output) => {
|
|
34
|
+
if (!config.swagger) config.swagger = { output };
|
|
35
|
+
else config.swagger.output = output;
|
|
33
36
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
cli.setArgv([
|
|
67
|
-
process.argv[0],
|
|
68
|
-
process.argv[1],
|
|
69
|
-
"nestia",
|
|
70
|
-
...elements,
|
|
71
|
-
]);
|
|
72
|
-
const command: ICommand = cli.parse({
|
|
73
|
-
exclude: ["e", "Something to exclude", "string", null],
|
|
74
|
-
out: ["o", "Output path of the SDK files", "string", null],
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
const inputs: string[] = [];
|
|
78
|
-
for (const arg of elements) {
|
|
79
|
-
if (arg[0] === "-") break;
|
|
80
|
-
inputs.push(arg);
|
|
81
|
-
}
|
|
82
|
-
await generate(task, inputs, command, output);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async function generate(
|
|
86
|
-
task: (app: NestiaSdkApplication) => Promise<void>,
|
|
87
|
-
include: string[],
|
|
88
|
-
command: ICommand,
|
|
89
|
-
output: IOutput,
|
|
90
|
-
): Promise<void> {
|
|
91
|
-
// CONFIGURATION
|
|
92
|
-
const config: INestiaConfig =
|
|
93
|
-
(await get_nestia_config(output.validate)) ??
|
|
94
|
-
parse_cli(include, command, output);
|
|
95
|
-
|
|
96
|
-
const options = await get_typescript_options();
|
|
97
|
-
|
|
98
|
-
config.compilerOptions = {
|
|
99
|
-
...options,
|
|
100
|
-
...(config.compilerOptions || {}),
|
|
37
|
+
validate: (config) => !!config.swagger && !!config.swagger.output,
|
|
38
|
+
location: (config) => config.swagger!.output!,
|
|
39
|
+
})(argv)((app) => app.swagger());
|
|
40
|
+
|
|
41
|
+
export const e2e = (argv: string[]) =>
|
|
42
|
+
main({
|
|
43
|
+
assign: (config, output) => (config.output = output),
|
|
44
|
+
validate: (config) => !!config.output,
|
|
45
|
+
location: (config) => config.output!,
|
|
46
|
+
})(argv)((app) => app.sdk());
|
|
47
|
+
|
|
48
|
+
const main =
|
|
49
|
+
(props: IProps) =>
|
|
50
|
+
(argv: string[]) =>
|
|
51
|
+
async (task: (app: NestiaSdkApplication) => Promise<void>) => {
|
|
52
|
+
const command: ICommand = cli.parse({
|
|
53
|
+
exclude: ["e", "Something to exclude", "string", null],
|
|
54
|
+
out: ["o", "Output path of the SDK files", "string", null],
|
|
55
|
+
e2e: [
|
|
56
|
+
"e",
|
|
57
|
+
"Output path of e2e test function files",
|
|
58
|
+
"string",
|
|
59
|
+
null,
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const inputs: string[] = [];
|
|
64
|
+
for (const r of argv) {
|
|
65
|
+
if (r[0] === "-") break;
|
|
66
|
+
inputs.push(r);
|
|
67
|
+
}
|
|
68
|
+
await generate(props)(command)(inputs)(task);
|
|
101
69
|
};
|
|
102
70
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
71
|
+
const generate =
|
|
72
|
+
(props: IProps) =>
|
|
73
|
+
(command: ICommand) =>
|
|
74
|
+
(include: string[]) =>
|
|
75
|
+
async (task: (app: NestiaSdkApplication) => Promise<void>) => {
|
|
76
|
+
// CONFIGURATION
|
|
77
|
+
const config: INestiaConfig =
|
|
78
|
+
(await get_nestia_config(props.validate)) ??
|
|
79
|
+
parse_cli(props)(command)(include);
|
|
80
|
+
|
|
81
|
+
const options = await get_typescript_options();
|
|
82
|
+
config.compilerOptions = {
|
|
83
|
+
...options,
|
|
84
|
+
...(config.compilerOptions || {}),
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// CALL THE APP.GENERATE()
|
|
88
|
+
const app: NestiaSdkApplication = new NestiaSdkApplication(config);
|
|
89
|
+
await task(app);
|
|
90
|
+
};
|
|
107
91
|
|
|
108
92
|
async function get_typescript_options(): Promise<ts.CompilerOptions | null> {
|
|
109
93
|
const configFileName = ts.findConfigFile(
|
|
@@ -111,18 +95,14 @@ export namespace NestiaSdkCommand {
|
|
|
111
95
|
ts.sys.fileExists,
|
|
112
96
|
"tsconfig.json",
|
|
113
97
|
);
|
|
114
|
-
|
|
115
98
|
if (!configFileName) return null;
|
|
116
99
|
|
|
117
100
|
const { tsconfig } = await parseNative(configFileName);
|
|
118
|
-
|
|
119
101
|
const configFileText = JSON.stringify(tsconfig);
|
|
120
|
-
|
|
121
102
|
const { config } = ts.parseConfigFileTextToJson(
|
|
122
103
|
configFileName,
|
|
123
104
|
configFileText,
|
|
124
105
|
);
|
|
125
|
-
|
|
126
106
|
const configParseResult = ts.parseJsonConfigFileContent(
|
|
127
107
|
config,
|
|
128
108
|
ts.sys,
|
|
@@ -138,7 +118,9 @@ export namespace NestiaSdkCommand {
|
|
|
138
118
|
validate: (config: INestiaConfig) => boolean,
|
|
139
119
|
): Promise<INestiaConfig | null> {
|
|
140
120
|
const connector = new WorkerConnector(null, null, "process");
|
|
141
|
-
await connector.connect(
|
|
121
|
+
await connector.connect(
|
|
122
|
+
`${__dirname}/nestia.config.getter.${__filename.substr(-2)}`,
|
|
123
|
+
);
|
|
142
124
|
|
|
143
125
|
const driver = await connector.getDriver<typeof NestiaSdkConfig>();
|
|
144
126
|
const config: INestiaConfig | null = await driver.get();
|
|
@@ -152,23 +134,23 @@ export namespace NestiaSdkCommand {
|
|
|
152
134
|
return config;
|
|
153
135
|
}
|
|
154
136
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
command: ICommand
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
137
|
+
const parse_cli =
|
|
138
|
+
(props: IProps) =>
|
|
139
|
+
(command: ICommand) =>
|
|
140
|
+
(include: string[]): INestiaConfig => {
|
|
141
|
+
if (command.out === null)
|
|
142
|
+
throw new Error(
|
|
143
|
+
`Error on NestiaCommand.main(): output directory is not specified. Add the "--out <output_directory>" option.`,
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const config: INestiaConfig = {
|
|
147
|
+
input: {
|
|
148
|
+
include,
|
|
149
|
+
exclude: command.exclude ? [command.exclude] : undefined,
|
|
150
|
+
},
|
|
151
|
+
e2e: command.e2e ?? undefined,
|
|
152
|
+
};
|
|
153
|
+
props.assign(config, command.out);
|
|
154
|
+
return config;
|
|
170
155
|
};
|
|
171
|
-
output.assign(config, command.out);
|
|
172
|
-
return config;
|
|
173
|
-
}
|
|
174
156
|
}
|
package/src/executable/sdk.ts
CHANGED
|
@@ -14,14 +14,9 @@ npx @nestia/sdk [command] [options?]
|
|
|
14
14
|
- npx @nestia/sdk dependencies
|
|
15
15
|
- npx @nestia/sdk dependencies --manager pnpm
|
|
16
16
|
2. npx @nestia/sdk init
|
|
17
|
-
3. npx @nestia/sdk sdk
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- npx @nestia/sdk sdk src/**/*.controller.ts --out src/api
|
|
21
|
-
4. npx @nestia/sdk swagger <input> --out <output>
|
|
22
|
-
- npx @nestia/sdk swagger # when "nestia.config.ts" be configured
|
|
23
|
-
- npx @nestia/sdk swagger src/controllers --out src/api
|
|
24
|
-
- npx @nestia/sdk swagger src/**/*.controller.ts --out src/api
|
|
17
|
+
3. npx @nestia/sdk sdk
|
|
18
|
+
4. npx @nestia/sdk swagger
|
|
19
|
+
5. npx @nestia/sdk e2e
|
|
25
20
|
`;
|
|
26
21
|
|
|
27
22
|
function halt(desc: string): never {
|
|
@@ -66,6 +61,7 @@ async function main() {
|
|
|
66
61
|
else if (type === "init") await initialize();
|
|
67
62
|
else if (type === "sdk") await execute((c) => c.sdk(argv));
|
|
68
63
|
else if (type === "swagger") await execute((c) => c.swagger(argv));
|
|
64
|
+
else if (type === "e2e") await execute((c) => c.e2e(argv));
|
|
69
65
|
else halt(USAGE);
|
|
70
66
|
}
|
|
71
67
|
main().catch((exp) => {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
import { INestiaConfig } from "../INestiaConfig";
|
|
5
|
+
import { IRoute } from "../structures/IRoute";
|
|
6
|
+
import { NestiaConfigUtil } from "../utils/NestiaConfigUtil";
|
|
7
|
+
import { E2eFileProgrammer } from "./internal/E2eFileProgrammer";
|
|
8
|
+
|
|
9
|
+
export namespace E2eGenerator {
|
|
10
|
+
export const generate =
|
|
11
|
+
(config: INestiaConfig) =>
|
|
12
|
+
async (routeList: IRoute[]): Promise<void> => {
|
|
13
|
+
// PREPARE DIRECTORIES
|
|
14
|
+
const output: string = path.resolve(config.e2e!);
|
|
15
|
+
await mkdir(output);
|
|
16
|
+
await mkdir(path.join(output, "features"));
|
|
17
|
+
await mkdir(path.join(output, "features", "api"));
|
|
18
|
+
await mkdir(path.join(output, "features", "api", "automated"));
|
|
19
|
+
|
|
20
|
+
// GENERATE TEST INDEX FILE
|
|
21
|
+
await index(config)(path.join(config.e2e!, "index.ts"));
|
|
22
|
+
|
|
23
|
+
// GENERATE EACH TEST FILES
|
|
24
|
+
for (const route of routeList)
|
|
25
|
+
await E2eFileProgrammer.generate(config)({
|
|
26
|
+
api: path.resolve(config.output!),
|
|
27
|
+
current: path.join(output, "features", "api", "automated"),
|
|
28
|
+
})(route);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const index =
|
|
32
|
+
(config: INestiaConfig) =>
|
|
33
|
+
async (output: string): Promise<void> => {
|
|
34
|
+
if (fs.existsSync(output)) return;
|
|
35
|
+
|
|
36
|
+
const location: string = path.join(
|
|
37
|
+
__dirname,
|
|
38
|
+
"..",
|
|
39
|
+
"..",
|
|
40
|
+
"assets",
|
|
41
|
+
"bundle",
|
|
42
|
+
"e2e",
|
|
43
|
+
"index.ts",
|
|
44
|
+
);
|
|
45
|
+
const content: string = await fs.promises.readFile(
|
|
46
|
+
location,
|
|
47
|
+
"utf8",
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
await fs.promises.writeFile(
|
|
51
|
+
output,
|
|
52
|
+
content.replace(
|
|
53
|
+
"${input}",
|
|
54
|
+
JSON.stringify(NestiaConfigUtil.input(config.input)),
|
|
55
|
+
),
|
|
56
|
+
"utf8",
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const mkdir = async (location: string): Promise<void> => {
|
|
62
|
+
try {
|
|
63
|
+
await fs.promises.mkdir(location);
|
|
64
|
+
} catch {}
|
|
65
|
+
};
|