From 2191b01a9337bdb8c63a5653b7c1d5bf320ff523 Mon Sep 17 00:00:00 2001 From: CookieDasora Date: Sun, 1 Oct 2023 14:47:41 -0300 Subject: [PATCH] feat: added swagger for documentation --- package-lock.json | 42 +- package.json | 5 +- public/favicon.png | Bin 0 -> 15969 bytes public/swagger-ui.css | 1826 ++++++++++++++++++++++++++++++++++ src/app.ts | 14 +- src/config/swagger.ts | 9 + src/helpers/parse-swagger.ts | 7 + swagger.yaml | 521 ++++++++++ 8 files changed, 2421 insertions(+), 3 deletions(-) create mode 100644 public/favicon.png create mode 100644 public/swagger-ui.css create mode 100644 src/config/swagger.ts create mode 100644 src/helpers/parse-swagger.ts create mode 100644 swagger.yaml diff --git a/package-lock.json b/package-lock.json index d13f698..55a5fa5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,8 +26,10 @@ "redis": "^4.6.7", "sharp": "^0.32.3", "socket.io": "^4.7.2", + "swagger-ui-express": "^5.0.0", "validator": "^13.9.0", - "winston": "^3.10.0" + "winston": "^3.10.0", + "yaml": "^2.3.2" }, "devDependencies": { "@commitlint/cli": "^17.7.2", @@ -45,6 +47,7 @@ "@types/multer-s3": "^3.0.0", "@types/node": "^20.3.1", "@types/supertest": "^2.0.12", + "@types/swagger-ui-express": "^4.1.4", "@types/validator": "^13.7.17", "@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/parser": "^6.7.3", @@ -3414,6 +3417,16 @@ "@types/superagent": "*" } }, + "node_modules/@types/swagger-ui-express": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.4.tgz", + "integrity": "sha512-h6dfIPFveCJKpStDtjrB+4pig4DAf9Uu2Z51RB7Fj3s6AifexmqhZxBoG50K/k3Afz7wyXsIAY5ZIDTlC2VjrQ==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/serve-static": "*" + } + }, "node_modules/@types/triple-beam": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.3.tgz", @@ -11671,6 +11684,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-ui-dist": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.9.0.tgz", + "integrity": "sha512-NUHSYoe5XRTk/Are8jPJ6phzBh3l9l33nEyXosM17QInoV95/jng8+PuSGtbD407QoPf93MH3Bkh773OgesJpA==" + }, + "node_modules/swagger-ui-express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.0.tgz", + "integrity": "sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA==", + "dependencies": { + "swagger-ui-dist": ">=5.0.0" + }, + "engines": { + "node": ">= v0.10.32" + }, + "peerDependencies": { + "express": ">=4.0.0 || >=5.0.0-beta" + } + }, "node_modules/synckit": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", @@ -12887,6 +12919,14 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yaml": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", + "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "engines": { + "node": ">= 14" + } + }, "node_modules/yamljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", diff --git a/package.json b/package.json index 272dc9d..9c0ecd4 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@types/multer-s3": "^3.0.0", "@types/node": "^20.3.1", "@types/supertest": "^2.0.12", + "@types/swagger-ui-express": "^4.1.4", "@types/validator": "^13.7.17", "@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/parser": "^6.7.3", @@ -85,7 +86,9 @@ "redis": "^4.6.7", "sharp": "^0.32.3", "socket.io": "^4.7.2", + "swagger-ui-express": "^5.0.0", "validator": "^13.9.0", - "winston": "^3.10.0" + "winston": "^3.10.0", + "yaml": "^2.3.2" } } diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..f2ce71831006041602b37a393ef4738f9b368eeb GIT binary patch literal 15969 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 F{{YU6A$$M; literal 0 HcmV?d00001 diff --git a/public/swagger-ui.css b/public/swagger-ui.css new file mode 100644 index 0000000..01f6b95 --- /dev/null +++ b/public/swagger-ui.css @@ -0,0 +1,1826 @@ +/* Thanks ostranme for creating this amazing theme */ +/* https://github.com/ostranme/swagger-ui-themes */ + +@charset "UTF-8"; +.swagger-ui html { + box-sizing: border-box; +} + +.swagger-ui *, +.swagger-ui :after, +.swagger-ui :before { + box-sizing: inherit; +} + +.swagger-ui .topbar { + display: none; +} + +.swagger-ui body { + margin: 0; + background: #fafafa; +} + +.swagger-ui .wrapper { + width: 100%; + max-width: 1460px; + margin: 0 auto; + padding: 0 20px; +} + +.swagger-ui .opblock-tag-section { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} + +.swagger-ui .opblock-tag { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + padding: 10px 20px 10px 10px; + cursor: pointer; + -webkit-transition: all 0.2s; + transition: all 0.2s; + border-bottom: 1px solid rgba(59, 65, 81, 0.3); + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.swagger-ui .opblock-tag:hover { + background: rgba(0, 0, 0, 0.02); +} + +.swagger-ui .opblock-tag { + font-size: 24px; + margin: 0 0 5px; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .opblock-tag.no-desc span { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; +} + +.swagger-ui .opblock-tag svg { + -webkit-transition: all 0.4s; + transition: all 0.4s; +} + +.swagger-ui .opblock-tag small { + font-size: 14px; + font-weight: 400; + padding: 0 10px; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .parŠ°meter__type { + font-size: 12px; + padding: 5px 0; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #3b4151; +} + +.swagger-ui .view-line-link { + position: relative; + top: 3px; + width: 20px; + margin: 0 5px; + cursor: pointer; + -webkit-transition: all 0.5s; + transition: all 0.5s; +} + +.swagger-ui .opblock { + margin: 0 0 15px; + border: 1px solid #000; + border-radius: 4px; + box-shadow: 0 0 3px rgba(0, 0, 0, 0.19); +} + +.swagger-ui .opblock.is-open .opblock-summary { + border-bottom: 1px solid #000; +} + +.swagger-ui .opblock .opblock-section-header { + padding: 8px 20px; + background: hsla(0, 0%, 100%, 0.8); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.swagger-ui .opblock .opblock-section-header, +.swagger-ui .opblock .opblock-section-header label { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.swagger-ui .opblock .opblock-section-header label { + font-size: 12px; + font-weight: 700; + margin: 0; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .opblock .opblock-section-header label span { + padding: 0 10px 0 0; +} + +.swagger-ui .opblock .opblock-section-header h4 { + font-size: 14px; + margin: 0; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .opblock .opblock-summary-method { + font-size: 14px; + font-weight: 700; + min-width: 80px; + padding: 6px 15px; + text-align: center; + border-radius: 3px; + background: #000; + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + font-family: + Titillium Web, + sans-serif; + color: #fff; +} + +.swagger-ui .opblock .opblock-summary-path, +.swagger-ui .opblock .opblock-summary-path__deprecated { + font-size: 16px; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + padding: 0 10px; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #3b4151; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.swagger-ui .opblock .opblock-summary-path .view-line-link, +.swagger-ui .opblock .opblock-summary-path__deprecated .view-line-link { + position: relative; + top: 2px; + width: 0; + margin: 0; + cursor: pointer; + -webkit-transition: all 0.5s; + transition: all 0.5s; +} + +.swagger-ui .opblock .opblock-summary-path:hover .view-line-link, +.swagger-ui .opblock .opblock-summary-path__deprecated:hover .view-line-link { + width: 18px; + margin: 0 5px; +} + +.swagger-ui .opblock .opblock-summary-path__deprecated { + text-decoration: line-through; +} + +.swagger-ui .opblock .opblock-summary-description { + font-size: 13px; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .opblock .opblock-summary { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + padding: 5px; + cursor: pointer; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.swagger-ui .opblock.opblock-post { + border-color: #49cc90; + background: rgba(73, 204, 144, 0.1); +} + +.swagger-ui .opblock.opblock-post .opblock-summary-method { + background: #49cc90; +} + +.swagger-ui .opblock.opblock-post .opblock-summary { + border-color: #49cc90; +} + +.swagger-ui .opblock.opblock-put { + border-color: #fca130; + background: rgba(252, 161, 48, 0.1); +} + +.swagger-ui .opblock.opblock-put .opblock-summary-method { + background: #fca130; +} + +.swagger-ui .opblock.opblock-put .opblock-summary { + border-color: #fca130; +} + +.swagger-ui .opblock.opblock-delete { + border-color: #f93e3e; + background: rgba(249, 62, 62, 0.1); +} + +.swagger-ui .opblock.opblock-delete .opblock-summary-method { + background: #f93e3e; +} + +.swagger-ui .opblock.opblock-delete .opblock-summary { + border-color: #f93e3e; +} + +.swagger-ui .opblock.opblock-get { + border-color: #61affe; + background: rgba(97, 175, 254, 0.1); +} + +.swagger-ui .opblock.opblock-get .opblock-summary-method { + background: #61affe; +} + +.swagger-ui .opblock.opblock-get .opblock-summary { + border-color: #61affe; +} + +.swagger-ui .opblock.opblock-patch { + border-color: #50e3c2; + background: rgba(80, 227, 194, 0.1); +} + +.swagger-ui .opblock.opblock-patch .opblock-summary-method { + background: #50e3c2; +} + +.swagger-ui .opblock.opblock-patch .opblock-summary { + border-color: #50e3c2; +} + +.swagger-ui .opblock.opblock-head { + border-color: #9012fe; + background: rgba(144, 18, 254, 0.1); +} + +.swagger-ui .opblock.opblock-head .opblock-summary-method { + background: #9012fe; +} + +.swagger-ui .opblock.opblock-head .opblock-summary { + border-color: #9012fe; +} + +.swagger-ui .opblock.opblock-options { + border-color: #0d5aa7; + background: rgba(13, 90, 167, 0.1); +} + +.swagger-ui .opblock.opblock-options .opblock-summary-method { + background: #0d5aa7; +} + +.swagger-ui .opblock.opblock-options .opblock-summary { + border-color: #0d5aa7; +} + +.swagger-ui .opblock.opblock-deprecated { + opacity: 0.6; + border-color: #ebebeb; + background: hsla(0, 0%, 92%, 0.1); +} + +.swagger-ui .opblock.opblock-deprecated .opblock-summary-method { + background: #ebebeb; +} + +.swagger-ui .opblock.opblock-deprecated .opblock-summary { + border-color: #ebebeb; +} + +.swagger-ui .tab { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + margin: 20px 0 10px; + padding: 0; + list-style: none; +} + +.swagger-ui .tab li { + font-size: 12px; + min-width: 100px; + min-width: 90px; + padding: 0; + cursor: pointer; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .tab li:first-of-type { + position: relative; + padding-left: 0; +} + +.swagger-ui .tab li:first-of-type:after { + position: absolute; + top: 0; + right: 6px; + width: 1px; + height: 100%; + content: ''; + background: rgba(0, 0, 0, 0.2); +} + +.swagger-ui .tab li.active { + font-weight: 700; +} + +.swagger-ui .opblock-description-wrapper, +.swagger-ui .opblock-title_normal { + padding: 15px 20px; +} + +.swagger-ui .opblock-description-wrapper, +.swagger-ui .opblock-description-wrapper h4, +.swagger-ui .opblock-title_normal, +.swagger-ui .opblock-title_normal h4 { + font-size: 12px; + margin: 0 0 5px; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .opblock-description-wrapper p, +.swagger-ui .opblock-title_normal p { + font-size: 14px; + margin: 0; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .execute-wrapper { + padding: 20px; + text-align: right; +} + +.swagger-ui .execute-wrapper .btn { + width: 100%; + padding: 8px 40px; +} + +.swagger-ui .body-param-options { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} + +.swagger-ui .body-param-options .body-param-edit { + padding: 10px 0; +} + +.swagger-ui .body-param-options label { + padding: 8px 0; +} + +.swagger-ui .body-param-options label select { + margin: 3px 0 0; +} + +.swagger-ui .responses-inner { + padding: 20px; +} + +.swagger-ui .responses-inner h4, +.swagger-ui .responses-inner h5 { + font-size: 12px; + margin: 10px 0 5px; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .response-col_status { + font-size: 14px; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .response-col_status .response-undocumented { + font-size: 11px; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #999; +} + +.swagger-ui .response-col_description__inner span { + font-size: 12px; + font-style: italic; + display: block; + margin: 10px 0; + padding: 10px; + border-radius: 4px; + background: #41444e; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #fff; +} + +.swagger-ui .response-col_description__inner span p { + margin: 0; +} + +.swagger-ui .opblock-body pre { + font-size: 12px; + margin: 0; + padding: 10px; + white-space: pre-wrap; + border-radius: 4px; + background: #41444e; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #fff; +} + +.swagger-ui .opblock-body pre span { + color: #fff !important; +} + +.swagger-ui .scheme-container { + margin: 0 0 20px; + padding: 30px 0; + background: #fff; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15); +} + +.swagger-ui .scheme-container .schemes { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.swagger-ui .scheme-container .schemes > label { + font-size: 12px; + font-weight: 700; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + margin: -20px 15px 0 0; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .scheme-container .schemes > label select { + min-width: 130px; + text-transform: uppercase; +} + +.swagger-ui .loading-container { + padding: 40px 0 60px; +} + +.swagger-ui .loading-container .loading { + position: relative; +} + +.swagger-ui .loading-container .loading:after { + font-size: 10px; + font-weight: 700; + position: absolute; + top: 50%; + left: 50%; + content: 'loading'; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + text-transform: uppercase; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .loading-container .loading:before { + position: absolute; + top: 50%; + left: 50%; + display: block; + width: 60px; + height: 60px; + margin: -30px; + content: ''; + -webkit-animation: + rotation 1s infinite linear, + opacity 0.5s; + animation: + rotation 1s infinite linear, + opacity 0.5s; + opacity: 1; + border: 2px solid rgba(85, 85, 85, 0.1); + border-top-color: rgba(0, 0, 0, 0.6); + border-radius: 100%; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +@-webkit-keyframes rotation { + to { + -webkit-transform: rotate(1turn); + transform: rotate(1turn); + } +} + +@keyframes rotation { + to { + -webkit-transform: rotate(1turn); + transform: rotate(1turn); + } +} + +@-webkit-keyframes blinker { + 50% { + opacity: 0; + } +} + +@keyframes blinker { + 50% { + opacity: 0; + } +} + +.swagger-ui .btn { + font-size: 14px; + font-weight: 700; + padding: 5px 23px; + -webkit-transition: all 0.3s; + transition: all 0.3s; + border: 2px solid #888; + border-radius: 4px; + background: transparent; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .btn[disabled] { + cursor: not-allowed; + opacity: 0.3; +} + +.swagger-ui .btn:hover { + box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); +} + +.swagger-ui .btn.cancel { + border-color: #ff6060; + font-family: + Titillium Web, + sans-serif; + color: #ff6060; +} + +.swagger-ui .btn.authorize { + line-height: 1; + display: inline; + color: #49cc90; + border-color: #49cc90; +} + +.swagger-ui .btn.authorize span { + float: left; + padding: 4px 20px 0 0; +} + +.swagger-ui .btn.authorize svg { + fill: #49cc90; +} + +.swagger-ui .btn.execute { + -webkit-animation: pulse 2s infinite; + animation: pulse 2s infinite; + color: #fff; + border-color: #4990e2; +} + +@-webkit-keyframes pulse { + 0% { + color: #fff; + background: #4990e2; + box-shadow: 0 0 0 0 rgba(73, 144, 226, 0.8); + } + 70% { + box-shadow: 0 0 0 5px rgba(73, 144, 226, 0); + } + to { + color: #fff; + background: #4990e2; + box-shadow: 0 0 0 0 rgba(73, 144, 226, 0); + } +} + +@keyframes pulse { + 0% { + color: #fff; + background: #4990e2; + box-shadow: 0 0 0 0 rgba(73, 144, 226, 0.8); + } + 70% { + box-shadow: 0 0 0 5px rgba(73, 144, 226, 0); + } + to { + color: #fff; + background: #4990e2; + box-shadow: 0 0 0 0 rgba(73, 144, 226, 0); + } +} + +.swagger-ui .btn-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + padding: 30px; +} + +.swagger-ui .btn-group .btn { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; +} + +.swagger-ui .btn-group .btn:first-child { + border-radius: 4px 0 0 4px; +} + +.swagger-ui .btn-group .btn:last-child { + border-radius: 0 4px 4px 0; +} + +.swagger-ui .authorization__btn { + padding: 0 10px; + border: none; + background: none; +} + +.swagger-ui .authorization__btn.locked { + opacity: 1; +} + +.swagger-ui .authorization__btn.unlocked { + opacity: 0.4; +} + +.swagger-ui .expand-methods, +.swagger-ui .expand-operation { + border: none; + background: none; +} + +.swagger-ui .expand-methods svg, +.swagger-ui .expand-operation svg { + width: 20px; + height: 20px; +} + +.swagger-ui .expand-methods { + padding: 0 10px; +} + +.swagger-ui .expand-methods:hover svg { + fill: #444; +} + +.swagger-ui .expand-methods svg { + -webkit-transition: all 0.3s; + transition: all 0.3s; + fill: #777; +} + +.swagger-ui button { + cursor: pointer; + outline: none; +} + +.swagger-ui select { + font-size: 14px; + font-weight: 700; + padding: 5px 40px 5px 10px; + border: 2px solid #41444e; + border-radius: 4px; + background: #f7f7f7 + url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+ICAgIDxwYXRoIGQ9Ik0xMy40MTggNy44NTljLjI3MS0uMjY4LjcwOS0uMjY4Ljk3OCAwIC4yNy4yNjguMjcyLjcwMSAwIC45NjlsLTMuOTA4IDMuODNjLS4yNy4yNjgtLjcwNy4yNjgtLjk3OSAwbC0zLjkwOC0zLjgzYy0uMjctLjI2Ny0uMjctLjcwMSAwLS45NjkuMjcxLS4yNjguNzA5LS4yNjguOTc4IDBMMTAgMTFsMy40MTgtMy4xNDF6Ii8+PC9zdmc+) + right 10px center no-repeat; + background-size: 20px; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.25); + font-family: + Titillium Web, + sans-serif; + color: #3b4151; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.swagger-ui select[multiple] { + margin: 5px 0; + padding: 5px; + background: #f7f7f7; +} + +.swagger-ui .opblock-body select { + min-width: 230px; +} + +.swagger-ui label { + font-size: 12px; + font-weight: 700; + margin: 0 0 5px; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui input[type='email'], +.swagger-ui input[type='password'], +.swagger-ui input[type='search'], +.swagger-ui input[type='text'] { + min-width: 100px; + margin: 5px 0; + padding: 8px 10px; + border: 1px solid #d9d9d9; + border-radius: 4px; + background: #fff; +} + +.swagger-ui input[type='email'].invalid, +.swagger-ui input[type='password'].invalid, +.swagger-ui input[type='search'].invalid, +.swagger-ui input[type='text'].invalid { + -webkit-animation: shake 0.4s 1; + animation: shake 0.4s 1; + border-color: #f93e3e; + background: #feebeb; +} + +@-webkit-keyframes shake { + 10%, + 90% { + -webkit-transform: translate3d(-1px, 0, 0); + transform: translate3d(-1px, 0, 0); + } + 20%, + 80% { + -webkit-transform: translate3d(2px, 0, 0); + transform: translate3d(2px, 0, 0); + } + 30%, + 50%, + 70% { + -webkit-transform: translate3d(-4px, 0, 0); + transform: translate3d(-4px, 0, 0); + } + 40%, + 60% { + -webkit-transform: translate3d(4px, 0, 0); + transform: translate3d(4px, 0, 0); + } +} + +@keyframes shake { + 10%, + 90% { + -webkit-transform: translate3d(-1px, 0, 0); + transform: translate3d(-1px, 0, 0); + } + 20%, + 80% { + -webkit-transform: translate3d(2px, 0, 0); + transform: translate3d(2px, 0, 0); + } + 30%, + 50%, + 70% { + -webkit-transform: translate3d(-4px, 0, 0); + transform: translate3d(-4px, 0, 0); + } + 40%, + 60% { + -webkit-transform: translate3d(4px, 0, 0); + transform: translate3d(4px, 0, 0); + } +} + +.swagger-ui textarea { + font-size: 12px; + width: 100%; + min-height: 280px; + padding: 10px; + border: none; + border-radius: 4px; + outline: none; + background: hsla(0, 0%, 100%, 0.8); + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #3b4151; +} + +.swagger-ui textarea:focus { + border: 2px solid #61affe; +} + +.swagger-ui textarea.curl { + font-size: 12px; + min-height: 100px; + margin: 0; + padding: 10px; + resize: none; + border-radius: 4px; + background: #41444e; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #fff; +} + +.swagger-ui .checkbox { + padding: 5px 0 10px; + -webkit-transition: opacity 0.5s; + transition: opacity 0.5s; + color: #333; +} + +.swagger-ui .checkbox label { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} + +.swagger-ui .checkbox p { + font-weight: 400 !important; + font-style: italic; + margin: 0 !important; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #3b4151; +} + +.swagger-ui .checkbox input[type='checkbox'] { + display: none; +} + +.swagger-ui .checkbox input[type='checkbox'] + label > .item { + position: relative; + top: 3px; + display: inline-block; + width: 16px; + height: 16px; + margin: 0 8px 0 0; + padding: 5px; + cursor: pointer; + border-radius: 1px; + background: #e8e8e8; + box-shadow: 0 0 0 2px #e8e8e8; + -webkit-box-flex: 0; + -ms-flex: none; + flex: none; +} + +.swagger-ui .checkbox input[type='checkbox'] + label > .item:active { + -webkit-transform: scale(0.9); + transform: scale(0.9); +} + +.swagger-ui .checkbox input[type='checkbox']:checked + label > .item { + background: #e8e8e8 + url("data:image/svg+xml;charset=utf-8,%3Csvg width='10' height='8' viewBox='3 7 10 8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%2341474E' fill-rule='evenodd' d='M6.333 15L3 11.667l1.333-1.334 2 2L11.667 7 13 8.333z'/%3E%3C/svg%3E") + 50% no-repeat; +} + +.swagger-ui .dialog-ux { + position: fixed; + z-index: 9999; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.swagger-ui .dialog-ux .backdrop-ux { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(0, 0, 0, 0.8); +} + +.swagger-ui .dialog-ux .modal-ux { + position: absolute; + z-index: 9999; + top: 50%; + left: 50%; + width: 100%; + min-width: 300px; + max-width: 650px; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + border: 1px solid #ebebeb; + border-radius: 4px; + background: #fff; + box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.2); +} + +.swagger-ui .dialog-ux .modal-ux-content { + overflow-y: auto; + max-height: 540px; + padding: 20px; +} + +.swagger-ui .dialog-ux .modal-ux-content p { + font-size: 12px; + margin: 0 0 5px; + color: #41444e; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .dialog-ux .modal-ux-content h4 { + font-size: 18px; + font-weight: 600; + margin: 15px 0 0; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .dialog-ux .modal-ux-header { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + padding: 12px 0; + border-bottom: 1px solid #ebebeb; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.swagger-ui .dialog-ux .modal-ux-header .close-modal { + padding: 0 10px; + border: none; + background: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.swagger-ui .dialog-ux .modal-ux-header h3 { + font-size: 20px; + font-weight: 600; + margin: 0; + padding: 0 20px; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .model { + font-size: 12px; + font-weight: 300; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #3b4151; +} + +.swagger-ui .model-toggle { + font-size: 10px; + position: relative; + top: 6px; + display: inline-block; + margin: auto 0.3em; + cursor: pointer; + -webkit-transition: -webkit-transform 0.15s ease-in; + transition: -webkit-transform 0.15s ease-in; + transition: transform 0.15s ease-in; + transition: + transform 0.15s ease-in, + -webkit-transform 0.15s ease-in; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + -webkit-transform-origin: 50% 50%; + transform-origin: 50% 50%; +} + +.swagger-ui .model-toggle.collapsed { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); +} + +.swagger-ui .model-toggle:after { + display: block; + width: 20px; + height: 20px; + content: ''; + background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z'/%3E%3C/svg%3E") + 50% no-repeat; + background-size: 100%; +} + +.swagger-ui .model-jump-to-path { + position: relative; + cursor: pointer; +} + +.swagger-ui .model-jump-to-path .view-line-link { + position: absolute; + top: -0.4em; + cursor: pointer; +} + +.swagger-ui .model-title { + position: relative; +} + +.swagger-ui .model-title:hover .model-hint { + visibility: visible; +} + +.swagger-ui .model-hint { + position: absolute; + top: -1.8em; + visibility: hidden; + padding: 0.1em 0.5em; + white-space: nowrap; + color: #ebebeb; + border-radius: 4px; + background: rgba(0, 0, 0, 0.7); +} + +.swagger-ui section.models { + margin: 30px 0; + border: 1px solid rgba(59, 65, 81, 0.3); + border-radius: 4px; +} + +.swagger-ui section.models.is-open { + padding: 0 0 20px; +} + +.swagger-ui section.models.is-open h4 { + margin: 0 0 5px; + border-bottom: 1px solid rgba(59, 65, 81, 0.3); +} + +.swagger-ui section.models.is-open h4 svg { + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} + +.swagger-ui section.models h4 { + font-size: 16px; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + margin: 0; + padding: 10px 20px 10px 10px; + cursor: pointer; + -webkit-transition: all 0.2s; + transition: all 0.2s; + font-family: + Titillium Web, + sans-serif; + color: #777; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.swagger-ui section.models h4 svg { + -webkit-transition: all 0.4s; + transition: all 0.4s; +} + +.swagger-ui section.models h4 span { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; +} + +.swagger-ui section.models h4:hover { + background: rgba(0, 0, 0, 0.02); +} + +.swagger-ui section.models h5 { + font-size: 16px; + margin: 0 0 10px; + font-family: + Titillium Web, + sans-serif; + color: #777; +} + +.swagger-ui section.models .model-jump-to-path { + position: relative; + top: 5px; +} + +.swagger-ui section.models .model-container { + margin: 0 20px 15px; + -webkit-transition: all 0.5s; + transition: all 0.5s; + border-radius: 4px; + background: rgba(0, 0, 0, 0.05); +} + +.swagger-ui section.models .model-container:hover { + background: rgba(0, 0, 0, 0.07); +} + +.swagger-ui section.models .model-container:first-of-type { + margin: 20px; +} + +.swagger-ui section.models .model-container:last-of-type { + margin: 0 20px; +} + +.swagger-ui section.models .model-box { + background: none; +} + +.swagger-ui .model-box { + padding: 10px; + border-radius: 4px; + background: rgba(0, 0, 0, 0.1); +} + +.swagger-ui .model-box .model-jump-to-path { + position: relative; + top: 4px; +} + +.swagger-ui .model-title { + font-size: 16px; + font-family: + Titillium Web, + sans-serif; + color: #555; +} + +.swagger-ui span > span.model, +.swagger-ui span > span.model .brace-close { + padding: 0 0 0 10px; +} + +.swagger-ui .prop-type { + color: #55a; +} + +.swagger-ui .prop-enum { + display: block; +} + +.swagger-ui .prop-format { + color: #999; +} + +.swagger-ui table { + width: 100%; + padding: 0 10px; + border-collapse: collapse; +} + +.swagger-ui table.model tbody tr td { + padding: 0; + vertical-align: top; +} + +.swagger-ui table.model tbody tr td:first-of-type { + width: 100px; + padding: 0; +} + +.swagger-ui table.headers td { + font-size: 12px; + font-weight: 300; + vertical-align: middle; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #3b4151; +} + +.swagger-ui table tbody tr td { + padding: 10px 0 0; + vertical-align: top; +} + +.swagger-ui table tbody tr td:first-of-type { + width: 20%; + padding: 10px 0; +} + +.swagger-ui table thead tr td, +.swagger-ui table thead tr th { + font-size: 12px; + font-weight: 700; + padding: 12px 0; + text-align: left; + border-bottom: 1px solid rgba(59, 65, 81, 0.2); + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .parameters-col_description p { + font-size: 14px; + margin: 0; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .parameters-col_description input[type='text'] { + width: 100%; + max-width: 340px; +} + +.swagger-ui .parameter__name { + font-size: 16px; + font-weight: 400; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .parameter__name.required { + font-weight: 700; +} + +.swagger-ui .parameter__name.required:after { + font-size: 10px; + position: relative; + top: -6px; + padding: 5px; + content: 'required'; + color: rgba(255, 0, 0, 0.6); +} + +.swagger-ui .parameter__in { + font-size: 12px; + font-style: italic; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #888; +} + +.swagger-ui .table-container { + padding: 20px; +} + +.swagger-ui .topbar { + padding: 8px 30px; + background-color: #89bf04; +} + +.swagger-ui .topbar .topbar-wrapper { + -ms-flex-align: center; +} + +.swagger-ui .topbar .topbar-wrapper, +.swagger-ui .topbar a { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + align-items: center; +} + +.swagger-ui .topbar a { + font-size: 1.5em; + font-weight: 700; + text-decoration: none; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + -ms-flex-align: center; + font-family: + Titillium Web, + sans-serif; + color: #fff; +} + +.swagger-ui .topbar a span { + margin: 0; + padding: 0 10px; +} + +.swagger-ui .topbar .download-url-wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} + +.swagger-ui .topbar .download-url-wrapper input[type='text'] { + min-width: 350px; + margin: 0; + border: 2px solid #547f00; + border-radius: 4px 0 0 4px; + outline: none; +} + +.swagger-ui .topbar .download-url-wrapper .download-url-button { + font-size: 16px; + font-weight: 700; + padding: 4px 40px; + border: none; + border-radius: 0 4px 4px 0; + background: #547f00; + font-family: + Titillium Web, + sans-serif; + color: #fff; +} + +.swagger-ui .info { + margin: 50px 0; +} + +.swagger-ui .info hgroup.main { + margin: 0 0 20px; +} + +.swagger-ui .info hgroup.main a { + font-size: 12px; +} + +.swagger-ui .info p { + font-size: 14px; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .info code { + padding: 3px 5px; + border-radius: 4px; + background: rgba(0, 0, 0, 0.05); + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #9012fe; +} + +.swagger-ui .info a { + font-size: 14px; + -webkit-transition: all 0.4s; + transition: all 0.4s; + font-family: + Open Sans, + sans-serif; + color: #4990e2; +} + +.swagger-ui .info a:hover { + color: #1f69c0; +} + +.swagger-ui .info > div { + margin: 0 0 5px; +} + +.swagger-ui .info .base-url { + font-size: 12px; + font-weight: 300 !important; + margin: 0; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #3b4151; +} + +.swagger-ui .info .title { + font-size: 36px; + margin: 0; + font-family: + Open Sans, + sans-serif; + color: #3b4151; +} + +.swagger-ui .info .title small { + font-size: 10px; + position: relative; + top: -5px; + display: inline-block; + margin: 0 0 0 5px; + padding: 2px 4px; + vertical-align: super; + border-radius: 57px; + background: #7d8492; +} + +.swagger-ui .info .title small pre { + margin: 0; + font-family: + Titillium Web, + sans-serif; + color: #fff; +} + +.swagger-ui .auth-btn-wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + padding: 10px 0; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} + +.swagger-ui .auth-wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; +} + +.swagger-ui .auth-wrapper .authorize { + padding-right: 20px; +} + +.swagger-ui .auth-container { + margin: 0 0 10px; + padding: 10px 20px; + border-bottom: 1px solid #ebebeb; +} + +.swagger-ui .auth-container:last-of-type { + margin: 0; + padding: 10px 20px; + border: 0; +} + +.swagger-ui .auth-container h4 { + margin: 5px 0 15px !important; +} + +.swagger-ui .auth-container .wrapper { + margin: 0; + padding: 0; +} + +.swagger-ui .auth-container input[type='password'], +.swagger-ui .auth-container input[type='text'] { + min-width: 230px; +} + +.swagger-ui .auth-container .errors { + font-size: 12px; + padding: 10px; + border-radius: 4px; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #3b4151; +} + +.swagger-ui .scopes h2 { + font-size: 14px; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +.swagger-ui .scope-def { + padding: 0 0 20px; +} + +.swagger-ui .errors-wrapper { + margin: 20px; + padding: 10px 20px; + -webkit-animation: scaleUp 0.5s; + animation: scaleUp 0.5s; + border: 2px solid #f93e3e; + border-radius: 4px; + background: rgba(249, 62, 62, 0.1); +} + +.swagger-ui .errors-wrapper .error-wrapper { + margin: 0 0 10px; +} + +.swagger-ui .errors-wrapper .errors h4 { + font-size: 14px; + margin: 0; + font-family: + Source Code Pro, + monospace; + font-weight: 600; + color: #3b4151; +} + +.swagger-ui .errors-wrapper hgroup { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.swagger-ui .errors-wrapper hgroup h4 { + font-size: 20px; + margin: 0; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + font-family: + Titillium Web, + sans-serif; + color: #3b4151; +} + +@-webkit-keyframes scaleUp { + 0% { + -webkit-transform: scale(0.8); + transform: scale(0.8); + opacity: 0; + } + to { + -webkit-transform: scale(1); + transform: scale(1); + opacity: 1; + } +} + +@keyframes scaleUp { + 0% { + -webkit-transform: scale(0.8); + transform: scale(0.8); + opacity: 0; + } + to { + -webkit-transform: scale(1); + transform: scale(1); + opacity: 1; + } +} + +.swagger-ui .Resizer.vertical.disabled { + display: none; +} + +/*# sourceMappingURL=swagger-ui.css.map*/ + +/** + * Swagger UI Theme Overrides + * + * Theme: Flattop + * Author: Mark Ostrander + * Github: https://github.com/ostranme/swagger-ui-themes + */ + +.swagger-ui .opblock.opblock-post { + border-color: #dadfe1; + background: rgba(236, 240, 241, 0.1); +} + +.swagger-ui .opblock.opblock-post .opblock-summary-method { + background: #049372; +} + +.swagger-ui .opblock.opblock-post .opblock-summary { + border-color: #dadfe1; +} + +.swagger-ui .opblock.opblock-put { + border-color: #dadfe1; + background: rgba(236, 240, 241, 0.1); +} + +.swagger-ui .opblock.opblock-put .opblock-summary-method { + background: #eb9532; +} + +.swagger-ui .opblock.opblock-put .opblock-summary { + border-color: #dadfe1; +} + +.swagger-ui .opblock.opblock-delete { + border-color: #dadfe1; + background: rgba(236, 240, 241, 0.1); +} + +.swagger-ui .opblock.opblock-delete .opblock-summary-method { + background: #c0392b; +} + +.swagger-ui .opblock.opblock-delete .opblock-summary { + border-color: #dadfe1; +} + +.swagger-ui .opblock.opblock-get { + border-color: #dadfe1; + background: rgba(236, 240, 241, 0.1); +} + +.swagger-ui .opblock.opblock-get .opblock-summary-method { + background: #34495e; +} + +.swagger-ui .opblock.opblock-get .opblock-summary { + border-color: #dadfe1; +} + +.swagger-ui .opblock.opblock-patch { + border-color: #dadfe1; + background: rgba(236, 240, 241, 0.1); +} + +.swagger-ui .opblock.opblock-patch .opblock-summary-method { + background: #f57c00; +} + +.swagger-ui .opblock.opblock-patch .opblock-summary { + border-color: #dadfe1; +} + +.swagger-ui .opblock.opblock-head { + border-color: #dadfe1; + background: rgba(236, 240, 241, 0.1); +} + +.swagger-ui .opblock.opblock-head .opblock-summary-method { + background: #5c6bc0; +} + +.swagger-ui .opblock.opblock-head .opblock-summary { + border-color: #dadfe1; +} + +.swagger-ui .opblock.opblock-options { + border-color: #dadfe1; + background: rgba(236, 240, 241, 0.1); +} + +.swagger-ui .opblock.opblock-options .opblock-summary-method { + background: #3f51b5; +} + +.swagger-ui .opblock.opblock-options .opblock-summary { + border-color: #dadfe1; +} + +.swagger-ui .topbar { + padding: 8px 30px; + background-color: #2c3e50; +} + +.swagger-ui .topbar .download-url-wrapper input[type='text'] { + min-width: 350px; + margin: 0; + border: 2px solid #dadfe1; + border-radius: 4px 0 0 4px; + outline: none; +} + +.swagger-ui .topbar .download-url-wrapper .download-url-button { + font-size: 16px; + font-weight: 700; + padding: 4px 40px; + border: none; + border-radius: 0 4px 4px 0; + background: #dadfe1; + font-family: + Titillium Web, + sans-serif; + color: #2c3e50; +} + +.swagger-ui .info a { + font-size: 14px; + -webkit-transition: all 0.4s; + transition: all 0.4s; + font-family: + Open Sans, + sans-serif; + color: #336e7b; +} + +.swagger-ui .info a:hover { + color: #336e7b; +} + +.swagger-ui .btn.authorize { + line-height: 1; + display: inline; + color: #336e7b; + border-color: #336e7b; +} +.swagger-ui .btn.authorize svg { + fill: #336e7b; +} diff --git a/src/app.ts b/src/app.ts index 04c0b92..8f2ab0c 100644 --- a/src/app.ts +++ b/src/app.ts @@ -6,11 +6,13 @@ import express from 'express' import limiter from 'middlewares/rate-limit' import morganMiddleware from 'middlewares/morgan' import router from './routes' +import swaggerUI from 'swagger-ui-express' +import swaggerDocument from 'helpers/parse-swagger' +import swaggerConfig from 'config/swagger' const app = express() // TODO: test socket io, emit notifications when create one. -// TODO: start to create the client, or a barebone to test socket io app.use(express.json()) app.use(express.urlencoded({ extended: true })) @@ -24,10 +26,20 @@ app.use( optionsSuccessStatus: 200, }), ) +app.use(express.static('public')) app.use(limiter) app.use(router) +app.use( + '/docs', + swaggerUI.serve, + swaggerUI.setup(swaggerDocument, swaggerConfig), +) app.use(compression({ level: 9 })) +app.get('/', function (_req, res) { + res.redirect('/docs') +}) + app.use((_req, res) => { res.status(404).json({ error: 'Endpoint not found', diff --git a/src/config/swagger.ts b/src/config/swagger.ts new file mode 100644 index 0000000..749f089 --- /dev/null +++ b/src/config/swagger.ts @@ -0,0 +1,9 @@ +import type { SwaggerUiOptions } from 'swagger-ui-express' + +const swaggerConfig: SwaggerUiOptions = { + customCssUrl: '/swagger-ui.css', + customSiteTitle: 'Project Knedita Docs', + customfavIcon: '/favicon.png', +} + +export default swaggerConfig diff --git a/src/helpers/parse-swagger.ts b/src/helpers/parse-swagger.ts new file mode 100644 index 0000000..26111e8 --- /dev/null +++ b/src/helpers/parse-swagger.ts @@ -0,0 +1,7 @@ +import { parse } from 'yaml' +import { readFileSync } from 'fs' + +const swaggerConfigFile = readFileSync('./swagger.yaml', 'utf-8') +const swaggerDocument = parse(swaggerConfigFile) + +export default swaggerDocument diff --git a/swagger.yaml b/swagger.yaml new file mode 100644 index 0000000..cf074ce --- /dev/null +++ b/swagger.yaml @@ -0,0 +1,521 @@ +openapi: 3.0.0 + +info: + version: 0.0.1 + title: Project Knedita - Documentation + description: An open source social media project. + license: + name: MIT + url: https://opensource.org/licenses/MIT + +tags: + - name: Users + description: User related endpoints + - name: Posts + description: Post related endpoints + - name: Comments + description: Comment related endpoints + +paths: + # Users - GET paths + /user/info: + get: + summary: Returns information about a specific user. + description: Returns information about a specific user (profile picture, display name, etc). + tags: + - Users + parameters: + - name: u + in: query + required: true + schema: + type: string + example: 'cookie' + responses: + '200': + description: An object containing all user information. + content: + application/json: + schema: + type: object + properties: + id: + type: string + profileImage: + type: string + displayName: + type: string + username: + type: string + createdAt: + type: string + followers: + type: integer + example: 0 + following: + type: integer + example: 0 + posts: + type: array + items: + type: object + properties: + id: + type: string + content: + type: string + createdAt: + type: string + updatedAt: + type: string + likedPosts: + type: array + items: + type: object + properties: + postId: + type: string + '400': + $ref: '#/components/responses/BadRequest' + + /user/fetch-posts: + get: + summary: Returns all posts made by specific user. + description: Returns all posts made by specific user. + tags: + - Users + parameters: + - name: u + in: query + required: true + schema: + type: string + example: 'cookie' + responses: + '200': + description: An array of objects containing post information (returns an empty array if no posts were found). + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + content: + type: string + createdAt: + type: string + updatedAt: + type: string + author: + type: object + properties: + displayName: + type: string + username: + type: string + profileImage: + type: string + _count: + type: object + properties: + likes: + type: integer + comments: + type: integer + + /user/search: + get: + summary: Returns user with the provided username. + description: Returns up to 10 users with the provided username. + tags: + - Users + parameters: + - name: u + in: query + required: true + schema: + type: string + example: 'cookie' + responses: + '200': + description: An array of objects containing basic user information (returns an empty array if no users were found). + content: + application/json: + schema: + type: array + items: + type: object + properties: + displayName: + type: string + username: + type: string + profileImage: + type: string + + /user/auth: + post: + summary: Authenticate user + description: Authenticate the provided user + tags: + - Users + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + email: + type: string + password: + type: string + responses: + '200': + description: Returns authentication token and user's username + content: + application/json: + schema: + type: object + properties: + token: + type: string + user: + type: string + example: 'cookie' + '400': + $ref: '#/components/responses/BadRequest' + + /user/signup: + post: + summary: Creates a new user + description: Creates a new user + tags: + - Users + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + username: + type: string + email: + type: string + password: + type: string + responses: + '200': + description: An object containing basic user information + content: + application/json: + schema: + type: object + properties: + displayName: + type: string + username: + type: string + createdAt: + type: string + '400': + $ref: '#/components/responses/BadRequest' + + # Users - POST paths + /user/delete: + post: + summary: Deletes an authenticated user + description: Deletes an authenticated user + tags: + - Users + security: + - JWTAuth: [] + responses: + '200': + $ref: '#/components/responses/EmptyResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + + /user/follow-user: + post: + summary: Follows a user + description: Follows a user + security: + - JWTAuth: [] + tags: + - Users + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + userToFollow: + type: string + example: 'cookie1' + responses: + '200': + $ref: '#/components/responses/EmptyResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + + /user/like-comment: + post: + summary: Likes a post comment + description: Likes a post comment + security: + - JWTAuth: [] + tags: + - Users + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + commentId: + type: string + example: '7fb6e6e7-8e37-4814-bab6-36e5aa35796c' + responses: + '200': + $ref: '#/components/responses/EmptyResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + + /user/like-post: + post: + summary: Likes a post + description: Likes a post + security: + - JWTAuth: [] + tags: + - Users + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + postId: + type: string + example: f4e2b724-f226-4674-8e3b-0c0c512b09d4 + responses: + '200': + $ref: '#/components/responses/EmptyResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + + /user/me: + post: + summary: Returns basic information about the authenticated user + description: Returns basic information about the authenticated user + security: + - JWTAuth: [] + tags: + - Users + responses: + '200': + description: Authenticated user information + content: + application/json: + schema: + type: object + properties: + id: + type: string + profileImage: + type: string + displayName: + type: string + username: + type: string + createdAt: + type: string + followers: + type: integer + example: 0 + following: + type: integer + example: 0 + posts: + type: array + items: + type: object + properties: + id: + type: string + content: + type: string + createdAt: + type: string + updatedAt: + type: string + likedPosts: + type: array + items: + type: object + properties: + postId: + type: string + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + + # Users - PUT paths + /user/profile-picture/upload: + put: + summary: Uploads a profile picture for the authenticated user + description: Uploads a profile picture for the authenticated user + security: + - JWTAuth: [] + tags: + - Users + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + image: + type: string + format: binary + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + profileImage: + type: string + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + + /user/update-name: + put: + security: + - JWTAuth: [] + tags: + - Users + + /user/update-email: + put: + security: + - JWTAuth: [] + tags: + - Users + + /user/update-password: + put: + security: + - JWTAuth: [] + tags: + - Users + + # Posts - GET paths + /post/info: + get: + tags: + - Posts + + /post/fetch-likes: + get: + tags: + - Posts + + # Posts - POST paths + /post/create: + post: + tags: + - Posts + + /post/delete: + post: + tags: + - Posts + + # Posts - PUT paths + /post/update: + put: + tags: + - Posts + + # Comments - GET paths + /comment/info: + get: + tags: + - Comments + + /comment/fetch-likes: + get: + tags: + - Comments + + # Comments - POST paths + /comment/create: + post: + tags: + - Comments + + /comment/delete: + post: + tags: + - Comments + + # Comments - PUT paths + /comment/update: + put: + tags: + - Comments + +components: + securitySchemes: + JWTAuth: + type: http + scheme: bearer + description: JWT Authentication via Authorization header + responses: + BadRequest: + description: Bad Request + content: + application/json: + schema: + type: object + properties: + error: + type: string + EmptyResponse: + description: Successful Response (empty response) + content: + application/json: + schema: + type: object + Unauthorized: + description: Unauthorized + content: + application/json: + schema: + type: object + properties: + error: + type: string