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.
Files changed (116) hide show
  1. package/.github/workflows/build.yml +2 -4
  2. package/README.md +84 -14
  3. package/{src/bundle → bundle}/HttpError.ts +0 -0
  4. package/{src/bundle → bundle}/IConnection.ts +0 -0
  5. package/{src/bundle → bundle}/Primitive.ts +0 -0
  6. package/{src/bundle → bundle}/__internal/AesPkcs5.ts +0 -0
  7. package/{src/bundle → bundle}/__internal/Fetcher.ts +0 -0
  8. package/lib/IConfiguration.d.ts +71 -0
  9. package/lib/IConfiguration.d.ts.map +1 -0
  10. package/lib/IConfiguration.js +3 -0
  11. package/lib/NestiaApplication.d.ts +12 -0
  12. package/lib/NestiaApplication.d.ts.map +1 -0
  13. package/lib/NestiaApplication.js +340 -0
  14. package/lib/analyses/ControllerAnalyzer.d.ts +7 -0
  15. package/lib/analyses/ControllerAnalyzer.d.ts.map +1 -0
  16. package/lib/analyses/ControllerAnalyzer.js +191 -0
  17. package/lib/analyses/GenericAnalyzer.d.ts +6 -0
  18. package/lib/analyses/GenericAnalyzer.d.ts.map +1 -0
  19. package/lib/analyses/GenericAnalyzer.js +100 -0
  20. package/lib/analyses/ImportAnalyzer.d.ts +14 -0
  21. package/lib/analyses/ImportAnalyzer.d.ts.map +1 -0
  22. package/lib/analyses/ImportAnalyzer.js +79 -0
  23. package/lib/analyses/ReflectAnalyzer.d.ts +5 -0
  24. package/lib/analyses/ReflectAnalyzer.d.ts.map +1 -0
  25. package/lib/analyses/ReflectAnalyzer.js +313 -0
  26. package/lib/analyses/SourceFinder.d.ts +5 -0
  27. package/lib/analyses/SourceFinder.d.ts.map +1 -0
  28. package/lib/analyses/SourceFinder.js +260 -0
  29. package/lib/executable/internal/CompilerOptions.d.ts +14 -0
  30. package/lib/executable/internal/CompilerOptions.d.ts.map +1 -0
  31. package/lib/executable/internal/CompilerOptions.js +126 -0
  32. package/lib/executable/internal/NestiaCommand.d.ts +5 -0
  33. package/lib/executable/internal/NestiaCommand.d.ts.map +1 -0
  34. package/lib/executable/internal/NestiaCommand.js +228 -0
  35. package/lib/executable/internal/NestiaConfig.d.ts +5 -0
  36. package/lib/executable/internal/NestiaConfig.d.ts.map +1 -0
  37. package/lib/executable/internal/NestiaConfig.js +277 -0
  38. package/lib/executable/internal/nestia.config.getter.d.ts +2 -0
  39. package/lib/executable/internal/nestia.config.getter.d.ts.map +1 -0
  40. package/lib/executable/internal/nestia.config.getter.js +60 -0
  41. package/lib/executable/nestia.d.ts +3 -0
  42. package/lib/executable/nestia.d.ts.map +1 -0
  43. package/lib/executable/nestia.js +129 -0
  44. package/lib/generates/FileGenerator.d.ts +6 -0
  45. package/lib/generates/FileGenerator.d.ts.map +1 -0
  46. package/lib/generates/FileGenerator.js +326 -0
  47. package/lib/generates/FunctionGenerator.d.ts +6 -0
  48. package/lib/generates/FunctionGenerator.d.ts.map +1 -0
  49. package/lib/generates/FunctionGenerator.js +217 -0
  50. package/lib/generates/SdkGenerator.d.ts +8 -0
  51. package/lib/generates/SdkGenerator.d.ts.map +1 -0
  52. package/lib/generates/SdkGenerator.js +128 -0
  53. package/lib/generates/SwaggerGenerator.d.ts +7 -0
  54. package/lib/generates/SwaggerGenerator.d.ts.map +1 -0
  55. package/lib/generates/SwaggerGenerator.js +258 -0
  56. package/lib/index.d.ts +3 -0
  57. package/lib/index.d.ts.map +1 -0
  58. package/lib/index.js +28 -0
  59. package/lib/module.d.ts +3 -0
  60. package/lib/module.d.ts.map +1 -0
  61. package/lib/module.js +19 -0
  62. package/{src/structures/IController.ts → lib/structures/IController.d.ts} +6 -13
  63. package/lib/structures/IController.d.ts.map +1 -0
  64. package/lib/structures/IController.js +3 -0
  65. package/{src/structures/IRoute.ts → lib/structures/IRoute.d.ts} +8 -13
  66. package/lib/structures/IRoute.d.ts.map +1 -0
  67. package/lib/structures/IRoute.js +3 -0
  68. package/lib/structures/ISwagger.d.ts +36 -0
  69. package/lib/structures/ISwagger.d.ts.map +1 -0
  70. package/lib/structures/ISwagger.js +3 -0
  71. package/lib/structures/IType.d.ts +6 -0
  72. package/lib/structures/IType.d.ts.map +1 -0
  73. package/lib/structures/IType.js +3 -0
  74. package/lib/structures/MethodType.d.ts +5 -0
  75. package/lib/structures/MethodType.d.ts.map +1 -0
  76. package/lib/structures/MethodType.js +8 -0
  77. package/lib/structures/ParamCategory.d.ts +2 -0
  78. package/lib/structures/ParamCategory.d.ts.map +1 -0
  79. package/lib/structures/ParamCategory.js +3 -0
  80. package/lib/utils/ArrayUtil.d.ts +6 -0
  81. package/lib/utils/ArrayUtil.d.ts.map +1 -0
  82. package/lib/utils/ArrayUtil.js +144 -0
  83. package/lib/utils/DirectoryUtil.d.ts +6 -0
  84. package/lib/utils/DirectoryUtil.d.ts.map +1 -0
  85. package/lib/utils/DirectoryUtil.js +190 -0
  86. package/lib/utils/ImportDictionary.d.ts +7 -0
  87. package/lib/utils/ImportDictionary.d.ts.map +1 -0
  88. package/lib/utils/ImportDictionary.js +83 -0
  89. package/lib/utils/MapUtil.d.ts +4 -0
  90. package/lib/utils/MapUtil.d.ts.map +1 -0
  91. package/lib/utils/MapUtil.js +16 -0
  92. package/lib/utils/StringUtil.d.ts +4 -0
  93. package/lib/utils/StringUtil.d.ts.map +1 -0
  94. package/lib/utils/StringUtil.js +13 -0
  95. package/package.json +17 -10
  96. package/src/IConfiguration.ts +0 -17
  97. package/src/NestiaApplication.ts +0 -96
  98. package/src/analyses/ControllerAnalyzer.ts +0 -154
  99. package/src/analyses/GenericAnalyzer.ts +0 -52
  100. package/src/analyses/ImportAnalyzer.ts +0 -93
  101. package/src/analyses/ReflectAnalyzer.ts +0 -221
  102. package/src/analyses/SourceFinder.ts +0 -73
  103. package/src/bin/nestia.ts +0 -125
  104. package/src/executable/sdk.ts +0 -89
  105. package/src/generates/FileGenerator.ts +0 -150
  106. package/src/generates/FunctionGenerator.ts +0 -201
  107. package/src/generates/SdkGenerator.ts +0 -39
  108. package/src/internal/CompilerOptions.ts +0 -142
  109. package/src/structures/MethodType.ts +0 -6
  110. package/src/structures/ParamCategory.ts +0 -1
  111. package/src/utils/ArrayUtil.ts +0 -26
  112. package/src/utils/DirectoryUtil.ts +0 -48
  113. package/src/utils/ImportDictionary.ts +0 -44
  114. package/src/utils/StringUtil.ts +0 -10
  115. package/src/utils/stripJsonComments.ts +0 -79
  116. 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,4 @@
1
+ export declare namespace MapUtil {
2
+ function take<Key, T>(dict: Map<Key, T>, key: Key, generator: () => T): T;
3
+ }
4
+ //# sourceMappingURL=MapUtil.d.ts.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,4 @@
1
+ export declare namespace StringUtil {
2
+ function betweens(str: string, start: string, end: string): string[];
3
+ }
4
+ //# sourceMappingURL=StringUtil.d.ts.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.20220414",
3
+ "version": "2.1.0-dev.20220430",
4
4
  "description": "Automatic SDK and Document generator for the NestJS",
5
- "main": "src/index.ts",
5
+ "main": "lib/index.js",
6
+ "typings": "lib/index.d.ts",
6
7
  "bin": {
7
- "nestia": "./src/bin/nestia.ts"
8
+ "nestia": "./lib/executable/nestia.js"
8
9
  },
9
10
  "scripts": {
10
- "dev": "tsc --watch",
11
- "test": "ts-node test/index"
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
- "tstl": "^2.5.3",
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
  }
@@ -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
- }
@@ -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
- }