nestia 2.1.0-dev.20220414 → 2.1.0-dev.20220430
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/.github/workflows/build.yml +2 -4
- package/README.md +84 -14
- package/{src/bundle → bundle}/HttpError.ts +0 -0
- package/{src/bundle → bundle}/IConnection.ts +0 -0
- package/{src/bundle → bundle}/Primitive.ts +0 -0
- package/{src/bundle → bundle}/__internal/AesPkcs5.ts +0 -0
- package/{src/bundle → bundle}/__internal/Fetcher.ts +0 -0
- package/lib/IConfiguration.d.ts +71 -0
- package/lib/IConfiguration.d.ts.map +1 -0
- package/lib/IConfiguration.js +3 -0
- package/lib/NestiaApplication.d.ts +12 -0
- package/lib/NestiaApplication.d.ts.map +1 -0
- package/lib/NestiaApplication.js +340 -0
- package/lib/analyses/ControllerAnalyzer.d.ts +7 -0
- package/lib/analyses/ControllerAnalyzer.d.ts.map +1 -0
- package/lib/analyses/ControllerAnalyzer.js +191 -0
- package/lib/analyses/GenericAnalyzer.d.ts +6 -0
- package/lib/analyses/GenericAnalyzer.d.ts.map +1 -0
- package/lib/analyses/GenericAnalyzer.js +100 -0
- package/lib/analyses/ImportAnalyzer.d.ts +14 -0
- package/lib/analyses/ImportAnalyzer.d.ts.map +1 -0
- package/lib/analyses/ImportAnalyzer.js +79 -0
- package/lib/analyses/ReflectAnalyzer.d.ts +5 -0
- package/lib/analyses/ReflectAnalyzer.d.ts.map +1 -0
- package/lib/analyses/ReflectAnalyzer.js +313 -0
- package/lib/analyses/SourceFinder.d.ts +5 -0
- package/lib/analyses/SourceFinder.d.ts.map +1 -0
- package/lib/analyses/SourceFinder.js +260 -0
- package/lib/executable/internal/CompilerOptions.d.ts +14 -0
- package/lib/executable/internal/CompilerOptions.d.ts.map +1 -0
- package/lib/executable/internal/CompilerOptions.js +126 -0
- package/lib/executable/internal/NestiaCommand.d.ts +5 -0
- package/lib/executable/internal/NestiaCommand.d.ts.map +1 -0
- package/lib/executable/internal/NestiaCommand.js +228 -0
- package/lib/executable/internal/NestiaConfig.d.ts +5 -0
- package/lib/executable/internal/NestiaConfig.d.ts.map +1 -0
- package/lib/executable/internal/NestiaConfig.js +277 -0
- package/lib/executable/internal/nestia.config.getter.d.ts +2 -0
- package/lib/executable/internal/nestia.config.getter.d.ts.map +1 -0
- package/lib/executable/internal/nestia.config.getter.js +60 -0
- package/lib/executable/nestia.d.ts +3 -0
- package/lib/executable/nestia.d.ts.map +1 -0
- package/lib/executable/nestia.js +129 -0
- package/lib/generates/FileGenerator.d.ts +6 -0
- package/lib/generates/FileGenerator.d.ts.map +1 -0
- package/lib/generates/FileGenerator.js +326 -0
- package/lib/generates/FunctionGenerator.d.ts +6 -0
- package/lib/generates/FunctionGenerator.d.ts.map +1 -0
- package/lib/generates/FunctionGenerator.js +217 -0
- package/lib/generates/SdkGenerator.d.ts +8 -0
- package/lib/generates/SdkGenerator.d.ts.map +1 -0
- package/lib/generates/SdkGenerator.js +128 -0
- package/lib/generates/SwaggerGenerator.d.ts +7 -0
- package/lib/generates/SwaggerGenerator.d.ts.map +1 -0
- package/lib/generates/SwaggerGenerator.js +258 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +28 -0
- package/lib/module.d.ts +3 -0
- package/lib/module.d.ts.map +1 -0
- package/lib/module.js +19 -0
- package/{src/structures/IController.ts → lib/structures/IController.d.ts} +6 -13
- package/lib/structures/IController.d.ts.map +1 -0
- package/lib/structures/IController.js +3 -0
- package/{src/structures/IRoute.ts → lib/structures/IRoute.d.ts} +8 -13
- package/lib/structures/IRoute.d.ts.map +1 -0
- package/lib/structures/IRoute.js +3 -0
- package/lib/structures/ISwagger.d.ts +36 -0
- package/lib/structures/ISwagger.d.ts.map +1 -0
- package/lib/structures/ISwagger.js +3 -0
- package/lib/structures/IType.d.ts +6 -0
- package/lib/structures/IType.d.ts.map +1 -0
- package/lib/structures/IType.js +3 -0
- package/lib/structures/MethodType.d.ts +5 -0
- package/lib/structures/MethodType.d.ts.map +1 -0
- package/lib/structures/MethodType.js +8 -0
- package/lib/structures/ParamCategory.d.ts +2 -0
- package/lib/structures/ParamCategory.d.ts.map +1 -0
- package/lib/structures/ParamCategory.js +3 -0
- package/lib/utils/ArrayUtil.d.ts +6 -0
- package/lib/utils/ArrayUtil.d.ts.map +1 -0
- package/lib/utils/ArrayUtil.js +144 -0
- package/lib/utils/DirectoryUtil.d.ts +6 -0
- package/lib/utils/DirectoryUtil.d.ts.map +1 -0
- package/lib/utils/DirectoryUtil.js +190 -0
- package/lib/utils/ImportDictionary.d.ts +7 -0
- package/lib/utils/ImportDictionary.d.ts.map +1 -0
- package/lib/utils/ImportDictionary.js +83 -0
- package/lib/utils/MapUtil.d.ts +4 -0
- package/lib/utils/MapUtil.d.ts.map +1 -0
- package/lib/utils/MapUtil.js +16 -0
- package/lib/utils/StringUtil.d.ts +4 -0
- package/lib/utils/StringUtil.d.ts.map +1 -0
- package/lib/utils/StringUtil.js +13 -0
- package/package.json +17 -10
- package/src/IConfiguration.ts +0 -17
- package/src/NestiaApplication.ts +0 -96
- package/src/analyses/ControllerAnalyzer.ts +0 -154
- package/src/analyses/GenericAnalyzer.ts +0 -52
- package/src/analyses/ImportAnalyzer.ts +0 -93
- package/src/analyses/ReflectAnalyzer.ts +0 -221
- package/src/analyses/SourceFinder.ts +0 -73
- package/src/bin/nestia.ts +0 -125
- package/src/executable/sdk.ts +0 -89
- package/src/generates/FileGenerator.ts +0 -150
- package/src/generates/FunctionGenerator.ts +0 -201
- package/src/generates/SdkGenerator.ts +0 -39
- package/src/internal/CompilerOptions.ts +0 -142
- package/src/structures/MethodType.ts +0 -6
- package/src/structures/ParamCategory.ts +0 -1
- package/src/utils/ArrayUtil.ts +0 -26
- package/src/utils/DirectoryUtil.ts +0 -48
- package/src/utils/ImportDictionary.ts +0 -44
- package/src/utils/StringUtil.ts +0 -10
- package/src/utils/stripJsonComments.ts +0 -79
- package/tsconfig.json +0 -82
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import * as NodePath from "path";
|
|
2
|
-
import { equal } from "tstl/ranges/module";
|
|
3
|
-
|
|
4
|
-
import { ArrayUtil } from "../utils/ArrayUtil";
|
|
5
|
-
import { StringUtil } from "../utils/StringUtil";
|
|
6
|
-
|
|
7
|
-
import { IController } from "../structures/IController";
|
|
8
|
-
import { ParamCategory } from "../structures/ParamCategory";
|
|
9
|
-
|
|
10
|
-
type IModule =
|
|
11
|
-
{
|
|
12
|
-
[key: string]: any;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export namespace ReflectAnalyzer
|
|
16
|
-
{
|
|
17
|
-
export async function analyze(unique: WeakSet<any>, file: string): Promise<IController[]>
|
|
18
|
-
{
|
|
19
|
-
const module: IModule = await import(file);
|
|
20
|
-
const ret: IController[] = [];
|
|
21
|
-
|
|
22
|
-
for (const tuple of Object.entries(module))
|
|
23
|
-
{
|
|
24
|
-
if (unique.has(tuple[1]))
|
|
25
|
-
continue;
|
|
26
|
-
else
|
|
27
|
-
unique.add(tuple[1]);
|
|
28
|
-
|
|
29
|
-
const controller: IController | null = _Analyze_controller(file, ...tuple);
|
|
30
|
-
if (controller !== null)
|
|
31
|
-
ret.push(controller);
|
|
32
|
-
}
|
|
33
|
-
return ret;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/* ---------------------------------------------------------
|
|
37
|
-
CONTROLLER
|
|
38
|
-
--------------------------------------------------------- */
|
|
39
|
-
function _Analyze_controller(file: string, name: string, creator: any): IController | null
|
|
40
|
-
{
|
|
41
|
-
//----
|
|
42
|
-
// VALIDATIONS
|
|
43
|
-
//----
|
|
44
|
-
// MUST BE TYPE OF A CREATOR WHO HAS THE CONSTRUCTOR
|
|
45
|
-
if (!(creator instanceof Function && creator.constructor instanceof Function))
|
|
46
|
-
return null;
|
|
47
|
-
|
|
48
|
-
// MUST HAVE THOSE MATADATA
|
|
49
|
-
else if (ArrayUtil.has(Reflect.getMetadataKeys(creator), "path", "host", "scope:options") === false)
|
|
50
|
-
return null;
|
|
51
|
-
|
|
52
|
-
//----
|
|
53
|
-
// CONSTRUCTION
|
|
54
|
-
//----
|
|
55
|
-
// BASIC INFO
|
|
56
|
-
const meta: IController = {
|
|
57
|
-
file,
|
|
58
|
-
name,
|
|
59
|
-
path: Reflect.getMetadata("path", creator),
|
|
60
|
-
functions: []
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// PARSE CHILDREN DATA
|
|
64
|
-
for (const tuple of _Get_prototype_entries(creator))
|
|
65
|
-
{
|
|
66
|
-
const child: IController.IFunction | null = _Analyze_function(creator.prototype, meta, ...tuple);
|
|
67
|
-
if (child !== null)
|
|
68
|
-
meta.functions.push(child);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// RETURNS
|
|
72
|
-
return meta;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function _Get_prototype_entries(creator: any): Array<[string, unknown]>
|
|
76
|
-
{
|
|
77
|
-
const tuple = Object.entries(creator.prototype);
|
|
78
|
-
const parent = Object.getPrototypeOf(creator);
|
|
79
|
-
|
|
80
|
-
if (parent.prototype !== undefined)
|
|
81
|
-
tuple.push(..._Get_prototype_entries(parent));
|
|
82
|
-
|
|
83
|
-
return tuple;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/* ---------------------------------------------------------
|
|
87
|
-
FUNCTION
|
|
88
|
-
--------------------------------------------------------- */
|
|
89
|
-
function _Analyze_function(classProto: any, controller: IController, name: string, proto: any): IController.IFunction | null
|
|
90
|
-
{
|
|
91
|
-
//----
|
|
92
|
-
// VALIDATIONS
|
|
93
|
-
//----
|
|
94
|
-
// MUST BE TYPE OF A FUNCTION
|
|
95
|
-
if (!(proto instanceof Function))
|
|
96
|
-
return null;
|
|
97
|
-
|
|
98
|
-
// MUST HAVE THOSE METADATE
|
|
99
|
-
else if (ArrayUtil.has(Reflect.getMetadataKeys(proto), "path", "method") === false)
|
|
100
|
-
return null;
|
|
101
|
-
|
|
102
|
-
//----
|
|
103
|
-
// CONSTRUCTION
|
|
104
|
-
//----
|
|
105
|
-
// BASIC INFO
|
|
106
|
-
const meta: IController.IFunction = {
|
|
107
|
-
name,
|
|
108
|
-
method: METHODS[Reflect.getMetadata("method", proto)],
|
|
109
|
-
path: Reflect.getMetadata("path", proto),
|
|
110
|
-
parameters: [],
|
|
111
|
-
encrypted: Reflect.hasMetadata("__interceptors__", proto)
|
|
112
|
-
&& Reflect.getMetadata("__interceptors__", proto)[0]?.constructor?.name === "EncryptedRouteInterceptor"
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// PARSE CHILDREN DATA
|
|
116
|
-
const nestParameters: NestParameters | undefined = Reflect.getMetadata("__routeArguments__", classProto.constructor, name);
|
|
117
|
-
if (nestParameters === undefined)
|
|
118
|
-
meta.parameters = [];
|
|
119
|
-
else
|
|
120
|
-
{
|
|
121
|
-
for (const tuple of Object.entries(nestParameters))
|
|
122
|
-
{
|
|
123
|
-
const child: IController.IParameter | null = _Analyze_parameter(...tuple);
|
|
124
|
-
if (child !== null)
|
|
125
|
-
meta.parameters.push(child);
|
|
126
|
-
}
|
|
127
|
-
meta.parameters = meta.parameters.sort((x, y) => x.index - y.index);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// VALIDATE PATH ARGUMENTS
|
|
131
|
-
const funcPathArguments: string[] = StringUtil.betweens(NodePath.join(controller.path, meta.path).split("\\").join("/"), ":", "/").sort();
|
|
132
|
-
const paramPathArguments: string[] = meta.parameters.filter(param => param.category === "param").map(param => param.field!).sort();
|
|
133
|
-
|
|
134
|
-
if (equal(funcPathArguments, paramPathArguments) === false)
|
|
135
|
-
throw new Error(`Error on ${controller.name}.${name}(): binded arguments in the "path" between function's decorator and parameters' decorators are different (function: [${funcPathArguments.join(", ")}], parameters: [${paramPathArguments.join(", ")}])`);
|
|
136
|
-
|
|
137
|
-
// RETURNS
|
|
138
|
-
return meta;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH"];
|
|
142
|
-
|
|
143
|
-
/* ---------------------------------------------------------
|
|
144
|
-
PARAMETER
|
|
145
|
-
--------------------------------------------------------- */
|
|
146
|
-
function _Analyze_parameter(key: string, param: INestParam): IController.IParameter | null
|
|
147
|
-
{
|
|
148
|
-
const symbol: string = key.split(":")[0];
|
|
149
|
-
if (symbol.indexOf("__custom") !== -1)
|
|
150
|
-
return _Analyze_custom_parameter(param);
|
|
151
|
-
|
|
152
|
-
const typeIndex: number = Number(symbol[0]);
|
|
153
|
-
if (isNaN(typeIndex) === true)
|
|
154
|
-
return null;
|
|
155
|
-
|
|
156
|
-
const type: ParamCategory | undefined = NEST_PARAMETER_TYPES[typeIndex];
|
|
157
|
-
if (type === undefined)
|
|
158
|
-
return null;
|
|
159
|
-
|
|
160
|
-
return {
|
|
161
|
-
name: key,
|
|
162
|
-
category: type,
|
|
163
|
-
index: param.index,
|
|
164
|
-
field: param.data,
|
|
165
|
-
encrypted: false
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function _Analyze_custom_parameter(param: INestParam): IController.IParameter | null
|
|
170
|
-
{
|
|
171
|
-
if (param.factory === undefined)
|
|
172
|
-
return null;
|
|
173
|
-
else if (param.factory.name === "EncryptedBody" || param.factory.name === "PlainBody")
|
|
174
|
-
{
|
|
175
|
-
return {
|
|
176
|
-
category: "body",
|
|
177
|
-
index: param.index,
|
|
178
|
-
name: param.name,
|
|
179
|
-
field: param.data,
|
|
180
|
-
encrypted: param.factory.name === "EncryptedBody"
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
else if (param.factory.name === "TypedParam")
|
|
184
|
-
return {
|
|
185
|
-
name: param.name,
|
|
186
|
-
category: "param",
|
|
187
|
-
index: param.index,
|
|
188
|
-
field: param.data,
|
|
189
|
-
encrypted: false
|
|
190
|
-
};
|
|
191
|
-
else
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
type NestParameters = {
|
|
196
|
-
[key: string]: INestParam;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
interface INestParam
|
|
200
|
-
{
|
|
201
|
-
name: string;
|
|
202
|
-
index: number;
|
|
203
|
-
factory?: Function;
|
|
204
|
-
data: string | undefined;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const NEST_PARAMETER_TYPES = [
|
|
208
|
-
undefined,
|
|
209
|
-
undefined,
|
|
210
|
-
undefined,
|
|
211
|
-
"body",
|
|
212
|
-
"query",
|
|
213
|
-
"param",
|
|
214
|
-
undefined,
|
|
215
|
-
undefined,
|
|
216
|
-
undefined,
|
|
217
|
-
undefined,
|
|
218
|
-
undefined,
|
|
219
|
-
undefined
|
|
220
|
-
] as const;
|
|
221
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import glob from "glob";
|
|
3
|
-
import * as path from "path";
|
|
4
|
-
|
|
5
|
-
import { IConfiguration } from "../IConfiguration";
|
|
6
|
-
|
|
7
|
-
export namespace SourceFinder
|
|
8
|
-
{
|
|
9
|
-
export async function find(input: IConfiguration.IInput): Promise<string[]>
|
|
10
|
-
{
|
|
11
|
-
const dict: Set<string> = new Set();
|
|
12
|
-
await decode(input.include, str => dict.add(str));
|
|
13
|
-
if (input.exclude)
|
|
14
|
-
await decode(input.exclude, str => dict.delete(str));
|
|
15
|
-
|
|
16
|
-
return [...dict];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async function decode
|
|
20
|
-
(
|
|
21
|
-
input: string[],
|
|
22
|
-
closure: (location: string) => void,
|
|
23
|
-
): Promise<void>
|
|
24
|
-
{
|
|
25
|
-
for (const pattern of input)
|
|
26
|
-
for (const location of await _Glob(path.resolve(pattern)))
|
|
27
|
-
{
|
|
28
|
-
const stats: fs.Stats = await fs.promises.stat(location);
|
|
29
|
-
if (stats.isDirectory() === true)
|
|
30
|
-
await iterate(closure, location);
|
|
31
|
-
else if (stats.isFile() && _Is_ts_file(location))
|
|
32
|
-
closure(location);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function iterate
|
|
37
|
-
(
|
|
38
|
-
closure: (location: string) => void,
|
|
39
|
-
location: string
|
|
40
|
-
): Promise<void>
|
|
41
|
-
{
|
|
42
|
-
const directory: string[] = await fs.promises.readdir(location);
|
|
43
|
-
for (const file of directory)
|
|
44
|
-
{
|
|
45
|
-
const next: string = path.resolve(`${location}/${file}`);
|
|
46
|
-
const stats: fs.Stats = await fs.promises.stat(next);
|
|
47
|
-
|
|
48
|
-
if (stats.isDirectory() === true)
|
|
49
|
-
await iterate(closure, next);
|
|
50
|
-
else if (stats.isFile() && _Is_ts_file(file))
|
|
51
|
-
closure(next);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function _Glob(pattern: string): Promise<string[]>
|
|
56
|
-
{
|
|
57
|
-
return new Promise((resolve, reject) =>
|
|
58
|
-
{
|
|
59
|
-
glob(pattern, (err, matches) =>
|
|
60
|
-
{
|
|
61
|
-
if (err)
|
|
62
|
-
reject(err);
|
|
63
|
-
else
|
|
64
|
-
resolve(matches.map(str => path.resolve(str)));
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function _Is_ts_file(file: string): boolean
|
|
70
|
-
{
|
|
71
|
-
return file.substr(-3) === ".ts" && file.substr(-5) !== ".d.ts";
|
|
72
|
-
}
|
|
73
|
-
}
|
package/src/bin/nestia.ts
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ts-node
|
|
2
|
-
|
|
3
|
-
import * as cp from "child_process";
|
|
4
|
-
import * as fs from "fs";
|
|
5
|
-
import * as path from "path";
|
|
6
|
-
import * as process from "process";
|
|
7
|
-
|
|
8
|
-
import { CompilerOptions } from "../internal/CompilerOptions";
|
|
9
|
-
import { stripJsonComments } from "../utils/stripJsonComments";
|
|
10
|
-
|
|
11
|
-
interface IConfig
|
|
12
|
-
{
|
|
13
|
-
compilerOptions?: CompilerOptions;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function install(): void
|
|
17
|
-
{
|
|
18
|
-
// INSTALL DEPENDENCIES
|
|
19
|
-
for (const lib of ["nestia-fetcher", "typescript-is"])
|
|
20
|
-
{
|
|
21
|
-
const command: string = `npm install ${lib}`;
|
|
22
|
-
cp.execSync(command, { stdio: "inherit" });
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function sdk(file: string): void
|
|
27
|
-
{
|
|
28
|
-
// PREPARE COMMAND
|
|
29
|
-
const parameters: string[] = [
|
|
30
|
-
`npx ts-node -C ttypescript --project "${file}"`,
|
|
31
|
-
`"${path.relative(process.cwd(), `${__dirname}/../executable/sdk`)}"`,
|
|
32
|
-
...process.argv.slice(3)
|
|
33
|
-
];
|
|
34
|
-
const command: string = parameters.join(" ");
|
|
35
|
-
|
|
36
|
-
// EXECUTE THE COMMAND, BUT IGNORE WARNINGS
|
|
37
|
-
cp.execSync
|
|
38
|
-
(
|
|
39
|
-
command,
|
|
40
|
-
{
|
|
41
|
-
stdio: "inherit",
|
|
42
|
-
env: {
|
|
43
|
-
...process.env,
|
|
44
|
-
"NODE_NO_WARNINGS": "1"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function configure(config: IConfig): boolean
|
|
51
|
-
{
|
|
52
|
-
if (!config.compilerOptions)
|
|
53
|
-
{
|
|
54
|
-
config.compilerOptions = CompilerOptions.DEFAULT;
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
else
|
|
58
|
-
return CompilerOptions.emend(config.compilerOptions);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async function tsconfig(task: (file: string) => void): Promise<void>
|
|
62
|
-
{
|
|
63
|
-
//----
|
|
64
|
-
// PREPARE ASSETS
|
|
65
|
-
//----
|
|
66
|
-
let prepare: null | (() => Promise<[string, () => Promise<void>]>) = null;
|
|
67
|
-
|
|
68
|
-
// NO TSCONFIG.JSON?
|
|
69
|
-
if (fs.existsSync("tsconfig.json") === false)
|
|
70
|
-
{
|
|
71
|
-
const config = { compilerOptions: CompilerOptions.DEFAULT };
|
|
72
|
-
prepare = CompilerOptions.temporary(config);
|
|
73
|
-
}
|
|
74
|
-
else
|
|
75
|
-
{
|
|
76
|
-
// HAS TSCONFIG.JSON
|
|
77
|
-
const content: string = await fs.promises.readFile("tsconfig.json", "utf8");
|
|
78
|
-
const config = JSON.parse(stripJsonComments(content));
|
|
79
|
-
|
|
80
|
-
// NEED TO ADD TRANSFORM PLUGINS
|
|
81
|
-
const changed: boolean = configure(config);
|
|
82
|
-
if (changed === true)
|
|
83
|
-
prepare = CompilerOptions.temporary(config);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
//----
|
|
87
|
-
// EXECUTION
|
|
88
|
-
//----
|
|
89
|
-
// CREATE TEMPORARY TSCONFIG
|
|
90
|
-
const [file, erasure] = prepare ? await prepare() : ["tsconfig.json", null];
|
|
91
|
-
|
|
92
|
-
// EXECUTE THE TASK
|
|
93
|
-
let error: Error | null = null;
|
|
94
|
-
try
|
|
95
|
-
{
|
|
96
|
-
task(file);
|
|
97
|
-
}
|
|
98
|
-
catch (exp)
|
|
99
|
-
{
|
|
100
|
-
error = exp as Error;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// REMOVE THE TEMPORARY TSCONFIG
|
|
104
|
-
if (erasure)
|
|
105
|
-
await erasure();
|
|
106
|
-
|
|
107
|
-
// THROW ERROR IF EXISTS
|
|
108
|
-
if (error)
|
|
109
|
-
throw error;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async function main()
|
|
113
|
-
{
|
|
114
|
-
if (process.argv[2] === "install")
|
|
115
|
-
await install();
|
|
116
|
-
else if (process.argv[2] === "sdk")
|
|
117
|
-
await tsconfig(sdk);
|
|
118
|
-
else
|
|
119
|
-
throw new Error(`nestia supports only two commands; install and sdk, however you typed ${process.argv[2]}`);
|
|
120
|
-
}
|
|
121
|
-
main().catch(exp =>
|
|
122
|
-
{
|
|
123
|
-
console.log(exp.message);
|
|
124
|
-
process.exit(-1);
|
|
125
|
-
});
|
package/src/executable/sdk.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import * as cli from "cli";
|
|
2
|
-
import * as fs from "fs";
|
|
3
|
-
import * as path from "path";
|
|
4
|
-
import * as tsc from "typescript";
|
|
5
|
-
import { Primitive } from "nestia-fetcher";
|
|
6
|
-
|
|
7
|
-
import { IConfiguration } from "../IConfiguration";
|
|
8
|
-
import { NestiaApplication } from "../NestiaApplication";
|
|
9
|
-
import { stripJsonComments } from "../utils/stripJsonComments";
|
|
10
|
-
|
|
11
|
-
interface ICommand
|
|
12
|
-
{
|
|
13
|
-
exclude: string | null;
|
|
14
|
-
out: string | null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function sdk(include: string[], command: ICommand): Promise<void>
|
|
18
|
-
{
|
|
19
|
-
// CONFIGURATION
|
|
20
|
-
let config: IConfiguration;
|
|
21
|
-
if (fs.existsSync("nestia.config.ts") === true)
|
|
22
|
-
config = Primitive.clone
|
|
23
|
-
(
|
|
24
|
-
await import(path.resolve("nestia.config.ts"))
|
|
25
|
-
);
|
|
26
|
-
else
|
|
27
|
-
{
|
|
28
|
-
if (command.out === null)
|
|
29
|
-
throw new Error(`Output directory is not specified. Add the "--out <output_directory>" option.`);
|
|
30
|
-
config = {
|
|
31
|
-
input: {
|
|
32
|
-
include,
|
|
33
|
-
exclude: command.exclude
|
|
34
|
-
? [command.exclude]
|
|
35
|
-
: undefined
|
|
36
|
-
},
|
|
37
|
-
output: command.out
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// VALIDATE OUTPUT DIRECTORY
|
|
42
|
-
const parentPath: string = path.resolve(config.output + "/..");
|
|
43
|
-
const parentStats: fs.Stats = await fs.promises.stat(parentPath);
|
|
44
|
-
|
|
45
|
-
if (parentStats.isDirectory() === false)
|
|
46
|
-
throw new Error(`Unable to find parent directory of the output path: "${parentPath}".`);
|
|
47
|
-
|
|
48
|
-
// GENERATION
|
|
49
|
-
if (fs.existsSync("tsconfig.json") === true)
|
|
50
|
-
{
|
|
51
|
-
const content: string = await fs.promises.readFile("tsconfig.json", "utf8");
|
|
52
|
-
const options: tsc.CompilerOptions = JSON.parse(stripJsonComments(content)).compilerOptions;
|
|
53
|
-
|
|
54
|
-
config.compilerOptions = {
|
|
55
|
-
...options,
|
|
56
|
-
...(config.compilerOptions || {})
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// CALL THE APP.GENERATE()
|
|
61
|
-
const app: NestiaApplication = new NestiaApplication(config);
|
|
62
|
-
await app.generate();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async function main(): Promise<void>
|
|
66
|
-
{
|
|
67
|
-
const command: ICommand = cli.parse({
|
|
68
|
-
exclude: ["e", "Something to exclude", "string", null],
|
|
69
|
-
out: ["o", "Output path of the SDK files", "string", null],
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
try
|
|
73
|
-
{
|
|
74
|
-
const inputs: string[] = [];
|
|
75
|
-
for (const arg of process.argv.slice(2))
|
|
76
|
-
{
|
|
77
|
-
if (arg[0] === "-")
|
|
78
|
-
break;
|
|
79
|
-
inputs.push(arg);
|
|
80
|
-
}
|
|
81
|
-
await sdk(inputs, command);
|
|
82
|
-
}
|
|
83
|
-
catch (exp)
|
|
84
|
-
{
|
|
85
|
-
console.log(exp);
|
|
86
|
-
process.exit(-1);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
main();
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import { HashMap } from "tstl/container/HashMap";
|
|
3
|
-
import { IConfiguration } from "../IConfiguration";
|
|
4
|
-
|
|
5
|
-
import { IRoute } from "../structures/IRoute";
|
|
6
|
-
import { ImportDictionary } from "../utils/ImportDictionary";
|
|
7
|
-
import { FunctionGenerator } from "./FunctionGenerator";
|
|
8
|
-
|
|
9
|
-
export namespace FileGenerator
|
|
10
|
-
{
|
|
11
|
-
/* ---------------------------------------------------------
|
|
12
|
-
CONSTRUCTOR
|
|
13
|
-
--------------------------------------------------------- */
|
|
14
|
-
export async function generate(config: IConfiguration, routeList: IRoute[]): Promise<void>
|
|
15
|
-
{
|
|
16
|
-
// CONSTRUCT FOLDER TREE
|
|
17
|
-
const root: Directory = new Directory(null, "functional");
|
|
18
|
-
for (const route of routeList)
|
|
19
|
-
emplace(root, route);
|
|
20
|
-
|
|
21
|
-
// RELOCATE FOR ONLY ONE CONTROLLER METHOD IN AN URL CASE
|
|
22
|
-
relocate(root);
|
|
23
|
-
|
|
24
|
-
// ITERATE FILES
|
|
25
|
-
await iterate(!!config.assert, config.output + "/functional", root);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function emplace(directory: Directory, route: IRoute): void
|
|
29
|
-
{
|
|
30
|
-
// SEPARATE IDENTIFIERS
|
|
31
|
-
const identifiers: string[] = route.path
|
|
32
|
-
.split("/")
|
|
33
|
-
.filter(str => str[0] !== ":" && str.length !== 0)
|
|
34
|
-
.map(str => str.split("-").join("_").split(".").join("_"));
|
|
35
|
-
|
|
36
|
-
for (const key of identifiers)
|
|
37
|
-
{
|
|
38
|
-
// EMPLACE IF REQUIRED
|
|
39
|
-
let it: HashMap.Iterator<string, Directory> = directory.directories.find(key);
|
|
40
|
-
if (it.equals(directory.directories.end()) === true)
|
|
41
|
-
it = directory.directories.emplace(key, new Directory(directory, key)).first;
|
|
42
|
-
|
|
43
|
-
// FOR THE NEXT STEP
|
|
44
|
-
directory = it.second;
|
|
45
|
-
}
|
|
46
|
-
directory.routes.push(route);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function relocate(directory: Directory): void
|
|
50
|
-
{
|
|
51
|
-
if (directory.parent !== null
|
|
52
|
-
&& directory.directories.empty()
|
|
53
|
-
&& directory.routes.length === 1
|
|
54
|
-
&& directory.name === directory.routes[0].name)
|
|
55
|
-
{
|
|
56
|
-
directory.parent.routes.push(directory.routes[0]);
|
|
57
|
-
directory.parent.directories.erase(directory.name);
|
|
58
|
-
}
|
|
59
|
-
else if (directory.directories.empty() === false)
|
|
60
|
-
for (const it of directory.directories)
|
|
61
|
-
relocate(it.second);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/* ---------------------------------------------------------
|
|
65
|
-
FILE ITERATOR
|
|
66
|
-
--------------------------------------------------------- */
|
|
67
|
-
async function iterate
|
|
68
|
-
(
|
|
69
|
-
assert: boolean,
|
|
70
|
-
outDir: string,
|
|
71
|
-
directory: Directory
|
|
72
|
-
): Promise<void>
|
|
73
|
-
{
|
|
74
|
-
// CREATE A NEW DIRECTORY
|
|
75
|
-
try
|
|
76
|
-
{
|
|
77
|
-
await fs.promises.mkdir(outDir);
|
|
78
|
-
}
|
|
79
|
-
catch {}
|
|
80
|
-
|
|
81
|
-
// ITERATE CHILDREN
|
|
82
|
-
let content: string = "";
|
|
83
|
-
for (const it of directory.directories)
|
|
84
|
-
{
|
|
85
|
-
await iterate(assert, `${outDir}/${it.first}`, it.second);
|
|
86
|
-
content += `export * as ${it.first} from "./${it.first}";\n`;
|
|
87
|
-
}
|
|
88
|
-
content += "\n";
|
|
89
|
-
|
|
90
|
-
// ITERATE ROUTES
|
|
91
|
-
const importDict: ImportDictionary = new ImportDictionary();
|
|
92
|
-
for (const route of directory.routes)
|
|
93
|
-
{
|
|
94
|
-
for (const tuple of route.imports)
|
|
95
|
-
for (const instance of tuple[1])
|
|
96
|
-
importDict.emplace(tuple[0], false, instance);
|
|
97
|
-
content += FunctionGenerator.generate(assert, route) + "\n\n";
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// FINALIZE THE CONTENT
|
|
101
|
-
if (directory.routes.length !== 0)
|
|
102
|
-
{
|
|
103
|
-
const primitived: boolean = directory.routes.some(route => route.output !== "void"
|
|
104
|
-
|| route.parameters.some(param => param.category !== "param")
|
|
105
|
-
);
|
|
106
|
-
const asserted: boolean = assert
|
|
107
|
-
&& directory.routes.some(route => route.parameters.length !== 0);
|
|
108
|
-
|
|
109
|
-
const fetcher: string[] = ["Fetcher"];
|
|
110
|
-
if (primitived)
|
|
111
|
-
fetcher.push("Primitive");
|
|
112
|
-
|
|
113
|
-
content = ""
|
|
114
|
-
+ `import { ${fetcher.join(", ")} } from "nestia-fetcher";\n`
|
|
115
|
-
+ `import type { IConnection } from "nestia-fetcher";\n`
|
|
116
|
-
+ (asserted ? `import { assertType } from "typescript-is";\n` : "")
|
|
117
|
-
+
|
|
118
|
-
(
|
|
119
|
-
importDict.empty()
|
|
120
|
-
? ""
|
|
121
|
-
: "\n" + importDict.toScript(outDir) + "\n"
|
|
122
|
-
)
|
|
123
|
-
+ content;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
content = "/**\n"
|
|
127
|
-
+ " * @packageDocumentation\n"
|
|
128
|
-
+ ` * @module ${directory.module}\n`
|
|
129
|
-
+ " */\n"
|
|
130
|
-
+ "//================================================================\n"
|
|
131
|
-
+ content;
|
|
132
|
-
await fs.promises.writeFile(`${outDir}/index.ts`, content, "utf8");
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
class Directory
|
|
137
|
-
{
|
|
138
|
-
public readonly module: string;
|
|
139
|
-
public readonly directories: HashMap<string, Directory>;
|
|
140
|
-
public readonly routes: IRoute[];
|
|
141
|
-
|
|
142
|
-
public constructor(readonly parent: Directory | null, readonly name: string)
|
|
143
|
-
{
|
|
144
|
-
this.directories = new HashMap();
|
|
145
|
-
this.routes = [];
|
|
146
|
-
this.module = (this.parent !== null)
|
|
147
|
-
? `${this.parent.module}.${name}`
|
|
148
|
-
: `api.${name}`;
|
|
149
|
-
}
|
|
150
|
-
}
|