@nestia/sdk 3.0.0-dev.20231209 → 3.0.0

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 (168) hide show
  1. package/README.md +12 -9
  2. package/assets/config/nestia.config.ts +82 -79
  3. package/lib/INestiaConfig.d.ts +28 -6
  4. package/lib/NestiaSdkApplication.js +12 -10
  5. package/lib/NestiaSdkApplication.js.map +1 -1
  6. package/lib/analyses/ConfigAnalyzer.js +1 -1
  7. package/lib/analyses/ConfigAnalyzer.js.map +1 -1
  8. package/lib/analyses/ControllerAnalyzer.js +30 -15
  9. package/lib/analyses/ControllerAnalyzer.js.map +1 -1
  10. package/lib/analyses/ExceptionAnalyzer.js +35 -6
  11. package/lib/analyses/ExceptionAnalyzer.js.map +1 -1
  12. package/lib/analyses/ImportAnalyzer.d.ts +1 -2
  13. package/lib/analyses/ImportAnalyzer.js +2 -2
  14. package/lib/analyses/ImportAnalyzer.js.map +1 -1
  15. package/lib/analyses/PathAnalyzer.d.ts +2 -4
  16. package/lib/analyses/PathAnalyzer.js +27 -11
  17. package/lib/analyses/PathAnalyzer.js.map +1 -1
  18. package/lib/analyses/ReflectAnalyzer.js +34 -22
  19. package/lib/analyses/ReflectAnalyzer.js.map +1 -1
  20. package/lib/analyses/SecurityAnalyzer.js +13 -8
  21. package/lib/analyses/SecurityAnalyzer.js.map +1 -1
  22. package/lib/executable/internal/NestiaConfigLoader.js +300 -220
  23. package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
  24. package/lib/executable/sdk.js +11 -11
  25. package/lib/generates/CloneGenerator.d.ts +6 -0
  26. package/lib/generates/CloneGenerator.js +62 -0
  27. package/lib/generates/CloneGenerator.js.map +1 -0
  28. package/lib/generates/E2eGenerator.d.ts +2 -1
  29. package/lib/generates/E2eGenerator.js +2 -2
  30. package/lib/generates/E2eGenerator.js.map +1 -1
  31. package/lib/generates/SdkGenerator.js +3 -11
  32. package/lib/generates/SdkGenerator.js.map +1 -1
  33. package/lib/generates/SwaggerGenerator.d.ts +2 -0
  34. package/lib/generates/SwaggerGenerator.js +119 -62
  35. package/lib/generates/SwaggerGenerator.js.map +1 -1
  36. package/lib/generates/internal/E2eFileProgrammer.d.ts +2 -1
  37. package/lib/generates/internal/E2eFileProgrammer.js +49 -53
  38. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  39. package/lib/generates/internal/FilePrinter.d.ts +10 -0
  40. package/lib/generates/internal/FilePrinter.js +46 -0
  41. package/lib/generates/internal/FilePrinter.js.map +1 -0
  42. package/lib/{utils → generates/internal}/ImportDictionary.d.ts +2 -1
  43. package/lib/{utils → generates/internal}/ImportDictionary.js +20 -14
  44. package/lib/generates/internal/ImportDictionary.js.map +1 -0
  45. package/lib/generates/internal/SdkAliasCollection.d.ts +12 -0
  46. package/lib/generates/internal/SdkAliasCollection.js +97 -0
  47. package/lib/generates/internal/SdkAliasCollection.js.map +1 -0
  48. package/lib/generates/internal/SdkCloneProgrammer.d.ts +12 -0
  49. package/lib/generates/internal/SdkCloneProgrammer.js +99 -0
  50. package/lib/generates/internal/SdkCloneProgrammer.js.map +1 -0
  51. package/lib/generates/internal/SdkFileProgrammer.d.ts +2 -1
  52. package/lib/generates/internal/SdkFileProgrammer.js +27 -28
  53. package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
  54. package/lib/generates/internal/SdkFunctionProgrammer.d.ts +7 -2
  55. package/lib/generates/internal/SdkFunctionProgrammer.js +115 -322
  56. package/lib/generates/internal/SdkFunctionProgrammer.js.map +1 -1
  57. package/lib/generates/internal/SdkImportWizard.d.ts +1 -1
  58. package/lib/generates/internal/SdkNamespaceProgrammer.d.ts +11 -0
  59. package/lib/generates/internal/SdkNamespaceProgrammer.js +180 -0
  60. package/lib/generates/internal/SdkNamespaceProgrammer.js.map +1 -0
  61. package/lib/generates/internal/SdkRouteProgrammer.d.ts +7 -0
  62. package/lib/generates/internal/SdkRouteProgrammer.js +55 -0
  63. package/lib/generates/internal/SdkRouteProgrammer.js.map +1 -0
  64. package/lib/generates/internal/SdkSimulationProgrammer.d.ts +8 -2
  65. package/lib/generates/internal/SdkSimulationProgrammer.js +103 -89
  66. package/lib/generates/internal/SdkSimulationProgrammer.js.map +1 -1
  67. package/lib/generates/internal/SdkTypeProgrammer.d.ts +9 -0
  68. package/lib/generates/internal/SdkTypeProgrammer.js +228 -0
  69. package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -0
  70. package/lib/generates/internal/SwaggerSchemaGenerator.d.ts +4 -4
  71. package/lib/generates/internal/SwaggerSchemaGenerator.js +30 -28
  72. package/lib/generates/internal/SwaggerSchemaGenerator.js.map +1 -1
  73. package/lib/structures/IController.d.ts +4 -2
  74. package/lib/structures/IRoute.d.ts +5 -4
  75. package/lib/structures/ISwaggerLazyProperty.d.ts +2 -2
  76. package/lib/structures/ISwaggerLazySchema.d.ts +2 -2
  77. package/lib/structures/ParamCategory.d.ts +1 -1
  78. package/lib/structures/TypeEntry.js +2 -2
  79. package/lib/structures/TypeEntry.js.map +1 -1
  80. package/lib/utils/StringUtil.d.ts +3 -0
  81. package/lib/utils/StringUtil.js +8 -0
  82. package/lib/utils/StringUtil.js.map +1 -0
  83. package/package.json +12 -16
  84. package/src/INestiaConfig.ts +30 -6
  85. package/src/NestiaSdkApplication.ts +255 -253
  86. package/src/analyses/AccessorAnalyzer.ts +60 -60
  87. package/src/analyses/ConfigAnalyzer.ts +147 -147
  88. package/src/analyses/ControllerAnalyzer.ts +42 -19
  89. package/src/analyses/ExceptionAnalyzer.ts +148 -115
  90. package/src/analyses/GenericAnalyzer.ts +51 -51
  91. package/src/analyses/ImportAnalyzer.ts +1 -2
  92. package/src/analyses/PathAnalyzer.ts +110 -98
  93. package/src/analyses/ReflectAnalyzer.ts +39 -35
  94. package/src/analyses/SecurityAnalyzer.ts +24 -20
  95. package/src/executable/internal/CommandParser.ts +15 -15
  96. package/src/executable/internal/NestiaConfigLoader.ts +67 -67
  97. package/src/executable/internal/NestiaSdkCommand.ts +60 -60
  98. package/src/executable/sdk.ts +73 -73
  99. package/src/generates/CloneGenerator.ts +62 -0
  100. package/src/generates/E2eGenerator.ts +66 -64
  101. package/src/generates/SdkGenerator.ts +84 -96
  102. package/src/generates/SwaggerGenerator.ts +145 -53
  103. package/src/generates/internal/E2eFileProgrammer.ts +182 -123
  104. package/src/generates/internal/FilePrinter.ts +53 -0
  105. package/src/{utils → generates/internal}/ImportDictionary.ts +35 -13
  106. package/src/generates/internal/SdkAliasCollection.ts +152 -0
  107. package/src/generates/internal/SdkCloneProgrammer.ts +155 -0
  108. package/src/generates/internal/SdkDistributionComposer.ts +91 -91
  109. package/src/generates/internal/SdkFileProgrammer.ts +115 -106
  110. package/src/generates/internal/SdkFunctionProgrammer.ts +298 -518
  111. package/src/generates/internal/SdkImportWizard.ts +55 -55
  112. package/src/generates/internal/SdkNamespaceProgrammer.ts +510 -0
  113. package/src/generates/internal/SdkRouteDirectory.ts +17 -17
  114. package/src/generates/internal/SdkRouteProgrammer.ts +83 -0
  115. package/src/generates/internal/SdkSimulationProgrammer.ts +365 -133
  116. package/src/generates/internal/SdkTypeProgrammer.ts +386 -0
  117. package/src/generates/internal/SwaggerSchemaGenerator.ts +437 -427
  118. package/src/generates/internal/SwaggerSchemaValidator.ts +198 -198
  119. package/src/index.ts +4 -4
  120. package/src/module.ts +2 -2
  121. package/src/structures/IController.ts +94 -95
  122. package/src/structures/IErrorReport.ts +6 -6
  123. package/src/structures/INestiaProject.ts +13 -13
  124. package/src/structures/INormalizedInput.ts +20 -20
  125. package/src/structures/IRoute.ts +53 -53
  126. package/src/structures/ISwaggerLazyProperty.ts +2 -2
  127. package/src/structures/ISwaggerLazySchema.ts +2 -2
  128. package/src/structures/ITypeTuple.ts +6 -6
  129. package/src/structures/MethodType.ts +5 -5
  130. package/src/structures/ParamCategory.ts +1 -1
  131. package/src/structures/TypeEntry.ts +1 -1
  132. package/src/utils/ArrayUtil.ts +26 -26
  133. package/src/utils/FileRetriever.ts +22 -22
  134. package/src/utils/MapUtil.ts +14 -14
  135. package/src/utils/PathUtil.ts +10 -10
  136. package/src/utils/SourceFinder.ts +66 -66
  137. package/src/utils/StringUtil.ts +6 -0
  138. package/src/utils/StripEnums.ts +5 -5
  139. package/assets/bundle/api/utils/NestiaSimulator.ts +0 -70
  140. package/lib/generates/internal/SdkDtoGenerator.d.ts +0 -9
  141. package/lib/generates/internal/SdkDtoGenerator.js +0 -294
  142. package/lib/generates/internal/SdkDtoGenerator.js.map +0 -1
  143. package/lib/generates/internal/SdkTypeDefiner.d.ts +0 -11
  144. package/lib/generates/internal/SdkTypeDefiner.js +0 -82
  145. package/lib/generates/internal/SdkTypeDefiner.js.map +0 -1
  146. package/lib/structures/ISwagger.d.ts +0 -72
  147. package/lib/structures/ISwagger.js +0 -3
  148. package/lib/structures/ISwagger.js.map +0 -1
  149. package/lib/structures/ISwaggerComponents.d.ts +0 -26
  150. package/lib/structures/ISwaggerComponents.js +0 -3
  151. package/lib/structures/ISwaggerComponents.js.map +0 -1
  152. package/lib/structures/ISwaggerInfo.d.ts +0 -71
  153. package/lib/structures/ISwaggerInfo.js +0 -3
  154. package/lib/structures/ISwaggerInfo.js.map +0 -1
  155. package/lib/structures/ISwaggerRoute.d.ts +0 -47
  156. package/lib/structures/ISwaggerRoute.js +0 -3
  157. package/lib/structures/ISwaggerRoute.js.map +0 -1
  158. package/lib/structures/ISwaggerSecurityScheme.d.ts +0 -56
  159. package/lib/structures/ISwaggerSecurityScheme.js +0 -3
  160. package/lib/structures/ISwaggerSecurityScheme.js.map +0 -1
  161. package/lib/utils/ImportDictionary.js.map +0 -1
  162. package/src/generates/internal/SdkDtoGenerator.ts +0 -424
  163. package/src/generates/internal/SdkTypeDefiner.ts +0 -119
  164. package/src/structures/ISwagger.ts +0 -91
  165. package/src/structures/ISwaggerComponents.ts +0 -29
  166. package/src/structures/ISwaggerInfo.ts +0 -80
  167. package/src/structures/ISwaggerRoute.ts +0 -51
  168. package/src/structures/ISwaggerSecurityScheme.ts +0 -65
