nestia 0.3.5 → 1.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.
package/README.md CHANGED
@@ -70,18 +70,19 @@ Just type the `nestia sdk <input> --out <output>` command in the console. If the
70
70
 
71
71
  Also, when generating a SDK using the cli options, `compilerOptions` would follow the `tsconfig.json`, that is configured for the backend server. If no `tsconfig.json` file exists in your project, the configuration would be default option (`ES5` with `strict` mode). If you want to use different `compilerOptions` with the `tsconfig.json`, you should configure the [nestia.config.ts](#nestiaconfigts).
72
72
 
73
- ```bash
74
- npx nestia install
75
- ```
76
-
77
73
  ### Dependencies
78
- SDK library generated by the **Nestia** has some dependencies like below.
79
-
80
- When you type the `nestia install` command in the console, those dependencies would be automatically installed and enrolled to the `dependencies` and `devDependencies` fields in the `package.json`
74
+ SDK library generated by the **Nestia** requires the [nestia-fetcher](https://github.com/samchon/nestia-fetcher) module.
81
75
 
82
- - [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node)
83
- - [node-fetch](https://github.com/node-fetch/node-fetch)
76
+ Therefore, when you publish an SDK library generated by this **Nestia**, you have to write the [nestia-fetcher](https://github.com/samchon/nestia-fetcher) module into the `dependencies` property of the `package.json` file like below. You also can configure the `dependencies` property of the `package.json` file by typing the `npm install --save nestia-fetcher` command in the console, too.
84
77
 
78
+ ```json
79
+ {
80
+ "name": "payments-server-api",
81
+ "dependencies": {
82
+ "nestia-fetcher": "^1.0.2"
83
+ }
84
+ }
85
+ ```
85
86
 
86
87
 
87
88
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestia",
3
- "version": "0.3.5",
3
+ "version": "1.0.0",
4
4
  "description": "Automatic SDK and Document generator for the NestJS",
5
5
  "main": "src/index.ts",
6
6
  "bin": {
@@ -36,11 +36,10 @@
36
36
  "del": "^6.0.0",
37
37
  "ts-node": "^9.1.1",
38
38
  "tstl": "^2.5.0",
39
- "ttypescript": "^1.5.12",
40
39
  "typescript": "^4.3.2"
41
40
  },
42
41
  "devDependencies": {
43
- "encrypted-nestjs": "^0.1.5",
42
+ "nestia-helper": "^1.0.0",
44
43
  "rimraf": "^3.0.2"
45
44
  }
46
45
  }
@@ -104,6 +104,8 @@ export namespace ControllerAnalyzer
104
104
  let path: string = NodePath.join(controller.path, func.path).split("\\").join("/");
105
105
  if (path[0] !== "/")
106
106
  path = "/" + path;
107
+ if (path[path.length - 1] === "/" && path !== "/")
108
+ path = path.substr(0, path.length - 1);
107
109
 
108
110
  // RETURNS
109
111
  return {
@@ -1,4 +1,4 @@
1
- import * as path from "path";
1
+ import Pather from "path";
2
2
 
3
3
  import { ArrayUtil } from "../utils/ArrayUtil";
4
4
  import { StringUtil } from "../utils/StringUtil";
@@ -128,7 +128,7 @@ export namespace ReflectAnalyzer
128
128
  }
129
129
 
130
130
  // VALIDATE PATH ARGUMENTS
131
- const funcPathArguments: string[] = StringUtil.betweens(path.join(controller.path, meta.path).split("\\").join("/"), ":", "/").sort();
131
+ const funcPathArguments: string[] = StringUtil.betweens(Pather.join(controller.path, meta.path).split("\\").join("/"), ":", "/").sort();
132
132
  const paramPathArguments: string[] = meta.parameters.filter(param => param.category === "param").map(param => param.field!).sort();
133
133
 
134
134
  if (equal(funcPathArguments, paramPathArguments) === false)
@@ -158,6 +158,7 @@ export namespace ReflectAnalyzer
158
158
  return null;
159
159
 
160
160
  return {
161
+ name: key,
161
162
  category: type,
162
163
  index: param.index,
163
164
  field: param.data,
@@ -169,15 +170,19 @@ export namespace ReflectAnalyzer
169
170
  {
170
171
  if (param.factory === undefined)
171
172
  return null;
172
- else if (param.factory.name === "EncryptedBody")
173
+ else if (param.factory.name === "EncryptedBody" || param.factory.name === "PlainBody")
174
+ {
173
175
  return {
174
176
  category: "body",
175
177
  index: param.index,
178
+ name: param.name,
176
179
  field: param.data,
177
- encrypted: true
180
+ encrypted: param.factory.name === "EncryptedBody"
178
181
  };
182
+ }
179
183
  else if (param.factory.name === "TypedParam")
180
184
  return {
185
+ name: param.name,
181
186
  category: "param",
182
187
  index: param.index,
183
188
  field: param.data,
@@ -193,6 +198,7 @@ export namespace ReflectAnalyzer
193
198
 
194
199
  interface INestParam
195
200
  {
201
+ name: string;
196
202
  index: number;
197
203
  factory?: Function;
198
204
  data: string | undefined;
package/src/bin/nestia.ts CHANGED
@@ -78,11 +78,7 @@ async function sdk(input: string[], command: ICommand): Promise<void>
78
78
 
79
79
  async function install(): Promise<void>
80
80
  {
81
- for (const module of ["@types/node", "node-fetch"])
82
- {
83
- console.log(`installing ${module}...`);
84
- await Terminal.execute(`npm install --save-dev ${module}`);
85
- }
81
+ await Terminal.execute("npm install --save nestia-fetcher");
86
82
  }
87
83
 
88
84
  async function main(): Promise<void>
@@ -1,33 +1 @@
1
- /**
2
- * @packageDocumentation
3
- * @module api
4
- */
5
- //================================================================
6
- /**
7
- * HTTP Error from the backend server.
8
- *
9
- * @author Jeongho Nam - https://github.com/samchon
10
- */
11
- export class HttpError extends Error
12
- {
13
- public readonly method: string;
14
- public readonly path: string;
15
- public readonly status: number;
16
-
17
- public constructor(method: string, path: string, status: number, message: string)
18
- {
19
- super(message);
20
-
21
- // INHERITANCE POLYFILL
22
- const proto: HttpError = new.target.prototype;
23
- if (Object.setPrototypeOf)
24
- Object.setPrototypeOf(this, proto);
25
- else
26
- (this as any).__proto__ = proto;
27
-
28
- // ASSIGN MEMBERS
29
- this.method = method;
30
- this.path = path;
31
- this.status = status;
32
- }
33
- }
1
+ export { HttpError } from "nestia-fetcher";
@@ -1,26 +1 @@
1
- /**
2
- * @packageDocumentation
3
- * @module api
4
- */
5
- //================================================================
6
- export interface IConnection
7
- {
8
- host: string;
9
- headers?: Record<string, string>;
10
- encryption?: IConnection.IEncyptionPassword | IConnection.EncryptionClosure;
11
- path?: (path: string) => string;
12
- }
13
-
14
- export namespace IConnection
15
- {
16
- export interface IEncyptionPassword
17
- {
18
- key: string;
19
- iv: string;
20
- }
21
-
22
- export interface EncryptionClosure
23
- {
24
- (content: string, isEncode: boolean): IEncyptionPassword;
25
- }
26
- }
1
+ export { IConnection } from "nestia-fetcher";
@@ -1,113 +1 @@
1
- /**
2
- * @packageDocumentation
3
- * @module api
4
- */
5
- //================================================================
6
- /**
7
- * 객체의 원시 타입.
8
- *
9
- * `Primitive` 는 대상 인스턴스의 모든 메서드를 제거하여, 그 타입을 pritimive object 의 형태로
10
- * 바꾸어주는 TMP (Type Meta Programming) 타입이다.
11
- *
12
- * @template Instance 대상 인스턴스
13
- * @author Samchon
14
- */
15
- export type Primitive<Instance> = value_of<Instance> extends object
16
- ? Instance extends object
17
- ? Instance extends IJsonable<infer Raw>
18
- ? value_of<Raw> extends object
19
- ? Raw extends object
20
- ? PrimitiveObject<Raw> // object would be primitified
21
- : never // cannot be
22
- : value_of<Raw> // atomic value
23
- : PrimitiveObject<Instance> // object would be primitified
24
- : never // cannot be
25
- : value_of<Instance>;
26
-
27
- export namespace Primitive
28
- {
29
- /**
30
- * Primitive object 하드 카피.
31
- *
32
- * `Primitive.clone()` 은 파라미터 인스턴스를 원시 오브젝트 형태로 hard copy 하는 함수이다.
33
- *
34
- * @param instance 복사 대상 인스턴스
35
- * @return 복사된 객체
36
- */
37
- export function clone<Instance>(instance: Instance): Primitive<Instance>
38
- {
39
- return JSON.parse(JSON.stringify(instance));
40
- }
41
-
42
- /**
43
- * @todo
44
- */
45
- export function equal_to<Instance>(x: Instance, y: Instance): boolean
46
- {
47
- return JSON.stringify(x) === JSON.stringify(y) || recursive_equal_to(x, y);
48
- }
49
- }
50
-
51
- type PrimitiveObject<Instance extends object> = Instance extends Array<infer T>
52
- ? Primitive<T>[]
53
- :
54
- {
55
- [P in keyof Instance]: Instance[P] extends Function
56
- ? never
57
- : Primitive<Instance[P]>
58
- };
59
-
60
- type value_of<Instance> =
61
- is_value_of<Instance, Boolean> extends true ? boolean
62
- : is_value_of<Instance, Number> extends true ? number
63
- : is_value_of<Instance, String> extends true ? string
64
- : Instance;
65
-
66
- type is_value_of<Instance, Object extends IValueOf<any>> =
67
- Instance extends Object
68
- ? Object extends IValueOf<infer Primitive>
69
- ? Instance extends Primitive
70
- ? false
71
- : true // not Primitive, but Object
72
- : false // cannot be
73
- : false;
74
-
75
- interface IValueOf<T>
76
- {
77
- valueOf(): T;
78
- }
79
-
80
- interface IJsonable<T>
81
- {
82
- toJSON(): T;
83
- }
84
-
85
- function object_equal_to<T extends object>(x: T, y: T): boolean
86
- {
87
- for (const key in x)
88
- if (recursive_equal_to(x[key], y[key]) === false)
89
- return false;
90
- return true;
91
- }
92
-
93
- function array_equal_to<T>(x: T[], y: T[]): boolean
94
- {
95
- if (x.length !== y.length)
96
- return false;
97
-
98
- return x.every((value, index) => recursive_equal_to(value, y[index]));
99
- }
100
-
101
- function recursive_equal_to<T>(x: T, y: T): boolean
102
- {
103
- const type = typeof x;
104
- if (type !== typeof y)
105
- return false;
106
- else if (type === "object")
107
- if (x instanceof Array)
108
- return array_equal_to(x, y as typeof x);
109
- else
110
- return object_equal_to(<any>x as object, <any>y as object);
111
- else
112
- return x === y;
113
- }
1
+ export { Primitive } from "nestia-fetcher";
@@ -1,51 +1 @@
1
- /**
2
- * @packageDocumentation
3
- * @module api.__internal
4
- */
5
- //================================================================
6
- import * as crypto from "crypto";
7
-
8
- /**
9
- * Utility class for AES Encryption.
10
- *
11
- * - AES-128/256
12
- * - CBC mode
13
- * - PKCS#5 Padding
14
- * - Base64 Encoding
15
- *
16
- * @author Jeongho Nam - https://github.com/samchon
17
- */
18
- export namespace AesPkcs5
19
- {
20
- /**
21
- * Encode data
22
- *
23
- * @param data Target data
24
- * @param key Key value of the encryption.
25
- * @param iv Initializer Vector for the encryption
26
- * @return Encoded data
27
- */
28
- export function encode(data: string, key: string, iv: string): string
29
- {
30
- const bytes: number = key.length * 8;
31
- const cipher: crypto.Cipher = crypto.createCipheriv(`AES-${bytes}-CBC`, key, iv);
32
-
33
- return cipher.update(data, "utf8", "base64") + cipher.final("base64");
34
- }
35
-
36
- /**
37
- * Decode data.
38
- *
39
- * @param data Target data
40
- * @param key Key value of the decryption.
41
- * @param iv Initializer Vector for the decryption
42
- * @return Decoded data.
43
- */
44
- export function decode(data: string, key: string, iv: string): string
45
- {
46
- const bytes: number = key.length * 8;
47
- const decipher: crypto.Decipher = crypto.createDecipheriv(`AES-${bytes}-CBC`, key, iv);
48
-
49
- return decipher.update(data, "base64", "utf8") + decipher.final("utf8");
50
- }
51
- }
1
+ export { AesPkcs5 } from "nestia-fetcher";
@@ -1,126 +1 @@
1
- /**
2
- * @packageDocumentation
3
- * @module api.__internal
4
- */
5
- //================================================================
6
- import { AesPkcs5 } from "./AesPkcs5";
7
- import { HttpError } from "../HttpError";
8
- import { IConnection } from "../IConnection";
9
- import { Primitive } from "../Primitive";
10
-
11
- // POLYFILL FOR NODE
12
- if (typeof global === "object"
13
- && typeof global.process === "object"
14
- && typeof global.process.versions === "object"
15
- && typeof global.process.versions.node !== undefined)
16
- (global as any).fetch = require("node-fetch");
17
-
18
- export class Fetcher
19
- {
20
- public static fetch<Output>(connection: IConnection, config: Fetcher.IConfig, method: "GET" | "DELETE", path: string): Promise<Primitive<Output>>;
21
- public static fetch<Input, Output>(connection: IConnection, config: Fetcher.IConfig, method: "POST" | "PUT" | "PATCH", path: string, input: Input): Promise<Primitive<Output>>;
22
-
23
- public static async fetch<Output>
24
- (
25
- connection: IConnection,
26
- config: Fetcher.IConfig,
27
- method: string,
28
- path: string,
29
- input?: object
30
- ): Promise<Primitive<Output>>
31
- {
32
- if (config.input_encrypted === true || config.output_encrypted === true)
33
- if (connection.encryption === undefined)
34
- throw new Error("Error on nestia.Fetcher.encrypt(): the encryption password has not been configured.");
35
-
36
- //----
37
- // REQUEST MESSSAGE
38
- //----
39
- // METHOD & HEADERS
40
- const init: RequestInit = {
41
- method,
42
- headers: config.input_encrypted === false && input !== undefined && typeof input === "object"
43
- ? {
44
- ...connection.headers,
45
- "Content-Type": "application/json"
46
- }
47
- : connection.headers
48
- };
49
-
50
- // REQUEST BODY (WITH ENCRYPTION)
51
- if (input !== undefined)
52
- {
53
- let content: string = JSON.stringify(input);
54
- if (config.input_encrypted === true)
55
- {
56
- const password: IConnection.IEncyptionPassword = connection.encryption instanceof Function
57
- ? connection.encryption!(content, true)
58
- : connection.encryption!;
59
- content = AesPkcs5.encode(content, password.key, password.iv);
60
- }
61
- init.body = content;
62
- }
63
-
64
- //----
65
- // RESPONSE MESSAGE
66
- //----
67
- // URL SPECIFICATION
68
- if (connection.host[connection.host.length - 1] !== "/" && path[0] !== "/")
69
- path = "/" + path;
70
- if (connection.path)
71
- path = connection.path(path);
72
-
73
- const url: URL = new URL(`${connection.host}${path}`);
74
-
75
- // DO FETCH
76
- const response: Response = await fetch(url.href, init);
77
- let content: string = await response.text();
78
-
79
- if (!content)
80
- return undefined!;
81
-
82
- // CHECK THE STATUS CODE
83
- if (response.status !== 200 && response.status !== 201)
84
- throw new HttpError(method, path, response.status, content);
85
-
86
- // FINALIZATION (WITH DECODING)
87
- if (config.output_encrypted === true)
88
- {
89
- const password: IConnection.IEncyptionPassword = connection.encryption instanceof Function
90
- ? connection.encryption!(content, false)
91
- : connection.encryption!;
92
- content = AesPkcs5.decode(content, password.key, password.iv);
93
- }
94
-
95
- //----
96
- // OUTPUT
97
- //----
98
- let ret: { __set_headers__: Record<string, any> } & Primitive<Output> = content as any;
99
- try
100
- {
101
- // PARSE RESPONSE BODY
102
- ret = JSON.parse(ret as any);
103
-
104
- // FIND __SET_HEADERS__ FIELD
105
- if (ret.__set_headers__ !== undefined && typeof ret.__set_headers__ === "object")
106
- {
107
- if (connection.headers === undefined)
108
- connection.headers = {};
109
- Object.assign(connection.headers, ret.__set_headers__);
110
- }
111
- }
112
- catch {}
113
-
114
- // RETURNS
115
- return ret;
116
- }
117
- }
118
-
119
- export namespace Fetcher
120
- {
121
- export interface IConfig
122
- {
123
- input_encrypted?: boolean;
124
- output_encrypted: boolean;
125
- }
126
- }
1
+ export { Fetcher } from "nestia-fetcher";
@@ -2,7 +2,6 @@ import * as fs from "fs";
2
2
  import { HashMap } from "tstl/container/HashMap";
3
3
 
4
4
  import { IRoute } from "../structures/IRoute";
5
- import { DirectoryUtil } from "../utils/DirectoryUtil";
6
5
  import { ImportDictionary } from "../utils/ImportDictionary";
7
6
  import { FunctionGenerator } from "./FunctionGenerator";
8
7
 
@@ -21,14 +20,8 @@ export namespace FileGenerator
21
20
  // RELOCATE FOR ONLY ONE CONTROLLER METHOD IN AN URL CASE
22
21
  relocate(root);
23
22
 
24
- const defaultImportDict: ImportDictionary = new ImportDictionary();
25
- defaultImportDict.emplace(`${outDir}/__internal/AesPkcs5.ts`, true, "AesPkcs5");
26
- defaultImportDict.emplace(`${outDir}/__internal/Fetcher.ts`, true, "Fetcher");
27
- defaultImportDict.emplace(`${outDir}/Primitive.ts`, true, "Primitive");
28
- defaultImportDict.emplace(`${outDir}/IConnection.ts`, false, "IConnection");
29
-
30
- await DirectoryUtil.remove(outDir + "/functional");
31
- await iterate(defaultImportDict, outDir + "/functional", root);
23
+ // ITERATE FILES
24
+ await iterate(outDir + "/functional", root);
32
25
  }
33
26
 
34
27
  function emplace(directory: Directory, route: IRoute): void
@@ -70,7 +63,7 @@ export namespace FileGenerator
70
63
  /* ---------------------------------------------------------
71
64
  FILE ITERATOR
72
65
  --------------------------------------------------------- */
73
- async function iterate(defaultImportDict: ImportDictionary, outDir: string, directory: Directory): Promise<void>
66
+ async function iterate(outDir: string, directory: Directory): Promise<void>
74
67
  {
75
68
  // CREATE A NEW DIRECTORY
76
69
  try
@@ -83,7 +76,7 @@ export namespace FileGenerator
83
76
  let content: string = "";
84
77
  for (const it of directory.directories)
85
78
  {
86
- await iterate(defaultImportDict, `${outDir}/${it.first}`, it.second);
79
+ await iterate(`${outDir}/${it.first}`, it.second);
87
80
  content += `export * as ${it.first} from "./${it.first}";\n`;
88
81
  }
89
82
  content += "\n";
@@ -100,10 +93,23 @@ export namespace FileGenerator
100
93
 
101
94
  // FINALIZE THE CONTENT
102
95
  if (directory.routes.length !== 0)
103
- content = defaultImportDict.toScript(outDir) + "\n\n"
104
- + importDict.toScript(outDir) + "\n\n"
96
+ content = ""
97
+ + `import { AesPkcs5, Fetcher, Primitive } from "nestia-fetcher";\n`
98
+ + `import type { IConnection } from "nestia-fetcher";\n`
99
+ +
100
+ (
101
+ importDict.empty()
102
+ ? ""
103
+ : "\n" + importDict.toScript(outDir) + "\n"
104
+ )
105
105
  + content + "\n\n"
106
- + defaultImportDict.listUp();
106
+ + "//---------------------------------------------------------\n"
107
+ + "// TO PREVENT THE UNUSED VARIABLE ERROR\n"
108
+ + "//---------------------------------------------------------\n"
109
+ + "AesPkcs5;\n"
110
+ + "Fetcher;\n"
111
+ + "Primitive;";
112
+
107
113
  content = "/**\n"
108
114
  + " * @packageDocumentation\n"
109
115
  + ` * @module ${directory.module}\n`
@@ -2,7 +2,6 @@ import type * as tsc from "typescript";
2
2
  import { Pair } from "tstl/utility/Pair";
3
3
  import { Vector } from "tstl/container/Vector";
4
4
 
5
- import { Fetcher } from "../bundle/__internal/Fetcher";
6
5
  import { IRoute } from "../structures/IRoute";
7
6
 
8
7
  export namespace FunctionGenerator
@@ -23,25 +22,17 @@ export namespace FunctionGenerator
23
22
  --------------------------------------------------------- */
24
23
  function body(route: IRoute, query: IRoute.IParameter | undefined, input: IRoute.IParameter | undefined): string
25
24
  {
26
- // PATH WITH ENCRYPTION
27
- const path: string = get_path(route, query);
28
- const config: Fetcher.IConfig = {
29
- input_encrypted: input !== undefined && input.encrypted,
30
- output_encrypted: route.encrypted
31
- };
32
-
33
25
  // FETCH ARGUMENTS WITH REQUST BODY
26
+ const parameters = filter_parameters(route, query);
34
27
  const fetchArguments: string[] =
35
28
  [
36
29
  "connection",
37
- JSON.stringify(config, null, 4)
38
- .split('"').join("")
39
- .split("\n").join("\n" + " ".repeat(8)),
40
- `"${route.method}"`,
41
- path
30
+ `${route.name}.ENCRYPTED`,
31
+ `${route.name}.METHOD`,
32
+ `${route.name}.path(${parameters.map(p => p.name).join(", ")})`
42
33
  ];
43
34
  if (input !== undefined)
44
- fetchArguments.push("input");
35
+ fetchArguments.push(input.name);
45
36
 
46
37
  // RETURNS WITH FINALIZATION
47
38
  return "{\n"
@@ -52,18 +43,12 @@ export namespace FunctionGenerator
52
43
  + "}";
53
44
  }
54
45
 
55
- function get_path(route: IRoute, query: IRoute.IParameter | undefined): string
46
+ function filter_parameters(route: IRoute, query: IRoute.IParameter | undefined): IRoute.IParameter[]
56
47
  {
57
48
  const parameters = route.parameters.filter(param => param.category === "param");
58
- let path: string = route.path;
59
-
60
- for (const param of parameters)
61
- path = path.replace(`:${param.field}`, `\${${param.name}}`);
62
-
63
- new URLSearchParams()
64
- return (query !== undefined)
65
- ? `\`${path}?\${new URLSearchParams(${query.name} as any).toString()}\``
66
- : `\`${path}\``
49
+ if (query)
50
+ parameters.push(query);
51
+ return parameters;
67
52
  }
68
53
 
69
54
  /* ---------------------------------------------------------
@@ -149,6 +134,7 @@ export namespace FunctionGenerator
149
134
 
150
135
  function tail(route: IRoute, query: IRoute.IParameter | undefined, input: IRoute.IParameter | undefined): string | null
151
136
  {
137
+ // LIST UP TYPES
152
138
  const types: Pair<string, string>[] = [];
153
139
  if (query !== undefined)
154
140
  types.push(new Pair("Query", query.type));
@@ -157,12 +143,36 @@ export namespace FunctionGenerator
157
143
  if (route.output !== "void")
158
144
  types.push(new Pair("Output", route.output));
159
145
 
160
- if (types.length === 0)
161
- return null;
162
-
146
+ // PATH WITH PARAMETERS
147
+ const parameters = filter_parameters(route, query);
148
+ let path: string = route.path;
149
+ for (const param of parameters)
150
+ if (param.category === "param")
151
+ path = path.replace(`:${param.field}`, `\${${param.name}}`);
152
+ path = (query !== undefined)
153
+ ? `\`${path}?\${new URLSearchParams(${query.name} as any).toString()}\``
154
+ : `\`${path}\``;
155
+
163
156
  return `export namespace ${route.name}\n`
164
157
  + "{\n"
165
- + (types.map(tuple => ` export type ${tuple.first} = Primitive<${tuple.second}>;`).join("\n")) + "\n"
158
+ +
159
+ (
160
+ types.length !== 0
161
+ ? types.map(tuple => ` export type ${tuple.first} = Primitive<${tuple.second}>;`).join("\n") + "\n"
162
+ : ""
163
+ )
164
+ + "\n"
165
+ + ` export const METHOD = "${route.method}" as const;\n`
166
+ + ` export const PATH: string = "${route.path}";\n`
167
+ + ` export const ENCRYPTED: Fetcher.IEncrypted = {\n`
168
+ + ` request: ${input !== undefined && input.encrypted},\n`
169
+ + ` response: ${route.encrypted},\n`
170
+ + ` };\n`
171
+ + "\n"
172
+ + ` export function path(${parameters.map(param => `${param.name}: ${param.type}`).join(", ")}): string\n`
173
+ + ` {\n`
174
+ + ` return ${path};\n`
175
+ + ` }\n`
166
176
  + "}";
167
177
  }
168
178
  }
@@ -22,6 +22,7 @@ export namespace IController
22
22
 
23
23
  export interface IParameter
24
24
  {
25
+ name: string;
25
26
  index: number;
26
27
  field: string | undefined;
27
28
  category: ParamCategory;
@@ -8,6 +8,11 @@ export class ImportDictionary
8
8
  {
9
9
  private readonly dict_: HashMap<string, Pair<boolean, HashSet<string>>> = new HashMap();
10
10
 
11
+ public empty(): boolean
12
+ {
13
+ return this.dict_.empty();
14
+ }
15
+
11
16
  public emplace(file: string, realistic: boolean, instance: string): void
12
17
  {
13
18
  if (file.substr(-5) === ".d.ts")
@@ -36,17 +41,4 @@ export class ImportDictionary
36
41
  }
37
42
  return statements.join("\n");
38
43
  }
39
-
40
- public listUp(): string
41
- {
42
- let content: string = ""
43
- + "//---------------------------------------------------------\n"
44
- + "// TO PREVENT THE UNUSED VARIABLE ERROR\n"
45
- + "//---------------------------------------------------------\n";
46
- for (const it of this.dict_)
47
- if (it.second.first === true)
48
- for (const instance of it.second.second)
49
- content += instance + ";\n";
50
- return content;
51
- }
52
44
  }
package/tsconfig.json CHANGED
@@ -68,6 +68,7 @@
68
68
  /* Experimental Options */
69
69
  "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
70
70
  "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
71
+ "stripInternal": true,
71
72
 
72
73
  /* Advanced Options */
73
74
  "skipLibCheck": true, /* Skip type checking of declaration files. */