diff --git a/backend/index.js b/backend/index.js index 4d48828..cac2fa7 100644 --- a/backend/index.js +++ b/backend/index.js @@ -14,12 +14,52 @@ const port = process.env.PORT const search = require("./routes/search"); const regions = require("./routes/regions"); const countries = require("./routes/countries"); -const climate = require("./routes/climate"); const places = require("./routes/place"); const update = require("./routes/update"); const app = express(); +const swaggerJsdoc = require('swagger-jsdoc'); +const swaggerUi = require('swagger-ui-express'); + +// Swagger set up +const swaggerOptions = { + swaggerDefinition: { + openapi: "3.0.0", + info: { + title: "TravOpti API", + version: "1.0.0", + description: + "Enable intrest controlled region searching with this API\n" + + "No API Key required.", + license: { + name: "Licensing Pending", + url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=youtu.be" + }, + contact: { + name: "travOpti", + url: "https://travopti.de/home", + email: "feedback@travopti.de" + } + }, + servers: [ + { + url: "http://localhost:3000/api/v1" + }, + { + url: "https://travopti.de/api/v1" + } + ] + }, + apis: [ + "./Routes/*.js", + "./Models/handleClimateUpdate.js", + "./Models/handleClimateUpdateV2.js", + ] +}; + +const swaggerDocs = swaggerJsdoc(swaggerOptions); + (async () => { try { const dbConn = await dbConnection(); @@ -29,12 +69,12 @@ const app = express(); app.use(express.static(path.join(__dirname, "../../dist"))); app.use(bodyParser.json()); app.use(cors()); + app.use('/api/v1/doc', swaggerUi.serve, swaggerUi.setup(swaggerDocs, {explorer: false, docExpansion: "list"})); // Express routes app.use(search(dbConn)); app.use(regions(dbConn)); app.use(countries(dbConn)); - app.use(climate(dbConn)); app.use(places(dbConn)); app.use(update(dbConn)) diff --git a/backend/package-lock.json b/backend/package-lock.json index 812b9c6..2ae376a 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -4,6 +4,45 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@apidevtools/json-schema-ref-parser": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-8.0.0.tgz", + "integrity": "sha512-n4YBtwQhdpLto1BaUCyAeflizmIbaloGShsPyRtFf5qdFJxfssj+GgLavczgKJFa3Bq+3St2CKcpRJdjtB4EBw==", + "requires": { + "@jsdevtools/ono": "^7.1.0", + "call-me-maybe": "^1.0.1", + "js-yaml": "^3.13.1" + } + }, + "@apidevtools/openapi-schemas": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.0.3.tgz", + "integrity": "sha512-QoPaxGXfgqgGpK1p21FJ400z56hV681a8DOcZt3J5z0WIHgFeaIZ4+6bX5ATqmOoCpRCsH4ITEwKaOyFMz7wOA==" + }, + "@apidevtools/swagger-methods": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.1.tgz", + "integrity": "sha512-1Vlm18XYW6Yg7uHunroXeunWz5FShPFAdxBbPy8H6niB2Elz9QQsCoYHMbcc11EL1pTxaIr9HXz2An/mHXlX1Q==" + }, + "@apidevtools/swagger-parser": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-9.0.1.tgz", + "integrity": "sha512-Irqybg4dQrcHhZcxJc/UM4vO7Ksoj1Id5e+K94XUOzllqX1n47HEA50EKiXTCQbykxuJ4cYGIivjx/MRSTC5OA==", + "requires": { + "@apidevtools/json-schema-ref-parser": "^8.0.0", + "@apidevtools/openapi-schemas": "^2.0.2", + "@apidevtools/swagger-methods": "^3.0.0", + "@jsdevtools/ono": "^7.1.0", + "call-me-maybe": "^1.0.1", + "openapi-types": "^1.3.5", + "z-schema": "^4.2.2" + } + }, + "@jsdevtools/ono": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.2.tgz", + "integrity": "sha512-qS/a24RA5FEoiJS9wiv6Pwg2c/kiUo3IVUQcfeM9JvsR6pM8Yx+yl/6xWYLckZCT5jpLNhslgjiA8p/XcGyMRQ==" + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -50,29 +89,6 @@ "negotiator": "0.6.2" } }, - "agent-base": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz", - "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==", - "requires": { - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, "ansi-align": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", @@ -126,6 +142,14 @@ "picomatch": "^2.0.4" } }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -142,8 +166,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "basic-auth": { "version": "2.0.1", @@ -196,7 +219,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -248,6 +270,11 @@ } } }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -342,11 +369,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "commander": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.0.0.tgz", + "integrity": "sha512-JrDGPAKjMGSP1G0DUoaceEJ3DZgAfr/q6X7FVk4+U5KxUSKviYGM2k6zWkfyyBHy5rAtzgYJFa1ro2O9PtoxwQ==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "configstore": { "version": "5.0.1", @@ -444,6 +475,14 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, "dot-prop": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", @@ -505,6 +544,11 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -598,6 +642,11 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, "fsevents": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", @@ -622,6 +671,19 @@ "pump": "^3.0.0" } }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "glob-parent": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", @@ -700,30 +762,6 @@ "resolved": "https://registry.npmjs.org/httpolyglot/-/httpolyglot-0.1.2.tgz", "integrity": "sha1-5NNH/omEpi9GfUBg31J/GFH2mXs=" }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "requires": { - "agent-base": "6", - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -750,6 +788,15 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -856,6 +903,15 @@ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", @@ -885,6 +941,16 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -988,7 +1054,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1169,11 +1234,15 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } }, + "openapi-types": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-1.3.5.tgz", + "integrity": "sha512-11oi4zYorsgvg5yBarZplAqbpev5HkuVNPlZaPTknPDzAynq+lnJdXAmruGWP0s+dNYZS7bjM+xrTpJw7184Fg==" + }, "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -1214,6 +1283,11 @@ "util": "^0.10.3" } }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -1452,6 +1526,11 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, "sqlstring": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz", @@ -1526,6 +1605,39 @@ "has-flag": "^3.0.0" } }, + "swagger-jsdoc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-4.0.0.tgz", + "integrity": "sha512-wHrmRvE/OQa3d387YIrRNPvsPwxkJc0tAYeCVa359gUIKPjC4ReduFhqq/+4erLUS79kY1T5Fv0hE0SV/PgBig==", + "requires": { + "commander": "5.0.0", + "doctrine": "3.0.0", + "glob": "7.1.6", + "js-yaml": "3.13.1", + "swagger-parser": "9.0.1" + } + }, + "swagger-parser": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-9.0.1.tgz", + "integrity": "sha512-oxOHUaeNetO9ChhTJm2fD+48DbGbLD09ZEOwPOWEqcW8J6zmjWxutXtSuOiXsoRgDWvORYlImbwM21Pn+EiuvQ==", + "requires": { + "@apidevtools/swagger-parser": "9.0.1" + } + }, + "swagger-ui-dist": { + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.28.0.tgz", + "integrity": "sha512-aPkfTzPv9djSiZI1NUkWr5HynCUsH+jaJ0WSx+/t19wq7MMGg9clHm9nGoIpAtqml1G51ofI+I75Ym72pukzFg==" + }, + "swagger-ui-express": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.1.4.tgz", + "integrity": "sha512-Ea96ecpC+Iq9GUqkeD/LFR32xSs8gYqmTW1gXCuKg81c26WV6ZC2FsBSPVExQP6WkyUuz5HEiR0sEv/HCC343g==", + "requires": { + "swagger-ui-dist": "^3.18.1" + } + }, "term-size": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", @@ -1651,6 +1763,11 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "validator": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-12.2.0.tgz", + "integrity": "sha512-jJfE/DW6tIK1Ek8nCfNFqt8Wb3nzMoAbocBF6/Icgg1ZFSBpObdnwVY2jQj6qUqzhx5jc71fpvBWyLGO7Xl+nQ==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -1668,8 +1785,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-file-atomic": { "version": "3.0.3", @@ -1693,6 +1809,25 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "z-schema": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-4.2.3.tgz", + "integrity": "sha512-zkvK/9TC6p38IwcrbnT3ul9in1UX4cm1y/VZSs4GHKIiDCrlafc+YQBgQBUdDXLAoZHf2qvQ7gJJOo6yT1LH6A==", + "requires": { + "commander": "^2.7.1", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^12.0.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "optional": true + } + } } } } diff --git a/backend/package.json b/backend/package.json index 5ae1253..af8739e 100644 --- a/backend/package.json +++ b/backend/package.json @@ -21,7 +21,9 @@ "morgan": "^1.10.0", "mysql2": "^2.1.0", "path": "^0.12.7", - "sqlstring": "^2.3.2" + "sqlstring": "^2.3.2", + "swagger-jsdoc": "^4.0.0", + "swagger-ui-express": "^4.1.4" }, "devDependencies": { "nodemon": "^2.0.4" diff --git a/backend/routes/climate.js b/backend/routes/climate.js deleted file mode 100644 index 672a588..0000000 --- a/backend/routes/climate.js +++ /dev/null @@ -1,19 +0,0 @@ -const router = require("express").Router() - -// Models -const handleClimateUpdate = require("../models/handleClimateUpdate.js") -const handleClimateUpdateV2 = require("../models/handleClimateUpdateV2.js") - -module.exports = dbConn => { - router.put("/api/v1/climate/update", async (req, res) => { - const update = await handleClimateUpdate(dbConn) - res.json(update) - }); - - router.put("/api/v1/climate/update/v2", async (req, res) => { - const update = await handleClimateUpdateV2(dbConn) - res.json(update) - }); - - return router; -}; diff --git a/backend/routes/countries.js b/backend/routes/countries.js index 23407db..15eb091 100644 --- a/backend/routes/countries.js +++ b/backend/routes/countries.js @@ -1,3 +1,10 @@ +/** + * @swagger + * tags: + * name: Countries + * description: Access country data. + */ + const router = require("express").Router(); // Models @@ -8,10 +15,37 @@ const getCountryById = require("../models/getCountryById.js"); const sqlSanitzer = require("../util/sqlstring_sanitizer.js") module.exports = dbConn => { + /** + * @swagger + * /countries: + * get: + * summary: Get all countries + * tags: [Countries] + * responses: + * "200": + * description: Returns aviable data for all countries + */ router.get("/api/v1/countries", async (req, res) => { res.json(await getCountries(dbConn)); }); + /** + * @swagger + * /countries/{id}: + * get: + * summary: Get a specific country by id + * tags: [Countries] + * parameters: + * - name: "id" + * in: "path" + * required: true + * type: int + * example: 23 + * responses: + * "200": + * description: Returns aviable data for the country + * example: test + */ router.get("/api/v1/countries/:id", async (req, res) => { const id = sqlSanitzer(req.params.id); res.json(await getCountryById(dbConn, id)) diff --git a/backend/routes/place.js b/backend/routes/place.js index 80bd9b2..5ee5529 100644 --- a/backend/routes/place.js +++ b/backend/routes/place.js @@ -1,3 +1,10 @@ +/** + * @swagger + * tags: + * name: Places + * description: Access to the Google Place API via the Key used in backend. Only for manual use in the prototype application! + */ + const router = require("express").Router() // Models @@ -9,11 +16,51 @@ const getPlacePhoto = require("../models/getPlacePhoto.js") const sqlSanitzer = require("../util/sqlstring_sanitizer.js") module.exports = dbConn => { + /** + * @swagger + * /place: + * get: + * summary: Get a specific place + * tags: [Places] + * parameters: + * - name: "q" + * in: "query" + * required: true + * type: int + * description: "Querystring, by which the place is searched" + * example: Berlin + * responses: + * "200": + * description: Returns a place from the google places API. + */ router.get("/api/v1/place", async (req, res) => { const place = await getPlace(req.query.q) res.json(place) }); + /** + * @swagger + * /place/nearby: + * get: + * summary: Get nearby touristic places + * tags: [Places] + * parameters: + * - name: "lat" + * in: "query" + * required: true + * type: float + * description: "Latitiude" + * example: 52.520365 + * - name: "lng" + * in: "query" + * required: true + * type: float + * description: "Longitude" + * example: 13.403509 + * responses: + * "200": + * description: Returns nearby places from the google places API. + */ router.get("/api/v1/place/nearby", async (req, res) => { const lat = req.query.lat const lng = req.query.lng @@ -21,6 +68,23 @@ module.exports = dbConn => { res.json(place) }); + /** + * @swagger + * /place/photo: + * get: + * summary: Get a photo for a place + * tags: [Places] + * parameters: + * - name: "photoref" + * in: "query" + * required: true + * type: int + * description: "Photo_Reference which is returned for a place by Google Places API" + * example: CmRaAAAAbupojmH94negtiCnLGdfx2azxhVTEDI1rtTrYnQ7KclEI-Yy9_YGxN9h63AKrCzd22kk5z-UiK7fS4-zXnO5OqfNRZu2hrmfcp8b77rItediibAVovOOA5LnyJ9YYuofEhAAr0Im0zuiAtbDKPjbPUSBGhTFkSrH6FZxenbo1bCkdCXaUMhOug + * responses: + * "200": + * description: Returns the matching url to the photo. + */ router.get("/api/v1/place/photo", async (req, res) => { const photoref = req.query.photoref const photo = await getPlacePhoto(photoref) diff --git a/backend/routes/regions.js b/backend/routes/regions.js index 9ede6e5..e6ca903 100644 --- a/backend/routes/regions.js +++ b/backend/routes/regions.js @@ -1,3 +1,10 @@ +/** + * @swagger + * tags: + * name: Regions + * description: Access region data. + */ + const router = require("express").Router(); // Models @@ -12,6 +19,16 @@ const _ = require('lodash') const sqlSanitzer = require("../util/sqlstring_sanitizer.js") module.exports = dbConn => { + /** + * @swagger + * /regions: + * get: + * summary: Get all regions + * tags: [Regions] + * responses: + * "200": + * description: Returns available data for all regions + */ router.get("/api/v1/regions", async (req, res) => { const data = await getRegions(dbConn) if (req.query.randomize) { @@ -22,6 +39,21 @@ module.exports = dbConn => { } }); + /** + * @swagger + * /regions/{id}: + * get: + * summary: Get a specific region by id + * tags: [Regions] + * parameters: + * - name: "id" + * in: "path" + * required: true + * type: int + * responses: + * "200": + * description: Returns available data for the region + */ router.get("/api/v1/regions/:id", async (req, res) => { console.log(typeof req.params.id) const id = sqlSanitzer(req.params.id); @@ -29,14 +61,49 @@ module.exports = dbConn => { res.json(await getRegionById(dbConn, id)) }); + /** + * @swagger + * /regions/{id}/image: + * get: + * summary: Get image for specific region + * tags: [Regions] + * parameters: + * - name: "id" + * in: "path" + * required: true + * type: int + * responses: + * "200": + * description: Returns the image for a specific region + * "404": + * description: Returns a placeholder image for the region + */ router.get('/api/v1/regions/:id/image', (req, res) => { + console.log("HERE") if (fs.existsSync(path.join(__dirname, `../data/regions/images/${req.params.id}.jpg`))) { - res.sendFile(path.join(__dirname, `../data/regions/images/${req.params.id}.jpg`)) + console.log("EXISTS") + res.status(200).sendFile(path.join(__dirname, `../data/regions/images/${req.params.id}.jpg`)) } else { - res.sendFile(path.join(__dirname, `../data/regions/images/x.png`)) + console.log("NOT EXISTS") + res.status(404).sendFile(path.join(__dirname, `../data/regions/images/x.png`)) } }) + /** + * @swagger + * /regions/{id}/nearby: + * get: + * summary: Get nearby places of a specific region by id + * tags: [Regions] + * parameters: + * - name: "id" + * in: "path" + * required: true + * type: int + * responses: + * "200": + * description: Returns all nearby places for the region + */ router.get("/api/v1/regions/:id/nearby", async (req,res) => { const id = sqlSanitzer(req.params.id); res.json(await getRegionNearbyById(dbConn,id)) diff --git a/backend/routes/search.js b/backend/routes/search.js index 43c390e..fad1a97 100644 --- a/backend/routes/search.js +++ b/backend/routes/search.js @@ -1,3 +1,10 @@ +/** + * @swagger + * tags: + * name: Search + * description: Access the search algorithm and the data provided for searching. + */ + const router = require("express").Router(); // Models @@ -12,8 +19,47 @@ const oldToNewQuerySyntax = require("../util/oldToNewQuerySyntax.js") const { getUniqueTags } = require("../models/getTags.js"); module.exports = dbConn => { + /** + * @swagger + * /search: + * get: + * summary: Get Searchresults + * tags: [Search] + * parameters: + * - name: "q" + * in: "query" + * required: true + * type: int + * description: "Base64 encoded JS-Object with searchparameters" + * example: eyJmcm9tIjoxNTkzNjQ4MDAwMDAwLCJ0byI6MTU5NDI1MjgwMDAwMCwidGFncyI6W119 + * responses: + * "200": + * description: Returns the region information and scores for the searchresults + */ router.get("/api/v1/search", searchHandler(dbConn)); + + /** + * @swagger + * /search/presets: + * get: + * summary: Get the presets for the search parameters + * tags: [Search] + * responses: + * "200": + * description: Returns all presets for the search parameters + */ router.get("/api/v1/search/presets", presetHandler(dbConn)); + + /** + * @swagger + * /search/tags: + * get: + * summary: Get the existing searchtags + * tags: [Search] + * responses: + * "200": + * description: Returns all existing searchtags + */ router.get("/api/v1/search/tags", tagsHandler(dbConn)); return router; diff --git a/backend/routes/update.js b/backend/routes/update.js index 4ef9eae..6ad723e 100644 --- a/backend/routes/update.js +++ b/backend/routes/update.js @@ -1,6 +1,15 @@ +/** + * @swagger + * tags: + * name: Update + * description: Endpoint for updating region specific data. Only for manual use in the prototype application! + */ + const router = require("express").Router(); // Models +const handleClimateUpdate = require("../models/handleClimateUpdate.js") +const handleClimateUpdateV2 = require("../models/handleClimateUpdateV2.js") const handleUpdateRegionNearby = require("../models/handleUpdateRegionNearby.js") const handleUpdateRegionNearbyById = require("../models/handleUpdateRegionNearbyById.js") const handleUpdateRegionNearbyImgUrl = require("../models/handleUpdateRegionNearbyImgUrl.js") @@ -10,24 +19,114 @@ const handleUpdateRegionNearbyImgUrlById = require("../models/handleUpdateRegion const sqlSanitzer = require("../util/sqlstring_sanitizer.js") module.exports = dbConn => { - router.patch("/api/v1/update/regions/all/nearby", async (req, res) => { + /** + * @swagger + * /update/climate/v1: + * put: + * summary: Pull monthly data from meteostat API V1 + * tags: [Update] + * responses: + * "200": + * description: Update information is logged in backend + */ + router.put("/api/v1/update/climate/v1", async (req, res) => { + const update = await handleClimateUpdate(dbConn) + res.json(update) + }); + + /** + * @swagger + * /update/climate/v2: + * put: + * summary: Pull daily data from meteostat API V2. Data is written to Travopti database and must be processed manually before it can be used. + * tags: [Update] + * responses: + * "200": + * description: Update information is logged in backend + */ + router.put("/api/v1/update/climate/v2", async (req, res) => { + const update = await handleClimateUpdateV2(dbConn) + res.json(update) + }); + + /** + * @swagger + * /update/regions/all/nearby: + * put: + * summary: Updates all nearby data for all regions + * tags: [Update] + * responses: + * "200": + * description: Updates all nearby data for all regions + */ + router.put("/api/v1/update/regions/all/nearby", async (req, res) => { res.json(await handleUpdateRegionNearby(dbConn)) }); - router.patch("/api/v1/update/regions/all/lonlat", async (req,res) => { + /** + * @swagger + * /update/regions/all/lonlat: + * put: + * summary: Updates all coordinate data for all regions + * tags: [Update] + * responses: + * "200": + * description: Updates all coordinate data for all regions + */ + router.put("/api/v1/update/regions/all/lonlat", async (req,res) => { res.json(await handleRegionLonLat(dbConn)) }); - router.patch("/api/v1/update/regions/:id/nearby", async (req, res) => { + /** + * @swagger + * /update/regions/all/nearby/image: + * put: + * summary: Updates the nearby image urls for all regions + * tags: [Update] + * responses: + * "200": + * description: Updates the nearby image urls for all regions + */ + router.put("/api/v1/update/regions/all/nearby/image", async (req, res) => { + res.json(await handleUpdateRegionNearbyImgUrl(dbConn)) + }); + + /** + * @swagger + * /update/regions/{id}/nearby: + * put: + * summary: Updates the nearby data for a specific region + * tags: [Update] + * parameters: + * - name: "id" + * in: "path" + * required: true + * type: int + * responses: + * "200": + * description: Updates the nearby data for a specific region + */ + router.put("/api/v1/update/regions/:id/nearby", async (req, res) => { const id = sqlSanitzer(req.params.id); res.json(await handleUpdateRegionNearbyById(dbConn, id)) }); - router.patch("/api/v1/update/regions/all/nearby/imgurl", async (req, res) => { - res.json(await handleUpdateRegionNearbyImgUrl(dbConn)) - }); - - router.patch("/api/v1/update/regions/:id/nearby/imgurl", async (req, res) => { + /** + * @swagger + * /update/regions/{id}/nearby/image: + * put: + * summary: Updates the nearby image urls for a specific region + * tags: [Update] + * parameters: + * - name: "id" + * in: "path" + * required: true + * type: int + * responses: + * "200": + * description: Updates the nearby image urls for a specific region + */ + router.put("/api/v1/update/regions/:id/nearby/image", async (req, res) => { const id = sqlSanitzer(req.params.id); res.json(await handleUpdateRegionNearbyImgUrlById(dbConn, id)) });