@nestia/migrate 0.14.3 → 0.15.1

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/package.json CHANGED
@@ -1,85 +1,85 @@
1
- {
2
- "name": "@nestia/migrate",
3
- "version": "0.14.3",
4
- "description": "Migration program from swagger to NestJS",
5
- "main": "lib/index.js",
6
- "typings": "lib/index.d.ts",
7
- "bin": {
8
- "@nestia/migrate": "lib/executable/migrate.js"
9
- },
10
- "scripts": {
11
- "build": "rimraf lib && tsc",
12
- "bundle": "ts-node src/executable/bundle.ts",
13
- "dev": "npm run build -- --watch",
14
- "package:next": "npm publish --access public --tag next",
15
- "prepare": "ts-patch install && typia patch && npm run bundle",
16
- "test": "node lib/test"
17
- },
18
- "repository": {
19
- "type": "git",
20
- "url": "https://github.com/samchon/nestia"
21
- },
22
- "keywords": [
23
- "migration",
24
- "swagger",
25
- "openapi generator",
26
- "NestJS",
27
- "nestia",
28
- "SDK",
29
- "RPC",
30
- "Mockup Simulator"
31
- ],
32
- "author": "Jeongho Nam",
33
- "license": "MIT",
34
- "bugs": {
35
- "url": "https://github.com/samchon/nestia/issues"
36
- },
37
- "homepage": "https://nestia.io",
38
- "devDependencies": {
39
- "@nestia/benchmark": "^0.1.0",
40
- "@nestia/core": "^3.5.0",
41
- "@nestia/e2e": "^0.7.0",
42
- "@nestia/fetcher": "^3.5.0",
43
- "@nestjs/common": "^10.3.8",
44
- "@nestjs/core": "^10.3.8",
45
- "@nestjs/platform-express": "^10.3.8",
46
- "@nestjs/platform-fastify": "^10.3.8",
47
- "@trivago/prettier-plugin-sort-imports": "^4.3.0",
48
- "@types/cli-progress": "^3.11.5",
49
- "@types/express": "^4.17.21",
50
- "@types/inquirer": "^9.0.7",
51
- "@types/node": "^20.3.3",
52
- "@types/swagger-ui-express": "^4.1.6",
53
- "chalk": "4.1.2",
54
- "cli-progress": "^3.12.0",
55
- "dotenv": "^16.3.1",
56
- "dotenv-expand": "^10.0.0",
57
- "express": "^4.19.2",
58
- "rimraf": "^5.0.1",
59
- "serialize-error": "^4.1.0",
60
- "source-map-support": "^0.5.21",
61
- "swagger-ui-express": "^5.0.0",
62
- "tgrid": "^1.0.2",
63
- "ts-node": "^10.9.1",
64
- "ts-patch": "^3.2.1",
65
- "typescript-transform-paths": "^3.4.6"
66
- },
67
- "dependencies": {
68
- "@samchon/openapi": "^0.3.2",
69
- "commander": "10.0.0",
70
- "inquirer": "8.2.5",
71
- "prettier": "^3.2.5",
72
- "tstl": "^3.0.0",
73
- "typescript": "^5.5.3",
74
- "typia": "^6.4.3"
75
- },
76
- "files": [
77
- "lib",
78
- "src",
79
- "!lib/test",
80
- "!src/test",
81
- "package.json",
82
- "README.md",
83
- "LICENSE"
84
- ]
85
- }
1
+ {
2
+ "name": "@nestia/migrate",
3
+ "version": "0.15.1",
4
+ "description": "Migration program from swagger to NestJS",
5
+ "main": "lib/index.js",
6
+ "typings": "lib/index.d.ts",
7
+ "bin": {
8
+ "@nestia/migrate": "lib/executable/migrate.js"
9
+ },
10
+ "scripts": {
11
+ "build": "rimraf lib && tsc",
12
+ "bundle": "ts-node src/executable/bundle.ts",
13
+ "dev": "npm run build -- --watch",
14
+ "package:next": "npm publish --access public --tag next",
15
+ "prepare": "ts-patch install && typia patch && npm run bundle",
16
+ "test": "node lib/test"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/samchon/nestia"
21
+ },
22
+ "keywords": [
23
+ "migration",
24
+ "swagger",
25
+ "openapi generator",
26
+ "NestJS",
27
+ "nestia",
28
+ "SDK",
29
+ "RPC",
30
+ "Mockup Simulator"
31
+ ],
32
+ "author": "Jeongho Nam",
33
+ "license": "MIT",
34
+ "bugs": {
35
+ "url": "https://github.com/samchon/nestia/issues"
36
+ },
37
+ "homepage": "https://nestia.io",
38
+ "devDependencies": {
39
+ "@nestia/benchmark": "^0.2.0",
40
+ "@nestia/core": "^3.8.1",
41
+ "@nestia/e2e": "^0.7.0",
42
+ "@nestia/fetcher": "^3.8.1",
43
+ "@nestjs/common": "^10.3.8",
44
+ "@nestjs/core": "^10.3.8",
45
+ "@nestjs/platform-express": "^10.3.8",
46
+ "@nestjs/platform-fastify": "^10.3.8",
47
+ "@trivago/prettier-plugin-sort-imports": "^4.3.0",
48
+ "@types/cli-progress": "^3.11.5",
49
+ "@types/express": "^4.17.21",
50
+ "@types/inquirer": "^9.0.7",
51
+ "@types/node": "^20.3.3",
52
+ "@types/swagger-ui-express": "^4.1.6",
53
+ "chalk": "4.1.2",
54
+ "cli-progress": "^3.12.0",
55
+ "dotenv": "^16.3.1",
56
+ "dotenv-expand": "^10.0.0",
57
+ "express": "^4.19.2",
58
+ "rimraf": "^5.0.1",
59
+ "serialize-error": "^4.1.0",
60
+ "source-map-support": "^0.5.21",
61
+ "swagger-ui-express": "^5.0.0",
62
+ "tgrid": "^1.0.2",
63
+ "ts-node": "^10.9.1",
64
+ "ts-patch": "^3.2.1",
65
+ "typescript-transform-paths": "^3.4.6"
66
+ },
67
+ "dependencies": {
68
+ "@samchon/openapi": "^0.4.2",
69
+ "commander": "10.0.0",
70
+ "inquirer": "8.2.5",
71
+ "prettier": "^3.2.5",
72
+ "tstl": "^3.0.0",
73
+ "typescript": "^5.5.3",
74
+ "typia": "^6.5.4"
75
+ },
76
+ "files": [
77
+ "lib",
78
+ "src",
79
+ "!lib/test",
80
+ "!src/test",
81
+ "package.json",
82
+ "README.md",
83
+ "LICENSE"
84
+ ]
85
+ }
@@ -37,7 +37,7 @@ export const NEST_TEMPLATE = [
37
37
  {
38
38
  "location": "docs/benchmarks",
39
39
  "file": "AMD Ryzen 9 7940HS w Radeon 780M Graphics.md",
40
- "content": "# Benchmark Report\r\n> Generated by [`@nestia/e2e`](https://github.com/samchon/nestia)\r\n\r\n - Specifications\r\n - CPU: AMD Ryzen 9 7940HS w/ Radeon 780M Graphics \r\n - RAM: 31 GB\r\n - NodeJS Version: v20.10.0\r\n - Backend Server: 1 core / 1 thread\r\n - Arguments\r\n - Count: 1,024\r\n - Threads: 4\r\n - Simultaneous: 32\r\n - Time\r\n - Start: 2024-06-21T13:24:13.810Z\r\n - Complete: 2024-06-21T13:24:16.611Z\r\n - Elapsed: 2,801 ms\r\n\r\nType | Count | Success | Mean. | Stdev. | Minimum | Maximum\r\n----|----|----|----|----|----|----\r\nTotal | 3,955 | 3,955 | 20.34 | 24.96 | 2 | 152\r\n\r\n> Unit: milliseconds\r\n\r\n## Endpoints\r\nType | Count | Success | Mean. | Stdev. | Minimum | Maximum\r\n----|----|----|----|----|----|----\r\nPATCH /bbs/articles/:section | 656 | 656 | 50.46 | 40.03 | 2 | 152\r\nGET /bbs/articles/:section/:id | 43 | 43 | 18.39 | 5.2 | 9 | 31\r\nPUT /bbs/articles/:section/:id | 22 | 22 | 16.77 | 3.46 | 12 | 28\r\nPOST /bbs/articles/:section | 3,234 | 3,234 | 14.28 | 14.68 | 6 | 132\r\n\r\n> Unit: milliseconds\r\n\r\n## Failures\r\nMethod | Path | Count | Failures\r\n-------|------|-------|----------"
40
+ "content": "# Benchmark Report\r\n> Generated by [`@nestia/benchmark`](https://github.com/samchon/nestia)\r\n\r\n - Specifications\r\n - CPU: AMD Ryzen 9 7940HS w/ Radeon 780M Graphics \r\n - RAM: 31 GB\r\n - NodeJS Version: v20.10.0\r\n - Backend Server: 1 core / 1 thread\r\n - Arguments\r\n - Count: 40,000\r\n - Threads: 4\r\n - Simultaneous: 32\r\n - Time\r\n - Start: 2024-07-25T19:14:00.253Z\r\n - Complete: 2024-07-25T19:16:37.125Z\r\n - Elapsed: 156,872 ms\r\n\r\nType | Count | Success | Mean. | Stdev. | Minimum | Maximum\r\n----|----|----|----|----|----|----\r\nTotal | 41,226 | 41,226 | 114 | 109.72 | 8 | 998\r\n\r\n> Unit: milliseconds\r\n\r\n## Memory Usage\r\n```mermaid\r\nxychart-beta\r\n x-axis \"Time (second)\"\r\n y-axis \"Memory (MB)\"\r\n line [37, 44, 33, 40, 66, 95, 114, 119, 123, 43, 42, 47, 68, 70, 66, 81, 87, 87, 97, 115, 135, 47, 58, 54, 61, 75, 45, 43, 49, 62, 83, 51, 65, 78, 54, 61, 63, 71, 72, 53, 70, 69, 61, 68, 88, 62, 70, 65, 67, 85, 62, 75, 81, 78, 58, 75, 77, 64, 69, 84, 98, 64, 70, 89, 98, 102, 58, 76, 82, 97, 61, 74, 77, 95, 70, 79, 92, 80, 92, 94, 94, 109, 71, 83, 80, 59, 70, 77, 92, 97, 75, 82, 89, 95, 78, 84, 100, 105, 117, 134, 129, 71, 85, 86, 88, 69, 76, 91, 92, 85, 86, 91, 104, 102, 78, 91, 81, 76, 91, 118, 114, 115, 135, 143, 73, 90, 91, 92, 102, 77, 85, 98, 81, 92, 83, 94, 72, 112, 92, 107, 100, 102, 115]\r\n```\r\n\r\n## Endpoints\r\nType | Count | Success | Mean. | Stdev. | Minimum | Maximum\r\n----|----|----|----|----|----|----\r\nPATCH /bbs/articles/:section | 6,703 | 6,703 | 167.16 | 125.5 | 8 | 996\r\nPUT /bbs/articles/:section/:id | 326 | 326 | 117.86 | 101.2 | 11 | 546\r\nGET /bbs/articles/:section/:id | 680 | 680 | 110.42 | 93.49 | 10 | 579\r\nPOST /bbs/articles/:section | 33,517 | 33,517 | 103.4 | 103.45 | 8 | 998\r\n\r\n> Unit: milliseconds\r\n\r\n## Failures\r\nMethod | Path | Count | Failures\r\n-------|------|-------|----------"
41
41
  },
42
42
  {
43
43
  "location": "",
@@ -52,12 +52,12 @@ export const NEST_TEMPLATE = [
52
52
  {
53
53
  "location": "",
54
54
  "file": "package.json",
55
- "content": "{\r\n \"private\": true,\r\n \"name\": \"@ORGANIZATION/PROJECT\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"Starter kit of Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"scripts\": {\r\n \"benchmark\": \"node bin/test/benchmark\",\r\n \"test\": \"node bin/test\",\r\n \"test:webpack\": \"npm run webpack && node bin/test/webpack.js\",\r\n \"------------------------BUILDS------------------------\": \"\",\r\n \"build\": \"npm run build:sdk && npm run build:main && npm run build:test\",\r\n \"build:api\": \"rimraf packages/api/lib && npm run build:sdk && rimraf packages/api/lib && tsc -p packages/api/tsconfig.json && rollup -c packages/api/rollup.config.js\",\r\n \"build:main\": \"rimraf lib && tsc\",\r\n \"build:sdk\": \"rimraf src/api/functional && nestia sdk\",\r\n \"build:swagger\": \"npx nestia swagger\",\r\n \"build:test\": \"rimraf bin && tsc -p test/tsconfig.json\",\r\n \"dev\": \"npm run build:test -- --watch\",\r\n \"eslint\": \"eslint src && eslint test\",\r\n \"eslint:fix\": \"eslint --fix src && eslint --fix test\",\r\n \"prepare\": \"ts-patch install && typia patch\",\r\n \"prettier\": \"prettier src --write && prettier test --write\",\r\n \"------------------------WEBPACK------------------------\": \"\",\r\n \"webpack\": \"rimraf dist && webpack\",\r\n \"webpack:start\": \"cd dist && node dist/server\",\r\n \"------------------------DEPLOYS------------------------\": \"\",\r\n \"package:api\": \"npm run build:swagger && npm run build:api && cd packages/api && npm publish\",\r\n \"start\": \"node lib/executable/server\",\r\n \"start:swagger\": \"ts-node src/executable/swagger.ts\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia-start\"\r\n },\r\n \"keywords\": [\r\n \"nestia\",\r\n \"template\",\r\n \"boilerplate\"\r\n ],\r\n \"author\": \"AUTHOR\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia-start/issues\"\r\n },\r\n \"homepage\": \"https://github.com/samchon/nestia-start#readme\",\r\n \"devDependencies\": {\r\n \"@nestia/benchmark\": \"^0.1.0\",\r\n \"@nestia/e2e\": \"^0.7.0\",\r\n \"@nestia/sdk\": \"^3.5.0\",\r\n \"@rollup/plugin-terser\": \"^0.4.4\",\r\n \"@rollup/plugin-typescript\": \"^11.1.6\",\r\n \"@trivago/prettier-plugin-sort-imports\": \"^4.3.0\",\r\n \"@types/cli\": \"^0.11.21\",\r\n \"@types/cli-progress\": \"^3.11.5\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"@types/inquirer\": \"^8.2.5\",\r\n \"@types/node\": \"^18.11.0\",\r\n \"@types/uuid\": \"^8.3.4\",\r\n \"@typescript-eslint/eslint-plugin\": \"^6.19.1\",\r\n \"@typescript-eslint/parser\": \"^6.19.1\",\r\n \"chalk\": \"^4.1.2\",\r\n \"cli\": \"^1.0.1\",\r\n \"cli-progress\": \"^3.12.0\",\r\n \"copy-webpack-plugin\": \"^11.0.0\",\r\n \"eslint-plugin-deprecation\": \"^2.0.0\",\r\n \"express\": \"^4.18.2\",\r\n \"nestia\": \"^5.3.1\",\r\n \"prettier\": \"^3.2.4\",\r\n \"prettier-plugin-prisma\": \"^5.0.0\",\r\n \"rimraf\": \"^3.0.2\",\r\n \"rollup\": \"^4.18.0\",\r\n \"source-map-support\": \"^0.5.21\",\r\n \"swagger-ui-express\": \"^5.0.0\",\r\n \"ts-loader\": \"^9.5.1\",\r\n \"ts-node\": \"^10.9.1\",\r\n \"ts-patch\": \"^3.2.1\",\r\n \"typescript\": \"^5.5.3\",\r\n \"typescript-transform-paths\": \"^3.4.6\",\r\n \"webpack\": \"^5.89.0\",\r\n \"webpack-cli\": \"^5.1.4\",\r\n \"write-file-webpack-plugin\": \"^4.5.1\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/core\": \"^3.5.0\",\r\n \"@nestia/fetcher\": \"^3.5.0\",\r\n \"@nestjs/common\": \"^10.3.10\",\r\n \"@nestjs/core\": \"^10.3.10\",\r\n \"@nestjs/platform-express\": \"^10.3.10\",\r\n \"commander\": \"10.0.0\",\r\n \"dotenv\": \"^16.3.1\",\r\n \"dotenv-expand\": \"^10.0.0\",\r\n \"inquirer\": \"8.2.5\",\r\n \"serialize-error\": \"^4.1.0\",\r\n \"tgrid\": \"^1.0.2\",\r\n \"tstl\": \"^3.0.0\",\r\n \"typia\": \"^6.4.3\",\r\n \"uuid\": \"^9.0.0\"\r\n },\r\n \"stackblitz\": {\r\n \"startCommand\": \"npm run prepare && npm run build:test && npm run test\"\r\n }\r\n}"
55
+ "content": "{\r\n \"private\": true,\r\n \"name\": \"@ORGANIZATION/PROJECT\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"Starter kit of Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"scripts\": {\r\n \"benchmark\": \"node bin/test/benchmark\",\r\n \"test\": \"node bin/test\",\r\n \"test:webpack\": \"npm run webpack && node bin/test/webpack.js\",\r\n \"------------------------BUILDS------------------------\": \"\",\r\n \"build\": \"npm run build:sdk && npm run build:main && npm run build:test\",\r\n \"build:api\": \"rimraf packages/api/lib && npm run build:sdk && rimraf packages/api/lib && tsc -p packages/api/tsconfig.json && rollup -c packages/api/rollup.config.js\",\r\n \"build:main\": \"rimraf lib && tsc\",\r\n \"build:sdk\": \"rimraf src/api/functional && nestia sdk\",\r\n \"build:swagger\": \"npx nestia swagger\",\r\n \"build:test\": \"rimraf bin && tsc -p test/tsconfig.json\",\r\n \"dev\": \"npm run build:test -- --watch\",\r\n \"eslint\": \"eslint src && eslint test\",\r\n \"eslint:fix\": \"eslint --fix src && eslint --fix test\",\r\n \"prepare\": \"ts-patch install && typia patch\",\r\n \"prettier\": \"prettier src --write && prettier test --write\",\r\n \"------------------------WEBPACK------------------------\": \"\",\r\n \"webpack\": \"rimraf dist && webpack\",\r\n \"webpack:start\": \"cd dist && node dist/server\",\r\n \"webpack:test\": \"npm run webpack && node bin/test/webpack.js\",\r\n \"------------------------DEPLOYS------------------------\": \"\",\r\n \"package:api\": \"npm run build:swagger && npm run build:api && cd packages/api && npm publish\",\r\n \"start\": \"node lib/executable/server\",\r\n \"start:swagger\": \"ts-node src/executable/swagger.ts\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia-start\"\r\n },\r\n \"keywords\": [\r\n \"nestia\",\r\n \"template\",\r\n \"boilerplate\"\r\n ],\r\n \"author\": \"AUTHOR\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia-start/issues\"\r\n },\r\n \"homepage\": \"https://github.com/samchon/nestia-start#readme\",\r\n \"devDependencies\": {\r\n \"@nestia/benchmark\": \"^0.2.0\",\r\n \"@nestia/e2e\": \"^0.7.0\",\r\n \"@nestia/sdk\": \"^3.8.1\",\r\n \"@rollup/plugin-terser\": \"^0.4.4\",\r\n \"@rollup/plugin-typescript\": \"^11.1.6\",\r\n \"@trivago/prettier-plugin-sort-imports\": \"^4.3.0\",\r\n \"@types/cli\": \"^0.11.21\",\r\n \"@types/cli-progress\": \"^3.11.5\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"@types/inquirer\": \"^8.2.5\",\r\n \"@types/node\": \"^18.11.0\",\r\n \"@types/uuid\": \"^8.3.4\",\r\n \"@typescript-eslint/eslint-plugin\": \"^6.19.1\",\r\n \"@typescript-eslint/parser\": \"^6.19.1\",\r\n \"chalk\": \"^4.1.2\",\r\n \"cli\": \"^1.0.1\",\r\n \"cli-progress\": \"^3.12.0\",\r\n \"copy-webpack-plugin\": \"^11.0.0\",\r\n \"eslint-plugin-deprecation\": \"^2.0.0\",\r\n \"express\": \"^4.18.2\",\r\n \"nestia\": \"^5.5.0\",\r\n \"prettier\": \"^3.2.4\",\r\n \"prettier-plugin-prisma\": \"^5.0.0\",\r\n \"rimraf\": \"^3.0.2\",\r\n \"rollup\": \"^4.18.0\",\r\n \"source-map-support\": \"^0.5.21\",\r\n \"swagger-ui-express\": \"^5.0.0\",\r\n \"ts-loader\": \"^9.5.1\",\r\n \"ts-node\": \"^10.9.1\",\r\n \"ts-patch\": \"^3.2.1\",\r\n \"typescript\": \"^5.5.4\",\r\n \"typescript-transform-paths\": \"^3.4.6\",\r\n \"webpack\": \"^5.89.0\",\r\n \"webpack-cli\": \"^5.1.4\",\r\n \"write-file-webpack-plugin\": \"^4.5.1\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/core\": \"^3.8.1\",\r\n \"@nestia/fetcher\": \"^3.8.1\",\r\n \"@nestjs/common\": \"^10.3.10\",\r\n \"@nestjs/core\": \"^10.3.10\",\r\n \"@nestjs/platform-express\": \"^10.3.10\",\r\n \"commander\": \"10.0.0\",\r\n \"dotenv\": \"^16.3.1\",\r\n \"dotenv-expand\": \"^10.0.0\",\r\n \"inquirer\": \"8.2.5\",\r\n \"serialize-error\": \"^4.1.0\",\r\n \"tgrid\": \"^1.0.2\",\r\n \"tstl\": \"^3.0.0\",\r\n \"typia\": \"^6.5.4\",\r\n \"uuid\": \"^9.0.0\"\r\n },\r\n \"stackblitz\": {\r\n \"startCommand\": \"npm run prepare && npm run build:test && npm run test\"\r\n }\r\n}"
56
56
  },
57
57
  {
58
58
  "location": "packages/api",
59
59
  "file": ".gitignore",
60
- "content": "lib/\r\nnode_modules/\r\n\r\nswagger.json"
60
+ "content": "lib/\r\nnode_modules/\r\n\r\nswagger.json\r\nopenai.json"
61
61
  },
62
62
  {
63
63
  "location": "packages/api",
@@ -67,7 +67,7 @@ export const NEST_TEMPLATE = [
67
67
  {
68
68
  "location": "packages/api",
69
69
  "file": "package.json",
70
- "content": "{\r\n \"name\": \"@ORGANIZATION/PROJECT-api\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"SDK library generated by Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"module\": \"lib/index.mjs\",\r\n \"typings\": \"lib/index.d.ts\",\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia\"\r\n },\r\n \"author\": \"Jeongho Nam\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia/issues\"\r\n },\r\n \"homepage\": \"https://nestia.io\",\r\n \"files\": [\r\n \"lib\",\r\n \"swagger.json\",\r\n \"package.json\",\r\n \"README.md\"\r\n ],\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^3.5.0\",\r\n \"tgrid\": \"^1.0.2\",\r\n \"typia\": \"^6.4.3\"\r\n }\r\n}"
70
+ "content": "{\r\n \"name\": \"@ORGANIZATION/PROJECT-api\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"SDK library generated by Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"module\": \"lib/index.mjs\",\r\n \"typings\": \"lib/index.d.ts\",\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia\"\r\n },\r\n \"author\": \"Jeongho Nam\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia/issues\"\r\n },\r\n \"homepage\": \"https://nestia.io\",\r\n \"files\": [\r\n \"lib\",\r\n \"package.json\",\r\n \"swagger.json\",\r\n \"openai.json\",\r\n \"README.md\"\r\n ],\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^3.8.0\",\r\n \"tgrid\": \"^1.0.2\",\r\n \"typia\": \"^6.5.4\"\r\n }\r\n}"
71
71
  },
72
72
  {
73
73
  "location": "packages/api",
@@ -92,7 +92,7 @@ export const NEST_TEMPLATE = [
92
92
  {
93
93
  "location": "",
94
94
  "file": "README.md",
95
- "content": "# Nestia Template\r\n## Outline\r\n[![Build Status](https://github.com/samchon/nestia-start/workflows/build/badge.svg)](https://github.com/samchon/nestia-start/actions?query=workflow%3Abuild)\r\n\r\nA template repository for backend projects using [nestia](https://github.com/samchon/nestia).\r\n\r\nYou can create a new project from this boilerplate by running below command:\r\n\r\n```bash\r\nnpx nestia start <directory>\r\n```\r\n\r\nFor reference, this is a minimal boilerplate project concentrating only on [nestia](https://github.com/samchon/nestia) SDK generation. \r\n\r\nIf you wanna much detailed boilerplate project, visit [`@samchon/backend`](https://github.com/samchon/backend).\r\n\r\n\r\n\r\n\r\n## Directories and Files\r\nThis template project has categorized directories like below.\r\n\r\nAs you can see from the below, all of the Backend source files are placed into the [src](src/) directory. When you build the TypeScript source files, compiled files would be placed into the `lib` directory following the [tsconfig.json](tsconfig.json) configuration. Otherwise you build client [SDK](#32-sdk) library for npm publishing and their compiled files would be placed into the [packages](packages) directory.\r\n\r\n - [packages/api/](packages/api): SDK module built by `npm run build:api`\r\n - [src/](src): Backend source directory\r\n - [src/api/](src/api/): Client SDK that would be published to the `@ORGANIZATION/PROJECT-api`\r\n - [**src/api/functional/**](src/api/functional/): API functions generated by the [`nestia`](https://github.com/samchon/nestia)\r\n - [**src/api/structures/**](src/api/structures/): DTO structures\r\n - [src/controllers/](src/controllers/): Controller classes of the Main Program\r\n - [**test/**](test): Test Automation Program\r\n - [nestia.config.ts](nestia.config.ts): Configuration file of [`nestia`](https://github.com/samchon/nestia)\r\n - [package.json](package.json): NPM configuration\r\n - [tsconfig.json](tsconfig.json): TypeScript configuration for the main program\r\n - [tsconfig.api.json](tsconfig.api.json): TypeScript configuration for the SDK generation\r\n\r\n\r\n\r\n\r\n## NPM Run Commands\r\nList of the run commands defined in the [package.json](package.json) are like below:\r\n\r\n - `build`: Build everything\r\n - `build:api`: Build client SDK libray for the client developers\r\n - `build:main`: Build main program (`src` directory)\r\n - `build:sdk`: Build SDK into main program only\r\n - `build:swagger`: Build Swagger Documents\r\n - `build:test` Build test automation program (`test` directory)\r\n - `dev`: Incremental build for development (test program)\r\n - `eslint` & `eslint:fix` & `prettier`: Prettier and ESLint execution\r\n - `start`: Start local NestJS server\r\n - `test`: Run test automation program\r\n - `benchmark`: Run performance benchmark program\r\n\r\n\r\n\r\n\r\n## Specialization\r\nTransform this template project to be yours.\r\n\r\nWhen you've created a new backend project through this template project, you can specialize it to be suitable for you by changing some words. Replace below words through IDE specific function like `Edit > Replace in Files` (*Ctrl + Shift + H*), who've been supported by the VSCode.\r\n\r\n| Before | After\r\n|-----------------|----------------------------------------\r\n| ORGANIZATION | Your account or corporation name\r\n| PROJECT | Your own project name\r\n| AUTHOR | Author name\r\n| https://github.com/samchon/nestia-start | Your repository URL\r\n\r\n\r\n\r\n\r\n## Test Driven Development\r\nWith [nestia](https://github.com/samchon/nestia) helps to accomplish TDD (Test Driven Development). \r\n\r\nJust define DTOs and API controllers' methods (only declarations) first. After the definitions, and build SDK (Software Development Kit) through [nestia](https://github.com/samchon/nestia) (`npm run build:sdk`). After buildling those SDK, develop test automation program using the SDK, following use-case scenarios in the framework of client side.\r\n\r\nDuring the test automation program development, you can find that which API is mis-designed or which requirement analysis is not exact. Development of the main program must be the last step after such validation process during TDD.\r\n\r\n> Visit the [samchon/backend](https://github.com/samchon/backend), then you may find much detailed story about this TDD.\r\n>\r\n> 1. Definitions\r\n> 2. SDK\r\n> 3. Test Automation Program\r\n> 4. Main Program\r\n\r\n```typescript\r\nimport {\r\n ArrayUtil,\r\n GaffComparator,\r\n RandomGenerator,\r\n TestValidator,\r\n} from \"@nestia/e2e\";\r\n\r\nimport api from \"@ORGANIZATION/PROJECT-api/lib/index\";\r\nimport { IBbsArticle } from \"@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@ORGANIZATION/PROJECT-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_api_bbs_article_index_sort(\r\n connection: api.IConnection,\r\n): Promise<void> {\r\n // GENERATE 100 ARTICLES\r\n const section: string = \"general\";\r\n await ArrayUtil.asyncRepeat(100)(() =>\r\n api.functional.bbs.articles.create(connection, section, {\r\n writer: RandomGenerator.name(),\r\n title: RandomGenerator.paragraph(5)(),\r\n body: RandomGenerator.content(8)()(),\r\n format: \"txt\",\r\n files: [],\r\n password: RandomGenerator.alphabets(8),\r\n }),\r\n );\r\n\r\n // PREPARE VALIDATOR\r\n const validator = TestValidator.sort(\"BbsArticleProvider.index()\")(async (\r\n sort: IPage.Sort<IBbsArticle.IRequest.SortableColumns>,\r\n ) => {\r\n const page: IPage<IBbsArticle.ISummary> =\r\n await api.functional.bbs.articles.index(connection, section, {\r\n limit: 100,\r\n sort,\r\n });\r\n return page.data;\r\n });\r\n\r\n // DO VALIDATE\r\n const components = [\r\n validator(\"created_at\")(GaffComparator.dates((x) => x.created_at)),\r\n validator(\"updated_at\")(GaffComparator.dates((x) => x.updated_at)),\r\n validator(\"title\")(GaffComparator.strings((x) => x.title)),\r\n validator(\"writer\")(GaffComparator.strings((x) => x.writer)),\r\n validator(\r\n \"writer\",\r\n \"title\",\r\n )(GaffComparator.strings((x) => [x.writer, x.title])),\r\n ];\r\n for (const comp of components) {\r\n await comp(\"+\", false);\r\n await comp(\"-\", false);\r\n }\r\n}\r\n```\r\n\r\nFor reference, if you run `npm run benchmark` command, your test functions defined in the [test/features/api](test/features/api) directory would be utilized for performance benchmarking. If you want to see the performance bench result earlier, visit below link please:\r\n\r\n - [docs/benchmarks/AMD Ryzen 9 7940HS w Radeon 780M Graphics.md](https://github.com/samchon/nestia-start/blob/master/docs/benchmarks/AMD%20Ryzen%209%207940HS%20w%20Radeon%20780M%20Graphics.md)"
95
+ "content": "# Nestia Template\r\n## Outline\r\n[![Build Status](https://github.com/samchon/nestia-start/workflows/build/badge.svg)](https://github.com/samchon/nestia-start/actions?query=workflow%3Abuild)\r\n\r\nA template repository for backend projects using [nestia](https://github.com/samchon/nestia).\r\n\r\nYou can create a new project from this boilerplate by running below command:\r\n\r\n```bash\r\nnpx nestia start <directory>\r\n```\r\n\r\nFor reference, this is a minimal boilerplate project concentrating only on [nestia](https://github.com/samchon/nestia) SDK generation. \r\n\r\nIf you wanna much detailed boilerplate project, visit [`@samchon/backend`](https://github.com/samchon/backend).\r\n\r\n\r\n\r\n\r\n## Directories and Files\r\nThis template project has categorized directories like below.\r\n\r\nAs you can see from the below, all of the Backend source files are placed into the [src](src/) directory. When you build the TypeScript source files, compiled files would be placed into the `lib` directory following the [tsconfig.json](tsconfig.json) configuration. Otherwise you build client [SDK](#32-sdk) library for npm publishing and their compiled files would be placed into the [packages](packages) directory.\r\n\r\n - [packages/api/](packages/api): SDK module built by `npm run build:api`\r\n - [src/](src): Backend source directory\r\n - [src/api/](src/api/): Client SDK that would be published to the `@ORGANIZATION/PROJECT-api`\r\n - [**src/api/functional/**](src/api/functional/): API functions generated by the [`nestia`](https://github.com/samchon/nestia)\r\n - [**src/api/structures/**](src/api/structures/): DTO structures\r\n - [src/controllers/](src/controllers/): Controller classes of the Main Program\r\n - [**test/**](test): Test Automation Program\r\n - [nestia.config.ts](nestia.config.ts): Configuration file of [`nestia`](https://github.com/samchon/nestia)\r\n - [package.json](package.json): NPM configuration\r\n - [tsconfig.json](tsconfig.json): TypeScript configuration for the main program\r\n - [tsconfig.api.json](tsconfig.api.json): TypeScript configuration for the SDK generation\r\n\r\n\r\n\r\n\r\n## NPM Run Commands\r\nList of the run commands defined in the [package.json](package.json) are like below:\r\n\r\n - Test\r\n - **`test`**: Run test automation program\r\n - `benchmark`: Run performance benchmark program\r\n - Build\r\n - `build`: Build everything\r\n - `build:main`: Build main program (`src` directory)\r\n - `build:test` Build test automation program (`test` directory)\r\n - `build:sdk`: Build SDK into main program only\r\n - `build:swagger`: Build Swagger Documents\r\n - **`dev`**: Incremental build for development (test program)\r\n - Deploy\r\n - `package:api`: Build and deploy the SDK library to the NPM\r\n - `start`: Start local NestJS server\r\n - Webpack\r\n - `webpack`: Run webpack bundler\r\n - `webpack:start`: Start the backend server built by webpack\r\n - `webpack:test`: Run test program to the webpack built\r\n\r\n\r\n\r\n\r\n## Specialization\r\nTransform this template project to be yours.\r\n\r\nWhen you've created a new backend project through this template project, you can specialize it to be suitable for you by changing some words. Replace below words through IDE specific function like `Edit > Replace in Files` (*Ctrl + Shift + H*), who've been supported by the VSCode.\r\n\r\n| Before | After\r\n|-----------------|----------------------------------------\r\n| ORGANIZATION | Your account or corporation name\r\n| PROJECT | Your own project name\r\n| AUTHOR | Author name\r\n| https://github.com/samchon/nestia-start | Your repository URL\r\n\r\n\r\n\r\n\r\n## Test Driven Development\r\nWith [nestia](https://github.com/samchon/nestia) helps to accomplish TDD (Test Driven Development). \r\n\r\nJust define DTOs and API controllers' methods (only declarations) first. After the definitions, and build SDK (Software Development Kit) through [nestia](https://github.com/samchon/nestia) (`npm run build:sdk`). After buildling those SDK, develop test automation program using the SDK, following use-case scenarios in the framework of client side.\r\n\r\nDuring the test automation program development, you can find that which API is mis-designed or which requirement analysis is not exact. Development of the main program must be the last step after such validation process during TDD.\r\n\r\n> Visit the [samchon/backend](https://github.com/samchon/backend), then you may find much detailed story about this TDD.\r\n>\r\n> 1. Definitions\r\n> 2. SDK\r\n> 3. Test Automation Program\r\n> 4. Main Program\r\n\r\n```typescript\r\nimport {\r\n ArrayUtil,\r\n GaffComparator,\r\n RandomGenerator,\r\n TestValidator,\r\n} from \"@nestia/e2e\";\r\n\r\nimport api from \"@ORGANIZATION/PROJECT-api/lib/index\";\r\nimport { IBbsArticle } from \"@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@ORGANIZATION/PROJECT-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_api_bbs_article_index_sort(\r\n connection: api.IConnection,\r\n): Promise<void> {\r\n // GENERATE 100 ARTICLES\r\n const section: string = \"general\";\r\n await ArrayUtil.asyncRepeat(100)(() =>\r\n api.functional.bbs.articles.create(connection, section, {\r\n writer: RandomGenerator.name(),\r\n title: RandomGenerator.paragraph(5)(),\r\n body: RandomGenerator.content(8)()(),\r\n format: \"txt\",\r\n files: [],\r\n password: RandomGenerator.alphabets(8),\r\n }),\r\n );\r\n\r\n // PREPARE VALIDATOR\r\n const validator = TestValidator.sort(\"BbsArticleProvider.index()\")(async (\r\n sort: IPage.Sort<IBbsArticle.IRequest.SortableColumns>,\r\n ) => {\r\n const page: IPage<IBbsArticle.ISummary> =\r\n await api.functional.bbs.articles.index(connection, section, {\r\n limit: 100,\r\n sort,\r\n });\r\n return page.data;\r\n });\r\n\r\n // DO VALIDATE\r\n const components = [\r\n validator(\"created_at\")(GaffComparator.dates((x) => x.created_at)),\r\n validator(\"updated_at\")(GaffComparator.dates((x) => x.updated_at)),\r\n validator(\"title\")(GaffComparator.strings((x) => x.title)),\r\n validator(\"writer\")(GaffComparator.strings((x) => x.writer)),\r\n validator(\r\n \"writer\",\r\n \"title\",\r\n )(GaffComparator.strings((x) => [x.writer, x.title])),\r\n ];\r\n for (const comp of components) {\r\n await comp(\"+\", false);\r\n await comp(\"-\", false);\r\n }\r\n}\r\n```\r\n\r\nFor reference, if you run `npm run benchmark` command, your test functions defined in the [test/features/api](test/features/api) directory would be utilized for performance benchmarking. If you want to see the performance bench result earlier, visit below link please:\r\n\r\n - [docs/benchmarks/AMD Ryzen 9 7940HS w Radeon 780M Graphics.md](https://github.com/samchon/nestia-start/blob/master/docs/benchmarks/AMD%20Ryzen%209%207940HS%20w%20Radeon%20780M%20Graphics.md)"
96
96
  },
97
97
  {
98
98
  "location": "src/api",
@@ -137,7 +137,7 @@ export const NEST_TEMPLATE = [
137
137
  {
138
138
  "location": "src/executable",
139
139
  "file": "server.ts",
140
- "content": "import fs from \"fs\";\r\nimport { Singleton, randint } from \"tstl\";\r\n\r\nimport { MyBackend } from \"../MyBackend\";\r\nimport { MyConfiguration } from \"../MyConfiguration\";\r\nimport { ErrorUtil } from \"../utils/ErrorUtil\";\r\n\r\nconst EXTENSION = __filename.substring(__filename.length - 2);\r\nif (EXTENSION === \"js\") require(\"source-map-support/register\");\r\n\r\nconst directory = new Singleton(async () => {\r\n await mkdir(`${MyConfiguration.ROOT}/assets`);\r\n await mkdir(`${MyConfiguration.ROOT}/assets/logs`);\r\n await mkdir(`${MyConfiguration.ROOT}/assets/logs/errors`);\r\n});\r\n\r\nfunction cipher(val: number): string {\r\n if (val < 10) return \"0\" + val;\r\n else return String(val);\r\n}\r\n\r\nasync function mkdir(path: string): Promise<void> {\r\n try {\r\n await fs.promises.mkdir(path);\r\n } catch {}\r\n}\r\n\r\nasync function handle_error(exp: any): Promise<void> {\r\n try {\r\n const date: Date = new Date();\r\n const fileName: string = `${date.getFullYear()}${cipher(\r\n date.getMonth() + 1,\r\n )}${cipher(date.getDate())}${cipher(date.getHours())}${cipher(\r\n date.getMinutes(),\r\n )}${cipher(date.getSeconds())}.${randint(0, Number.MAX_SAFE_INTEGER)}`;\r\n const content: string = JSON.stringify(ErrorUtil.toJSON(exp), null, 4);\r\n\r\n await directory.get();\r\n await fs.promises.writeFile(\r\n `${MyConfiguration.ROOT}/assets/logs/errors/${fileName}.log`,\r\n content,\r\n \"utf8\",\r\n );\r\n } catch {}\r\n}\r\n\r\nasync function main(): Promise<void> {\r\n // BACKEND SEVER\r\n const backend: MyBackend = new MyBackend();\r\n await backend.open();\r\n\r\n // UNEXPECTED ERRORS\r\n global.process.on(\"uncaughtException\", handle_error);\r\n global.process.on(\"unhandledRejection\", handle_error);\r\n}\r\nmain().catch((exp) => {\r\n console.log(exp);\r\n process.exit(-1);\r\n});\r\n"
140
+ "content": "import { MyBackend } from \"../MyBackend\";\r\n\r\nconst EXTENSION = __filename.substring(__filename.length - 2);\r\nif (EXTENSION === \"js\") require(\"source-map-support/register\");\r\n\r\nasync function main(): Promise<void> {\r\n // BACKEND SEVER\r\n const backend: MyBackend = new MyBackend();\r\n await backend.open();\r\n\r\n // UNEXPECTED ERRORS\r\n global.process.on(\"uncaughtException\", console.error);\r\n global.process.on(\"unhandledRejection\", console.error);\r\n}\r\nmain().catch((exp) => {\r\n console.log(exp);\r\n process.exit(-1);\r\n});\r\n"
141
141
  },
142
142
  {
143
143
  "location": "src/executable",
@@ -162,7 +162,7 @@ export const NEST_TEMPLATE = [
162
162
  {
163
163
  "location": "src/utils",
164
164
  "file": "ErrorUtil.ts",
165
- "content": "import fs from \"fs\";\r\nimport { Singleton, randint } from \"tstl\";\r\n\r\nimport { MyConfiguration } from \"../MyConfiguration\";\r\n\r\nimport serializeError = require(\"serialize-error\");\r\n\r\nexport namespace ErrorUtil {\r\n export const toJSON = (err: any): object =>\r\n err instanceof Object && err.toJSON instanceof Function\r\n ? err.toJSON()\r\n : serializeError(err);\r\n\r\n export const log =\r\n (prefix: string) =>\r\n async (error: string | object | Error): Promise<void> => {\r\n try {\r\n if (error instanceof Error) error = toJSON(error);\r\n\r\n const date: Date = new Date();\r\n const fileName: string = `${date.getFullYear()}${cipher(\r\n date.getMonth() + 1,\r\n )}${cipher(date.getDate())}${cipher(date.getHours())}${cipher(\r\n date.getMinutes(),\r\n )}${cipher(date.getSeconds())}.${randint(0, Number.MAX_SAFE_INTEGER)}`;\r\n const content: string = JSON.stringify(error, null, 4);\r\n\r\n await directory.get();\r\n await fs.promises.writeFile(\r\n `${MyConfiguration.ROOT}/assets/logs/errors/${prefix}_${fileName}.log`,\r\n content,\r\n \"utf8\",\r\n );\r\n } catch {}\r\n };\r\n}\r\n\r\nconst cipher = (val: number): string => String(val).padStart(2, \"0\");\r\nconst directory = new Singleton(async () => {\r\n await mkdir(`${MyConfiguration.ROOT}/assets/logs`);\r\n await mkdir(`${MyConfiguration.ROOT}/assets/logs/errors`);\r\n});\r\nasync function mkdir(path: string): Promise<void> {\r\n try {\r\n await fs.promises.mkdir(path);\r\n } catch {}\r\n}\r\n"
165
+ "content": "import serializeError = require(\"serialize-error\");\r\n\r\nexport namespace ErrorUtil {\r\n export const toJSON = (err: any): object =>\r\n err instanceof Object && err.toJSON instanceof Function\r\n ? err.toJSON()\r\n : serializeError(err);\r\n}\r\n"
166
166
  },
167
167
  {
168
168
  "location": "src/utils",
@@ -187,7 +187,7 @@ export const NEST_TEMPLATE = [
187
187
  {
188
188
  "location": "test",
189
189
  "file": "index.ts",
190
- "content": "import { DynamicExecutor } from \"@nestia/e2e\";\r\nimport chalk from \"chalk\";\r\n\r\nimport api from \"@ORGANIZATION/PROJECT-api\";\r\n\r\nimport { MyBackend } from \"../src/MyBackend\";\r\nimport { MyConfiguration } from \"../src/MyConfiguration\";\r\nimport { MyGlobal } from \"../src/MyGlobal\";\r\nimport { ArgumentParser } from \"./helpers/ArgumentParser\";\r\n\r\ninterface IOptions {\r\n include?: string[];\r\n exclude?: string[];\r\n}\r\n\r\nconst getOptions = () =>\r\n ArgumentParser.parse<IOptions>(async (command, _prompt, action) => {\r\n // command.option(\"--mode <string>\", \"target mode\");\r\n // command.option(\"--reset <true|false>\", \"reset local DB or not\");\r\n command.option(\"--include <string...>\", \"include feature files\");\r\n command.option(\"--exclude <string...>\", \"exclude feature files\");\r\n\r\n return action(async (options) => {\r\n // if (typeof options.reset === \"string\")\r\n // options.reset = options.reset === \"true\";\r\n // options.mode ??= await prompt.select(\"mode\")(\"Select mode\")([\r\n // \"LOCAL\",\r\n // \"DEV\",\r\n // \"REAL\",\r\n // ]);\r\n // options.reset ??= await prompt.boolean(\"reset\")(\"Reset local DB\");\r\n return options as IOptions;\r\n });\r\n });\r\n\r\nasync function main(): Promise<void> {\r\n // CONFIGURATIONS\r\n const options: IOptions = await getOptions();\r\n MyGlobal.testing = true;\r\n\r\n // BACKEND SERVER\r\n const backend: MyBackend = new MyBackend();\r\n await backend.open();\r\n\r\n //----\r\n // CLINET CONNECTOR\r\n //----\r\n // DO TEST\r\n const connection: api.IConnection = {\r\n host: `http://127.0.0.1:${MyConfiguration.API_PORT()}`,\r\n };\r\n const report: DynamicExecutor.IReport = await DynamicExecutor.validate({\r\n prefix: \"test\",\r\n location: __dirname + \"/features\",\r\n parameters: () => [\r\n {\r\n host: connection.host,\r\n encryption: connection.encryption,\r\n },\r\n ],\r\n filter: (func) =>\r\n (!options.include?.length ||\r\n (options.include ?? []).some((str) => func.includes(str))) &&\r\n (!options.exclude?.length ||\r\n (options.exclude ?? []).every((str) => !func.includes(str))),\r\n onComplete: (exec) => {\r\n if (exec.error === null) {\r\n const elapsed: number =\r\n new Date(exec.completed_at).getTime() -\r\n new Date(exec.started_at).getTime();\r\n console.log(\r\n ` - ${exec.name}: ${chalk.green(elapsed.toLocaleString())} ms`,\r\n );\r\n } else console.log(` - ${exec.name}: ${chalk.red(exec.error.name)}`);\r\n },\r\n });\r\n await backend.close();\r\n\r\n const failures: DynamicExecutor.IExecution[] = report.executions.filter(\r\n (exec) => exec.error !== null,\r\n );\r\n if (failures.length === 0) {\r\n console.log(\"Success\");\r\n console.log(\"Elapsed time\", report.time.toLocaleString(), `ms`);\r\n } else {\r\n for (const f of failures) console.log(f.error);\r\n process.exit(-1);\r\n }\r\n\r\n console.log(\r\n [\r\n `All: #${report.executions.length}`,\r\n `Success: #${report.executions.length - failures.length}`,\r\n `Failed: #${failures.length}`,\r\n ].join(\"\\n\"),\r\n );\r\n}\r\nmain().catch((exp) => {\r\n console.log(exp);\r\n process.exit(-1);\r\n});\r\n"
190
+ "content": "import { DynamicExecutor } from \"@nestia/e2e\";\r\nimport chalk from \"chalk\";\r\n\r\nimport api from \"@ORGANIZATION/PROJECT-api\";\r\n\r\nimport { MyBackend } from \"../src/MyBackend\";\r\nimport { MyConfiguration } from \"../src/MyConfiguration\";\r\nimport { MyGlobal } from \"../src/MyGlobal\";\r\nimport { ArgumentParser } from \"./helpers/ArgumentParser\";\r\n\r\ninterface IOptions {\r\n include?: string[];\r\n exclude?: string[];\r\n}\r\n\r\nconst getOptions = () =>\r\n ArgumentParser.parse<IOptions>(async (command, _prompt, action) => {\r\n // command.option(\"--mode <string>\", \"target mode\");\r\n // command.option(\"--reset <true|false>\", \"reset local DB or not\");\r\n command.option(\"--include <string...>\", \"include feature files\");\r\n command.option(\"--exclude <string...>\", \"exclude feature files\");\r\n\r\n return action(async (options) => {\r\n // if (typeof options.reset === \"string\")\r\n // options.reset = options.reset === \"true\";\r\n // options.mode ??= await prompt.select(\"mode\")(\"Select mode\")([\r\n // \"LOCAL\",\r\n // \"DEV\",\r\n // \"REAL\",\r\n // ]);\r\n // options.reset ??= await prompt.boolean(\"reset\")(\"Reset local DB\");\r\n return options as IOptions;\r\n });\r\n });\r\n\r\nasync function main(): Promise<void> {\r\n // CONFIGURATIONS\r\n const options: IOptions = await getOptions();\r\n MyGlobal.testing = true;\r\n\r\n // BACKEND SERVER\r\n const backend: MyBackend = new MyBackend();\r\n await backend.open();\r\n\r\n //----\r\n // CLINET CONNECTOR\r\n //----\r\n // DO TEST\r\n const connection: api.IConnection = {\r\n host: `http://127.0.0.1:${MyConfiguration.API_PORT()}`,\r\n };\r\n const report: DynamicExecutor.IReport = await DynamicExecutor.validate({\r\n prefix: \"test\",\r\n location: __dirname + \"/features\",\r\n parameters: () => [\r\n {\r\n host: connection.host,\r\n encryption: connection.encryption,\r\n },\r\n ],\r\n filter: (func) =>\r\n (!options.include?.length ||\r\n (options.include ?? []).some((str) => func.includes(str))) &&\r\n (!options.exclude?.length ||\r\n (options.exclude ?? []).every((str) => !func.includes(str))),\r\n onComplete: (exec) => {\r\n const trace = (str: string) =>\r\n console.log(` - ${chalk.green(exec.name)}: ${str}`);\r\n if (exec.error === null) {\r\n const elapsed: number =\r\n new Date(exec.completed_at).getTime() -\r\n new Date(exec.started_at).getTime();\r\n trace(`${chalk.yellow(elapsed.toLocaleString())} ms`);\r\n } else trace(chalk.red(exec.error.name));\r\n },\r\n });\r\n await backend.close();\r\n\r\n const failures: DynamicExecutor.IExecution[] = report.executions.filter(\r\n (exec) => exec.error !== null,\r\n );\r\n if (failures.length === 0) {\r\n console.log(\"Success\");\r\n console.log(\"Elapsed time\", report.time.toLocaleString(), `ms`);\r\n } else {\r\n for (const f of failures) console.log(f.error);\r\n process.exit(-1);\r\n }\r\n\r\n console.log(\r\n [\r\n `All: #${report.executions.length}`,\r\n `Success: #${report.executions.length - failures.length}`,\r\n `Failed: #${failures.length}`,\r\n ].join(\"\\n\"),\r\n );\r\n}\r\nmain().catch((exp) => {\r\n console.log(exp);\r\n process.exit(-1);\r\n});\r\n"
191
191
  },
192
192
  {
193
193
  "location": "test",
@@ -197,7 +197,7 @@ export const NEST_TEMPLATE = [
197
197
  {
198
198
  "location": "test",
199
199
  "file": "webpack.ts",
200
- "content": "import { DynamicExecutor } from \"@nestia/e2e\";\r\nimport chalk from \"chalk\";\r\nimport cp from \"child_process\";\r\nimport { sleep_for } from \"tstl\";\r\n\r\nimport { MyConfiguration } from \"../src/MyConfiguration\";\r\nimport api from \"../src/api\";\r\n\r\nconst main = async (): Promise<void> => {\r\n // OPEN BUNDLED SERVER\r\n const backend = cp.fork(`${MyConfiguration.ROOT}/dist/server.js`, {\r\n cwd: `${MyConfiguration.ROOT}/dist`,\r\n });\r\n await sleep_for(2_500);\r\n\r\n // DO TEST\r\n const connection: api.IConnection = {\r\n host: `http://127.0.0.1:${MyConfiguration.API_PORT()}`,\r\n };\r\n const report: DynamicExecutor.IReport = await DynamicExecutor.validate({\r\n prefix: \"test\",\r\n location: __dirname + \"/features\",\r\n parameters: () => [\r\n {\r\n host: connection.host,\r\n encryption: connection.encryption,\r\n },\r\n ],\r\n onComplete: (exec) => {\r\n if (exec.error === null) {\r\n const elapsed: number =\r\n new Date(exec.completed_at).getTime() -\r\n new Date(exec.started_at).getTime();\r\n console.log(\r\n ` - ${exec.name}: ${chalk.green(elapsed.toLocaleString())} ms`,\r\n );\r\n } else console.log(` - ${exec.name}: ${chalk.red(exec.error.name)}`);\r\n },\r\n });\r\n\r\n backend.kill();\r\n\r\n const failures: DynamicExecutor.IExecution[] = report.executions.filter(\r\n (exec) => exec.error !== null,\r\n );\r\n if (failures.length === 0) {\r\n console.log(\"Success\");\r\n console.log(\"Elapsed time\", report.time.toLocaleString(), `ms`);\r\n } else {\r\n for (const f of failures) console.log(f.error);\r\n process.exit(-1);\r\n }\r\n};\r\nmain().catch((exp) => {\r\n console.log(exp);\r\n process.exit(-1);\r\n});\r\n"
200
+ "content": "import { DynamicExecutor } from \"@nestia/e2e\";\r\nimport chalk from \"chalk\";\r\nimport cp from \"child_process\";\r\nimport { sleep_for } from \"tstl\";\r\n\r\nimport { MyConfiguration } from \"../src/MyConfiguration\";\r\nimport api from \"../src/api\";\r\n\r\nconst main = async (): Promise<void> => {\r\n // OPEN BUNDLED SERVER\r\n const backend = cp.fork(`${MyConfiguration.ROOT}/dist/server.js`, {\r\n cwd: `${MyConfiguration.ROOT}/dist`,\r\n });\r\n await sleep_for(2_500);\r\n\r\n // DO TEST\r\n const connection: api.IConnection = {\r\n host: `http://127.0.0.1:${MyConfiguration.API_PORT()}`,\r\n };\r\n const report: DynamicExecutor.IReport = await DynamicExecutor.validate({\r\n prefix: \"test\",\r\n location: __dirname + \"/features\",\r\n parameters: () => [\r\n {\r\n host: connection.host,\r\n encryption: connection.encryption,\r\n },\r\n ],\r\n onComplete: (exec) => {\r\n const trace = (str: string) =>\r\n console.log(` - ${chalk.green(exec.name)}: ${str}`);\r\n if (exec.error === null) {\r\n const elapsed: number =\r\n new Date(exec.completed_at).getTime() -\r\n new Date(exec.started_at).getTime();\r\n trace(`${chalk.yellow(elapsed.toLocaleString())} ms`);\r\n } else trace(chalk.red(exec.error.name));\r\n },\r\n });\r\n\r\n backend.kill();\r\n\r\n const failures: DynamicExecutor.IExecution[] = report.executions.filter(\r\n (exec) => exec.error !== null,\r\n );\r\n if (failures.length === 0) {\r\n console.log(\"Success\");\r\n console.log(\"Elapsed time\", report.time.toLocaleString(), `ms`);\r\n } else {\r\n for (const f of failures) console.log(f.error);\r\n process.exit(-1);\r\n }\r\n};\r\nmain().catch((exp) => {\r\n console.log(exp);\r\n process.exit(-1);\r\n});\r\n"
201
201
  },
202
202
  {
203
203
  "location": "",
@@ -27,7 +27,7 @@ export const SDK_TEMPLATE = [
27
27
  {
28
28
  "location": "",
29
29
  "file": "package.json",
30
- "content": "{\r\n \"name\": \"@ORGANIZATION/PROJECT-api\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"SDK library generated by Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"module\": \"lib/index.mjs\",\r\n \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"rimraf lib && tsc && rollup -c\",\r\n \"build:test\": \"rimraf bin && tsc --project test/tsconfig.json\",\r\n \"deploy\": \"npm run build && npm publish\",\r\n \"dev\": \"npm run build:test -- --watch\",\r\n \"hello\": \"node hello\",\r\n \"prepare\": \"ts-patch install && typia patch\",\r\n \"start\": \"ts-node test/start.ts\",\r\n \"swagger\": \"ts-node test/swagger.ts\",\r\n \"test\": \"ts-node test/index.ts\",\r\n \"test:simulate\": \"ts-node test/index.ts --simulate true\",\r\n \"test:manual\": \"ts-node test/manual.ts\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia\"\r\n },\r\n \"author\": \"Jeongho Nam\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia/issues\"\r\n },\r\n \"homepage\": \"https://nestia.io\",\r\n \"files\": [\r\n \"lib\",\r\n \"swagger.json\",\r\n \"package.json\",\r\n \"README.md\"\r\n ],\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^3.5.0\",\r\n \"tgrid\": \"^1.0.2\",\r\n \"typia\": \"^6.4.3\"\r\n },\r\n \"devDependencies\": {\r\n \"@nestia/e2e\": \"^0.7.0\",\r\n \"@rollup/plugin-terser\": \"^0.4.4\",\r\n \"@rollup/plugin-typescript\": \"^11.1.6\",\r\n \"@trivago/prettier-plugin-sort-imports\": \"^4.3.0\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"@types/inquirer\": \"8.2.5\",\r\n \"@types/swagger-ui-express\": \"^4.1.6\",\r\n \"chalk\": \"4.1.2\",\r\n \"commander\": \"^10.0.0\",\r\n \"express\": \"^4.19.2\",\r\n \"inquirer\": \"8.2.5\",\r\n \"prettier\": \"^3.2.5\",\r\n \"rimraf\": \"^5.0.5\",\r\n \"rollup\": \"^4.13.2\",\r\n \"swagger-ui-express\": \"^5.0.0\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.2.1\",\r\n \"typescript\": \"^5.5.3\",\r\n \"typescript-transform-paths\": \"^3.4.6\"\r\n }\r\n}"
30
+ "content": "{\r\n \"name\": \"@ORGANIZATION/PROJECT-api\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"SDK library generated by Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"module\": \"lib/index.mjs\",\r\n \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"rimraf lib && tsc && rollup -c\",\r\n \"build:test\": \"rimraf bin && tsc --project test/tsconfig.json\",\r\n \"deploy\": \"npm run build && npm publish\",\r\n \"dev\": \"npm run build:test -- --watch\",\r\n \"hello\": \"node hello\",\r\n \"prepare\": \"ts-patch install && typia patch\",\r\n \"start\": \"ts-node test/start.ts\",\r\n \"swagger\": \"ts-node test/swagger.ts\",\r\n \"test\": \"ts-node test/index.ts\",\r\n \"test:simulate\": \"ts-node test/index.ts --simulate true\",\r\n \"test:manual\": \"ts-node test/manual.ts\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia\"\r\n },\r\n \"author\": \"Jeongho Nam\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia/issues\"\r\n },\r\n \"homepage\": \"https://nestia.io\",\r\n \"files\": [\r\n \"lib\",\r\n \"swagger.json\",\r\n \"package.json\",\r\n \"README.md\"\r\n ],\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^3.8.0\",\r\n \"tgrid\": \"^1.0.2\",\r\n \"typia\": \"^6.5.4\"\r\n },\r\n \"devDependencies\": {\r\n \"@nestia/e2e\": \"^0.7.0\",\r\n \"@rollup/plugin-terser\": \"^0.4.4\",\r\n \"@rollup/plugin-typescript\": \"^11.1.6\",\r\n \"@trivago/prettier-plugin-sort-imports\": \"^4.3.0\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"@types/inquirer\": \"8.2.5\",\r\n \"@types/swagger-ui-express\": \"^4.1.6\",\r\n \"chalk\": \"4.1.2\",\r\n \"commander\": \"^10.0.0\",\r\n \"express\": \"^4.19.2\",\r\n \"inquirer\": \"8.2.5\",\r\n \"prettier\": \"^3.2.5\",\r\n \"rimraf\": \"^5.0.5\",\r\n \"rollup\": \"^4.13.2\",\r\n \"swagger-ui-express\": \"^5.0.0\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.2.1\",\r\n \"typescript\": \"^5.5.4\",\r\n \"typescript-transform-paths\": \"^3.4.6\"\r\n }\r\n}"
31
31
  },
32
32
  {
33
33
  "location": "",
@@ -77,12 +77,7 @@ export const SDK_TEMPLATE = [
77
77
  {
78
78
  "location": "test",
79
79
  "file": "index.ts",
80
- "content": "import { DynamicExecutor } from \"@nestia/e2e\";\r\nimport chalk from \"chalk\";\r\n\r\nimport { TestGlobal } from \"./TestGlobal\";\r\nimport { ArgumentParser } from \"./utils/ArgumentParser\";\r\n\r\ninterface IOptions {\r\n simulate: boolean;\r\n include?: string[];\r\n exclude?: string[];\r\n trace: boolean;\r\n}\r\n\r\nconst getOptions = () =>\r\n ArgumentParser.parse<IOptions>(async (command, prompt, action) => {\r\n command.option(\"--simulate <boolean>\", \"Mockup Simultator\");\r\n command.option(\"--include <string...>\", \"include feature files\");\r\n command.option(\"--exclude <string...>\", \"exclude feature files\");\r\n command.option(\"--trace <boolean>\", \"trace detailed errors\");\r\n\r\n return action(async (options) => {\r\n if (typeof options.simulate === \"string\")\r\n options.simulate = options.simulate === \"true\";\r\n options.simulate ??= await prompt.boolean(\"simulate\")(\"Mockup Simulator\");\r\n options.trace = options.trace !== (\"false\" as any);\r\n return options as IOptions;\r\n });\r\n });\r\n\r\nconst main = async (): Promise<void> => {\r\n // DO TEST\r\n const options: IOptions = await getOptions();\r\n const report: DynamicExecutor.IReport = await DynamicExecutor.validate({\r\n prefix: \"test\",\r\n location: __dirname + \"/features\",\r\n extension: __filename.substring(__filename.length - 2),\r\n parameters: () => [\r\n {\r\n ...TestGlobal.connection(),\r\n simulate: options.simulate,\r\n },\r\n ],\r\n filter: (func) =>\r\n (!options.include?.length ||\r\n (options.include ?? []).some((str) => func.includes(str))) &&\r\n (!options.exclude?.length ||\r\n (options.exclude ?? []).every((str) => !func.includes(str))),\r\n onComplete: (exec) => {\r\n if (exec.error === null) {\r\n const elapsed: number =\r\n new Date(exec.completed_at).getTime() -\r\n new Date(exec.started_at).getTime();\r\n console.log(\r\n ` - ${exec.name}: ${chalk.green(elapsed.toLocaleString())} ms`,\r\n );\r\n } else console.log(` - ${exec.name}: ${chalk.red(exec.error.name)}`);\r\n },\r\n });\r\n\r\n // REPORT EXCEPTIONS\r\n const exceptions: Error[] = report.executions\r\n .filter((exec) => exec.error !== null)\r\n .map((exec) => exec.error!);\r\n if (exceptions.length === 0) {\r\n console.log(\"Success\");\r\n console.log(\"Elapsed time\", report.time.toLocaleString(), `ms`);\r\n } else {\r\n if (options.trace !== false) for (const exp of exceptions) console.log(exp);\r\n console.log(\"Failed\");\r\n console.log(\"Elapsed time\", report.time.toLocaleString(), `ms`);\r\n }\r\n\r\n // TERMINATE\r\n if (exceptions.length) process.exit(-1);\r\n else process.exit(0);\r\n};\r\nmain().catch((exp) => {\r\n console.log(exp);\r\n process.exit(-1);\r\n});\r\n"
81
- },
82
- {
83
- "location": "test",
84
- "file": "manual.ts",
85
- "content": ""
80
+ "content": "import { DynamicExecutor } from \"@nestia/e2e\";\r\nimport chalk from \"chalk\";\r\n\r\nimport { TestGlobal } from \"./TestGlobal\";\r\nimport { ArgumentParser } from \"./utils/ArgumentParser\";\r\n\r\ninterface IOptions {\r\n simulate: boolean;\r\n include?: string[];\r\n exclude?: string[];\r\n trace: boolean;\r\n}\r\n\r\nconst getOptions = () =>\r\n ArgumentParser.parse<IOptions>(async (command, prompt, action) => {\r\n command.option(\"--simulate <boolean>\", \"Mockup Simultator\");\r\n command.option(\"--include <string...>\", \"include feature files\");\r\n command.option(\"--exclude <string...>\", \"exclude feature files\");\r\n command.option(\"--trace <boolean>\", \"trace detailed errors\");\r\n\r\n return action(async (options) => {\r\n if (typeof options.simulate === \"string\")\r\n options.simulate = options.simulate === \"true\";\r\n options.simulate ??= await prompt.boolean(\"simulate\")(\"Mockup Simulator\");\r\n options.trace = options.trace !== (\"false\" as any);\r\n return options as IOptions;\r\n });\r\n });\r\n\r\nconst main = async (): Promise<void> => {\r\n // DO TEST\r\n const options: IOptions = await getOptions();\r\n const report: DynamicExecutor.IReport = await DynamicExecutor.validate({\r\n prefix: \"test\",\r\n location: __dirname + \"/features\",\r\n extension: __filename.substring(__filename.length - 2),\r\n parameters: () => [\r\n {\r\n ...TestGlobal.connection(),\r\n simulate: options.simulate,\r\n },\r\n ],\r\n filter: (func) =>\r\n (!options.include?.length ||\r\n (options.include ?? []).some((str) => func.includes(str))) &&\r\n (!options.exclude?.length ||\r\n (options.exclude ?? []).every((str) => !func.includes(str))),\r\n onComplete: (exec) => {\r\n const trace = (str: string) =>\r\n console.log(` - ${chalk.green(exec.name)}: ${str}`);\r\n if (exec.error === null) {\r\n const elapsed: number =\r\n new Date(exec.completed_at).getTime() -\r\n new Date(exec.started_at).getTime();\r\n trace(`${chalk.yellow(elapsed.toLocaleString())} ms`);\r\n } else trace(chalk.red(exec.error.name));\r\n },\r\n });\r\n\r\n // REPORT EXCEPTIONS\r\n const exceptions: Error[] = report.executions\r\n .filter((exec) => exec.error !== null)\r\n .map((exec) => exec.error!);\r\n if (exceptions.length === 0) {\r\n console.log(\"Success\");\r\n console.log(\"Elapsed time\", report.time.toLocaleString(), `ms`);\r\n } else {\r\n if (options.trace !== false) for (const exp of exceptions) console.log(exp);\r\n console.log(\"Failed\");\r\n console.log(\"Elapsed time\", report.time.toLocaleString(), `ms`);\r\n }\r\n\r\n // TERMINATE\r\n if (exceptions.length) process.exit(-1);\r\n else process.exit(0);\r\n};\r\nmain().catch((exp) => {\r\n console.log(exp);\r\n process.exit(-1);\r\n});\r\n"
86
81
  },
87
82
  {
88
83
  "location": "test",
@@ -2,6 +2,7 @@ import { OpenApi } from "@samchon/openapi";
2
2
  import ts from "typescript";
3
3
  import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
4
4
  import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
5
+ import { LiteralFactory } from "typia/lib/factories/LiteralFactory";
5
6
  import { TypeFactory } from "typia/lib/factories/TypeFactory";
6
7
 
7
8
  import { IMigrateRoute } from "../structures/IMigrateRoute";
@@ -87,6 +88,17 @@ export namespace MigrateNestMethodProgrammer {
87
88
  name: instance,
88
89
  }),
89
90
  );
91
+
92
+ // EXAMPLES
93
+ const decorators: ts.Decorator[] = [];
94
+ if (route.success)
95
+ decorators.push(
96
+ ...writeExampleDecorators("Response")(importer)(
97
+ route.success.media(),
98
+ ),
99
+ );
100
+
101
+ // ROUTER
90
102
  const router = (instance: string) =>
91
103
  ts.factory.createDecorator(
92
104
  ts.factory.createCallExpression(
@@ -97,8 +109,6 @@ export namespace MigrateNestMethodProgrammer {
97
109
  [ts.factory.createStringLiteral(route.path)],
98
110
  ),
99
111
  );
100
-
101
- const decorators: ts.Decorator[] = [];
102
112
  if (route.success?.["x-nestia-encrypted"])
103
113
  decorators.push(router("EncryptedRoute"));
104
114
  else if (route.success?.type === "text/plain")
@@ -142,8 +152,12 @@ export namespace MigrateNestMethodProgrammer {
142
152
  isNaN(Number(key))
143
153
  ? ts.factory.createStringLiteral(key)
144
154
  : ExpressionFactory.number(Number(key)),
145
- ...(value.description?.length
146
- ? [ts.factory.createStringLiteral(value.description)]
155
+ ...(value.response().description?.length
156
+ ? [
157
+ ts.factory.createStringLiteral(
158
+ value.response().description!,
159
+ ),
160
+ ]
147
161
  : []),
148
162
  ],
149
163
  ),
@@ -156,9 +170,10 @@ export namespace MigrateNestMethodProgrammer {
156
170
  (components: OpenApi.IComponents) =>
157
171
  (importer: MigrateImportProgrammer) =>
158
172
  (route: IMigrateRoute): ts.ParameterDeclaration[] => [
159
- ...route.parameters.map(({ key, schema: value }) =>
173
+ ...route.parameters.map((p) =>
160
174
  ts.factory.createParameterDeclaration(
161
175
  [
176
+ ...writeExampleDecorators("Parameter")(importer)(p.parameter()),
162
177
  ts.factory.createDecorator(
163
178
  ts.factory.createCallExpression(
164
179
  ts.factory.createIdentifier(
@@ -169,28 +184,36 @@ export namespace MigrateNestMethodProgrammer {
169
184
  }),
170
185
  ),
171
186
  undefined,
172
- [ts.factory.createStringLiteral(key)],
187
+ [ts.factory.createStringLiteral(p.key)],
173
188
  ),
174
189
  ),
175
190
  ],
176
191
  undefined,
177
- key,
192
+ p.key,
178
193
  undefined,
179
- MigrateSchemaProgrammer.write(components)(importer)(value),
194
+ MigrateSchemaProgrammer.write(components)(importer)(p.schema),
180
195
  ),
181
196
  ),
182
197
  ...(route.headers
183
198
  ? [
184
199
  writeDtoParameter({ method: "TypedHeaders", variable: "headers" })(
185
200
  components,
186
- )(importer)(route.headers.schema),
201
+ )(importer)({
202
+ schema: route.headers.schema,
203
+ example: route.headers.example(),
204
+ examples: route.headers.examples(),
205
+ }),
187
206
  ]
188
207
  : []),
189
208
  ...(route.query
190
209
  ? [
191
210
  writeDtoParameter({ method: "TypedQuery", variable: "query" })(
192
211
  components,
193
- )(importer)(route.query.schema),
212
+ )(importer)({
213
+ schema: route.query.schema,
214
+ example: route.query.example(),
215
+ examples: route.query.examples(),
216
+ }),
194
217
  ]
195
218
  : []),
196
219
  ...(route.body
@@ -208,7 +231,11 @@ export namespace MigrateNestMethodProgrammer {
208
231
  ? ["TypedFormData", "Body"]
209
232
  : "TypedBody",
210
233
  variable: "body",
211
- })(components)(importer)(route.body.schema),
234
+ })(components)(importer)({
235
+ schema: route.body.schema,
236
+ example: route.body.media().example,
237
+ examples: route.body.media().examples,
238
+ }),
212
239
  ]
213
240
  : []),
214
241
  ];
@@ -217,7 +244,11 @@ export namespace MigrateNestMethodProgrammer {
217
244
  (accessor: { method: string | [string, string]; variable: string }) =>
218
245
  (components: OpenApi.IComponents) =>
219
246
  (importer: MigrateImportProgrammer) =>
220
- (schema: OpenApi.IJsonSchema): ts.ParameterDeclaration => {
247
+ (props: {
248
+ schema: OpenApi.IJsonSchema;
249
+ example?: any;
250
+ examples?: Record<string, any>;
251
+ }): ts.ParameterDeclaration => {
221
252
  const instance = ts.factory.createIdentifier(
222
253
  importer.external({
223
254
  type: "instance",
@@ -230,6 +261,7 @@ export namespace MigrateNestMethodProgrammer {
230
261
  );
231
262
  return ts.factory.createParameterDeclaration(
232
263
  [
264
+ ...writeExampleDecorators("Parameter")(importer)(props),
233
265
  ts.factory.createDecorator(
234
266
  ts.factory.createCallExpression(
235
267
  typeof accessor.method === "string"
@@ -243,7 +275,55 @@ export namespace MigrateNestMethodProgrammer {
243
275
  undefined,
244
276
  accessor.variable,
245
277
  undefined,
246
- MigrateSchemaProgrammer.write(components)(importer)(schema),
278
+ MigrateSchemaProgrammer.write(components)(importer)(props.schema),
247
279
  );
248
280
  };
281
+
282
+ const writeExampleDecorators =
283
+ (kind: "Response" | "Parameter") =>
284
+ (importer: MigrateImportProgrammer) =>
285
+ (media: {
286
+ example?: any;
287
+ examples?: Record<string, any>;
288
+ }): ts.Decorator[] => [
289
+ ...(media.example !== undefined
290
+ ? [
291
+ ts.factory.createDecorator(
292
+ ts.factory.createCallExpression(
293
+ IdentifierFactory.access(
294
+ ts.factory.createIdentifier(
295
+ importer.external({
296
+ type: "instance",
297
+ library: "@nestia/core",
298
+ name: "SwaggerExample",
299
+ }),
300
+ ),
301
+ )(kind),
302
+ [],
303
+ [LiteralFactory.generate(media.example)],
304
+ ),
305
+ ),
306
+ ]
307
+ : []),
308
+ ...Object.entries(media.examples ?? {}).map(([key, value]) =>
309
+ ts.factory.createDecorator(
310
+ ts.factory.createCallExpression(
311
+ IdentifierFactory.access(
312
+ ts.factory.createIdentifier(
313
+ importer.external({
314
+ type: "instance",
315
+ library: "@nestia/core",
316
+ name: "SwaggerExample",
317
+ }),
318
+ ),
319
+ )(kind),
320
+ [],
321
+ [
322
+ ts.factory.createStringLiteral(key),
323
+ LiteralFactory.generate(value),
324
+ ],
325
+ ),
326
+ ),
327
+ ),
328
+ ];
249
329
  }