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
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __values = (this && this.__values) || function(o) {
|
|
26
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
27
|
+
if (m) return m.call(o);
|
|
28
|
+
if (o && typeof o.length === "number") return {
|
|
29
|
+
next: function () {
|
|
30
|
+
if (o && i >= o.length) o = void 0;
|
|
31
|
+
return { value: o && o[i++], done: !o };
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.ImportDictionary = void 0;
|
|
38
|
+
var path = __importStar(require("path"));
|
|
39
|
+
var HashMap_1 = require("tstl/container/HashMap");
|
|
40
|
+
var HashSet_1 = require("tstl/container/HashSet");
|
|
41
|
+
var Pair_1 = require("tstl/utility/Pair");
|
|
42
|
+
var ImportDictionary = /** @class */ (function () {
|
|
43
|
+
function ImportDictionary() {
|
|
44
|
+
this.dict_ = new HashMap_1.HashMap();
|
|
45
|
+
}
|
|
46
|
+
ImportDictionary.prototype.empty = function () {
|
|
47
|
+
return this.dict_.empty();
|
|
48
|
+
};
|
|
49
|
+
ImportDictionary.prototype.emplace = function (file, realistic, instance) {
|
|
50
|
+
if (file.substr(-5) === ".d.ts")
|
|
51
|
+
file = file.substr(0, file.length - 5);
|
|
52
|
+
else if (file.substr(-3) === ".ts")
|
|
53
|
+
file = file.substr(0, file.length - 3);
|
|
54
|
+
else
|
|
55
|
+
throw new Error("Error on ImportDictionary.emplace(): extension of the target file \"".concat(file, "\" is not \"ts\"."));
|
|
56
|
+
var pair = this.dict_.take(file, function () { return new Pair_1.Pair(realistic, new HashSet_1.HashSet()); });
|
|
57
|
+
pair.second.insert(instance);
|
|
58
|
+
};
|
|
59
|
+
ImportDictionary.prototype.toScript = function (outDir) {
|
|
60
|
+
var e_1, _a;
|
|
61
|
+
var statements = [];
|
|
62
|
+
try {
|
|
63
|
+
for (var _b = __values(this.dict_), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
64
|
+
var it = _c.value;
|
|
65
|
+
var file = path.relative(outDir, it.first).split("\\").join("/");
|
|
66
|
+
var realistic = it.second.first;
|
|
67
|
+
var instances = it.second.second.toJSON();
|
|
68
|
+
statements.push("import ".concat(!realistic ? "type " : "", "{ ").concat(instances.join(", "), " } from \"./").concat(file, "\";"));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
72
|
+
finally {
|
|
73
|
+
try {
|
|
74
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
75
|
+
}
|
|
76
|
+
finally { if (e_1) throw e_1.error; }
|
|
77
|
+
}
|
|
78
|
+
return statements.join("\n");
|
|
79
|
+
};
|
|
80
|
+
return ImportDictionary;
|
|
81
|
+
}());
|
|
82
|
+
exports.ImportDictionary = ImportDictionary;
|
|
83
|
+
//# sourceMappingURL=ImportDictionary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MapUtil.d.ts","sourceRoot":"","sources":["../../src/utils/MapUtil.ts"],"names":[],"mappings":"AAAA,yBAAiB,OAAO,CACxB;IACI,SAAgB,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CASvD;CACJ"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MapUtil = void 0;
|
|
4
|
+
var MapUtil;
|
|
5
|
+
(function (MapUtil) {
|
|
6
|
+
function take(dict, key, generator) {
|
|
7
|
+
var oldbie = dict.get(key);
|
|
8
|
+
if (oldbie)
|
|
9
|
+
return oldbie;
|
|
10
|
+
var value = generator();
|
|
11
|
+
dict.set(key, value);
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
MapUtil.take = take;
|
|
15
|
+
})(MapUtil = exports.MapUtil || (exports.MapUtil = {}));
|
|
16
|
+
//# sourceMappingURL=MapUtil.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StringUtil.d.ts","sourceRoot":"","sources":["../../src/utils/StringUtil.ts"],"names":[],"mappings":"AAAA,yBAAiB,UAAU,CAC3B;IACI,SAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAM1E;CACJ"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StringUtil = void 0;
|
|
4
|
+
var StringUtil;
|
|
5
|
+
(function (StringUtil) {
|
|
6
|
+
function betweens(str, start, end) {
|
|
7
|
+
var ret = str.split(start);
|
|
8
|
+
ret.splice(0, 1);
|
|
9
|
+
return ret.map(function (str) { return str.split(end)[0]; });
|
|
10
|
+
}
|
|
11
|
+
StringUtil.betweens = betweens;
|
|
12
|
+
})(StringUtil = exports.StringUtil || (exports.StringUtil = {}));
|
|
13
|
+
//# sourceMappingURL=StringUtil.js.map
|
package/package.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nestia",
|
|
3
|
-
"version": "2.1.0-dev.
|
|
3
|
+
"version": "2.1.0-dev.20220430",
|
|
4
4
|
"description": "Automatic SDK and Document generator for the NestJS",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "lib/index.d.ts",
|
|
6
7
|
"bin": {
|
|
7
|
-
"nestia": "./
|
|
8
|
+
"nestia": "./lib/executable/nestia.js"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
11
|
+
"build": "rimraf lib && ttsc",
|
|
12
|
+
"dev": "npm run build -- --watch",
|
|
13
|
+
"test": "node lib/test"
|
|
12
14
|
},
|
|
13
15
|
"repository": {
|
|
14
16
|
"type": "git",
|
|
@@ -28,21 +30,26 @@
|
|
|
28
30
|
},
|
|
29
31
|
"homepage": "https://github.com/samchon/nestia#readme",
|
|
30
32
|
"dependencies": {
|
|
31
|
-
"@types/cli": "^0.11.19",
|
|
32
|
-
"@types/glob": "^7.2.0",
|
|
33
|
-
"@types/node": "^17.0.23",
|
|
34
|
-
"@types/reflect-metadata": "^0.1.0",
|
|
35
33
|
"cli": "^1.0.1",
|
|
36
34
|
"del": "^6.0.0",
|
|
37
35
|
"glob": "^7.2.0",
|
|
36
|
+
"jsonc-simple-parser": "^2.2.1",
|
|
37
|
+
"nestia-fetcher": "^2.0.1",
|
|
38
|
+
"tgrid": "^0.8.6",
|
|
38
39
|
"ts-node": "^10.7.0",
|
|
39
|
-
"
|
|
40
|
+
"tsconfig-paths": "^3.14.1",
|
|
41
|
+
"tstl": "^2.5.5",
|
|
40
42
|
"ttypescript": "^1.5.13",
|
|
41
43
|
"typescript": "^4.6.3",
|
|
42
44
|
"typescript-is": "^0.19.0",
|
|
45
|
+
"typescript-json": "^2.0.5",
|
|
43
46
|
"typescript-transform-paths": "^3.3.1"
|
|
44
47
|
},
|
|
45
48
|
"devDependencies": {
|
|
49
|
+
"@types/cli": "^0.11.19",
|
|
50
|
+
"@types/glob": "^7.2.0",
|
|
51
|
+
"@types/node": "^17.0.23",
|
|
52
|
+
"@types/reflect-metadata": "^0.1.0",
|
|
46
53
|
"nestia-helper": "^2.0.0",
|
|
47
54
|
"rimraf": "^3.0.2"
|
|
48
55
|
}
|
package/src/IConfiguration.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import * as tsc from "typescript";
|
|
2
|
-
|
|
3
|
-
export interface IConfiguration
|
|
4
|
-
{
|
|
5
|
-
input: string | string[] | IConfiguration.IInput;
|
|
6
|
-
output: string;
|
|
7
|
-
compilerOptions?: tsc.CompilerOptions;
|
|
8
|
-
assert?: boolean;
|
|
9
|
-
}
|
|
10
|
-
export namespace IConfiguration
|
|
11
|
-
{
|
|
12
|
-
export interface IInput
|
|
13
|
-
{
|
|
14
|
-
include: string[];
|
|
15
|
-
exclude?: string[];
|
|
16
|
-
}
|
|
17
|
-
}
|
package/src/NestiaApplication.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import * as path from "path";
|
|
3
|
-
import * as tsc from "typescript";
|
|
4
|
-
import { Pair } from "tstl/utility/Pair";
|
|
5
|
-
import { Singleton } from "tstl/thread/Singleton";
|
|
6
|
-
|
|
7
|
-
import { ControllerAnalyzer } from "./analyses/ControllerAnalyzer";
|
|
8
|
-
import { ReflectAnalyzer } from "./analyses/ReflectAnalyzer";
|
|
9
|
-
import { SourceFinder } from "./analyses/SourceFinder";
|
|
10
|
-
import { SdkGenerator } from "./generates/SdkGenerator";
|
|
11
|
-
|
|
12
|
-
import { IConfiguration } from "./IConfiguration";
|
|
13
|
-
import { IController } from "./structures/IController";
|
|
14
|
-
import { IRoute } from "./structures/IRoute";
|
|
15
|
-
import { ArrayUtil } from "./utils/ArrayUtil";
|
|
16
|
-
|
|
17
|
-
export class NestiaApplication
|
|
18
|
-
{
|
|
19
|
-
private readonly config_: IConfiguration;
|
|
20
|
-
private readonly bundle_checker_: Singleton<Promise<(str: string) => boolean>>;
|
|
21
|
-
|
|
22
|
-
public constructor(config: IConfiguration)
|
|
23
|
-
{
|
|
24
|
-
this.config_ = config;
|
|
25
|
-
this.bundle_checker_ = new Singleton(async () =>
|
|
26
|
-
{
|
|
27
|
-
const bundles: string[] = await fs.promises.readdir(`${__dirname}${path.sep}bundle`);
|
|
28
|
-
const tuples: Pair<string, boolean>[] = await ArrayUtil.asyncMap(bundles, async file =>
|
|
29
|
-
{
|
|
30
|
-
const relative: string = `${this.config_.output}${path.sep}${file}`;
|
|
31
|
-
const stats: fs.Stats = await fs.promises.stat(`${__dirname}${path.sep}bundle${path.sep}${file}`);
|
|
32
|
-
|
|
33
|
-
return new Pair(relative, stats.isDirectory());
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
return (file: string): boolean =>
|
|
37
|
-
{
|
|
38
|
-
for (const it of tuples)
|
|
39
|
-
if (it.second === false && file === it.first)
|
|
40
|
-
return true;
|
|
41
|
-
else if (it.second === true && file.indexOf(it.first) === 0)
|
|
42
|
-
return true;
|
|
43
|
-
return false;
|
|
44
|
-
};
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public async generate(): Promise<void>
|
|
49
|
-
{
|
|
50
|
-
// LOAD CONTROLLER FILES
|
|
51
|
-
const input: IConfiguration.IInput = this.config_.input instanceof Array
|
|
52
|
-
? { include: this.config_.input }
|
|
53
|
-
: typeof this.config_.input === "string"
|
|
54
|
-
? { include: [ this.config_.input ] }
|
|
55
|
-
: this.config_.input;
|
|
56
|
-
const fileList: string[] = await ArrayUtil.asyncFilter
|
|
57
|
-
(
|
|
58
|
-
await SourceFinder.find(input),
|
|
59
|
-
file => this.is_not_excluded(file)
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
// ANALYZE REFLECTS
|
|
63
|
-
const unique: WeakSet<any> = new WeakSet();
|
|
64
|
-
const controllerList: IController[] = [];
|
|
65
|
-
|
|
66
|
-
for (const file of fileList)
|
|
67
|
-
controllerList.push(...await ReflectAnalyzer.analyze(unique, file));
|
|
68
|
-
|
|
69
|
-
// ANALYZE TYPESCRIPT CODE
|
|
70
|
-
const program: tsc.Program = tsc.createProgram
|
|
71
|
-
(
|
|
72
|
-
controllerList.map(c => c.file),
|
|
73
|
-
this.config_.compilerOptions || {}
|
|
74
|
-
);
|
|
75
|
-
const checker: tsc.TypeChecker = program.getTypeChecker();
|
|
76
|
-
|
|
77
|
-
const routeList: IRoute[] = [];
|
|
78
|
-
for (const controller of controllerList)
|
|
79
|
-
{
|
|
80
|
-
const sourceFile: tsc.SourceFile | undefined = program.getSourceFile(controller.file);
|
|
81
|
-
if (sourceFile === undefined)
|
|
82
|
-
continue;
|
|
83
|
-
|
|
84
|
-
routeList.push(...ControllerAnalyzer.analyze(checker, sourceFile, controller));
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// DO GENERATE
|
|
88
|
-
await SdkGenerator.generate(this.config_, routeList);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
private async is_not_excluded(file: string): Promise<boolean>
|
|
92
|
-
{
|
|
93
|
-
return file.indexOf(`${this.config_.output}${path.sep}functional`) === -1
|
|
94
|
-
&& (await this.bundle_checker_.get())(file) === false;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import * as NodePath from "path";
|
|
2
|
-
import * as tsc from "typescript";
|
|
3
|
-
import { HashMap } from "tstl/container/HashMap";
|
|
4
|
-
|
|
5
|
-
import { IController } from "../structures/IController";
|
|
6
|
-
import { IRoute } from "../structures/IRoute";
|
|
7
|
-
|
|
8
|
-
import { GenericAnalyzer } from "./GenericAnalyzer";
|
|
9
|
-
import { ImportAnalyzer } from "./ImportAnalyzer";
|
|
10
|
-
|
|
11
|
-
export namespace ControllerAnalyzer
|
|
12
|
-
{
|
|
13
|
-
export function analyze(checker: tsc.TypeChecker, sourceFile: tsc.SourceFile, controller: IController): IRoute[]
|
|
14
|
-
{
|
|
15
|
-
// FIND CONTROLLER CLASS
|
|
16
|
-
const ret: IRoute[] = [];
|
|
17
|
-
tsc.forEachChild(sourceFile, node =>
|
|
18
|
-
{
|
|
19
|
-
if (tsc.isClassDeclaration(node) && node.name?.escapedText === controller.name)
|
|
20
|
-
{
|
|
21
|
-
// ANALYZE THE CONTROLLER
|
|
22
|
-
ret.push(..._Analyze_controller(checker, controller, node));
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
return ret;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/* ---------------------------------------------------------
|
|
30
|
-
CLASS
|
|
31
|
-
--------------------------------------------------------- */
|
|
32
|
-
function _Analyze_controller
|
|
33
|
-
(
|
|
34
|
-
checker: tsc.TypeChecker,
|
|
35
|
-
controller: IController,
|
|
36
|
-
classNode: tsc.ClassDeclaration
|
|
37
|
-
): IRoute[]
|
|
38
|
-
{
|
|
39
|
-
const ret: IRoute[] = [];
|
|
40
|
-
const classType: tsc.InterfaceType = checker.getTypeAtLocation(classNode) as tsc.InterfaceType;
|
|
41
|
-
const genericDict: GenericAnalyzer.Dictionary = GenericAnalyzer.analyze(checker, classNode);
|
|
42
|
-
|
|
43
|
-
for (const property of classType.getProperties())
|
|
44
|
-
if (property.declarations)
|
|
45
|
-
for (const declaration of property.declarations)
|
|
46
|
-
{
|
|
47
|
-
// TARGET ONLY METHOD
|
|
48
|
-
if (!tsc.isMethodDeclaration(declaration))
|
|
49
|
-
continue;
|
|
50
|
-
|
|
51
|
-
// IT MUST BE
|
|
52
|
-
const identifier = declaration.name;
|
|
53
|
-
if (!tsc.isIdentifier(identifier))
|
|
54
|
-
continue;
|
|
55
|
-
|
|
56
|
-
// ANALYZED WITH THE REFLECTED-FUNCTION
|
|
57
|
-
const func: IController.IFunction | undefined = controller.functions.find(f => f.name === identifier.escapedText);
|
|
58
|
-
if (func !== undefined)
|
|
59
|
-
ret.push(_Analyze_function(checker, controller, genericDict, func, declaration));
|
|
60
|
-
}
|
|
61
|
-
return ret;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/* ---------------------------------------------------------
|
|
65
|
-
FUNCTION
|
|
66
|
-
--------------------------------------------------------- */
|
|
67
|
-
function _Analyze_function
|
|
68
|
-
(
|
|
69
|
-
checker: tsc.TypeChecker,
|
|
70
|
-
controller: IController,
|
|
71
|
-
genericDict: GenericAnalyzer.Dictionary,
|
|
72
|
-
func: IController.IFunction,
|
|
73
|
-
declaration: tsc.MethodDeclaration
|
|
74
|
-
): IRoute
|
|
75
|
-
{
|
|
76
|
-
// PREPARE ASSETS
|
|
77
|
-
const signature: tsc.Signature | undefined = checker.getSignatureFromDeclaration(declaration);
|
|
78
|
-
if (signature === undefined)
|
|
79
|
-
throw new Error(`Error on ControllerAnalyzer._Analyze_function(): unable to get the ignature from the ${controller.name}.${func.name}().`);
|
|
80
|
-
|
|
81
|
-
const importDict: ImportAnalyzer.Dictionary = new HashMap();
|
|
82
|
-
|
|
83
|
-
// EXPLORE CHILDREN TYPES
|
|
84
|
-
const parameters: IRoute.IParameter[] = func.parameters.map(param => _Analyze_parameter
|
|
85
|
-
(
|
|
86
|
-
checker,
|
|
87
|
-
genericDict,
|
|
88
|
-
importDict,
|
|
89
|
-
controller,
|
|
90
|
-
func.name,
|
|
91
|
-
param,
|
|
92
|
-
declaration.parameters[param.index]
|
|
93
|
-
));
|
|
94
|
-
const output: string = ImportAnalyzer.analyze
|
|
95
|
-
(
|
|
96
|
-
checker,
|
|
97
|
-
genericDict,
|
|
98
|
-
importDict,
|
|
99
|
-
checker.getReturnTypeOfSignature(signature),
|
|
100
|
-
);
|
|
101
|
-
const imports: [string, string[]][] = importDict.toJSON().map(pair => [pair.first, pair.second.toJSON()]);
|
|
102
|
-
|
|
103
|
-
// CONFIGURE PATH
|
|
104
|
-
let path: string = NodePath.join(controller.path, func.path).split("\\").join("/");
|
|
105
|
-
if (path[0] !== "/")
|
|
106
|
-
path = "/" + path;
|
|
107
|
-
if (path[path.length - 1] === "/" && path !== "/")
|
|
108
|
-
path = path.substr(0, path.length - 1);
|
|
109
|
-
|
|
110
|
-
// RETURNS
|
|
111
|
-
return {
|
|
112
|
-
...func,
|
|
113
|
-
path,
|
|
114
|
-
parameters,
|
|
115
|
-
output,
|
|
116
|
-
imports,
|
|
117
|
-
|
|
118
|
-
symbol: `${controller.name}.${func.name}()`,
|
|
119
|
-
comments: signature.getDocumentationComment(undefined),
|
|
120
|
-
tags: signature.getJsDocTags()
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/* ---------------------------------------------------------
|
|
125
|
-
PARAMETER
|
|
126
|
-
--------------------------------------------------------- */
|
|
127
|
-
function _Analyze_parameter
|
|
128
|
-
(
|
|
129
|
-
checker: tsc.TypeChecker,
|
|
130
|
-
genericDict: GenericAnalyzer.Dictionary,
|
|
131
|
-
importDict: ImportAnalyzer.Dictionary,
|
|
132
|
-
controller: IController,
|
|
133
|
-
funcName: string,
|
|
134
|
-
param: IController.IParameter,
|
|
135
|
-
declaration: tsc.ParameterDeclaration
|
|
136
|
-
): IRoute.IParameter
|
|
137
|
-
{
|
|
138
|
-
const symbol: tsc.Symbol = checker.getSymbolAtLocation(declaration.name)!;
|
|
139
|
-
const type: tsc.Type = checker.getTypeOfSymbolAtLocation(symbol, declaration);
|
|
140
|
-
const name: string = symbol.getEscapedName().toString();
|
|
141
|
-
|
|
142
|
-
// VALIDATE PARAMETERS
|
|
143
|
-
if ((param.category === "query" || param.category === "body") && param.field !== undefined)
|
|
144
|
-
throw new Error(`Error on ${controller.name}.${funcName}(): parameter ${name} is specifying a field ${param.field} of the request ${param.category} message, however, Nestia does not support the field specialization for the request ${param.category} message. Erase the ${controller.name}.${funcName}()#${name} parameter and re-define a new decorator accepting full structured message.`);
|
|
145
|
-
|
|
146
|
-
return {
|
|
147
|
-
name,
|
|
148
|
-
category: param.category,
|
|
149
|
-
field: param.field,
|
|
150
|
-
encrypted: param.encrypted,
|
|
151
|
-
type: ImportAnalyzer.analyze(checker, genericDict, importDict, type)
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import * as tsc from "typescript";
|
|
2
|
-
|
|
3
|
-
export namespace GenericAnalyzer
|
|
4
|
-
{
|
|
5
|
-
export type Dictionary = WeakMap<tsc.Type, tsc.Type>;
|
|
6
|
-
|
|
7
|
-
export function analyze(checker: tsc.TypeChecker, classNode: tsc.ClassDeclaration): Dictionary
|
|
8
|
-
{
|
|
9
|
-
const dict: Dictionary = new WeakMap();
|
|
10
|
-
explore(checker, dict, classNode);
|
|
11
|
-
return dict;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function explore(checker: tsc.TypeChecker, dict: Dictionary, classNode: tsc.ClassDeclaration): void
|
|
15
|
-
{
|
|
16
|
-
if (classNode.heritageClauses === undefined)
|
|
17
|
-
return;
|
|
18
|
-
|
|
19
|
-
for (const heritage of classNode.heritageClauses)
|
|
20
|
-
for (const hType of heritage.types)
|
|
21
|
-
{
|
|
22
|
-
// MUST BE CLASS
|
|
23
|
-
const expression: tsc.Type = checker.getTypeAtLocation(hType.expression);
|
|
24
|
-
const superNode: tsc.Declaration = expression.symbol.getDeclarations()![0];
|
|
25
|
-
|
|
26
|
-
if (!tsc.isClassDeclaration(superNode))
|
|
27
|
-
continue;
|
|
28
|
-
|
|
29
|
-
// SPECIFY GENERICS
|
|
30
|
-
const usages: ReadonlyArray<tsc.TypeNode> = if_undefined_array(hType.typeArguments);
|
|
31
|
-
const parameters: ReadonlyArray<tsc.TypeParameterDeclaration> = if_undefined_array(superNode.typeParameters);
|
|
32
|
-
|
|
33
|
-
parameters.forEach((param, index) =>
|
|
34
|
-
{
|
|
35
|
-
const paramType: tsc.Type = checker.getTypeAtLocation(param);
|
|
36
|
-
const usageType: tsc.Type = (usages[index] !== undefined)
|
|
37
|
-
? checker.getTypeAtLocation(usages[index])
|
|
38
|
-
: checker.getTypeAtLocation(param.default!);
|
|
39
|
-
|
|
40
|
-
dict.set(paramType, usageType);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// RECUSRIVE EXPLORATION
|
|
44
|
-
explore(checker, dict, superNode);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function if_undefined_array<T>(array: ReadonlyArray<T> | undefined): ReadonlyArray<T>
|
|
49
|
-
{
|
|
50
|
-
return array !== undefined ? array : [];
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import * as tsc from "typescript";
|
|
2
|
-
|
|
3
|
-
import { HashMap } from "tstl/container/HashMap";
|
|
4
|
-
import { HashSet } from "tstl/container/HashSet";
|
|
5
|
-
import { GenericAnalyzer } from "./GenericAnalyzer";
|
|
6
|
-
|
|
7
|
-
export namespace ImportAnalyzer
|
|
8
|
-
{
|
|
9
|
-
export interface IOutput
|
|
10
|
-
{
|
|
11
|
-
features: [string, string[]][];
|
|
12
|
-
alias: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type Dictionary = HashMap<string, HashSet<string>>;
|
|
16
|
-
|
|
17
|
-
export function analyze
|
|
18
|
-
(
|
|
19
|
-
checker: tsc.TypeChecker,
|
|
20
|
-
genericDict: GenericAnalyzer.Dictionary,
|
|
21
|
-
importDict: Dictionary,
|
|
22
|
-
type: tsc.Type
|
|
23
|
-
): string
|
|
24
|
-
{
|
|
25
|
-
return explore(checker, genericDict, importDict, type);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function explore
|
|
29
|
-
(
|
|
30
|
-
checker: tsc.TypeChecker,
|
|
31
|
-
genericDict: GenericAnalyzer.Dictionary,
|
|
32
|
-
importDict: Dictionary,
|
|
33
|
-
type: tsc.Type
|
|
34
|
-
): string
|
|
35
|
-
{
|
|
36
|
-
//----
|
|
37
|
-
// CONDITIONAL BRANCHES
|
|
38
|
-
//----
|
|
39
|
-
// DECOMPOSE GENERIC ARGUMENT
|
|
40
|
-
while (genericDict.has(type) === true)
|
|
41
|
-
type = genericDict.get(type)!;
|
|
42
|
-
|
|
43
|
-
// PRIMITIVE
|
|
44
|
-
const symbol: tsc.Symbol | undefined = type.getSymbol() || type.aliasSymbol;
|
|
45
|
-
if (symbol === undefined)
|
|
46
|
-
return checker.typeToString(type, undefined, undefined);
|
|
47
|
-
|
|
48
|
-
// UNION OR INTERSECT
|
|
49
|
-
else if (type.aliasSymbol === undefined && type.isUnionOrIntersection())
|
|
50
|
-
{
|
|
51
|
-
const joiner: string = type.isIntersection() ? " & " : " | ";
|
|
52
|
-
return type.types.map(child => explore(checker, genericDict, importDict, child)).join(joiner);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
//----
|
|
56
|
-
// SPECIALIZATION
|
|
57
|
-
//----
|
|
58
|
-
const name: string = get_name(symbol);
|
|
59
|
-
const sourceFile: tsc.SourceFile = symbol.declarations![0].getSourceFile();
|
|
60
|
-
|
|
61
|
-
if (sourceFile.fileName.indexOf("typescript/lib") === -1)
|
|
62
|
-
{
|
|
63
|
-
let it: HashMap.Iterator<string, HashSet<string>> = importDict.find(sourceFile.fileName);
|
|
64
|
-
if (it.equals(importDict.end()) === true)
|
|
65
|
-
it = importDict.emplace(sourceFile.fileName, new HashSet()).first;
|
|
66
|
-
it.second.insert(name.split(".")[0]);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// CHECK GENERIC
|
|
70
|
-
const generic: readonly tsc.Type[] = checker.getTypeArguments(type as tsc.TypeReference);
|
|
71
|
-
if (generic.length)
|
|
72
|
-
{
|
|
73
|
-
return name === "Promise"
|
|
74
|
-
? explore(checker, genericDict, importDict, generic[0])
|
|
75
|
-
: `${name}<${generic.map(child => explore(checker, genericDict, importDict, child)).join(", ")}>`;
|
|
76
|
-
}
|
|
77
|
-
else
|
|
78
|
-
return name;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function get_name(symbol: tsc.Symbol): string
|
|
82
|
-
{
|
|
83
|
-
let name: string = symbol.escapedName.toString();
|
|
84
|
-
let decl: tsc.Node = symbol.getDeclarations()![0].parent;
|
|
85
|
-
|
|
86
|
-
while (tsc.isModuleBlock(decl))
|
|
87
|
-
{
|
|
88
|
-
name = `${decl.parent.name.getText()}.${name}`;
|
|
89
|
-
decl = decl.parent.parent;
|
|
90
|
-
}
|
|
91
|
-
return name;
|
|
92
|
-
}
|
|
93
|
-
}
|