@@ -1,60 +1,60 @@
1
- import { Escaper } from "typia/lib/utils/Escaper";
2
-
3
- import { IRoute } from "../structures/IRoute";
4
-
5
- export namespace AccessorAnalyzer {
6
- export const analyze = (routes: IRoute[]) => {
7
- shrink(routes);
8
- variable(routes);
9
- shrink(routes);
10
- for (const r of routes) r.name = r.accessors.at(-1) ?? r.name;
11
- };
12
-
13
- const prepare = (routeList: IRoute[]): Map<string, number> => {
14
- const dict: Map<string, number> = new Map();
15
- for (const route of routeList)
16
- route.accessors.forEach((_a, i) => {
17
- const key: string = route.accessors.slice(0, i + 1).join(".");
18
- dict.set(key, (dict.get(key) ?? 0) + 1);
19
- });
20
- return dict;
21
- };
22
-
23
- const variable = (routeList: IRoute[]) => {
24
- const dict: Map<string, number> = prepare(routeList);
25
- for (const route of routeList) {
26
- const emended: string[] = route.accessors.slice();
27
- route.accessors.forEach((accessor, i) => {
28
- if (Escaper.variable(accessor)) return;
29
- while (true) {
30
- accessor = "$" + accessor;
31
- const partial: string = [
32
- ...route.accessors.slice(0, i),
33
- accessor,
34
- ].join(".");
35
- if (dict.has(partial) === false) {
36
- emended[i] = accessor;
37
- break;
38
- }
39
- }
40
- });
41
- route.accessors.splice(0, route.accessors.length, ...emended);
42
- }
43
- };
44
-
45
- const shrink = (routeList: IRoute[]) => {
46
- const dict: Map<string, number> = prepare(routeList);
47
- for (const route of routeList) {
48
- if (
49
- route.accessors.length < 2 ||
50
- route.accessors.at(-1) !== route.accessors.at(-2)
51
- )
52
- continue;
53
-
54
- const cut: string[] = route.accessors.slice(0, -1);
55
- if ((dict.get(cut.join(".")) ?? 0) > 1) continue;
56
-
57
- route.accessors = cut;
58
- }
59
- };
60
- }
1
+ import { Escaper } from "typia/lib/utils/Escaper";
2
+
3
+ import { IRoute } from "../structures/IRoute";
4
+
5
+ export namespace AccessorAnalyzer {
6
+ export const analyze = (routes: IRoute[]) => {
7
+ shrink(routes);
8
+ variable(routes);
9
+ shrink(routes);
10
+ for (const r of routes) r.name = r.accessors.at(-1) ?? r.name;
11
+ };
12
+
13
+ const prepare = (routeList: IRoute[]): Map<string, number> => {
14
+ const dict: Map<string, number> = new Map();
15
+ for (const route of routeList)
16
+ route.accessors.forEach((_a, i) => {
17
+ const key: string = route.accessors.slice(0, i + 1).join(".");
18
+ dict.set(key, (dict.get(key) ?? 0) + 1);
19
+ });
20
+ return dict;
21
+ };
22
+
23
+ const variable = (routeList: IRoute[]) => {
24
+ const dict: Map<string, number> = prepare(routeList);
25
+ for (const route of routeList) {
26
+ const emended: string[] = route.accessors.slice();
27
+ route.accessors.forEach((accessor, i) => {
28
+ if (Escaper.variable(accessor)) return;
29
+ while (true) {
30
+ accessor = "$" + accessor;
31
+ const partial: string = [
32
+ ...route.accessors.slice(0, i),
33
+ accessor,
34
+ ].join(".");
35
+ if (dict.has(partial) === false) {
36
+ emended[i] = accessor;
37
+ break;
38
+ }
39
+ }
40
+ });
41
+ route.accessors.splice(0, route.accessors.length, ...emended);
42
+ }
43
+ };
44
+
45
+ const shrink = (routeList: IRoute[]) => {
46
+ const dict: Map<string, number> = prepare(routeList);
47
+ for (const route of routeList) {
48
+ if (
49
+ route.accessors.length < 2 ||
50
+ route.accessors.at(-1) !== route.accessors.at(-2)
51
+ )
52
+ continue;
53
+
54
+ const cut: string[] = route.accessors.slice(0, -1);
55
+ if ((dict.get(cut.join(".")) ?? 0) > 1) continue;
56
+
57
+ route.accessors = cut;
58
+ }
59
+ };
60
+ }
@@ -1,147 +1,147 @@
1
- import { INestApplication, VersioningType } from "@nestjs/common";
2
- import { MODULE_PATH } from "@nestjs/common/constants";
3
- import { NestContainer } from "@nestjs/core";
4
- import { Module } from "@nestjs/core/injector/module";
5
- import fs from "fs";
6
- import path from "path";
7
- import { HashMap, Pair, Singleton } from "tstl";
8
-
9
- import { INestiaConfig } from "../INestiaConfig";
10
- import { SdkGenerator } from "../generates/SdkGenerator";
11
- import { INormalizedInput } from "../structures/INormalizedInput";
12
- import { ArrayUtil } from "../utils/ArrayUtil";
13
- import { MapUtil } from "../utils/MapUtil";
14
- import { SourceFinder } from "../utils/SourceFinder";
15
-
16
- export namespace ConfigAnalyzer {
17
- export const input = (config: INestiaConfig): Promise<INormalizedInput> =>
18
- MapUtil.take(memory, config, async () => {
19
- const input = config.input;
20
- if (Array.isArray(input)) return transform_input(config)(input);
21
- else if (typeof input === "function")
22
- return analyze_application(await input());
23
- else if (typeof input === "object")
24
- if (input === null)
25
- throw new Error("Invalid input config. It can't be null.");
26
- else return transform_input(config)(input.include, input.exclude);
27
- else if (typeof input === "string")
28
- return transform_input(config)([input]);
29
- else throw new Error("Invalid input config.");
30
- });
31
-
32
- const analyze_application = async (
33
- app: INestApplication,
34
- ): Promise<INormalizedInput> => {
35
- const files: HashMap<Pair<Function, string>, Set<string>> = new HashMap();
36
- const container: NestContainer = (app as any).container as NestContainer;
37
- const modules: Module[] = [...container.getModules().values()].filter(
38
- (m) => !!m.controllers.size,
39
- );
40
- for (const m of modules) {
41
- const path: string =
42
- Reflect.getMetadata(
43
- MODULE_PATH + container.getModules().applicationId,
44
- m.metatype,
45
- ) ??
46
- Reflect.getMetadata(MODULE_PATH, m.metatype) ??
47
- "";
48
- for (const controller of [...m.controllers.keys()]) {
49
- const file: string | null =
50
- (await require("get-function-location")(controller))?.source ?? null;
51
- if (file === null) continue;
52
-
53
- const location: string = normalize_file(file);
54
- if (location.length === 0) continue;
55
-
56
- const key: Pair<Function, string> = new Pair(
57
- controller as Function,
58
- location,
59
- );
60
- files.take(key, () => new Set([])).add(path);
61
- }
62
- }
63
-
64
- const versioning = (app as any).config?.versioningOptions;
65
- return {
66
- include: files.toJSON().map((pair) => ({
67
- controller: pair.first.first,
68
- file: pair.first.second,
69
- paths: [...pair.second.values()],
70
- })),
71
- globalPrefix:
72
- typeof (app as any).config?.globalPrefix === "string"
73
- ? {
74
- prefix: (app as any).config.globalPrefix,
75
- exclude: (app as any).config.globalPrefixOptions?.exclude ?? {},
76
- }
77
- : undefined,
78
- versioning:
79
- versioning === undefined || versioning.type !== VersioningType.URI
80
- ? undefined
81
- : {
82
- prefix:
83
- versioning.prefix === undefined || versioning.prefix === false
84
- ? "v"
85
- : versioning.prefix,
86
- defaultVersion: versioning.defaultVersion,
87
- },
88
- };
89
- };
90
-
91
- const normalize_file = (str: string) =>
92
- str.substring(
93
- str.startsWith("file:///")
94
- ? process.cwd()[0] === "/"
95
- ? 7
96
- : 8
97
- : str.startsWith("file://")
98
- ? 7
99
- : 0,
100
- );
101
-
102
- const transform_input =
103
- (config: INestiaConfig) =>
104
- async (include: string[], exclude?: string[]) => ({
105
- include: (
106
- await SourceFinder.find({
107
- include,
108
- exclude,
109
- filter: filter(config),
110
- })
111
- ).map((file) => ({
112
- paths: [""],
113
- file,
114
- })),
115
- });
116
-
117
- const filter =
118
- (config: INestiaConfig) =>
119
- async (location: string): Promise<boolean> =>
120
- location.endsWith(".ts") &&
121
- !location.endsWith(".d.ts") &&
122
- (config.output === undefined ||
123
- (location.indexOf(path.join(config.output, "functional")) === -1 &&
124
- (await (
125
- await bundler.get(config.output)
126
- )(location))) === false);
127
- }
128
-
129
- const memory = new Map<INestiaConfig, Promise<INormalizedInput>>();
130
- const bundler = new Singleton(async (output: string) => {
131
- const assets: string[] = await fs.promises.readdir(SdkGenerator.BUNDLE_PATH);
132
- const tuples: Pair<string, boolean>[] = await ArrayUtil.asyncMap(
133
- assets,
134
- async (file) => {
135
- const relative: string = path.join(output, file);
136
- const location: string = path.join(SdkGenerator.BUNDLE_PATH, file);
137
- const stats: fs.Stats = await fs.promises.stat(location);
138
- return new Pair(relative, stats.isDirectory());
139
- },
140
- );
141
- return async (file: string): Promise<boolean> => {
142
- for (const it of tuples)
143
- if (it.second === false && file === it.first) return true;
144
- else if (it.second === true && file.indexOf(it.first) === 0) return true;
145
- return false;
146
- };
147
- });
1
+ import { INestApplication, VersioningType } from "@nestjs/common";
2
+ import { MODULE_PATH } from "@nestjs/common/constants";
3
+ import { NestContainer } from "@nestjs/core";
4
+ import { Module } from "@nestjs/core/injector/module";
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import { HashMap, Pair, Singleton } from "tstl";
8
+
9
+ import { INestiaConfig } from "../INestiaConfig";
10
+ import { SdkGenerator } from "../generates/SdkGenerator";
11
+ import { INormalizedInput } from "../structures/INormalizedInput";
12
+ import { ArrayUtil } from "../utils/ArrayUtil";
13
+ import { MapUtil } from "../utils/MapUtil";
14
+ import { SourceFinder } from "../utils/SourceFinder";
15
+
16
+ export namespace ConfigAnalyzer {
17
+ export const input = (config: INestiaConfig): Promise<INormalizedInput> =>
18
+ MapUtil.take(memory, config, async () => {
19
+ const input = config.input;
20
+ if (Array.isArray(input)) return transform_input(config)(input);
21
+ else if (typeof input === "function")
22
+ return analyze_application(await input());
23
+ else if (typeof input === "object")
24
+ if (input === null)
25
+ throw new Error("Invalid input config. It can't be null.");
26
+ else return transform_input(config)(input.include, input.exclude);
27
+ else if (typeof input === "string")
28
+ return transform_input(config)([input]);
29
+ else throw new Error("Invalid input config.");
30
+ });
31
+
32
+ const analyze_application = async (
33
+ app: INestApplication,
34
+ ): Promise<INormalizedInput> => {
35
+ const files: HashMap<Pair<Function, string>, Set<string>> = new HashMap();
36
+ const container: NestContainer = (app as any).container as NestContainer;
37
+ const modules: Module[] = [...container.getModules().values()].filter(
38
+ (m) => !!m.controllers.size,
39
+ );
40
+ for (const m of modules) {
41
+ const path: string =
42
+ Reflect.getMetadata(
43
+ MODULE_PATH + container.getModules().applicationId,
44
+ m.metatype,
45
+ ) ??
46
+ Reflect.getMetadata(MODULE_PATH, m.metatype) ??
47
+ "";
48
+ for (const controller of [...m.controllers.keys()]) {
49
+ const file: string | null =
50
+ (await require("get-function-location")(controller))?.source ?? null;
51
+ if (file === null) continue;
52
+
53
+ const location: string = normalize_file(file);
54
+ if (location.length === 0) continue;
55
+
56
+ const key: Pair<Function, string> = new Pair(
57
+ controller as Function,
58
+ location,
59
+ );
60
+ files.take(key, () => new Set([])).add(path);
61
+ }
62
+ }
63
+
64
+ const versioning = (app as any).config?.versioningOptions;
65
+ return {
66
+ include: files.toJSON().map((pair) => ({
67
+ controller: pair.first.first,
68
+ file: decodeURIComponent(pair.first.second),
69
+ paths: [...pair.second.values()],
70
+ })),
71
+ globalPrefix:
72
+ typeof (app as any).config?.globalPrefix === "string"
73
+ ? {
74
+ prefix: (app as any).config.globalPrefix,
75
+ exclude: (app as any).config.globalPrefixOptions?.exclude ?? {},
76
+ }
77
+ : undefined,
78
+ versioning:
79
+ versioning === undefined || versioning.type !== VersioningType.URI
80
+ ? undefined
81
+ : {
82
+ prefix:
83
+ versioning.prefix === undefined || versioning.prefix === false
84
+ ? "v"
85
+ : versioning.prefix,
86
+ defaultVersion: versioning.defaultVersion,
87
+ },
88
+ };
89
+ };
90
+
91
+ const normalize_file = (str: string) =>
92
+ str.substring(
93
+ str.startsWith("file:///")
94
+ ? process.cwd()[0] === "/"
95
+ ? 7
96
+ : 8
97
+ : str.startsWith("file://")
98
+ ? 7
99
+ : 0,
100
+ );
101
+
102
+ const transform_input =
103
+ (config: INestiaConfig) =>
104
+ async (include: string[], exclude?: string[]) => ({
105
+ include: (
106
+ await SourceFinder.find({
107
+ include,
108
+ exclude,
109
+ filter: filter(config),
110
+ })
111
+ ).map((file) => ({
112
+ paths: [""],
113
+ file,
114
+ })),
115
+ });
116
+
117
+ const filter =
118
+ (config: INestiaConfig) =>
119
+ async (location: string): Promise<boolean> =>
120
+ location.endsWith(".ts") &&
121
+ !location.endsWith(".d.ts") &&
122
+ (config.output === undefined ||
123
+ (location.indexOf(path.join(config.output, "functional")) === -1 &&
124
+ (await (
125
+ await bundler.get(config.output)
126
+ )(location))) === false);
127
+ }
128
+
129
+ const memory = new Map<INestiaConfig, Promise<INormalizedInput>>();
130
+ const bundler = new Singleton(async (output: string) => {
131
+ const assets: string[] = await fs.promises.readdir(SdkGenerator.BUNDLE_PATH);
132
+ const tuples: Pair<string, boolean>[] = await ArrayUtil.asyncMap(
133
+ assets,
134
+ async (file) => {
135
+ const relative: string = path.join(output, file);
136
+ const location: string = path.join(SdkGenerator.BUNDLE_PATH, file);
137
+ const stats: fs.Stats = await fs.promises.stat(location);
138
+ return new Pair(relative, stats.isDirectory());
139
+ },
140
+ );
141
+ return async (file: string): Promise<boolean> => {
142
+ for (const it of tuples)
143
+ if (it.second === false && file === it.first) return true;
144
+ else if (it.second === true && file.indexOf(it.first) === 0) return true;
145
+ return false;
146
+ };
147
+ });
@@ -1,6 +1,6 @@
1
1
  import { VERSION_NEUTRAL, VersionValue } from "@nestjs/common/interfaces";
