nestia 2.1.0-dev.20220414 → 2.1.0-dev.20220502
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 +343 -0
- package/lib/analyses/ControllerAnalyzer.d.ts +7 -0
- package/lib/analyses/ControllerAnalyzer.d.ts.map +1 -0
- package/lib/analyses/ControllerAnalyzer.js +171 -0
- package/lib/analyses/GenericAnalyzer.d.ts +6 -0
- package/lib/analyses/GenericAnalyzer.d.ts.map +1 -0
- package/lib/analyses/GenericAnalyzer.js +77 -0
- package/lib/analyses/ImportAnalyzer.d.ts +14 -0
- package/lib/analyses/ImportAnalyzer.d.ts.map +1 -0
- package/lib/analyses/ImportAnalyzer.js +78 -0
- package/lib/analyses/ReflectAnalyzer.d.ts +5 -0
- package/lib/analyses/ReflectAnalyzer.d.ts.map +1 -0
- package/lib/analyses/ReflectAnalyzer.js +316 -0
- package/lib/analyses/SourceFinder.d.ts +5 -0
- package/lib/analyses/SourceFinder.d.ts.map +1 -0
- package/lib/analyses/SourceFinder.js +237 -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 +280 -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 +109 -0
- package/lib/generates/FileGenerator.d.ts +6 -0
- package/lib/generates/FileGenerator.d.ts.map +1 -0
- package/lib/generates/FileGenerator.js +306 -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 +252 -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} +11 -16
- package/lib/structures/IRoute.d.ts.map +1 -0
- package/lib/structures/IRoute.js +3 -0
- package/lib/structures/ISwagger.d.ts +40 -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 +167 -0
- package/lib/utils/ImportDictionary.d.ts +7 -0
- package/lib/utils/ImportDictionary.d.ts.map +1 -0
- package/lib/utils/ImportDictionary.js +63 -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
|
@@ -3,14 +3,12 @@ on: [push, pull_request]
|
|
|
3
3
|
|
|
4
4
|
jobs:
|
|
5
5
|
Ubuntu:
|
|
6
|
-
runs-on:
|
|
7
|
-
strategy:
|
|
8
|
-
matrix:
|
|
9
|
-
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
6
|
+
runs-on: ubuntu-latest
|
|
10
7
|
steps:
|
|
11
8
|
- uses: actions/checkout@v1
|
|
12
9
|
- uses: actions/setup-node@v1
|
|
13
10
|
with:
|
|
14
11
|
node-version: 12.x
|
|
15
12
|
- run: npm install
|
|
13
|
+
- run: npm run build
|
|
16
14
|
- run: npm run test
|
package/README.md
CHANGED
|
@@ -15,6 +15,9 @@ npx nestia sdk "src/controller" --out "src/api"
|
|
|
15
15
|
|
|
16
16
|
# REGULAR NESTJS PATTERN
|
|
17
17
|
npx nestia sdk "src/**/*.controller.ts" --out "src/api"
|
|
18
|
+
|
|
19
|
+
# BUILDING SWAGGER.JSON IS ALSO POSSIBLE
|
|
20
|
+
npx nestia swagger "src/controller" -- out "swagger.json"
|
|
18
21
|
```
|
|
19
22
|
|
|
20
23
|
Don't write any `swagger` comment. Just deliver the SDK.
|
|
@@ -79,15 +82,20 @@ Just type the `nestia sdk <input> --out <output>` command in the console. When t
|
|
|
79
82
|
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).
|
|
80
83
|
|
|
81
84
|
### Dependencies
|
|
82
|
-
|
|
85
|
+
```bash
|
|
86
|
+
npx nestia install
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
SDK library generated by the **Nestia** requires the [nestia-fetcher](https://github.com/samchon/nestia-fetcher) and [typescript-is](https://github.com/woutervh-/typescript-is) modules.
|
|
83
90
|
|
|
84
|
-
|
|
91
|
+
The `npx nestia install` command installs those dependencies with `package.json` configuration.
|
|
85
92
|
|
|
86
93
|
```json
|
|
87
94
|
{
|
|
88
95
|
"name": "payments-server-api",
|
|
89
96
|
"dependencies": {
|
|
90
|
-
"nestia-fetcher": "^
|
|
97
|
+
"nestia-fetcher": "^2.0.0",
|
|
98
|
+
"typescript-is": "^0.19.0"
|
|
91
99
|
}
|
|
92
100
|
}
|
|
93
101
|
```
|
|
@@ -97,6 +105,11 @@ Therefore, when you publish an SDK library generated by this **Nestia**, you hav
|
|
|
97
105
|
## Advanced
|
|
98
106
|
### `nestia.config.ts`
|
|
99
107
|
```typescript
|
|
108
|
+
/**
|
|
109
|
+
* Definition for the `nestia.config.ts` file.
|
|
110
|
+
*
|
|
111
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
112
|
+
*/
|
|
100
113
|
export interface IConfiguration
|
|
101
114
|
{
|
|
102
115
|
/**
|
|
@@ -107,17 +120,43 @@ export interface IConfiguration
|
|
|
107
120
|
/**
|
|
108
121
|
* Output directory that SDK would be placed in.
|
|
109
122
|
*/
|
|
110
|
-
output
|
|
123
|
+
output?: string;
|
|
111
124
|
|
|
112
125
|
/**
|
|
113
126
|
* Compiler options for the TypeScript.
|
|
114
127
|
*
|
|
115
128
|
* If omitted, the configuration would follow the `tsconfig.json`.
|
|
116
129
|
*/
|
|
117
|
-
compilerOptions?:
|
|
130
|
+
compilerOptions?: ts.CompilerOptions;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Whether to assert parameter types or not.
|
|
134
|
+
*
|
|
135
|
+
* If you configure this option to be `true`, all of the function parameters would be
|
|
136
|
+
* checked through the [typescript-is](https://github.com/woutervh-/typescript-is).
|
|
137
|
+
*/
|
|
138
|
+
assert?: boolean;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Whether to optimize JSON string conversion 2x faster or not.
|
|
142
|
+
*
|
|
143
|
+
* If you configure this option to be `true`, the SDK library would utilize the
|
|
144
|
+
* [typescript-json](https://github.com/samchon/typescript-json) and the JSON string
|
|
145
|
+
* conversion speed really be 2x faster.
|
|
146
|
+
*/
|
|
147
|
+
json?: boolean;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Building `swagger.json` is also possible.
|
|
151
|
+
*/
|
|
152
|
+
swagger?: IConfiguration.ISwagger;
|
|
118
153
|
}
|
|
119
154
|
export namespace IConfiguration
|
|
120
155
|
{
|
|
156
|
+
/**
|
|
157
|
+
* List of files or directories to include or exclude to specifying the NestJS
|
|
158
|
+
* controllers.
|
|
159
|
+
*/
|
|
121
160
|
export interface IInput
|
|
122
161
|
{
|
|
123
162
|
/**
|
|
@@ -128,7 +167,22 @@ export namespace IConfiguration
|
|
|
128
167
|
/**
|
|
129
168
|
* List of files or directories to be excluded.
|
|
130
169
|
*/
|
|
131
|
-
exclude
|
|
170
|
+
exclude?: string[];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Building `swagger.json` is also possible.
|
|
175
|
+
*/
|
|
176
|
+
export interface ISwagger
|
|
177
|
+
{
|
|
178
|
+
/**
|
|
179
|
+
* Output path of the `swagger.json`.
|
|
180
|
+
*
|
|
181
|
+
* If you've configure only directory, the file name would be `swagger.json`.
|
|
182
|
+
* Otherwise you configure file name and extension, the `swagger.json` file would
|
|
183
|
+
* be renamed to what you've configured.
|
|
184
|
+
*/
|
|
185
|
+
output: string;
|
|
132
186
|
}
|
|
133
187
|
}
|
|
134
188
|
```
|
|
@@ -138,10 +192,14 @@ Instead of specifying `input` and `output` directories using the cli options, yo
|
|
|
138
192
|
Write below content as the `nestia.config.ts` file and place it onto the root directory of your backend project. After the configuration, you can generate the SDK only with the `npx nestia sdk` command, without any directory specification.
|
|
139
193
|
|
|
140
194
|
```typescript
|
|
141
|
-
|
|
195
|
+
import type nestia from "nestia";
|
|
196
|
+
|
|
197
|
+
const config: nestia.IConfiguration = {
|
|
142
198
|
input: "src/controllers",
|
|
143
|
-
output: "src/api"
|
|
199
|
+
output: "src/api",
|
|
200
|
+
assert: false
|
|
144
201
|
};
|
|
202
|
+
export default config;
|
|
145
203
|
```
|
|
146
204
|
|
|
147
205
|
> Alternative options for the regular NestJS project:
|
|
@@ -150,10 +208,11 @@ export = {
|
|
|
150
208
|
> export = {
|
|
151
209
|
> input: "src/**/*.controller.ts",
|
|
152
210
|
> /* input: {
|
|
153
|
-
> include: ["src/controllers
|
|
154
|
-
> exclude: ["src/controllers
|
|
211
|
+
> include: ["src/controllers/**\/*.controller.ts"],
|
|
212
|
+
> exclude: ["src/controllers/**\/fake_*.controller.ts"]
|
|
155
213
|
> },*/
|
|
156
|
-
> output: "src/api"
|
|
214
|
+
> output: "src/api",
|
|
215
|
+
> assert: true
|
|
157
216
|
> }
|
|
158
217
|
> ```
|
|
159
218
|
|
|
@@ -186,9 +245,20 @@ For your deep understanding about this directory structure with this **Nestia**,
|
|
|
186
245
|
## Demonstration
|
|
187
246
|
To demonstrate which SDK codes would be generated by this **Nestia**:
|
|
188
247
|
|
|
189
|
-
-
|
|
190
|
-
|
|
191
|
-
|
|
248
|
+
- Representative files
|
|
249
|
+
- [Controllers of the NestJS](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/default/src/controllers/base/SaleCommentsController.ts)
|
|
250
|
+
- [Structures used in the RestAPI](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/default/src/api/structures/sales/articles/ISaleArticle.ts)
|
|
251
|
+
- [SDK generated by this **Nestia**](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/default/src/api/functional/consumers/sales/reviews/index.ts)
|
|
252
|
+
- Demonstration Projects
|
|
253
|
+
- [absolute](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/absolute): Absolute path with the `baseUrl` option
|
|
254
|
+
- [alias@api](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/alias@api): The `src/api` directory has been aliased by `paths` option
|
|
255
|
+
- [alias@src](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/alias@src): Entire `src` directory has been aliased by `paths` option
|
|
256
|
+
- [default](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/default): No `tsconfig.json` and `nestia.config.ts`
|
|
257
|
+
- [esnext](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/esnext): ECMAScript target version is `ESNEXT`
|
|
258
|
+
- [exclude](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/exclude): Exclude option using the `--exclude` commad
|
|
259
|
+
- [nestia.config.ts](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/nestia.config.ts): Configured `nestia.config.ts` with `assert` mode
|
|
260
|
+
- [reference](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/reference): Configured input files as `src/**/*.controller.ts`
|
|
261
|
+
- [tsconfig.json](https://github.com/samchon/nestia/tree/master/src/test/demonstrations/tsconfig.json): Special configuration through the `tsconfig.json`
|
|
192
262
|
|
|
193
263
|
### Controller
|
|
194
264
|
If you've decided to adapt this **Nestia** and you want to generate the SDK directly, you don't need any extra work. Just keep you controller class down and do noting. The only one exceptional case that you need an extra dedication is, when you want to explain about the API function to the client developers through the comments.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
/**
|
|
3
|
+
* Definition for the `nestia.config.ts` file.
|
|
4
|
+
*
|
|
5
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
6
|
+
*/
|
|
7
|
+
export interface IConfiguration {
|
|
8
|
+
/**
|
|
9
|
+
* List of files or directories containing the NestJS controller classes.
|
|
10
|
+
*/
|
|
11
|
+
input: string | string[] | IConfiguration.IInput;
|
|
12
|
+
/**
|
|
13
|
+
* Output directory that SDK would be placed in.
|
|
14
|
+
*/
|
|
15
|
+
output?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Compiler options for the TypeScript.
|
|
18
|
+
*
|
|
19
|
+
* If omitted, the configuration would follow the `tsconfig.json`.
|
|
20
|
+
*/
|
|
21
|
+
compilerOptions?: ts.CompilerOptions;
|
|
22
|
+
/**
|
|
23
|
+
* Whether to assert parameter types or not.
|
|
24
|
+
*
|
|
25
|
+
* If you configure this option to be `true`, all of the function parameters would be
|
|
26
|
+
* checked through the [typescript-is](https://github.com/woutervh-/typescript-is).
|
|
27
|
+
*/
|
|
28
|
+
assert?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Whether to optimize JSON string conversion 2x faster or not.
|
|
31
|
+
*
|
|
32
|
+
* If you configure this option to be `true`, the SDK library would utilize the
|
|
33
|
+
* [typescript-json](https://github.com/samchon/typescript-json) and the JSON string
|
|
34
|
+
* conversion speed really be 2x faster.
|
|
35
|
+
*/
|
|
36
|
+
json?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Building `swagger.json` is also possible.
|
|
39
|
+
*/
|
|
40
|
+
swagger?: IConfiguration.ISwagger;
|
|
41
|
+
}
|
|
42
|
+
export declare namespace IConfiguration {
|
|
43
|
+
/**
|
|
44
|
+
* List of files or directories to include or exclude to specifying the NestJS
|
|
45
|
+
* controllers.
|
|
46
|
+
*/
|
|
47
|
+
interface IInput {
|
|
48
|
+
/**
|
|
49
|
+
* List of files or directories containing the NestJS controller classes.
|
|
50
|
+
*/
|
|
51
|
+
include: string[];
|
|
52
|
+
/**
|
|
53
|
+
* List of files or directories to be excluded.
|
|
54
|
+
*/
|
|
55
|
+
exclude?: string[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Building `swagger.json` is also possible.
|
|
59
|
+
*/
|
|
60
|
+
interface ISwagger {
|
|
61
|
+
/**
|
|
62
|
+
* Output path of the `swagger.json`.
|
|
63
|
+
*
|
|
64
|
+
* If you've configure only directory, the file name would be `swagger.json`.
|
|
65
|
+
* Otherwise you configure file name and extension, the `swagger.json` file would
|
|
66
|
+
* be renamed to what you've configured.
|
|
67
|
+
*/
|
|
68
|
+
output: string;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=IConfiguration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IConfiguration.d.ts","sourceRoot":"","sources":["../src/IConfiguration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAE3B;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC;IAEjD;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,eAAe,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC;IAErC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC;CACrC;AACD,yBAAiB,cAAc,CAC/B;IACI;;;OAGG;IACH,UAAiB,MAAM;QAEnB;;WAEG;QACH,OAAO,EAAE,MAAM,EAAE,CAAC;QAElB;;WAEG;QACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB;IAED;;OAEG;IACH,UAAiB,QAAQ;QAErB;;;;;;WAMG;QACH,MAAM,EAAE,MAAM,CAAC;KAClB;CACJ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IConfiguration } from "./IConfiguration";
|
|
2
|
+
export declare class NestiaApplication {
|
|
3
|
+
private readonly config_;
|
|
4
|
+
private readonly bundle_checker_;
|
|
5
|
+
constructor(config: IConfiguration);
|
|
6
|
+
sdk(): Promise<void>;
|
|
7
|
+
swagger(): Promise<void>;
|
|
8
|
+
private generate;
|
|
9
|
+
private prepare;
|
|
10
|
+
private is_not_excluded;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=NestiaApplication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NestiaApplication.d.ts","sourceRoot":"","sources":["../src/NestiaApplication.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIlD,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA+C;gBAE5D,MAAM,EAAE,cAAc;IA8B5B,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAapB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAgBvB,QAAQ;IAkDtB,OAAO,CAAC,OAAO;YA2BD,eAAe;CAShC"}
|
|
@@ -0,0 +1,343 @@
|
|
|
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
35
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
36
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
37
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
38
|
+
function step(op) {
|
|
39
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
40
|
+
while (_) try {
|
|
41
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
42
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
43
|
+
switch (op[0]) {
|
|
44
|
+
case 0: case 1: t = op; break;
|
|
45
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
46
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
47
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
48
|
+
default:
|
|
49
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
50
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
51
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
52
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
53
|
+
if (t[2]) _.ops.pop();
|
|
54
|
+
_.trys.pop(); continue;
|
|
55
|
+
}
|
|
56
|
+
op = body.call(thisArg, _);
|
|
57
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
58
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var __values = (this && this.__values) || function(o) {
|
|
62
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
63
|
+
if (m) return m.call(o);
|
|
64
|
+
if (o && typeof o.length === "number") return {
|
|
65
|
+
next: function () {
|
|
66
|
+
if (o && i >= o.length) o = void 0;
|
|
67
|
+
return { value: o && o[i++], done: !o };
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
71
|
+
};
|
|
72
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
73
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
74
|
+
if (!m) return o;
|
|
75
|
+
var i = m.call(o), r, ar = [], e;
|
|
76
|
+
try {
|
|
77
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
78
|
+
}
|
|
79
|
+
catch (error) { e = { error: error }; }
|
|
80
|
+
finally {
|
|
81
|
+
try {
|
|
82
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
83
|
+
}
|
|
84
|
+
finally { if (e) throw e.error; }
|
|
85
|
+
}
|
|
86
|
+
return ar;
|
|
87
|
+
};
|
|
88
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
89
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
90
|
+
if (ar || !(i in from)) {
|
|
91
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
92
|
+
ar[i] = from[i];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
96
|
+
};
|
|
97
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
98
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
99
|
+
};
|
|
100
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
101
|
+
exports.NestiaApplication = void 0;
|
|
102
|
+
var fs_1 = __importDefault(require("fs"));
|
|
103
|
+
var path_1 = __importDefault(require("path"));
|
|
104
|
+
var runner = __importStar(require("ts-node"));
|
|
105
|
+
var typescript_1 = __importDefault(require("typescript"));
|
|
106
|
+
var Pair_1 = require("tstl/utility/Pair");
|
|
107
|
+
var Singleton_1 = require("tstl/thread/Singleton");
|
|
108
|
+
var ControllerAnalyzer_1 = require("./analyses/ControllerAnalyzer");
|
|
109
|
+
var ReflectAnalyzer_1 = require("./analyses/ReflectAnalyzer");
|
|
110
|
+
var SourceFinder_1 = require("./analyses/SourceFinder");
|
|
111
|
+
var SdkGenerator_1 = require("./generates/SdkGenerator");
|
|
112
|
+
var SwaggerGenerator_1 = require("./generates/SwaggerGenerator");
|
|
113
|
+
var ArrayUtil_1 = require("./utils/ArrayUtil");
|
|
114
|
+
var CompilerOptions_1 = require("./executable/internal/CompilerOptions");
|
|
115
|
+
var NestiaApplication = /** @class */ (function () {
|
|
116
|
+
function NestiaApplication(config) {
|
|
117
|
+
var _this = this;
|
|
118
|
+
this.config_ = config;
|
|
119
|
+
this.bundle_checker_ = new Singleton_1.Singleton(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
120
|
+
var bundles, tuples;
|
|
121
|
+
var _this = this;
|
|
122
|
+
return __generator(this, function (_a) {
|
|
123
|
+
switch (_a.label) {
|
|
124
|
+
case 0:
|
|
125
|
+
if (!this.config_.output)
|
|
126
|
+
return [2 /*return*/, function () { return false; }];
|
|
127
|
+
return [4 /*yield*/, fs_1.default.promises.readdir(SdkGenerator_1.SdkGenerator.BUNDLE_PATH)];
|
|
128
|
+
case 1:
|
|
129
|
+
bundles = _a.sent();
|
|
130
|
+
return [4 /*yield*/, ArrayUtil_1.ArrayUtil.asyncMap(bundles, function (file) { return __awaiter(_this, void 0, void 0, function () {
|
|
131
|
+
var relative, location, stats;
|
|
132
|
+
return __generator(this, function (_a) {
|
|
133
|
+
switch (_a.label) {
|
|
134
|
+
case 0:
|
|
135
|
+
relative = path_1.default.join(this.config_.output, file);
|
|
136
|
+
location = path_1.default.join(SdkGenerator_1.SdkGenerator.BUNDLE_PATH, file);
|
|
137
|
+
return [4 /*yield*/, fs_1.default.promises.stat(location)];
|
|
138
|
+
case 1:
|
|
139
|
+
stats = _a.sent();
|
|
140
|
+
return [2 /*return*/, new Pair_1.Pair(relative, stats.isDirectory())];
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}); })];
|
|
144
|
+
case 2:
|
|
145
|
+
tuples = _a.sent();
|
|
146
|
+
return [2 /*return*/, function (file) {
|
|
147
|
+
var e_1, _a;
|
|
148
|
+
try {
|
|
149
|
+
for (var tuples_1 = __values(tuples), tuples_1_1 = tuples_1.next(); !tuples_1_1.done; tuples_1_1 = tuples_1.next()) {
|
|
150
|
+
var it = tuples_1_1.value;
|
|
151
|
+
if (it.second === false && file === it.first)
|
|
152
|
+
return true;
|
|
153
|
+
else if (it.second === true && file.indexOf(it.first) === 0)
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
158
|
+
finally {
|
|
159
|
+
try {
|
|
160
|
+
if (tuples_1_1 && !tuples_1_1.done && (_a = tuples_1.return)) _a.call(tuples_1);
|
|
161
|
+
}
|
|
162
|
+
finally { if (e_1) throw e_1.error; }
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}];
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}); });
|
|
169
|
+
}
|
|
170
|
+
NestiaApplication.prototype.sdk = function () {
|
|
171
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
172
|
+
var parent, stats;
|
|
173
|
+
return __generator(this, function (_a) {
|
|
174
|
+
switch (_a.label) {
|
|
175
|
+
case 0:
|
|
176
|
+
if (!this.config_.output)
|
|
177
|
+
throw new Error("Error on NestiaApplication.sdk(): output path is not specified.");
|
|
178
|
+
parent = path_1.default.resolve(this.config_.output + "/..");
|
|
179
|
+
return [4 /*yield*/, fs_1.default.promises.lstat(parent)];
|
|
180
|
+
case 1:
|
|
181
|
+
stats = _a.sent();
|
|
182
|
+
if (stats.isDirectory() === false)
|
|
183
|
+
throw new Error("Error on NestiaApplication.sdk(): output directory does not exists.");
|
|
184
|
+
return [4 /*yield*/, this.generate(function (config) { return config; }, SdkGenerator_1.SdkGenerator.generate)];
|
|
185
|
+
case 2:
|
|
186
|
+
_a.sent();
|
|
187
|
+
return [2 /*return*/];
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
NestiaApplication.prototype.swagger = function () {
|
|
193
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
194
|
+
var parsed, directory, stats;
|
|
195
|
+
return __generator(this, function (_a) {
|
|
196
|
+
switch (_a.label) {
|
|
197
|
+
case 0:
|
|
198
|
+
if (!this.config_.swagger || !this.config_.swagger.output)
|
|
199
|
+
throw new Error("Error on NestiaApplication.swagger(): output path of the \"swagger.json\" is not specified.");
|
|
200
|
+
parsed = path_1.default.parse(this.config_.swagger.output);
|
|
201
|
+
directory = !!parsed.ext
|
|
202
|
+
? path_1.default.resolve(parsed.dir)
|
|
203
|
+
: this.config_.swagger.output;
|
|
204
|
+
return [4 /*yield*/, fs_1.default.promises.lstat(directory)];
|
|
205
|
+
case 1:
|
|
206
|
+
stats = _a.sent();
|
|
207
|
+
if (stats.isDirectory() === false)
|
|
208
|
+
throw new Error("Error on NestiaApplication.swagger(): output directory does not exists.");
|
|
209
|
+
return [4 /*yield*/, this.generate(function (config) { return config.swagger; }, SwaggerGenerator_1.SwaggerGenerator.generate)];
|
|
210
|
+
case 2:
|
|
211
|
+
_a.sent();
|
|
212
|
+
return [2 /*return*/];
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
NestiaApplication.prototype.generate = function (config, archiver) {
|
|
218
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
219
|
+
var input, fileList, _a, _b, unique, controllerList, fileList_1, fileList_1_1, file, _c, _d, _e, _f, e_2_1, program, checker, routeList, controllerList_1, controllerList_1_1, controller, sourceFile;
|
|
220
|
+
var e_2, _g, e_3, _h;
|
|
221
|
+
var _this = this;
|
|
222
|
+
return __generator(this, function (_j) {
|
|
223
|
+
switch (_j.label) {
|
|
224
|
+
case 0:
|
|
225
|
+
// MOUNT TS-NODE
|
|
226
|
+
this.prepare();
|
|
227
|
+
input = this.config_.input instanceof Array
|
|
228
|
+
? { include: this.config_.input }
|
|
229
|
+
: typeof this.config_.input === "string"
|
|
230
|
+
? { include: [this.config_.input] }
|
|
231
|
+
: this.config_.input;
|
|
232
|
+
_b = (_a = ArrayUtil_1.ArrayUtil).asyncFilter;
|
|
233
|
+
return [4 /*yield*/, SourceFinder_1.SourceFinder.find(input)];
|
|
234
|
+
case 1: return [4 /*yield*/, _b.apply(_a, [_j.sent(), function (file) { return _this.is_not_excluded(file); }])];
|
|
235
|
+
case 2:
|
|
236
|
+
fileList = _j.sent();
|
|
237
|
+
unique = new WeakSet();
|
|
238
|
+
controllerList = [];
|
|
239
|
+
_j.label = 3;
|
|
240
|
+
case 3:
|
|
241
|
+
_j.trys.push([3, 8, 9, 10]);
|
|
242
|
+
fileList_1 = __values(fileList), fileList_1_1 = fileList_1.next();
|
|
243
|
+
_j.label = 4;
|
|
244
|
+
case 4:
|
|
245
|
+
if (!!fileList_1_1.done) return [3 /*break*/, 7];
|
|
246
|
+
file = fileList_1_1.value;
|
|
247
|
+
_d = (_c = controllerList.push).apply;
|
|
248
|
+
_e = [controllerList];
|
|
249
|
+
_f = [[]];
|
|
250
|
+
return [4 /*yield*/, ReflectAnalyzer_1.ReflectAnalyzer.analyze(unique, file)];
|
|
251
|
+
case 5:
|
|
252
|
+
_d.apply(_c, _e.concat([__spreadArray.apply(void 0, _f.concat([__read.apply(void 0, [_j.sent()]), false]))]));
|
|
253
|
+
_j.label = 6;
|
|
254
|
+
case 6:
|
|
255
|
+
fileList_1_1 = fileList_1.next();
|
|
256
|
+
return [3 /*break*/, 4];
|
|
257
|
+
case 7: return [3 /*break*/, 10];
|
|
258
|
+
case 8:
|
|
259
|
+
e_2_1 = _j.sent();
|
|
260
|
+
e_2 = { error: e_2_1 };
|
|
261
|
+
return [3 /*break*/, 10];
|
|
262
|
+
case 9:
|
|
263
|
+
try {
|
|
264
|
+
if (fileList_1_1 && !fileList_1_1.done && (_g = fileList_1.return)) _g.call(fileList_1);
|
|
265
|
+
}
|
|
266
|
+
finally { if (e_2) throw e_2.error; }
|
|
267
|
+
return [7 /*endfinally*/];
|
|
268
|
+
case 10:
|
|
269
|
+
program = typescript_1.default.createProgram(controllerList.map(function (c) { return c.file; }), this.config_.compilerOptions || { noEmit: true });
|
|
270
|
+
checker = program.getTypeChecker();
|
|
271
|
+
routeList = [];
|
|
272
|
+
try {
|
|
273
|
+
for (controllerList_1 = __values(controllerList), controllerList_1_1 = controllerList_1.next(); !controllerList_1_1.done; controllerList_1_1 = controllerList_1.next()) {
|
|
274
|
+
controller = controllerList_1_1.value;
|
|
275
|
+
sourceFile = program.getSourceFile(controller.file);
|
|
276
|
+
if (sourceFile === undefined)
|
|
277
|
+
continue;
|
|
278
|
+
routeList.push.apply(routeList, __spreadArray([], __read(ControllerAnalyzer_1.ControllerAnalyzer.analyze(checker, sourceFile, controller)), false));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
282
|
+
finally {
|
|
283
|
+
try {
|
|
284
|
+
if (controllerList_1_1 && !controllerList_1_1.done && (_h = controllerList_1.return)) _h.call(controllerList_1);
|
|
285
|
+
}
|
|
286
|
+
finally { if (e_3) throw e_3.error; }
|
|
287
|
+
}
|
|
288
|
+
// DO GENERATE
|
|
289
|
+
return [4 /*yield*/, archiver(checker, config(this.config_), routeList)];
|
|
290
|
+
case 11:
|
|
291
|
+
// DO GENERATE
|
|
292
|
+
_j.sent();
|
|
293
|
+
return [2 /*return*/];
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
};
|
|
298
|
+
NestiaApplication.prototype.prepare = function () {
|
|
299
|
+
var _this = this;
|
|
300
|
+
// CONSTRUCT OPTIONS
|
|
301
|
+
var predicator = this.config_.compilerOptions
|
|
302
|
+
? function () { return CompilerOptions_1.CompilerOptions.emend(_this.config_.compilerOptions, !!_this.config_.assert); }
|
|
303
|
+
: function () {
|
|
304
|
+
_this.config_.compilerOptions = CompilerOptions_1.CompilerOptions.DEFAULT_OPTIONS;
|
|
305
|
+
return [false, false];
|
|
306
|
+
};
|
|
307
|
+
// MOUNT TS-NODE
|
|
308
|
+
var _a = __read(predicator(), 2), transformed = _a[0], absoluted = _a[1];
|
|
309
|
+
runner.register({
|
|
310
|
+
emit: false,
|
|
311
|
+
compiler: transformed ? "ttypescript" : "typescript",
|
|
312
|
+
compilerOptions: this.config_.compilerOptions,
|
|
313
|
+
require: absoluted
|
|
314
|
+
? ["tsconfig-paths/register"]
|
|
315
|
+
: undefined
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
NestiaApplication.prototype.is_not_excluded = function (file) {
|
|
319
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
320
|
+
var _a, content;
|
|
321
|
+
return __generator(this, function (_b) {
|
|
322
|
+
switch (_b.label) {
|
|
323
|
+
case 0:
|
|
324
|
+
if (!this.config_.output) return [3 /*break*/, 3];
|
|
325
|
+
_a = file.indexOf(path_1.default.join(this.config_.output, "functional")) === -1;
|
|
326
|
+
if (!_a) return [3 /*break*/, 2];
|
|
327
|
+
return [4 /*yield*/, this.bundle_checker_.get()];
|
|
328
|
+
case 1:
|
|
329
|
+
_a = (_b.sent())(file) === false;
|
|
330
|
+
_b.label = 2;
|
|
331
|
+
case 2: return [2 /*return*/, _a];
|
|
332
|
+
case 3: return [4 /*yield*/, fs_1.default.promises.readFile(file, "utf8")];
|
|
333
|
+
case 4:
|
|
334
|
+
content = _b.sent();
|
|
335
|
+
return [2 /*return*/, content.indexOf(" * @nestia Generated by Nestia - https://github.com/samchon/nestia") === -1];
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
};
|
|
340
|
+
return NestiaApplication;
|
|
341
|
+
}());
|
|
342
|
+
exports.NestiaApplication = NestiaApplication;
|
|
343
|
+
//# sourceMappingURL=NestiaApplication.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { IController } from "../structures/IController";
|
|
3
|
+
import { IRoute } from "../structures/IRoute";
|
|
4
|
+
export declare namespace ControllerAnalyzer {
|
|
5
|
+
function analyze(checker: ts.TypeChecker, sourceFile: ts.SourceFile, controller: IController): IRoute[];
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=ControllerAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ControllerAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyses/ControllerAnalyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAM9C,yBAAiB,kBAAkB,CACnC;IACI,SAAgB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,GAAG,MAAM,EAAE,CAc7G;CAyIJ"}
|