diff --git a/package.json b/package.json index 7b5a263..cbf32a1 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "build": "npx tsc", "start": "node dist/index.js", - "dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\"" + "dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\"", + "swagger:gen": "node ./src/swagger.js" }, "keywords": [], "author": "", @@ -18,12 +19,15 @@ "reflect-metadata": "^0.1.13", "sequelize": "^6.32.1", "sequelize-typescript": "^2.1.5", + "swagger-autogen": "^2.23.5", + "swagger-ui-express": "^5.0.0", "zod": "^3.21.4" }, "devDependencies": { "@types/dotenv": "^8.2.0", "@types/express": "^4.17.17", "@types/node": "^20.4.8", + "@types/swagger-ui-express": "^4.1.3", "concurrently": "^8.2.0", "nodemon": "^3.0.1", "ts-node": "^10.9.1", diff --git a/src/index.ts b/src/index.ts index 67b3807..0905f17 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,7 @@ import express, { Express } from "express"; import bodyParser from "body-parser"; +import swaggerUi from "swagger-ui-express"; +import swaggerFile from "./swagger_output.json"; import "./config/env"; import { DBConnection } from "./config/database"; import { routes } from "./routes"; @@ -10,6 +12,8 @@ const port = process.env.PORT; app.use(bodyParser.json()); app.use("/v1", routes); +app.use("/", swaggerUi.serve, swaggerUi.setup(swaggerFile)); + const start = async (): Promise => { try { await DBConnection.sync(); diff --git a/src/swagger.js b/src/swagger.js new file mode 100644 index 0000000..27bd70f --- /dev/null +++ b/src/swagger.js @@ -0,0 +1,6 @@ +const swaggerAutogen = require("swagger-autogen")(); + +const outputFile = "./swagger_output.json"; +const endpointsFiles = ["./routes/index"]; + +swaggerAutogen(outputFile, endpointsFiles); diff --git a/src/swagger_output.json b/src/swagger_output.json new file mode 100644 index 0000000..a1920b5 --- /dev/null +++ b/src/swagger_output.json @@ -0,0 +1,47 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "REST API", + "description": "" + }, + "host": "localhost:3000", + "basePath": "/", + "schemes": ["http"], + "paths": { + "/": { + "get": { + "description": "", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/create": { + "post": { + "description": "Create a new world", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "name": { + "example": "string" + } + } + } + } + ], + "responses": { + "default": { + "description": "" + } + } + } + } + } +} diff --git a/tsconfig.json b/tsconfig.json index 783a675..96a3307 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,7 @@ "forceConsistentCasingInFileNames": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, + "resolveJsonModule": true, "strict": true, "skipLibCheck": true, "allowJs": true diff --git a/yarn.lock b/yarn.lock index fa296cb..0c5b592 100644 --- a/yarn.lock +++ b/yarn.lock @@ -93,7 +93,7 @@ "@types/range-parser" "*" "@types/send" "*" -"@types/express@^4.17.17": +"@types/express@*", "@types/express@^4.17.17": version "4.17.17" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== @@ -155,6 +155,14 @@ "@types/mime" "*" "@types/node" "*" +"@types/swagger-ui-express@^4.1.3": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@types/swagger-ui-express/-/swagger-ui-express-4.1.3.tgz#7adbbbf5343b45869debef1e9ff39c9ba73e380f" + integrity sha512-jqCjGU/tGEaqIplPy3WyQg+Nrp6y80DCFnDEAvVKWkJyv0VivSSDCChkppHRHAablvInZe6pijDFMnavtN0vqA== + dependencies: + "@types/express" "*" + "@types/serve-static" "*" + "@types/validator@^13.7.17": version "13.9.0" resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.9.0.tgz#e7a96da3ea6a936222c6e76bb54abdd3dc4c9e4a" @@ -178,6 +186,11 @@ acorn-walk@^8.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== +acorn@^7.4.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + acorn@^8.4.1: version "8.10.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" @@ -388,6 +401,11 @@ debug@^4.3.4: dependencies: ms "2.1.2" +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + denque@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" @@ -571,6 +589,18 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -685,6 +715,11 @@ is-property@^1.0.2: resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -749,7 +784,7 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -minimatch@^3.0.4, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -1113,6 +1148,28 @@ supports-color@^8.1.1: dependencies: has-flag "^4.0.0" +swagger-autogen@^2.23.5: + version "2.23.5" + resolved "https://registry.yarnpkg.com/swagger-autogen/-/swagger-autogen-2.23.5.tgz#fe86bde66daf991a2e9064ec83f2136319d19258" + integrity sha512-4Tl2+XhZMyHoBYkABnScHtQE0lKPKUD3NBt09mClrI6UKOUYljKlYw1xiFVwsHCTGR2hAXmhT4PpgjruCtt1ZA== + dependencies: + acorn "^7.4.1" + deepmerge "^4.2.2" + glob "^7.1.7" + json5 "^2.2.3" + +swagger-ui-dist@>=5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.3.1.tgz#ae76a74136152d790b06a8b71ca389cac35ab78f" + integrity sha512-El78OvXp9zMasfPrshtkW1CRx8AugAKoZuGGOTW+8llJzOV1RtDJYqQRz/6+2OakjeWWnZuRlN2Qj1Y0ilux3w== + +swagger-ui-express@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/swagger-ui-express/-/swagger-ui-express-5.0.0.tgz#7a00a18dd909574cb0d628574a299b9ba53d4d49" + integrity sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA== + dependencies: + swagger-ui-dist ">=5.0.0" + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"