From 17cc7ee30c795e3b12e0a37ba5f1f7f5a4fdf20b Mon Sep 17 00:00:00 2001 From: Amanda Burtness Date: Sun, 20 Feb 2022 21:30:37 -0600 Subject: [PATCH] mvp done --- api/.DS_Store | Bin 0 -> 6148 bytes api/hubs/hubs-model.js | 53 +++++++++ api/hubs/hubs-router.js | 117 ++++++++++++++++++++ api/messages/messages-model.js | 45 ++++++++ api/middlewares/middleware.js | 30 +++++ api/server.js | 31 ++++++ data/.DS_Store | Bin 0 -> 6148 bytes data/dbConfig.js | 5 + data/hubs.db3 | Bin 0 -> 28672 bytes data/migrations/20190211125952_bootstrap.js | 25 +++++ data/seeds/000-cleanup.js | 8 ++ data/seeds/001-hubs.js | 24 ++++ data/seeds/002-messages.js | 110 ++++++++++++++++++ index.js | 7 ++ knexfile.js | 21 ++++ 15 files changed, 476 insertions(+) create mode 100644 api/.DS_Store create mode 100644 api/hubs/hubs-model.js create mode 100644 api/hubs/hubs-router.js create mode 100644 api/messages/messages-model.js create mode 100644 api/middlewares/middleware.js create mode 100644 api/server.js create mode 100644 data/.DS_Store create mode 100644 data/dbConfig.js create mode 100644 data/hubs.db3 create mode 100644 data/migrations/20190211125952_bootstrap.js create mode 100644 data/seeds/000-cleanup.js create mode 100644 data/seeds/001-hubs.js create mode 100644 data/seeds/002-messages.js create mode 100644 index.js create mode 100644 knexfile.js diff --git a/api/.DS_Store b/api/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..3db247eda4002369f83f6b32ff1a592de96c7a83 GIT binary patch literal 6148 zcmeHKT~5O=40cK%hKA4{k>DXWK)XSi$_aJ>7)2XWt4>T4uQ>&0KwN`!@W?&*99vVP zwjf>*LU!eRsbeSZ*B>`T3H?!_;%BMHatQxPeb>#!*NS% z?xpKzA45KA9#lO`9=*AmwwuqmUz!)c2Q)=q4^-i(k<}BjdmPB_W!y8(F`O$`BlD)2 ze&;=qFXwDx3>X8(z)u)J&1RWQ1+6s(i~(cdzyN { + const {id} = req.params; + + try { + const hub = await Hubs.findById(id); + + if (!hub) { + res.status(404).json({message: `no hub ${id}, error`}) + } else { + req.hub = hub; // take the request object and make a new property inside it + next(); + } + + } catch(e) { + res.status(500).json({message: e.message}) + } +} + +const checkMessage = (req, res, next) => { // middleware to check the payload + if (!req.body.sender || !req.body.text) { + res.status(400).json("message and sender required") + } else { + next(); + } +} + +router.get('/', (req, res, next) => { + Hubs.find(req.query) + .then(hubs => { + res.status(200).json(hubs); + }) + .catch(error => { + // log error to server + next(error) + }); +}); + +router.get('/:id', checkHubId, (req, res, next) => { + res.status(200).json(req.hub); // this is from the new property we just made in the middleware +}); + +router.post('/', (req, res) => { + Hubs.add(req.body) + .then(hub => { + res.status(201).json(hub); + }) + .catch(error => { + // log error to server + next(error) + }); +}); + +router.delete('/:id', checkHubId, (req, res, next) => { + Hubs.remove(req.params.id) + .then(() => { + res.status(200).json({ message: 'The hub has been nuked' }); + }) + .catch(error => { + // log error to server when we try to delete the hub, after we already checked the id + next(error) + }); +}); + +router.put('/:id', checkHubId, (req, res, next) => { + Hubs.update(req.params.id, req.body) + .then(hub => { + res.status(200).json(hub); + }) + .catch(error => { + // log error to server + next(error) + }); +}); + +router.get('/:id/messages', checkHubId, (req, res, next) => { + Hubs.findHubMessages(req.params.id) + .then(messages => { + res.status(200).json(messages); + }) + .catch(error => { + // log error to server + next(error) + }); +}); + +router.post('/:id/messages', checkHubId, checkMessage, (req, res, next) => { + const messageInfo = { ...req.body, hub_id: req.params.id }; + + Messages.add(messageInfo) + .then(message => { + res.status(210).json(message); + }) + .catch(error => { + // log error to server + next(error) + }); +}); + +// ERROR ENDPOINT +// ERROR ENDPOINT +// ERROR ENDPOINT +router.use((err, req, res, next) => { + res.status(500).json({ + message: 'Error somewhere in there my dude', + error: err.message + }); +}) + +module.exports = router; diff --git a/api/messages/messages-model.js b/api/messages/messages-model.js new file mode 100644 index 000000000..31afb02c1 --- /dev/null +++ b/api/messages/messages-model.js @@ -0,0 +1,45 @@ +const db = require('../../data/dbConfig.js'); + +module.exports = { + find, + findById, + add, + remove, + update +}; + +function find(query) { + let { page = 1, limit = 5, sortby = 'id', sortdir = 'asc' } = query; + const offset = limit * (page - 1); + + let rows = db('messages') + .orderBy(sortby, sortdir) + .limit(limit) + .offset(offset); + + return rows; +} + +function findById(id) { + return db('messages') + .where({ id }) + .first(); +} + +async function add(message) { + const [id] = await db('messages').insert(message); + + return findById(id); +} + +function remove(id) { + return db('messages') + .where({ id }) + .del(); +} + +function update(id, changes) { + return db('messages') + .where({ id }) + .update(changes, '*'); +} diff --git a/api/middlewares/middleware.js b/api/middlewares/middleware.js new file mode 100644 index 000000000..00ec567bb --- /dev/null +++ b/api/middlewares/middleware.js @@ -0,0 +1,30 @@ +// make your own middleware [ client --> Middleware (call next()) --> server ] / pay close attention to where and when your middleweare is being applied +const logQuote = (coin) => (req, res, next) => { + console.log('a penny saved is a penny earned'); + + if (coin == 'quarter') { + console.log('yeet'); + next(); + } else if (coin == 'penny' || 'nickle') { + console.log(`smol ${coin} bb`); + next(); + } else { + res.json("not a valid coin"); + } + +} + +const checkWord = (req, res, next) => { + if (req.query.word === "bad") { + res.json(`you can't proceed with the word: ${req.query.word}`); + } else { + next(); + } +} + + + +module.exports = { + logQuote, + checkWord +} \ No newline at end of file diff --git a/api/server.js b/api/server.js new file mode 100644 index 000000000..3e4e293d3 --- /dev/null +++ b/api/server.js @@ -0,0 +1,31 @@ +const express = require('express'); // importing a CommonJS module + +const hubsRouter = require('./hubs/hubs-router.js'); + +const morgan = require("morgan") +const helmet = require("helmet") + +const { logQuote, checkWord } = require('./middlewares/middleware') + +const server = express(); + +server.use(express.json()); +server.use(morgan("dev")) // global middleware, in the console, lets you know what end point, the status, and how long it took to do +server.use(helmet()) // global middlewear that protects header in requests +server.use(logQuote("penny")) // your own middleware + +server.use('/api/hubs', hubsRouter); + +server.get('/', checkWord, (req, res) => { + res.send(` +