2
2
  import path from "path";
3
- import { HashMap } from "tstl/container/HashMap";
3
+ import { HashMap } from "tstl";
4
4
  import ts from "typescript";
5
5
  import { CommentFactory } from "typia/lib/factories/CommentFactory";
6
6
 
@@ -132,7 +132,12 @@ export namespace ControllerAnalyzer {
132
132
  importDict,
133
133
  signature.getReturnType(),
134
134
  );
135
- if (outputType === null || outputType.typeName === "__type") {
135
+ if (
136
+ outputType === null ||
137
+ (project.config.clone !== true &&
138
+ (outputType.typeName === "__type" ||
139
+ outputType.typeName === "__object"))
140
+ ) {
136
141
  project.errors.push({
137
142
  file: controller.file,
138
143
  controller: controller.name,
@@ -172,16 +177,18 @@ export namespace ControllerAnalyzer {
172
177
  ...jsDocTags
173
178
  .filter((tag) => tag.name === "security")
174
179
  .map((tag) =>
175
- (tag.text ?? []).map((text) => {
176
- const line: string[] = text.text
177
- .split(" ")
178
- .filter((s) => s.trim())
179
- .filter((s) => !!s.length);
180
- if (line.length === 0) return {};
181
- return {
182
- [line[0]]: line.slice(1),
183
- };
184
- }),
180
+ tag.text === undefined
181
+ ? [{}]
182
+ : tag.text.map((text) => {
183
+ const line: string[] = text.text
184
+ .split(" ")
185
+ .filter((s) => s.trim())
186
+ .filter((s) => !!s.length);
187
+ if (line.length === 0) return {};
188
+ return {
189
+ [line[0]]: line.slice(1),
190
+ };
191
+ }),
185
192
  )
186
193
  .flat(),
187
194
  );
@@ -189,6 +196,7 @@ export namespace ControllerAnalyzer {
189
196
  // CONSTRUCT COMMON DATA
190
197
  const common: Omit<IRoute, "path" | "accessors"> = {
191
198
  ...func,
199
+ controller: controller.target,
192
200
  parameters: parameters.filter((p) => p !== null) as IRoute.IParameter[],
193
201
  output: {
194
202
  type: outputType.type,
@@ -197,9 +205,9 @@ export namespace ControllerAnalyzer {
197
205
  },
198
206
  imports,
199
207
  status: func.status,
200
- symbol: {
201
- class: controller.name,
202
- function: func.name,
208
+ target: {
209
+ class: controller.target,
210
+ function: func.target,
203
211
  },
204
212
  location: (() => {
205
213
  const file = declaration.getSourceFile();
@@ -265,8 +273,8 @@ export namespace ControllerAnalyzer {
265
273
  v === null
266
274
  ? null
267
275
  : project.input.versioning?.prefix?.length
268
- ? `${project.input.versioning.prefix}${v}`
269
- : v,
276
+ ? `${project.input.versioning.prefix}${v}`
277
+ : v,
270
278
  ),
271
279
  )({
272
280
  method: func.method,
@@ -274,9 +282,20 @@ export namespace ControllerAnalyzer {
274
282
  }),
275
283
  )
276
284
  .flat()
285
+ .filter((path) => {
286
+ const escaped: string | null = PathAnalyzer.escape(path);
287
+ if (escaped === null)
288
+ project.errors.push({
289
+ file: controller.file,
290
+ controller: controller.name,
291
+ function: func.name,
292
+ message: `unable to escape the path "${path}".`,
293
+ });
294
+ return escaped !== null;
295
+ })
277
296
  .map((path) => ({
278
297
  ...common,
279
- path: PathAnalyzer.escape(path, () => "ControllerAnalyzer.analyze()"),
298
+ path: PathAnalyzer.escape(path)!,
280
299
  accessors: [...PathUtil.accessors(path), func.name],
281
300
  }));
282
301
  };
@@ -348,7 +367,11 @@ export namespace ControllerAnalyzer {
348
367
  importDict,
349
368
  type,
350
369
  );
351
- if (tuple === null || tuple.typeName === "__type")
370
+ if (
371
+ tuple === null ||
372
+ (project.config.clone !== true &&
373
+ (tuple.typeName === "__type" || tuple.typeName === "__object"))
374
+ )
352
375
  errors.push({
353
376
  file: controller.file,
354
377
  controller: controller.name,