From 01fba91e988a548834c621352a0ad598b3eb20a2 Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Mon, 25 Jan 2021 22:40:52 -0600 Subject: [PATCH 01/10] add fairing update script --- jobs/fairings.js | 134 ++++++++++++++++++++++++++++++++++++ jobs/launches.js | 28 ++++++++ jobs/worker.js | 5 ++ routes/v4/launches/model.js | 26 +++++-- 4 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 jobs/fairings.js diff --git a/jobs/fairings.js b/jobs/fairings.js new file mode 100644 index 00000000..a7355589 --- /dev/null +++ b/jobs/fairings.js @@ -0,0 +1,134 @@ +const got = require('got'); +const { logger } = require('../middleware/logger'); + +const API = process.env.SPACEX_API; +const KEY = process.env.SPACEX_KEY; +const HEALTHCHECK = process.env.FAIRINGS_HEALTHCHECK; + +/** + * Update fairing aggregate stats + * @return {Promise} + */ +module.exports = async () => { + try { + const fairings = await got.post(`${API}/fairings/query`, { + json: { + options: { + pagination: false, + }, + }, + resolveBodyOnly: true, + responseType: 'json', + }); + + const reuseUpdates = fairings.docs.map(async (fairing) => { + if (!fairing?.id) return; + const [ + netLandingAttempts, + netLanding, + waterLandingAttempts, + waterLanding, + ] = await Promise.all([ + got.post(`${API}/launches/query`, { + json: { + query: { + upcoming: false, + fairings: { + $elemMatch: { + fairing: fairing.id, + net_attempt: true, + }, + }, + }, + options: { + pagination: false, + }, + }, + resolveBodyOnly: true, + responseType: 'json', + throwHttpErrors: true, + }), + got.post(`${API}/launches/query`, { + json: { + query: { + upcoming: false, + fairings: { + $elemMatch: { + fairing: fairing.id, + net_attempt: true, + net_landing: true, + }, + }, + }, + options: { + pagination: false, + }, + }, + resolveBodyOnly: true, + responseType: 'json', + throwHttpErrors: true, + }), + got.post(`${API}/launches/query`, { + json: { + query: { + upcoming: false, + fairings: { + $elemMatch: { + fairing: fairing.id, + water_attempt: true, + }, + }, + }, + options: { + pagination: false, + }, + }, + resolveBodyOnly: true, + responseType: 'json', + throwHttpErrors: true, + }), + got.post(`${API}/launches/query`, { + json: { + query: { + upcoming: false, + fairings: { + $elemMatch: { + fairing: fairing.id, + water_attempt: true, + water_landing: true, + }, + }, + }, + options: { + pagination: false, + }, + }, + resolveBodyOnly: true, + responseType: 'json', + throwHttpErrors: true, + }), + ]); + await got.patch(`${API}/fairings/${fairing.id}`, { + json: { + reuse_count: (fairing.launches.length > 0) ? fairing.launches.length - 1 : 0, + net_landing_attempts: netLandingAttempts.totalDocs, + net_landing: netLanding.totalDocs, + water_landing_attempts: waterLandingAttempts.totalDocs, + water_landing: waterLanding.totalDocs, + }, + headers: { + 'spacex-key': KEY, + }, + }); + }); + + await Promise.all(reuseUpdates); + logger.info('Fairing reuse updated'); + + if (HEALTHCHECK) { + await got(HEALTHCHECK); + } + } catch (error) { + console.log(`Fairings Error: ${error.message}`); + } +}; diff --git a/jobs/launches.js b/jobs/launches.js index 8267bdf4..e3359b70 100644 --- a/jobs/launches.js +++ b/jobs/launches.js @@ -233,6 +233,34 @@ module.exports = async () => { }); await Promise.all(shipLaunches); + // Update fairing launches + const fairings = await got.post(`${API}/fairings/query`, { + json: { + options: { + pagination: false, + }, + }, + resolveBodyOnly: true, + responseType: 'json', + }); + + const fairingLaunches = fairings.docs.map(async (fairing) => { + const launchIds = launches.docs + .filter((launch) => launch.fairings.find((f) => f.fairing === fairing.id)) + .map(({ id }) => id); + + await got.patch(`${API}/fairings/${fairing.id}`, { + json: { + launches: launchIds, + }, + headers: { + 'spacex-key': KEY, + }, + }); + results.fairing = true; + }); + await Promise.all(fairingLaunches); + logger.info(results); if (HEALTHCHECK) { diff --git a/jobs/worker.js b/jobs/worker.js index 77a0d063..1658566b 100644 --- a/jobs/worker.js +++ b/jobs/worker.js @@ -11,6 +11,7 @@ const upcoming = require('./upcoming'); const starlink = require('./starlink'); const webcast = require('./webcast'); const launchLibrary = require('./launch-library'); +const fairings = require('./fairings'); // Every 10 minutes const launchesJob = new CronJob('*/10 * * * *', launches); @@ -45,6 +46,9 @@ const webcastJob = new CronJob('*/5 * * * *', webcast); // Every hour on :45 const launchLibraryJob = new CronJob('45 * * * *', launchLibrary); +// Every 10 minutes +const fairingsJob = new CronJob('*/10 * * * *', fairings); + try { launchesJob.start(); payloadsJob.start(); @@ -57,6 +61,7 @@ try { starlinkJob.start(); webcastJob.start(); launchLibraryJob.start(); + fairingsJob.start(); } catch (error) { const formatted = { name: 'worker', diff --git a/routes/v4/launches/model.js b/routes/v4/launches/model.js index 590425f7..af5d7464 100644 --- a/routes/v4/launches/model.js +++ b/routes/v4/launches/model.js @@ -80,16 +80,34 @@ const launchSchema = new mongoose.Schema({ type: String, default: null, }, - fairings: { + fairings: [{ + _id: false, + fairing: { + type: mongoose.ObjectId, + ref: 'Fairing', + default: null, + }, + flight: { + type: Number, + default: null, + }, reused: { type: Boolean, default: null, }, - recovery_attempt: { + net_attempt: { type: Boolean, default: null, }, - recovered: { + net_landing: { + type: Boolean, + default: null, + }, + water_attempt: { + type: Boolean, + default: null, + }, + water_landing: { type: Boolean, default: null, }, @@ -97,7 +115,7 @@ const launchSchema = new mongoose.Schema({ type: mongoose.ObjectId, ref: 'Ship', }], - }, + }], crew: [{ type: mongoose.ObjectId, ref: 'Crew', From 7f4170f142d268cdc2eb538ee4f423990254a702 Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Mon, 25 Jan 2021 22:53:25 -0600 Subject: [PATCH 02/10] add stage to deployment workflow --- .github/workflows/deploy.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f7fbc3ad..db4bc496 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,6 +5,7 @@ on: # Publish `master` as Docker `latest` image. branches: - master + - stage # Publish `v1.2.3` tags as releases. tags: @@ -60,6 +61,8 @@ jobs: # Use Docker `latest` tag convention [ "$VERSION" == "master" ] && VERSION=latest + [ "$VERSION" == "stage" ] && VERSION=stage + echo IMAGE_ID=$IMAGE_ID echo VERSION=$VERSION From 13a43fea60eaab25c24e2b986e7fe10018ca6f13 Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Fri, 29 Jan 2021 22:14:23 -0600 Subject: [PATCH 03/10] Add role to crew info for launches --- routes/v4/launches/model.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/routes/v4/launches/model.js b/routes/v4/launches/model.js index af5d7464..fef3b30c 100644 --- a/routes/v4/launches/model.js +++ b/routes/v4/launches/model.js @@ -117,8 +117,15 @@ const launchSchema = new mongoose.Schema({ }], }], crew: [{ - type: mongoose.ObjectId, - ref: 'Crew', + _id: false, + crew: { + type: mongoose.ObjectId, + ref: 'Crew', + }, + role: { + type: String, + default: null, + }, }], ships: [{ type: mongoose.ObjectId, From f779fe8acec7b3beb35d7b8ead416b47b1d049cb Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Fri, 29 Jan 2021 22:34:43 -0600 Subject: [PATCH 04/10] rename to crew_id for launch crew array --- routes/v4/launches/model.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/v4/launches/model.js b/routes/v4/launches/model.js index fef3b30c..baeaa217 100644 --- a/routes/v4/launches/model.js +++ b/routes/v4/launches/model.js @@ -118,7 +118,7 @@ const launchSchema = new mongoose.Schema({ }], crew: [{ _id: false, - crew: { + crew_id: { type: mongoose.ObjectId, ref: 'Crew', }, From db18452799eb04f0a090394af8adcdbfc2b868f8 Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Fri, 29 Jan 2021 22:47:28 -0600 Subject: [PATCH 05/10] Add null default to crew id --- routes/v4/launches/model.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/routes/v4/launches/model.js b/routes/v4/launches/model.js index baeaa217..24db7062 100644 --- a/routes/v4/launches/model.js +++ b/routes/v4/launches/model.js @@ -118,9 +118,10 @@ const launchSchema = new mongoose.Schema({ }], crew: [{ _id: false, - crew_id: { + crew: { type: mongoose.ObjectId, ref: 'Crew', + default: null, }, role: { type: String, From 0ed3c593b6b291bccf814e683c1b94cbcadf3af8 Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Sat, 30 Jan 2021 12:29:56 -0600 Subject: [PATCH 06/10] check for fairings array when updating launch array --- jobs/launches.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jobs/launches.js b/jobs/launches.js index e3359b70..f114ccd2 100644 --- a/jobs/launches.js +++ b/jobs/launches.js @@ -246,7 +246,12 @@ module.exports = async () => { const fairingLaunches = fairings.docs.map(async (fairing) => { const launchIds = launches.docs - .filter((launch) => launch.fairings.find((f) => f.fairing === fairing.id)) + .filter((launch) => { + if (launch.fairings && launch.fairings.length) { + return launch.fairings.find((f) => f.fairing === fairing.id); + } + return false; + }) .map(({ id }) => id); await got.patch(`${API}/fairings/${fairing.id}`, { From 663a3f46f6e4f0b56bdec7df6602ca00d4684198 Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Sat, 30 Jan 2021 13:56:53 -0600 Subject: [PATCH 07/10] Add missing recovered field --- routes/v4/launches/model.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routes/v4/launches/model.js b/routes/v4/launches/model.js index 24db7062..c35de16d 100644 --- a/routes/v4/launches/model.js +++ b/routes/v4/launches/model.js @@ -111,6 +111,10 @@ const launchSchema = new mongoose.Schema({ type: Boolean, default: null, }, + recovered: { + type: Boolean, + default: null, + }, ships: [{ type: mongoose.ObjectId, ref: 'Ship', From 0b09ae8b6d918faf7db03276a75a877b83e61582 Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Fri, 26 Mar 2021 20:46:34 -0500 Subject: [PATCH 08/10] add new routes for v5 changes --- app.js | 5 +- .../v4/capsules/model.js => models/capsule.js | 0 .../v4/company/model.js => models/company.js | 0 routes/v4/cores/model.js => models/core.js | 0 routes/v4/crew/model.js => models/crew.js | 0 .../v4/dragons/model.js => models/dragon.js | 0 .../v4/fairings/model.js => models/fairing.js | 0 .../v4/history/model.js => models/history.js | 0 .../v4/landpads/model.js => models/landpad.js | 0 .../v4/launches/model.js => models/launch.js | 0 .../model.js => models/launchpad.js | 0 .../v4/payloads/model.js => models/payload.js | 0 .../roadster/model.js => models/roadster.js | 0 .../v4/rockets/model.js => models/rocket.js | 0 routes/v4/ships/model.js => models/ship.js | 0 .../starlink/model.js => models/starlink.js | 0 routes/v4/users/model.js => models/user.js | 0 routes/index.js | 1 + routes/v4/capsules/routes.js | 2 +- routes/v4/company/routes.js | 2 +- routes/v4/cores/routes.js | 2 +- routes/v4/crew/routes.js | 2 +- routes/v4/dragons/routes.js | 2 +- routes/v4/history/routes.js | 2 +- routes/v4/index.js | 2 - routes/v4/landpads/routes.js | 2 +- routes/v4/launches/routes.js | 2 +- routes/v4/launchpads/routes.js | 2 +- routes/v4/payloads/routes.js | 2 +- routes/v4/roadster/routes.js | 2 +- routes/v4/rockets/routes.js | 2 +- routes/v4/ships/routes.js | 2 +- routes/v4/starlink/routes.js | 2 +- routes/v4/users/routes.js | 2 +- routes/{v4 => v5}/fairings/routes.js | 2 +- routes/v5/index.js | 12 ++ routes/v5/launches/routes.js | 151 ++++++++++++++++++ 37 files changed, 183 insertions(+), 20 deletions(-) rename routes/v4/capsules/model.js => models/capsule.js (100%) rename routes/v4/company/model.js => models/company.js (100%) rename routes/v4/cores/model.js => models/core.js (100%) rename routes/v4/crew/model.js => models/crew.js (100%) rename routes/v4/dragons/model.js => models/dragon.js (100%) rename routes/v4/fairings/model.js => models/fairing.js (100%) rename routes/v4/history/model.js => models/history.js (100%) rename routes/v4/landpads/model.js => models/landpad.js (100%) rename routes/v4/launches/model.js => models/launch.js (100%) rename routes/v4/launchpads/model.js => models/launchpad.js (100%) rename routes/v4/payloads/model.js => models/payload.js (100%) rename routes/v4/roadster/model.js => models/roadster.js (100%) rename routes/v4/rockets/model.js => models/rocket.js (100%) rename routes/v4/ships/model.js => models/ship.js (100%) rename routes/v4/starlink/model.js => models/starlink.js (100%) rename routes/v4/users/model.js => models/user.js (100%) rename routes/{v4 => v5}/fairings/routes.js (97%) create mode 100644 routes/v5/index.js create mode 100644 routes/v5/launches/routes.js diff --git a/app.js b/app.js index 47475d49..d0815402 100644 --- a/app.js +++ b/app.js @@ -7,7 +7,7 @@ const bodyParser = require('koa-bodyparser'); const mongoose = require('mongoose'); const { requestLogger, logger } = require('./middleware/logger'); const { responseTime, errors } = require('./middleware'); -const { v4 } = require('./routes'); +const { v4, v5 } = require('./routes'); const app = new Koa(); @@ -63,7 +63,8 @@ app.use(responseTime); // Request logging app.use(requestLogger); -// V4 routes +// Routes app.use(v4.routes()); +app.use(v5.routes()); module.exports = app; diff --git a/routes/v4/capsules/model.js b/models/capsule.js similarity index 100% rename from routes/v4/capsules/model.js rename to models/capsule.js diff --git a/routes/v4/company/model.js b/models/company.js similarity index 100% rename from routes/v4/company/model.js rename to models/company.js diff --git a/routes/v4/cores/model.js b/models/core.js similarity index 100% rename from routes/v4/cores/model.js rename to models/core.js diff --git a/routes/v4/crew/model.js b/models/crew.js similarity index 100% rename from routes/v4/crew/model.js rename to models/crew.js diff --git a/routes/v4/dragons/model.js b/models/dragon.js similarity index 100% rename from routes/v4/dragons/model.js rename to models/dragon.js diff --git a/routes/v4/fairings/model.js b/models/fairing.js similarity index 100% rename from routes/v4/fairings/model.js rename to models/fairing.js diff --git a/routes/v4/history/model.js b/models/history.js similarity index 100% rename from routes/v4/history/model.js rename to models/history.js diff --git a/routes/v4/landpads/model.js b/models/landpad.js similarity index 100% rename from routes/v4/landpads/model.js rename to models/landpad.js diff --git a/routes/v4/launches/model.js b/models/launch.js similarity index 100% rename from routes/v4/launches/model.js rename to models/launch.js diff --git a/routes/v4/launchpads/model.js b/models/launchpad.js similarity index 100% rename from routes/v4/launchpads/model.js rename to models/launchpad.js diff --git a/routes/v4/payloads/model.js b/models/payload.js similarity index 100% rename from routes/v4/payloads/model.js rename to models/payload.js diff --git a/routes/v4/roadster/model.js b/models/roadster.js similarity index 100% rename from routes/v4/roadster/model.js rename to models/roadster.js diff --git a/routes/v4/rockets/model.js b/models/rocket.js similarity index 100% rename from routes/v4/rockets/model.js rename to models/rocket.js diff --git a/routes/v4/ships/model.js b/models/ship.js similarity index 100% rename from routes/v4/ships/model.js rename to models/ship.js diff --git a/routes/v4/starlink/model.js b/models/starlink.js similarity index 100% rename from routes/v4/starlink/model.js rename to models/starlink.js diff --git a/routes/v4/users/model.js b/models/user.js similarity index 100% rename from routes/v4/users/model.js rename to models/user.js diff --git a/routes/index.js b/routes/index.js index 5f7747e2..7d16e601 100644 --- a/routes/index.js +++ b/routes/index.js @@ -2,3 +2,4 @@ * Export versions */ module.exports.v4 = require('./v4'); +module.exports.v5 = require('./v5'); diff --git a/routes/v4/capsules/routes.js b/routes/v4/capsules/routes.js index 2098320d..299d5983 100644 --- a/routes/v4/capsules/routes.js +++ b/routes/v4/capsules/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Capsule = require('./model'); +const Capsule = require('../../../models/capsule'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/company/routes.js b/routes/v4/company/routes.js index 59958d84..88f2f910 100644 --- a/routes/v4/company/routes.js +++ b/routes/v4/company/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Company = require('./model'); +const Company = require('../../../models/company'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/cores/routes.js b/routes/v4/cores/routes.js index 16ad106b..4a106c55 100644 --- a/routes/v4/cores/routes.js +++ b/routes/v4/cores/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Core = require('./model'); +const Core = require('../../../models/core'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/crew/routes.js b/routes/v4/crew/routes.js index 3e12e9cc..bc810932 100644 --- a/routes/v4/crew/routes.js +++ b/routes/v4/crew/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Crew = require('./model'); +const Crew = require('../../../models/crew'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/dragons/routes.js b/routes/v4/dragons/routes.js index c1065b74..2dd78c5f 100644 --- a/routes/v4/dragons/routes.js +++ b/routes/v4/dragons/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Dragon = require('./model'); +const Dragon = require('../../../models/dragon'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/history/routes.js b/routes/v4/history/routes.js index a34b9b37..8f520301 100644 --- a/routes/v4/history/routes.js +++ b/routes/v4/history/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const History = require('./model'); +const History = require('../../../models/history'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/index.js b/routes/v4/index.js index ae07fbbb..c726f261 100644 --- a/routes/v4/index.js +++ b/routes/v4/index.js @@ -15,7 +15,6 @@ const company = require('./company/routes'); const roadster = require('./roadster/routes'); const starlink = require('./starlink/routes'); const history = require('./history/routes'); -const fairings = require('./fairings/routes'); const v4 = new Router({ prefix: '/v4', @@ -37,6 +36,5 @@ v4.use(company.routes()); v4.use(roadster.routes()); v4.use(starlink.routes()); v4.use(history.routes()); -v4.use(fairings.routes()); module.exports = v4; diff --git a/routes/v4/landpads/routes.js b/routes/v4/landpads/routes.js index 9975050b..883ecff6 100644 --- a/routes/v4/landpads/routes.js +++ b/routes/v4/landpads/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Landpad = require('./model'); +const Landpad = require('../../../models/landpad'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/launches/routes.js b/routes/v4/launches/routes.js index e62bea1e..ed57d4c5 100644 --- a/routes/v4/launches/routes.js +++ b/routes/v4/launches/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Launch = require('./model'); +const Launch = require('../../../models/launch'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/launchpads/routes.js b/routes/v4/launchpads/routes.js index c04f2d92..332d48f3 100644 --- a/routes/v4/launchpads/routes.js +++ b/routes/v4/launchpads/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Launchpad = require('./model'); +const Launchpad = require('../../../models/launchpad'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/payloads/routes.js b/routes/v4/payloads/routes.js index e477dd89..008453a2 100644 --- a/routes/v4/payloads/routes.js +++ b/routes/v4/payloads/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Payload = require('./model'); +const Payload = require('../../../models/payload'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/roadster/routes.js b/routes/v4/roadster/routes.js index 3ffd20d7..e3a936f0 100644 --- a/routes/v4/roadster/routes.js +++ b/routes/v4/roadster/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Roadster = require('./model'); +const Roadster = require('../../../models/roadster'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/rockets/routes.js b/routes/v4/rockets/routes.js index e9b9a29a..4e89e7d6 100644 --- a/routes/v4/rockets/routes.js +++ b/routes/v4/rockets/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Rocket = require('./model'); +const Rocket = require('../../../models/rocket'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/ships/routes.js b/routes/v4/ships/routes.js index dbc96308..edd0e51b 100644 --- a/routes/v4/ships/routes.js +++ b/routes/v4/ships/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Ship = require('./model'); +const Ship = require('../../../models/ship'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/starlink/routes.js b/routes/v4/starlink/routes.js index 8dc09d76..79fa9dab 100644 --- a/routes/v4/starlink/routes.js +++ b/routes/v4/starlink/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Starlink = require('./model'); +const Starlink = require('../../../models/starlink'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/users/routes.js b/routes/v4/users/routes.js index 75a577f5..30e7e198 100644 --- a/routes/v4/users/routes.js +++ b/routes/v4/users/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const User = require('./model'); +const User = require('../../../models/user'); const { auth, authz } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v4/fairings/routes.js b/routes/v5/fairings/routes.js similarity index 97% rename from routes/v4/fairings/routes.js rename to routes/v5/fairings/routes.js index 653f46bb..499c4c49 100644 --- a/routes/v4/fairings/routes.js +++ b/routes/v5/fairings/routes.js @@ -1,5 +1,5 @@ const Router = require('koa-router'); -const Fairing = require('./model'); +const Fairing = require('../../../models/fairing'); const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ diff --git a/routes/v5/index.js b/routes/v5/index.js new file mode 100644 index 00000000..dcb64b44 --- /dev/null +++ b/routes/v5/index.js @@ -0,0 +1,12 @@ +const Router = require('koa-router'); +const launches = require('./launches/routes'); +const fairings = require('./fairings/routes'); + +const v5 = new Router({ + prefix: '/v5', +}); + +v5.use(launches.routes()); +v5.use(fairings.routes()); + +module.exports = v5; diff --git a/routes/v5/launches/routes.js b/routes/v5/launches/routes.js new file mode 100644 index 00000000..ed57d4c5 --- /dev/null +++ b/routes/v5/launches/routes.js @@ -0,0 +1,151 @@ +const Router = require('koa-router'); +const Launch = require('../../../models/launch'); +const { auth, authz, cache } = require('../../../middleware'); + +const router = new Router({ + prefix: '/launches', +}); + +// +// Convenience Endpoints +// + +// Get past launches +router.get('/past', cache(20), async (ctx) => { + try { + const result = await Launch.find({ + upcoming: false, + }, null, { + sort: { + flight_number: 'asc', + }, + }); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Get upcoming launches +router.get('/upcoming', cache(20), async (ctx) => { + try { + const result = await Launch.find({ + upcoming: true, + }, null, { + sort: { + flight_number: 'asc', + }, + }); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Get latest launch +router.get('/latest', cache(20), async (ctx) => { + try { + const result = await Launch.findOne({ + upcoming: false, + }, null, { + sort: { + flight_number: 'desc', + }, + }); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Get next launch +router.get('/next', cache(20), async (ctx) => { + try { + const result = await Launch.findOne({ + upcoming: true, + }, null, { + sort: { + flight_number: 'asc', + }, + }); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// +// Standard Endpoints +// + +// Get all launches +router.get('/', cache(20), async (ctx) => { + try { + const result = await Launch.find({}); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Get one launch +router.get('/:id', cache(20), async (ctx) => { + const result = await Launch.findById(ctx.params.id); + if (!result) { + ctx.throw(404); + } + ctx.status = 200; + ctx.body = result; +}); + +// Query launches +router.post('/query', cache(20), async (ctx) => { + const { query = {}, options = {} } = ctx.request.body; + try { + const result = await Launch.paginate(query, options); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Create a launch +router.post('/', auth, authz('launch:create'), async (ctx) => { + try { + const launch = new Launch(ctx.request.body); + await launch.save(); + ctx.status = 201; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Update a launch +router.patch('/:id', auth, authz('launch:update'), async (ctx) => { + try { + await Launch.findByIdAndUpdate(ctx.params.id, ctx.request.body, { + runValidators: true, + }); + ctx.status = 200; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Delete a launch +router.delete('/:id', auth, authz('launch:delete'), async (ctx) => { + try { + await Launch.findByIdAndDelete(ctx.params.id); + ctx.status = 200; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +module.exports = router; From 14537f4663b0efbabad188a7571a7def3beeaef8 Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Fri, 26 Mar 2021 23:41:31 -0500 Subject: [PATCH 09/10] add v4 converter for crew and fairings --- routes/v4/launches/_format-v4.js | 42 ++++++++++ routes/v4/launches/routes.js | 15 ++-- routes/v5/launches/routes.js | 132 +------------------------------ 3 files changed, 51 insertions(+), 138 deletions(-) create mode 100644 routes/v4/launches/_format-v4.js diff --git a/routes/v4/launches/_format-v4.js b/routes/v4/launches/_format-v4.js new file mode 100644 index 00000000..58c4d150 --- /dev/null +++ b/routes/v4/launches/_format-v4.js @@ -0,0 +1,42 @@ +/* eslint-disable no-underscore-dangle */ + +const buildFairings = (launch) => { + let fairings = {}; + if (launch?.fairings?.length) { + fairings.recovery_attempt = launch.fairings.some((f) => f.recovered); + fairings.reused = launch.fairings.some((f) => f.reused); + fairings.recovered = launch.fairings.some((f) => f.net_attempt || f.water_attempt); + fairings.ships = launch.fairings.flatMap((f) => f.ships); + } else { + fairings = null; + } + return fairings; +}; + +const buildCrew = (launch) => launch.crew.map((crew) => crew.crew); + +module.exports = async (payload) => { + if (Array.isArray(payload)) { + return payload.map((launch) => ({ + ...launch.toObject(), + fairings: buildFairings(launch.toObject()), + crew: buildCrew(launch), + })); + } + if (Array.isArray(payload?.docs)) { + const docs = payload.docs.map((launch) => ({ + ...launch.toObject(), + fairings: buildFairings(launch.toObject()), + crew: buildCrew(launch), + })); + return { + ...payload, + docs, + }; + } + return { + ...payload.toObject(), + fairings: buildFairings(payload.toObject()), + crew: buildCrew(payload._doc), + }; +}; diff --git a/routes/v4/launches/routes.js b/routes/v4/launches/routes.js index ed57d4c5..640f5f0b 100644 --- a/routes/v4/launches/routes.js +++ b/routes/v4/launches/routes.js @@ -1,6 +1,7 @@ const Router = require('koa-router'); const Launch = require('../../../models/launch'); const { auth, authz, cache } = require('../../../middleware'); +const formatV4 = require('./_format-v4'); const router = new Router({ prefix: '/launches', @@ -21,7 +22,7 @@ router.get('/past', cache(20), async (ctx) => { }, }); ctx.status = 200; - ctx.body = result; + ctx.body = await formatV4(result); } catch (error) { ctx.throw(400, error.message); } @@ -38,7 +39,7 @@ router.get('/upcoming', cache(20), async (ctx) => { }, }); ctx.status = 200; - ctx.body = result; + ctx.body = await formatV4(result); } catch (error) { ctx.throw(400, error.message); } @@ -55,7 +56,7 @@ router.get('/latest', cache(20), async (ctx) => { }, }); ctx.status = 200; - ctx.body = result; + ctx.body = await formatV4(result); } catch (error) { ctx.throw(400, error.message); } @@ -72,7 +73,7 @@ router.get('/next', cache(20), async (ctx) => { }, }); ctx.status = 200; - ctx.body = result; + ctx.body = await formatV4(result); } catch (error) { ctx.throw(400, error.message); } @@ -87,7 +88,7 @@ router.get('/', cache(20), async (ctx) => { try { const result = await Launch.find({}); ctx.status = 200; - ctx.body = result; + ctx.body = await formatV4(result); } catch (error) { ctx.throw(400, error.message); } @@ -100,7 +101,7 @@ router.get('/:id', cache(20), async (ctx) => { ctx.throw(404); } ctx.status = 200; - ctx.body = result; + ctx.body = await formatV4(result); }); // Query launches @@ -109,7 +110,7 @@ router.post('/query', cache(20), async (ctx) => { try { const result = await Launch.paginate(query, options); ctx.status = 200; - ctx.body = result; + ctx.body = await formatV4(result); } catch (error) { ctx.throw(400, error.message); } diff --git a/routes/v5/launches/routes.js b/routes/v5/launches/routes.js index ed57d4c5..6480ee01 100644 --- a/routes/v5/launches/routes.js +++ b/routes/v5/launches/routes.js @@ -1,108 +1,11 @@ const Router = require('koa-router'); const Launch = require('../../../models/launch'); -const { auth, authz, cache } = require('../../../middleware'); +const { cache } = require('../../../middleware'); const router = new Router({ prefix: '/launches', }); -// -// Convenience Endpoints -// - -// Get past launches -router.get('/past', cache(20), async (ctx) => { - try { - const result = await Launch.find({ - upcoming: false, - }, null, { - sort: { - flight_number: 'asc', - }, - }); - ctx.status = 200; - ctx.body = result; - } catch (error) { - ctx.throw(400, error.message); - } -}); - -// Get upcoming launches -router.get('/upcoming', cache(20), async (ctx) => { - try { - const result = await Launch.find({ - upcoming: true, - }, null, { - sort: { - flight_number: 'asc', - }, - }); - ctx.status = 200; - ctx.body = result; - } catch (error) { - ctx.throw(400, error.message); - } -}); - -// Get latest launch -router.get('/latest', cache(20), async (ctx) => { - try { - const result = await Launch.findOne({ - upcoming: false, - }, null, { - sort: { - flight_number: 'desc', - }, - }); - ctx.status = 200; - ctx.body = result; - } catch (error) { - ctx.throw(400, error.message); - } -}); - -// Get next launch -router.get('/next', cache(20), async (ctx) => { - try { - const result = await Launch.findOne({ - upcoming: true, - }, null, { - sort: { - flight_number: 'asc', - }, - }); - ctx.status = 200; - ctx.body = result; - } catch (error) { - ctx.throw(400, error.message); - } -}); - -// -// Standard Endpoints -// - -// Get all launches -router.get('/', cache(20), async (ctx) => { - try { - const result = await Launch.find({}); - ctx.status = 200; - ctx.body = result; - } catch (error) { - ctx.throw(400, error.message); - } -}); - -// Get one launch -router.get('/:id', cache(20), async (ctx) => { - const result = await Launch.findById(ctx.params.id); - if (!result) { - ctx.throw(404); - } - ctx.status = 200; - ctx.body = result; -}); - // Query launches router.post('/query', cache(20), async (ctx) => { const { query = {}, options = {} } = ctx.request.body; @@ -115,37 +18,4 @@ router.post('/query', cache(20), async (ctx) => { } }); -// Create a launch -router.post('/', auth, authz('launch:create'), async (ctx) => { - try { - const launch = new Launch(ctx.request.body); - await launch.save(); - ctx.status = 201; - } catch (error) { - ctx.throw(400, error.message); - } -}); - -// Update a launch -router.patch('/:id', auth, authz('launch:update'), async (ctx) => { - try { - await Launch.findByIdAndUpdate(ctx.params.id, ctx.request.body, { - runValidators: true, - }); - ctx.status = 200; - } catch (error) { - ctx.throw(400, error.message); - } -}); - -// Delete a launch -router.delete('/:id', auth, authz('launch:delete'), async (ctx) => { - try { - await Launch.findByIdAndDelete(ctx.params.id); - ctx.status = 200; - } catch (error) { - ctx.throw(400, error.message); - } -}); - module.exports = router; From 23e73b13745af99c2de38f4b72a0245f4278e36c Mon Sep 17 00:00:00 2001 From: Jake Meyer Date: Sat, 10 Apr 2021 11:41:21 -0500 Subject: [PATCH 10/10] add rest of v5 launch endpoints --- routes/v5/launches/routes.js | 132 ++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) diff --git a/routes/v5/launches/routes.js b/routes/v5/launches/routes.js index 6480ee01..ed57d4c5 100644 --- a/routes/v5/launches/routes.js +++ b/routes/v5/launches/routes.js @@ -1,11 +1,108 @@ const Router = require('koa-router'); const Launch = require('../../../models/launch'); -const { cache } = require('../../../middleware'); +const { auth, authz, cache } = require('../../../middleware'); const router = new Router({ prefix: '/launches', }); +// +// Convenience Endpoints +// + +// Get past launches +router.get('/past', cache(20), async (ctx) => { + try { + const result = await Launch.find({ + upcoming: false, + }, null, { + sort: { + flight_number: 'asc', + }, + }); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Get upcoming launches +router.get('/upcoming', cache(20), async (ctx) => { + try { + const result = await Launch.find({ + upcoming: true, + }, null, { + sort: { + flight_number: 'asc', + }, + }); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Get latest launch +router.get('/latest', cache(20), async (ctx) => { + try { + const result = await Launch.findOne({ + upcoming: false, + }, null, { + sort: { + flight_number: 'desc', + }, + }); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Get next launch +router.get('/next', cache(20), async (ctx) => { + try { + const result = await Launch.findOne({ + upcoming: true, + }, null, { + sort: { + flight_number: 'asc', + }, + }); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// +// Standard Endpoints +// + +// Get all launches +router.get('/', cache(20), async (ctx) => { + try { + const result = await Launch.find({}); + ctx.status = 200; + ctx.body = result; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Get one launch +router.get('/:id', cache(20), async (ctx) => { + const result = await Launch.findById(ctx.params.id); + if (!result) { + ctx.throw(404); + } + ctx.status = 200; + ctx.body = result; +}); + // Query launches router.post('/query', cache(20), async (ctx) => { const { query = {}, options = {} } = ctx.request.body; @@ -18,4 +115,37 @@ router.post('/query', cache(20), async (ctx) => { } }); +// Create a launch +router.post('/', auth, authz('launch:create'), async (ctx) => { + try { + const launch = new Launch(ctx.request.body); + await launch.save(); + ctx.status = 201; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Update a launch +router.patch('/:id', auth, authz('launch:update'), async (ctx) => { + try { + await Launch.findByIdAndUpdate(ctx.params.id, ctx.request.body, { + runValidators: true, + }); + ctx.status = 200; + } catch (error) { + ctx.throw(400, error.message); + } +}); + +// Delete a launch +router.delete('/:id', auth, authz('launch:delete'), async (ctx) => { + try { + await Launch.findByIdAndDelete(ctx.params.id); + ctx.status = 200; + } catch (error) { + ctx.throw(400, error.message); + } +}); + module.exports = router;