Hubs API

+

Welcome to the Hubs API

+ `); +}); + +server.use('*', (req, res) => { + // catch all 404 errors middleware + res.status(404).json({ message: `${req.method} ${req.baseUrl} not found!` }); +}); + +module.exports = server; diff --git a/data/.DS_Store b/data/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e267b16b1ea725c766ecc82e00d26b7f5f280f58 GIT binary patch literal 6148 zcmeHKQBK1!40Xzo#`s{LeC7!324N~E*acv88b~V{8~o=KoPe8f4(`IU9Zik8N_-(S z*_HEB$BxsNs&0tL&EK0D(UgeBP{!&4%@N^o)}B<^!h=rcc%V0WrbsWe?|GZyKQh33 zH=!20wx%6*_HVPEEgoaL)kRmYLw;?n>*XdcG0t|Wf-1x0I(0b`(K;7o6)T>tNe&;MnR-5CSMz)3OSM)jhe?CLd663PF?5=fp zm(xGvI1nuk7dR~v95{i5lmmN)BS;7d#9_rAI4mb5xNrb*L2y_OyjOO6CZljz1cyY= z8PB|`u6pm)_gH0VJDhyW2F0z`la5CI}U1c<;ZOWKmII_cr;xjVm`dc`NO1@$)U^w73dl*^?m;bj*Xq^Y|cC zz6eLWFGpM?u~tDR1f@Z|!dsCH92vIwo(Max2+udx*K4zxa6Oif;ugo>2YcP5z560l zD|l}tRWCqW=UdZZH6F^Y3}w)f5y#G`Wjw8M9dJi_67H$4ZtPs$xVDKs$-oi&J+%k9 ze06onep`W~k8tvCAbh!-1nOZTv7MjdxPN zkwSH8$sX?*%%}^Wx##g>*MEi9*myD6+V~UMLUn!J9#10N59Fg=U-d!}D;-3;p6>Kt z)OX~0*IqQlxQeJgVj`%CRk@!)wY!;o^}+@FfuR#U^x)oiH>Y5g-CYfCvx)B0vO)01+SpMBrs1 za6FT}P&)L{f@&p`J!PjKt2tS;vr9I93gpD({r?Xw_TkI2Jo1wW5CI}U1c(3;AOb{y z2oM1xKm>>Y5%>rMvUb)g&a*#Si;Uy@|9@d0u-~#@v7fP@uphG@uOvB%6~UuAdM zHTD^{!Z-}12N56wM1Tko0U|&IhyW2F0z`la5P?^aK>0-0T5c!Gb5<{v7iV&_e0(N1 z%ExAMy>c{bosMM`tDv`fslpDlnw5nEtwv@3K&xJ=WUZ4>$--T|RGLf0W~rQtjZ!HU z>xE+0T5{T}mkNc6&@AL9LZgtI2=(HTtW^~QwR#DHQZ`bvn3?u9;Qjx})q0uz3GV;T zSnQwduk82iUG_uvJ@#$3$u6^1c80yre$9T)e#*Yae74KB+4d_KVp>Y5g-CYfCvx)%bLqB+td616Z>*=abIp6- z*^~C<{=YI4n{zXUs%VA&n)&H`#$Tk*B0Jec(ibK{&D4Bl^<2^&i#GvcXRI)pUpj)>ldHx z|D(hp0z`la5CI}U1c<=@nZU=ZIcvFA8VTN0p%=R<;_xG&hIbT0`J#8Nb5FPJE6QtY zens?pDu}k?b2z{e0hA5bNyOVpqyi{9zQV7E+R-b#2Q|ZcTqiLf=_KTi*5Mj|pc5X& zasY+3W6fh%@=yzBg^R%9s*59GU~n#mTHr9qOzcVtMaN-iD8Xc)c|XuYR6WElGX;t- zyD@J|9u4In=DOSEvCe|yOVwT5xU-e2g}KJq79Z-wb2wDb1~sNmc`pI?VV3=em zZ`5wtH-$6eH-smgP)Tn`N?Z^c(ylek3|TPOLcfq^?I5BX`-z0+d9M%U{i|F8?Es#NG`$< z_(V`2{Gog&cDB@ia%Ao{9#;Y_< zA=|^g45G|y^Pr?TQF7bBi#2G0?JyK!_e|!?mAth)KAUp72g_e3%o$f$xMH1b1q;vo`Zde~ofdu*HO6lR?NlS;G^Vz9= z3}%FYVVn=q?1%*P;3PkZ;LIAj$~XgwKY}n$RrG)>oF))l&@0U$mf0>KsKxZq+2C#h zU&!EaUj%@{HTY_l$02cKLu$n50v*5ddy?)iJ>poA5p zs>$i10`L>F1lO~|Z^6-Q&Pilx&SE^?;Ua{yt9tleJL=Ee$>puu*gkZ8ZDJzfvQ1d< z$bf?@g0D`1qmaWlL}0A(@;+z|wqqTRGS`p53(wo>y001jW{2Yu3J1E`oqNJlBEa^H zFnlQm08D~GDB$>TG8eO;=YDCLXmZpfai2uJq0_QFa##cPvn_1uj H0wezoKCWn4 literal 0 HcmV?d00001 diff --git a/data/migrations/20190211125952_bootstrap.js b/data/migrations/20190211125952_bootstrap.js new file mode 100644 index 000000000..4f29cf844 --- /dev/null +++ b/data/migrations/20190211125952_bootstrap.js @@ -0,0 +1,25 @@ +exports.up = function (knex) { + return knex.schema + .createTable('hubs', tbl => { + tbl.increments(); + tbl.string('name').notNullable().unique(); + }) + .createTable('messages', tbl => { + tbl.increments(); + tbl.string('sender').notNullable(); + tbl.text('text').notNullable(); + tbl.integer('hub_id') + .unsigned() + .notNullable() + .references('id') + .inTable('hubs') + .onDelete('CASCADE') + .onUpdate('CASCADE'); + }); +}; + +exports.down = function (knex) { + return knex.schema + .dropTableIfExists('messages') + .dropTableIfExists('hubs'); +}; diff --git a/data/seeds/000-cleanup.js b/data/seeds/000-cleanup.js new file mode 100644 index 000000000..825dbfd6d --- /dev/null +++ b/data/seeds/000-cleanup.js @@ -0,0 +1,8 @@ +const cleaner = require('knex-cleaner'); + +exports.seed = function(knex) { + return cleaner.clean(knex, { + mode: 'truncate', + ignoreTables: ['knex_migrations', 'knex_migrations_lock'], + }); +}; diff --git a/data/seeds/001-hubs.js b/data/seeds/001-hubs.js new file mode 100644 index 000000000..5ba7ec29b --- /dev/null +++ b/data/seeds/001-hubs.js @@ -0,0 +1,24 @@ +exports.seed = function(knex, Promise) { + return knex('hubs').insert([ + { name: 'api-1' }, // 1 + { name: 'api-2' }, // 2 + { name: 'api-3' }, // 3 + { name: 'api-4' }, // 4 + { name: 'db-1' }, // 5 + { name: 'db-2' }, // 6 + { name: 'db-3' }, // 7 + { name: 'db-4' }, // 8 + { name: 'auth-1' }, // 9 + { name: 'auth-2' }, // 10 + { name: 'auth-3' }, // 11 + { name: 'auth-4' }, // 12 + { name: 'testing-1' }, // 13 + { name: 'testing-2' }, // 14 + { name: 'testing-3' }, // 15 + { name: 'testing-4' }, // 16 + { name: 'build-1' }, // 17 + { name: 'build-2' }, // 18 + { name: 'build-3' }, // 19 + { name: 'build-4' }, // 20 + ]); +}; diff --git a/data/seeds/002-messages.js b/data/seeds/002-messages.js new file mode 100644 index 000000000..3b9491f23 --- /dev/null +++ b/data/seeds/002-messages.js @@ -0,0 +1,110 @@ +exports.seed = function (knex) { + return knex('messages').insert([ + { + sender: 'Frodo', + text: 'Go back Sam, I am goin gto Mordor alone', + hub_id: 1, + }, + { + sender: 'Sam', + text: 'Of course you are, and I am coming with you', + hub_id: 1, + }, + { + sender: 'Boromir', + text: 'One does nto simply walk into Mordor', + hub_id: 1, + }, + { + sender: 'Aragorn', + text: 'Deeds will not be less valiant because they are unpraised', + hub_id: 2, + }, + { + sender: 'Lady Galadriel', + text: 'Even the smallest person can change the course of history', + hub_id: 2, + }, + { + sender: 'Sam', + text: "There is some good in this world, Mr. Frodo... and it's worth figting for", + hub_id: 2, + }, + { + sender: 'Aragorn', + text: 'A hunted man sometimes wearies of distrust and longs for friendship', + hub_id: 2, + }, + { + sender: 'Lord Elrond', + text: 'Yet such is oft the course of deeds that move the wheels of the world: small hands do them because the must, while the eyes of the great are elsewhere', + hub_id: 2, + }, + { + sender: 'Boromir', + text: 'It is a strange fate that we should suffer so much fear and doubt over so small a thing... such a little thing', + hub_id: 2, + }, + { + sender: 'Gandalf', + text: 'He that breaks a thing to find out what it is, has left the path of wisdom', + hub_id: 2, + }, + { + sender: 'Gandalf', + text: 'All we have to decide is what to do with the time that is given us', + hub_id: 2, + }, + { + sender: 'Gandalf', + text: 'The burned hand teaches best. After that advice about fire goes to the heart', + hub_id: 2, + }, + { sender: 'Gimli', text: 'Never toss a dwarf!', hub_id: 2 }, + { + sender: 'Gimli', + text: 'Faithless is he that says farewell when the road darkens', + hub_id: 2, + }, + { + sender: 'Arwen', + text: 'Your time will come. You will face the same Evil, and you will defeat it', + hub_id: 3, + }, + { + sender: 'Gandalf', + text: 'A wizard is never late, Frodo Baggins. Nor is he early. He arrives precisely when he means to', + hub_id: 3, + }, + { + sender: 'Sam', + text: "It's the job that's never started as takes longest to finish", + hub_id: 3, + }, + { + sender: 'Frodo', + text: 'I will take the Ring, though I do not know the way', + hub_id: 3, + }, + { + sender: 'Lady Galadriel', + text: 'Seeing is both good and perilous', + hub_id: 3, + }, + { + sender: 'Aragorn', + text: 'It is but a shadow and a thought that you love. I cannot give you what you seek', + hub_id: 3, + }, + { + sender: 'Frodo', + text: "I don't know and I would rather not guess", + hub_id: 3, + }, + { + sender: 'Bilbo Baggins', + text: "It's a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there's no knowing where you might be swept off to", + hub_id: 3, + }, + ]); +}; diff --git a/index.js b/index.js new file mode 100644 index 000000000..189be41a3 --- /dev/null +++ b/index.js @@ -0,0 +1,7 @@ +const server = require('./api/server.js'); + +const port = 9000; + +server.listen(port, () => { + console.log(`\n*** Server Running on http://localhost:${port} ***\n`); +}); diff --git a/knexfile.js b/knexfile.js new file mode 100644 index 000000000..f297a2bf1 --- /dev/null +++ b/knexfile.js @@ -0,0 +1,21 @@ +module.exports = { + development: { + client: 'sqlite3', + connection: { + filename: './data/hubs.db3', + }, + useNullAsDefault: true, + pool: { + afterCreate: (conn, done) => { + // runs after a connection is made to the sqlite engine + conn.run('PRAGMA foreign_keys = ON', done); + }, + }, + migrations: { + directory: './data/migrations', + }, + seeds: { + directory: './data/seeds', + }, + }, +};