@nestia/migrate 0.11.4 → 0.11.5
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/lib/bundles/NEST_TEMPLATE.js +5 -5
- package/lib/bundles/NEST_TEMPLATE.js.map +1 -1
- package/lib/bundles/SDK_TEMPLATE.js +1 -1
- package/lib/utils/openapi-down-convert/converter.js +2 -2
- package/package.json +2 -2
- package/src/MigrateApplication.ts +81 -81
- package/src/analyzers/MigrateAnalyzer.ts +9 -9
- package/src/analyzers/MigrateControllerAnalyzer.ts +135 -135
- package/src/analyzers/MigrateMethodAnalyzer.ts +439 -439
- package/src/archivers/MigrateFileArchiver.ts +38 -38
- package/src/bundles/NEST_TEMPLATE.ts +5 -5
- package/src/bundles/SDK_TEMPLATE.ts +1 -1
- package/src/executable/bundle.ts +110 -110
- package/src/internal/MigrateCommander.ts +70 -70
- package/src/internal/MigrateInquirer.ts +86 -86
- package/src/module.ts +14 -14
- package/src/programmers/MigrateApiFileProgrammer.ts +53 -53
- package/src/programmers/MigrateApiFunctionProgrammer.ts +199 -199
- package/src/programmers/MigrateApiNamespaceProgrammer.ts +431 -431
- package/src/programmers/MigrateApiProgrammer.ts +170 -170
- package/src/programmers/MigrateApiSimulatationProgrammer.ts +327 -327
- package/src/programmers/MigrateApiStartProgrammer.ts +194 -194
- package/src/programmers/MigrateDtoProgrammer.ts +78 -78
- package/src/programmers/MigrateE2eFileProgrammer.ts +117 -117
- package/src/programmers/MigrateE2eProgrammer.ts +36 -36
- package/src/programmers/MigrateImportProgrammer.ts +121 -121
- package/src/programmers/MigrateNestControllerProgrammer.ts +50 -50
- package/src/programmers/MigrateNestMethodProgrammer.ts +250 -250
- package/src/programmers/MigrateNestModuleProgrammer.ts +63 -63
- package/src/programmers/MigrateNestProgrammer.ts +74 -74
- package/src/programmers/MigrateSchemaProgrammer.ts +267 -267
- package/src/structures/IMigrateDto.ts +8 -8
- package/src/structures/IMigrateProgram.ts +27 -27
- package/src/structures/IMigrateRoute.ts +51 -51
- package/src/structures/ISwagger.ts +23 -23
- package/src/structures/ISwaggerComponents.ts +14 -14
- package/src/structures/ISwaggerRoute.ts +20 -20
- package/src/structures/ISwaggerRouteBodyContent.ts +15 -15
- package/src/structures/ISwaggerRouteParameter.ts +14 -14
- package/src/structures/ISwaggerRouteRequestBody.ts +12 -12
- package/src/structures/ISwaggerRouteResponse.ts +11 -11
- package/src/structures/ISwaggerSchema.ts +90 -90
- package/src/structures/ISwaggerSecurityScheme.ts +47 -47
- package/src/structures/ISwaggerV20.ts +10 -10
- package/src/structures/ISwaggerV31.ts +10 -10
- package/src/utils/FilePrinter.ts +36 -36
- package/src/utils/OpenApiConverter.ts +19 -19
- package/src/utils/StringUtil.ts +60 -60
- package/src/utils/SwaggerComponentsExplorer.ts +43 -43
- package/src/utils/SwaggerTypeChecker.ts +67 -67
- package/src/utils/openapi-down-convert/RefVisitor.ts +139 -139
- package/src/utils/openapi-down-convert/converter.ts +527 -527
@@ -15,7 +15,7 @@ exports.NEST_TEMPLATE = [
|
|
15
15
|
{
|
16
16
|
"location": ".github/workflows",
|
17
17
|
"file": "build.yml",
|
18
|
-
"content": "name: build\r\non: \r\n push:\r\n paths:\r\n - 'src/**'\r\n - 'test/**'\r\n pull_request:\r\n paths:\r\n - 'src/**'\r\n - 'test/**'\r\n\r\njobs:\r\n Ubuntu:\r\n runs-on: ubuntu-latest\r\n steps:\r\n - uses: actions/checkout@v4\r\n - uses: actions/setup-node@v4\r\n with:\r\n node-version: 20.x\r\n - uses: pnpm/action-setup@v2\r\n with:\r\n version: 8\r\n \r\n - name: Install Backend-Server\r\n run: pnpm install\r\n\r\n - name: Build Swagger\r\n run: npm run build:swagger\r\n\r\n - name: Build SDK\r\n run: npm run build:sdk\r\n\r\n - name: Compile Backend-Server\r\n run: npm run build\r\n\r\n - name: Run Test Program\r\n run: npm run test\r\n\r\n - name: Test Webpack\r\n run: npm run webpack && npm run test:webpack\r\n\r\n - name: EsLint\r\n run: npm run eslint\r\n"
|
18
|
+
"content": "name: build\r\non: \r\n push:\r\n paths:\r\n - package.json\r\n - 'src/**'\r\n - 'test/**'\r\n pull_request:\r\n paths:\r\n - package.json\r\n - 'src/**'\r\n - 'test/**'\r\n\r\njobs:\r\n Ubuntu:\r\n runs-on: ubuntu-latest\r\n steps:\r\n - uses: actions/checkout@v4\r\n - uses: actions/setup-node@v4\r\n with:\r\n node-version: 20.x\r\n - uses: pnpm/action-setup@v2\r\n with:\r\n version: 8\r\n \r\n - name: Install Backend-Server\r\n run: pnpm install\r\n\r\n - name: Build Swagger\r\n run: npm run build:swagger\r\n\r\n - name: Build SDK\r\n run: npm run build:sdk\r\n\r\n - name: Compile Backend-Server\r\n run: npm run build\r\n\r\n - name: Run Test Program\r\n run: npm run test\r\n\r\n - name: Test Webpack\r\n run: npm run webpack && npm run test:webpack\r\n\r\n - name: EsLint\r\n run: npm run eslint\r\n"
|
19
19
|
},
|
20
20
|
{
|
21
21
|
"location": "",
|
@@ -50,7 +50,7 @@ exports.NEST_TEMPLATE = [
|
|
50
50
|
{
|
51
51
|
"location": "",
|
52
52
|
"file": "package.json",
|
53
|
-
"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 \"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 && tsc -p packages/api/tsconfig.json\",\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/e2e\": \"^0.4.2\",\r\n \"@nestia/sdk\": \"^2.6.
|
53
|
+
"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 \"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 && tsc -p packages/api/tsconfig.json\",\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/e2e\": \"^0.4.2\",\r\n \"@nestia/sdk\": \"^2.6.3\",\r\n \"@trivago/prettier-plugin-sort-imports\": \"^4.3.0\",\r\n \"@types/cli\": \"^0.11.21\",\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.0\",\r\n \"cli\": \"^1.0.1\",\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.0\",\r\n \"prettier\": \"^3.2.4\",\r\n \"prettier-plugin-prisma\": \"^5.0.0\",\r\n \"rimraf\": \"^3.0.2\",\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.0.2\",\r\n \"typescript\": \"^5.3.2\",\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\": \"^2.6.3\",\r\n \"@nestia/fetcher\": \"^2.6.3\",\r\n \"@nestjs/common\": \"^10.3.7\",\r\n \"@nestjs/core\": \"^10.3.7\",\r\n \"@nestjs/platform-express\": \"^10.3.7\",\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 \"tstl\": \"^3.0.0\",\r\n \"typia\": \"^5.5.7\",\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}"
|
54
54
|
},
|
55
55
|
{
|
56
56
|
"location": "packages/api",
|
@@ -65,7 +65,7 @@ exports.NEST_TEMPLATE = [
|
|
65
65
|
{
|
66
66
|
"location": "packages/api",
|
67
67
|
"file": "package.json",
|
68
|
-
"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 \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"npm run build:sdk && npm run compile\",\r\n \"build:sdk\": \"rimraf ../../src/api/functional && cd ../.. && npx nestia sdk && cd packages/api\",\r\n \"compile\": \"rimraf lib && tsc\",\r\n \"deploy\": \"npm run build && npm publish\",\r\n \"prepare\": \"ts-patch install && typia patch\"\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 \"devDependencies\": {\r\n \"rimraf\": \"^5.0.5\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.1.2\",\r\n \"typescript\": \"^5.3.3\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^2.6.
|
68
|
+
"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 \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"npm run build:sdk && npm run compile\",\r\n \"build:sdk\": \"rimraf ../../src/api/functional && cd ../.. && npx nestia sdk && cd packages/api\",\r\n \"compile\": \"rimraf lib && tsc\",\r\n \"deploy\": \"npm run build && npm publish\",\r\n \"prepare\": \"ts-patch install && typia patch\"\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 \"devDependencies\": {\r\n \"rimraf\": \"^5.0.5\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.1.2\",\r\n \"typescript\": \"^5.3.3\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^2.6.3\",\r\n \"typia\": \"^5.5.7\"\r\n }\r\n}"
|
69
69
|
},
|
70
70
|
{
|
71
71
|
"location": "packages/api",
|
@@ -130,7 +130,7 @@ exports.NEST_TEMPLATE = [
|
|
130
130
|
{
|
131
131
|
"location": "src/executable",
|
132
132
|
"file": "server.ts",
|
133
|
-
"content": "import fs from \"fs\";\r\nimport { randint } from \"tstl
|
133
|
+
"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"
|
134
134
|
},
|
135
135
|
{
|
136
136
|
"location": "src/executable",
|
@@ -155,7 +155,7 @@ exports.NEST_TEMPLATE = [
|
|
155
155
|
{
|
156
156
|
"location": "src/utils",
|
157
157
|
"file": "ErrorUtil.ts",
|
158
|
-
"content": "import fs from \"fs\";\r\nimport { randint } from \"tstl
|
158
|
+
"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"
|
159
159
|
},
|
160
160
|
{
|
161
161
|
"location": "src/utils",
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"NEST_TEMPLATE.js","sourceRoot":"","sources":["../../src/bundles/NEST_TEMPLATE.ts"],"names":[],"mappings":";;;AAAa,QAAA,aAAa,GAAG;IAC3B;QACE,UAAU,EAAE,EAAE;QACd,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,+CAA+C;KAC3D;IACD;QACE,UAAU,EAAE,EAAE;QACd,MAAM,EAAE,eAAe;QACvB,SAAS,EAAE,m1BAAm1B;KAC/1B;IACD;QACE,UAAU,EAAE,mBAAmB;QAC/B,MAAM,EAAE,WAAW;QACnB,SAAS,EAAE,
|
1
|
+
{"version":3,"file":"NEST_TEMPLATE.js","sourceRoot":"","sources":["../../src/bundles/NEST_TEMPLATE.ts"],"names":[],"mappings":"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"}
|
@@ -25,7 +25,7 @@ exports.SDK_TEMPLATE = [
|
|
25
25
|
{
|
26
26
|
"location": "",
|
27
27
|
"file": "package.json",
|
28
|
-
"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 \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"rimraf lib && tsc\",\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 \"prepare\": \"ts-patch install && typia patch\",\r\n \"start\": \"npx ts-node test/start.ts\",\r\n \"test\": \"npx ts-node test/index.ts\",\r\n \"test:simulate\": \"npx ts-node test/index.ts --simulate true\"\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 \"devDependencies\": {\r\n \"@nestia/e2e\": \"^0.4.1\",\r\n \"@types/inquirer\": \"8.2.5\",\r\n \"commander\": \"^10.0.0\",\r\n \"inquirer\": \"8.2.5\",\r\n \"prettier\": \"^3.2.5\",\r\n \"rimraf\": \"^5.0.5\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.1.2\",\r\n \"typescript\": \"^5.3.3\",\r\n \"typescript-transform-paths\": \"^3.4.6\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^2.6.
|
28
|
+
"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 \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"rimraf lib && tsc\",\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 \"prepare\": \"ts-patch install && typia patch\",\r\n \"start\": \"npx ts-node test/start.ts\",\r\n \"test\": \"npx ts-node test/index.ts\",\r\n \"test:simulate\": \"npx ts-node test/index.ts --simulate true\"\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 \"devDependencies\": {\r\n \"@nestia/e2e\": \"^0.4.1\",\r\n \"@types/inquirer\": \"8.2.5\",\r\n \"commander\": \"^10.0.0\",\r\n \"inquirer\": \"8.2.5\",\r\n \"prettier\": \"^3.2.5\",\r\n \"rimraf\": \"^5.0.5\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.1.2\",\r\n \"typescript\": \"^5.3.3\",\r\n \"typescript-transform-paths\": \"^3.4.6\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^2.6.3\",\r\n \"typia\": \"^5.5.7\"\r\n }\r\n}"
|
29
29
|
},
|
30
30
|
{
|
31
31
|
"location": "",
|
@@ -352,8 +352,8 @@ class Converter {
|
|
352
352
|
this.log(`Converting openIdConnect security scheme to oauth2/authorizationCode`);
|
353
353
|
scheme.type = "oauth2";
|
354
354
|
const openIdConnectUrl = scheme.openIdConnectUrl;
|
355
|
-
scheme.description = `OAuth2 Authorization Code Flow. The client may
|
356
|
-
GET the OpenID Connect configuration JSON from \`${openIdConnectUrl}\`
|
355
|
+
scheme.description = `OAuth2 Authorization Code Flow. The client may
|
356
|
+
GET the OpenID Connect configuration JSON from \`${openIdConnectUrl}\`
|
357
357
|
to get the correct \`authorizationUrl\` and \`tokenUrl\`.`;
|
358
358
|
delete scheme.openIdConnectUrl;
|
359
359
|
const scopes = oauth2Scopes(schemeName);
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nestia/migrate",
|
3
|
-
"version": "0.11.
|
3
|
+
"version": "0.11.5",
|
4
4
|
"description": "Migration program from swagger to NestJS",
|
5
5
|
"main": "lib/index.js",
|
6
6
|
"typings": "lib/index.d.ts",
|
@@ -59,7 +59,7 @@
|
|
59
59
|
"inquirer": "8.2.5",
|
60
60
|
"openapi-types": "^12.1.3",
|
61
61
|
"prettier": "^3.2.5",
|
62
|
-
"tstl": "^
|
62
|
+
"tstl": "^3.0.0",
|
63
63
|
"typescript": "^5.4.2",
|
64
64
|
"typia": "^5.5.7"
|
65
65
|
},
|
@@ -1,81 +1,81 @@
|
|
1
|
-
import typia, { IValidation } from "typia";
|
2
|
-
|
3
|
-
import { MigrateAnalyzer } from "./analyzers/MigrateAnalyzer";
|
4
|
-
import { NEST_TEMPLATE } from "./bundles/NEST_TEMPLATE";
|
5
|
-
import { SDK_TEMPLATE } from "./bundles/SDK_TEMPLATE";
|
6
|
-
import { MigrateApiProgrammer } from "./programmers/MigrateApiProgrammer";
|
7
|
-
import { MigrateApiStartProgrammer } from "./programmers/MigrateApiStartProgrammer";
|
8
|
-
import { MigrateE2eProgrammer } from "./programmers/MigrateE2eProgrammer";
|
9
|
-
import { MigrateNestProgrammer } from "./programmers/MigrateNestProgrammer";
|
10
|
-
import { IMigrateFile } from "./structures/IMigrateFile";
|
11
|
-
import { IMigrateProgram } from "./structures/IMigrateProgram";
|
12
|
-
import { ISwagger } from "./structures/ISwagger";
|
13
|
-
import { ISwaggerV31 } from "./structures/ISwaggerV31";
|
14
|
-
import { OpenApiConverter } from "./utils/OpenApiConverter";
|
15
|
-
|
16
|
-
export class MigrateApplication {
|
17
|
-
private constructor(public readonly swagger: ISwagger) {}
|
18
|
-
|
19
|
-
public static async create(
|
20
|
-
swagger: ISwagger | ISwaggerV31,
|
21
|
-
): Promise<IValidation<MigrateApplication>> {
|
22
|
-
swagger = typia.is<ISwaggerV31.IVersion>(swagger)
|
23
|
-
? OpenApiConverter.v3_1(swagger)
|
24
|
-
: swagger;
|
25
|
-
const result = typia.validate<ISwagger>(swagger);
|
26
|
-
if (result.success === false) return result;
|
27
|
-
return {
|
28
|
-
success: true,
|
29
|
-
data: new MigrateApplication(swagger),
|
30
|
-
errors: [],
|
31
|
-
};
|
32
|
-
}
|
33
|
-
|
34
|
-
public nest(config: MigrateApplication.IConfig): MigrateApplication.IOutput {
|
35
|
-
const program: IMigrateProgram = MigrateAnalyzer.analyze({
|
36
|
-
mode: "nest",
|
37
|
-
swagger: this.swagger,
|
38
|
-
dictionary: new Map(),
|
39
|
-
simulate: config.simulate,
|
40
|
-
e2e: config.e2e,
|
41
|
-
});
|
42
|
-
return {
|
43
|
-
program,
|
44
|
-
files: [
|
45
|
-
...NEST_TEMPLATE,
|
46
|
-
...MigrateNestProgrammer.write(program),
|
47
|
-
...MigrateApiProgrammer.write(program),
|
48
|
-
...(config.e2e ? MigrateE2eProgrammer.write(program) : []),
|
49
|
-
],
|
50
|
-
};
|
51
|
-
}
|
52
|
-
|
53
|
-
public sdk(config: MigrateApplication.IConfig): MigrateApplication.IOutput {
|
54
|
-
const program: IMigrateProgram = MigrateAnalyzer.analyze({
|
55
|
-
mode: "sdk",
|
56
|
-
swagger: this.swagger,
|
57
|
-
dictionary: new Map(),
|
58
|
-
simulate: config.simulate,
|
59
|
-
e2e: config.e2e,
|
60
|
-
});
|
61
|
-
return {
|
62
|
-
program,
|
63
|
-
files: [
|
64
|
-
...SDK_TEMPLATE,
|
65
|
-
...MigrateApiProgrammer.write(program),
|
66
|
-
MigrateApiStartProgrammer.write(program),
|
67
|
-
...(config.e2e ? MigrateE2eProgrammer.write(program) : []),
|
68
|
-
],
|
69
|
-
};
|
70
|
-
}
|
71
|
-
}
|
72
|
-
export namespace MigrateApplication {
|
73
|
-
export interface IOutput {
|
74
|
-
program: IMigrateProgram;
|
75
|
-
files: IMigrateFile[];
|
76
|
-
}
|
77
|
-
export interface IConfig {
|
78
|
-
simulate: boolean;
|
79
|
-
e2e: boolean;
|
80
|
-
}
|
81
|
-
}
|
1
|
+
import typia, { IValidation } from "typia";
|
2
|
+
|
3
|
+
import { MigrateAnalyzer } from "./analyzers/MigrateAnalyzer";
|
4
|
+
import { NEST_TEMPLATE } from "./bundles/NEST_TEMPLATE";
|
5
|
+
import { SDK_TEMPLATE } from "./bundles/SDK_TEMPLATE";
|
6
|
+
import { MigrateApiProgrammer } from "./programmers/MigrateApiProgrammer";
|
7
|
+
import { MigrateApiStartProgrammer } from "./programmers/MigrateApiStartProgrammer";
|
8
|
+
import { MigrateE2eProgrammer } from "./programmers/MigrateE2eProgrammer";
|
9
|
+
import { MigrateNestProgrammer } from "./programmers/MigrateNestProgrammer";
|
10
|
+
import { IMigrateFile } from "./structures/IMigrateFile";
|
11
|
+
import { IMigrateProgram } from "./structures/IMigrateProgram";
|
12
|
+
import { ISwagger } from "./structures/ISwagger";
|
13
|
+
import { ISwaggerV31 } from "./structures/ISwaggerV31";
|
14
|
+
import { OpenApiConverter } from "./utils/OpenApiConverter";
|
15
|
+
|
16
|
+
export class MigrateApplication {
|
17
|
+
private constructor(public readonly swagger: ISwagger) {}
|
18
|
+
|
19
|
+
public static async create(
|
20
|
+
swagger: ISwagger | ISwaggerV31,
|
21
|
+
): Promise<IValidation<MigrateApplication>> {
|
22
|
+
swagger = typia.is<ISwaggerV31.IVersion>(swagger)
|
23
|
+
? OpenApiConverter.v3_1(swagger)
|
24
|
+
: swagger;
|
25
|
+
const result = typia.validate<ISwagger>(swagger);
|
26
|
+
if (result.success === false) return result;
|
27
|
+
return {
|
28
|
+
success: true,
|
29
|
+
data: new MigrateApplication(swagger),
|
30
|
+
errors: [],
|
31
|
+
};
|
32
|
+
}
|
33
|
+
|
34
|
+
public nest(config: MigrateApplication.IConfig): MigrateApplication.IOutput {
|
35
|
+
const program: IMigrateProgram = MigrateAnalyzer.analyze({
|
36
|
+
mode: "nest",
|
37
|
+
swagger: this.swagger,
|
38
|
+
dictionary: new Map(),
|
39
|
+
simulate: config.simulate,
|
40
|
+
e2e: config.e2e,
|
41
|
+
});
|
42
|
+
return {
|
43
|
+
program,
|
44
|
+
files: [
|
45
|
+
...NEST_TEMPLATE,
|
46
|
+
...MigrateNestProgrammer.write(program),
|
47
|
+
...MigrateApiProgrammer.write(program),
|
48
|
+
...(config.e2e ? MigrateE2eProgrammer.write(program) : []),
|
49
|
+
],
|
50
|
+
};
|
51
|
+
}
|
52
|
+
|
53
|
+
public sdk(config: MigrateApplication.IConfig): MigrateApplication.IOutput {
|
54
|
+
const program: IMigrateProgram = MigrateAnalyzer.analyze({
|
55
|
+
mode: "sdk",
|
56
|
+
swagger: this.swagger,
|
57
|
+
dictionary: new Map(),
|
58
|
+
simulate: config.simulate,
|
59
|
+
e2e: config.e2e,
|
60
|
+
});
|
61
|
+
return {
|
62
|
+
program,
|
63
|
+
files: [
|
64
|
+
...SDK_TEMPLATE,
|
65
|
+
...MigrateApiProgrammer.write(program),
|
66
|
+
MigrateApiStartProgrammer.write(program),
|
67
|
+
...(config.e2e ? MigrateE2eProgrammer.write(program) : []),
|
68
|
+
],
|
69
|
+
};
|
70
|
+
}
|
71
|
+
}
|
72
|
+
export namespace MigrateApplication {
|
73
|
+
export interface IOutput {
|
74
|
+
program: IMigrateProgram;
|
75
|
+
files: IMigrateFile[];
|
76
|
+
}
|
77
|
+
export interface IConfig {
|
78
|
+
simulate: boolean;
|
79
|
+
e2e: boolean;
|
80
|
+
}
|
81
|
+
}
|
@@ -1,9 +1,9 @@
|
|
1
|
-
import { IMigrateProgram } from "../structures/IMigrateProgram";
|
2
|
-
import { MigrateControllerAnalyzer } from "./MigrateControllerAnalyzer";
|
3
|
-
|
4
|
-
export namespace MigrateAnalyzer {
|
5
|
-
export const analyze = (props: IMigrateProgram.IProps): IMigrateProgram => ({
|
6
|
-
...props,
|
7
|
-
controllers: MigrateControllerAnalyzer.analyze(props),
|
8
|
-
});
|
9
|
-
}
|
1
|
+
import { IMigrateProgram } from "../structures/IMigrateProgram";
|
2
|
+
import { MigrateControllerAnalyzer } from "./MigrateControllerAnalyzer";
|
3
|
+
|
4
|
+
export namespace MigrateAnalyzer {
|
5
|
+
export const analyze = (props: IMigrateProgram.IProps): IMigrateProgram => ({
|
6
|
+
...props,
|
7
|
+
controllers: MigrateControllerAnalyzer.analyze(props),
|
8
|
+
});
|
9
|
+
}
|
@@ -1,135 +1,135 @@
|
|
1
|
-
import { Escaper } from "typia/lib/utils/Escaper";
|
2
|
-
|
3
|
-
import { IMigrateController } from "../structures/IMigrateController";
|
4
|
-
import { IMigrateProgram } from "../structures/IMigrateProgram";
|
5
|
-
import { IMigrateRoute } from "../structures/IMigrateRoute";
|
6
|
-
import { ISwaggerRoute } from "../structures/ISwaggerRoute";
|
7
|
-
import { MapUtil } from "../utils/MapUtil";
|
8
|
-
import { StringUtil } from "../utils/StringUtil";
|
9
|
-
import { MigrateMethodAnalzyer } from "./MigrateMethodAnalyzer";
|
10
|
-
|
11
|
-
export namespace MigrateControllerAnalyzer {
|
12
|
-
export const analyze = (
|
13
|
-
props: IMigrateProgram.IProps,
|
14
|
-
): IMigrateController[] => {
|
15
|
-
interface IEntry {
|
16
|
-
endpoint: ISwaggerRoute;
|
17
|
-
route: IMigrateRoute;
|
18
|
-
}
|
19
|
-
const endpoints: Map<string, IEntry[]> = new Map();
|
20
|
-
|
21
|
-
// GATHER ROUTES
|
22
|
-
for (const [path, collection] of Object.entries(props.swagger.paths)) {
|
23
|
-
if (collection === undefined) continue;
|
24
|
-
|
25
|
-
// PREPARE DIRECTORIES
|
26
|
-
const location: string = StringUtil.splitWithNormalization(path)
|
27
|
-
.filter((str) => str[0] !== "{" && str[0] !== ":")
|
28
|
-
.join("/");
|
29
|
-
for (const s of sequence(location)) MapUtil.take(endpoints)(s)(() => []);
|
30
|
-
|
31
|
-
// INSERT ROUTES TO THE LAST DIRECTORY
|
32
|
-
const routes: IEntry[] = MapUtil.take(endpoints)(location)(() => []);
|
33
|
-
for (const [method, value] of Object.entries(collection)) {
|
34
|
-
if (
|
35
|
-
value === undefined ||
|
36
|
-
["get", "post", "patch", "put", "delete"].includes(method) === false
|
37
|
-
)
|
38
|
-
continue;
|
39
|
-
const r: IMigrateRoute | null = MigrateMethodAnalzyer.analyze(props)({
|
40
|
-
path,
|
41
|
-
method,
|
42
|
-
})(value);
|
43
|
-
if (r === null) continue;
|
44
|
-
routes.push({
|
45
|
-
endpoint: value,
|
46
|
-
route: r,
|
47
|
-
});
|
48
|
-
}
|
49
|
-
}
|
50
|
-
|
51
|
-
// GENERATE CONTROLLERS
|
52
|
-
const total: IMigrateController[] = [...endpoints.entries()]
|
53
|
-
.filter(([_l, routes]) => !!routes.length)
|
54
|
-
.map(([location, routes]) => {
|
55
|
-
const prefix: string = StringUtil.commonPrefix(
|
56
|
-
routes.map((e) => e.route.path),
|
57
|
-
);
|
58
|
-
for (const e of routes)
|
59
|
-
e.route.path = StringUtil.reJoinWithDecimalParameters(
|
60
|
-
e.route.path.replace(prefix, ""),
|
61
|
-
);
|
62
|
-
const controller: IMigrateController = {
|
63
|
-
name: StringUtil.pascal(location) + "Controller",
|
64
|
-
path: StringUtil.reJoinWithDecimalParameters(prefix),
|
65
|
-
location: "src/controllers/" + location,
|
66
|
-
routes: routes.map((e) => e.route),
|
67
|
-
};
|
68
|
-
emend(controller);
|
69
|
-
|
70
|
-
for (const e of routes)
|
71
|
-
props.dictionary.set(e.endpoint, {
|
72
|
-
controller,
|
73
|
-
route: e.route,
|
74
|
-
});
|
75
|
-
return controller;
|
76
|
-
});
|
77
|
-
for (const c of total)
|
78
|
-
if (c.name === "Controller")
|
79
|
-
c.name = StringUtil.escapeDuplicate([...total.map((c) => c.name)])(
|
80
|
-
"AppController",
|
81
|
-
);
|
82
|
-
return total;
|
83
|
-
};
|
84
|
-
|
85
|
-
const sequence = (location: string): string[] =>
|
86
|
-
StringUtil.splitWithNormalization(location)
|
87
|
-
.map((_str, i, entire) => entire.slice(0, i + 1).join("/"))
|
88
|
-
.slice(0, -1)
|
89
|
-
.reverse();
|
90
|
-
|
91
|
-
const emend = (controller: IMigrateController): void => {
|
92
|
-
interface IRouteCapsule {
|
93
|
-
variables: string[];
|
94
|
-
route: IMigrateRoute;
|
95
|
-
}
|
96
|
-
const dict: Map<string, IRouteCapsule[]> = new Map();
|
97
|
-
for (const route of controller.routes) {
|
98
|
-
const additional: string[] = StringUtil.splitWithNormalization(
|
99
|
-
route.path,
|
100
|
-
);
|
101
|
-
const statics: string[] = additional.filter((str) => str[0] !== ":");
|
102
|
-
if (statics.length) route.name = StringUtil.camel(statics.join("/"));
|
103
|
-
else
|
104
|
-
MapUtil.take(dict)(route.method)(() => []).push({
|
105
|
-
variables: additional
|
106
|
-
.filter((str) => str[0] === ":")
|
107
|
-
.map((str) => str.substring(1)),
|
108
|
-
route,
|
109
|
-
});
|
110
|
-
}
|
111
|
-
for (const [method, capsules] of dict) {
|
112
|
-
const emended: string = method === "delete" ? "erase" : method;
|
113
|
-
for (const c of capsules) {
|
114
|
-
const empty: boolean = c.variables.length === 0;
|
115
|
-
c.route.name = empty
|
116
|
-
? emended
|
117
|
-
: StringUtil.camel(`${emended}By/${c.variables.join("/and/")}`);
|
118
|
-
}
|
119
|
-
}
|
120
|
-
for (const method of controller.routes) {
|
121
|
-
if (Escaper.variable(method.name) === false)
|
122
|
-
method.name = "_" + method.name;
|
123
|
-
for (const spec of [method.headers, method.query, method.body])
|
124
|
-
if (spec)
|
125
|
-
spec.key = StringUtil.escapeDuplicate(
|
126
|
-
method.parameters.map((p) => p.key),
|
127
|
-
)(spec.key);
|
128
|
-
}
|
129
|
-
controller.routes.forEach((r, i) => {
|
130
|
-
r.name = StringUtil.escapeDuplicate(
|
131
|
-
controller.routes.filter((_r, j) => i !== j).map((x) => x.name),
|
132
|
-
)(r.name);
|
133
|
-
});
|
134
|
-
};
|
135
|
-
}
|
1
|
+
import { Escaper } from "typia/lib/utils/Escaper";
|
2
|
+
|
3
|
+
import { IMigrateController } from "../structures/IMigrateController";
|
4
|
+
import { IMigrateProgram } from "../structures/IMigrateProgram";
|
5
|
+
import { IMigrateRoute } from "../structures/IMigrateRoute";
|
6
|
+
import { ISwaggerRoute } from "../structures/ISwaggerRoute";
|
7
|
+
import { MapUtil } from "../utils/MapUtil";
|
8
|
+
import { StringUtil } from "../utils/StringUtil";
|
9
|
+
import { MigrateMethodAnalzyer } from "./MigrateMethodAnalyzer";
|
10
|
+
|
11
|
+
export namespace MigrateControllerAnalyzer {
|
12
|
+
export const analyze = (
|
13
|
+
props: IMigrateProgram.IProps,
|
14
|
+
): IMigrateController[] => {
|
15
|
+
interface IEntry {
|
16
|
+
endpoint: ISwaggerRoute;
|
17
|
+
route: IMigrateRoute;
|
18
|
+
}
|
19
|
+
const endpoints: Map<string, IEntry[]> = new Map();
|
20
|
+
|
21
|
+
// GATHER ROUTES
|
22
|
+
for (const [path, collection] of Object.entries(props.swagger.paths)) {
|
23
|
+
if (collection === undefined) continue;
|
24
|
+
|
25
|
+
// PREPARE DIRECTORIES
|
26
|
+
const location: string = StringUtil.splitWithNormalization(path)
|
27
|
+
.filter((str) => str[0] !== "{" && str[0] !== ":")
|
28
|
+
.join("/");
|
29
|
+
for (const s of sequence(location)) MapUtil.take(endpoints)(s)(() => []);
|
30
|
+
|
31
|
+
// INSERT ROUTES TO THE LAST DIRECTORY
|
32
|
+
const routes: IEntry[] = MapUtil.take(endpoints)(location)(() => []);
|
33
|
+
for (const [method, value] of Object.entries(collection)) {
|
34
|
+
if (
|
35
|
+
value === undefined ||
|
36
|
+
["get", "post", "patch", "put", "delete"].includes(method) === false
|
37
|
+
)
|
38
|
+
continue;
|
39
|
+
const r: IMigrateRoute | null = MigrateMethodAnalzyer.analyze(props)({
|
40
|
+
path,
|
41
|
+
method,
|
42
|
+
})(value);
|
43
|
+
if (r === null) continue;
|
44
|
+
routes.push({
|
45
|
+
endpoint: value,
|
46
|
+
route: r,
|
47
|
+
});
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
// GENERATE CONTROLLERS
|
52
|
+
const total: IMigrateController[] = [...endpoints.entries()]
|
53
|
+
.filter(([_l, routes]) => !!routes.length)
|
54
|
+
.map(([location, routes]) => {
|
55
|
+
const prefix: string = StringUtil.commonPrefix(
|
56
|
+
routes.map((e) => e.route.path),
|
57
|
+
);
|
58
|
+
for (const e of routes)
|
59
|
+
e.route.path = StringUtil.reJoinWithDecimalParameters(
|
60
|
+
e.route.path.replace(prefix, ""),
|
61
|
+
);
|
62
|
+
const controller: IMigrateController = {
|
63
|
+
name: StringUtil.pascal(location) + "Controller",
|
64
|
+
path: StringUtil.reJoinWithDecimalParameters(prefix),
|
65
|
+
location: "src/controllers/" + location,
|
66
|
+
routes: routes.map((e) => e.route),
|
67
|
+
};
|
68
|
+
emend(controller);
|
69
|
+
|
70
|
+
for (const e of routes)
|
71
|
+
props.dictionary.set(e.endpoint, {
|
72
|
+
controller,
|
73
|
+
route: e.route,
|
74
|
+
});
|
75
|
+
return controller;
|
76
|
+
});
|
77
|
+
for (const c of total)
|
78
|
+
if (c.name === "Controller")
|
79
|
+
c.name = StringUtil.escapeDuplicate([...total.map((c) => c.name)])(
|
80
|
+
"AppController",
|
81
|
+
);
|
82
|
+
return total;
|
83
|
+
};
|
84
|
+
|
85
|
+
const sequence = (location: string): string[] =>
|
86
|
+
StringUtil.splitWithNormalization(location)
|
87
|
+
.map((_str, i, entire) => entire.slice(0, i + 1).join("/"))
|
88
|
+
.slice(0, -1)
|
89
|
+
.reverse();
|
90
|
+
|
91
|
+
const emend = (controller: IMigrateController): void => {
|
92
|
+
interface IRouteCapsule {
|
93
|
+
variables: string[];
|
94
|
+
route: IMigrateRoute;
|
95
|
+
}
|
96
|
+
const dict: Map<string, IRouteCapsule[]> = new Map();
|
97
|
+
for (const route of controller.routes) {
|
98
|
+
const additional: string[] = StringUtil.splitWithNormalization(
|
99
|
+
route.path,
|
100
|
+
);
|
101
|
+
const statics: string[] = additional.filter((str) => str[0] !== ":");
|
102
|
+
if (statics.length) route.name = StringUtil.camel(statics.join("/"));
|
103
|
+
else
|
104
|
+
MapUtil.take(dict)(route.method)(() => []).push({
|
105
|
+
variables: additional
|
106
|
+
.filter((str) => str[0] === ":")
|
107
|
+
.map((str) => str.substring(1)),
|
108
|
+
route,
|
109
|
+
});
|
110
|
+
}
|
111
|
+
for (const [method, capsules] of dict) {
|
112
|
+
const emended: string = method === "delete" ? "erase" : method;
|
113
|
+
for (const c of capsules) {
|
114
|
+
const empty: boolean = c.variables.length === 0;
|
115
|
+
c.route.name = empty
|
116
|
+
? emended
|
117
|
+
: StringUtil.camel(`${emended}By/${c.variables.join("/and/")}`);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
for (const method of controller.routes) {
|
121
|
+
if (Escaper.variable(method.name) === false)
|
122
|
+
method.name = "_" + method.name;
|
123
|
+
for (const spec of [method.headers, method.query, method.body])
|
124
|
+
if (spec)
|
125
|
+
spec.key = StringUtil.escapeDuplicate(
|
126
|
+
method.parameters.map((p) => p.key),
|
127
|
+
)(spec.key);
|
128
|
+
}
|
129
|
+
controller.routes.forEach((r, i) => {
|
130
|
+
r.name = StringUtil.escapeDuplicate(
|
131
|
+
controller.routes.filter((_r, j) => i !== j).map((x) => x.name),
|
132
|
+
)(r.name);
|
133
|
+
});
|
134
|
+
};
|
135
|
+
}
|