-
Notifications
You must be signed in to change notification settings - Fork 452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eric Whitcomb #481
base: master
Are you sure you want to change the base?
Eric Whitcomb #481
Changes from all commits
0a8301d
bbd3d3d
cf282f2
47d72a9
57d3439
6b4c5e1
31a3226
45256ea
d0c3364
4b4969f
530bda4
338e34c
2fcc016
931649a
680b54a
0c4db34
e925484
a3e7ca0
dd56ca6
5febded
a61812e
5904eef
e35ad70
e587316
0a40529
115ae3f
2b7af4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
node_modules | ||
.DS_Store | ||
.vscode | ||
.env |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
const express = require('express'); | ||
const noteModel = require('../data/models/noteModel'); | ||
const router = express.Router(); | ||
|
||
router.post('/', async (req, res) => { | ||
const note = req.body; | ||
if (note.title && note.content) { | ||
res.status(201).json(await noteModel.insert(note)); | ||
} else { | ||
res.status(400).json({ error: 'Note must contain title and content' }); | ||
} | ||
}); | ||
|
||
router.get('/', async (req, res) => { | ||
const note = await noteModel.get() | ||
res.status(200).json(note); | ||
}); | ||
|
||
router.get('/:id', async (req, res) => { | ||
try { | ||
const note = await noteModel.get(req.params.id); | ||
res.status(200).json(note); | ||
} catch (e) { | ||
res.status(404).json({error: "Invalid id"}); | ||
} | ||
}); | ||
|
||
router.put('/:id', async (req, res) => { | ||
try { | ||
const note = await noteModel.update(req.params.id, req.body); | ||
res.status(200).json(note); | ||
} catch (e) { | ||
res.status(404).json({error: "Invalid id"}); | ||
} | ||
|
||
}); | ||
|
||
router.delete('/:id', async (req, res) => { | ||
try { | ||
const count = await noteModel.remove(req.params.id); | ||
res.status(200).json({ count }); | ||
} catch (e) { | ||
res.status(404).json({error: "Invalid id"}); | ||
} | ||
}); | ||
|
||
module.exports = router; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const express = require('express'); | ||
const router = express.Router(); | ||
|
||
router.use('/notes', require('./noteRouter')); | ||
|
||
router.get('/', (req, res) => { | ||
res.json({api: "active"}); | ||
}); | ||
|
||
module.exports = router; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
const express = require('express'); | ||
var cors = require('cors'); | ||
const app = express(); | ||
|
||
app.use(express.json()); | ||
app.use(cors()); | ||
app.use('/api', require('./api/rootRouter')); | ||
|
||
const PORT = process.env.PORT || '3300'; | ||
|
||
app.get('/', (req, res) => { | ||
res.status(200).send(`API active on port: ${PORT}`); | ||
}); | ||
|
||
module.exports = app; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
const knex = require('knex'); | ||
const config = require('../knexfile.js'); | ||
|
||
const dbEnv = process.env.DB_ENV || 'development'; | ||
|
||
module.exports = knex(config[dbEnv]); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
exports.up = function(knex, Promise) { | ||
return knex.schema.createTable('notes', (notes) => { | ||
notes.increments(); | ||
notes.string('title').notNullable(); | ||
notes.text('content').notNullable(); | ||
}); | ||
}; | ||
|
||
exports.down = function(knex, Promise) { | ||
return knex.schema.dropTableIfExists('notes'); | ||
}; |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,138 @@ | ||||||
const db = require('../dbConfig.js'); | ||||||
|
||||||
const get = async (id) => { | ||||||
if (id) { | ||||||
const note = await db('notes').where('id', id); | ||||||
if (note.length) { | ||||||
return note[0]; | ||||||
} else { | ||||||
const e = new Error("id does not exist"); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be easiest just to do this all on one line
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then you won't need the next two lines |
||||||
e.name = "InvalidID"; | ||||||
throw e; | ||||||
} | ||||||
} | ||||||
|
||||||
const notes = await db('notes'); | ||||||
return notes; | ||||||
}; | ||||||
|
||||||
const insert = async (note) => { | ||||||
|
||||||
// check for missing note object | ||||||
if (typeof note === 'undefined') { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think you need this check 🤔 is there ever a case where this would happen? |
||||||
const e = new Error("note object"); | ||||||
e.name = "MissingParam"; | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check if note is object | ||||||
if (typeof note !== 'object') { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for this. Would this ever not be an object? |
||||||
const e = new TypeError("note is not an object"); | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check for missing title key | ||||||
if (!note.hasOwnProperty('title')) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since
Suggested change
Side Note: Now if it something like
|
||||||
const e = new Error("title"); | ||||||
e.name = "MissingKey"; | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check for missing content key | ||||||
if (!note.hasOwnProperty('content')) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
const e = new Error("content"); | ||||||
e.name = "MissingKey"; | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check for title not string | ||||||
if (typeof note.title !== 'string') { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this will always be a string. Even if the user types in a number like |
||||||
const e = new TypeError("'title' value must be string"); | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check for content not string | ||||||
if (typeof note.content !== 'string') { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing here |
||||||
const e = new TypeError("'content' value must be string"); | ||||||
throw e; | ||||||
} | ||||||
|
||||||
const ids = await db('notes').insert(note, 'id'); | ||||||
const n = await get(ids[0]); | ||||||
return n; | ||||||
}; | ||||||
|
||||||
const update = async (id, note) => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing as above. Double check to make sure you aren't making unnecessary checks |
||||||
|
||||||
// check for missing id | ||||||
if (typeof id === 'undefined') { | ||||||
const e = new Error("note id"); | ||||||
e.name = "MissingParam"; | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check for missing note object | ||||||
if (typeof note === 'undefined') { | ||||||
const e = new Error("note object"); | ||||||
e.name = "MissingParam"; | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check if note is object | ||||||
if (typeof note !== 'object') { | ||||||
const e = new TypeError("note is not an object"); | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check for empty note object | ||||||
if (!note.hasOwnProperty('title') && !note.hasOwnProperty('content')) { | ||||||
const e = new Error("note object missing 'title' and 'content'"); | ||||||
e.name = "EmptyObject"; | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check for title not string | ||||||
if (note.hasOwnProperty('title') && typeof note.title !== 'string') { | ||||||
const e = new TypeError("'title' value must be string"); | ||||||
throw e; | ||||||
} | ||||||
|
||||||
// check for content not string | ||||||
if (note.hasOwnProperty('content') && typeof note.content !== 'string') { | ||||||
const e = new TypeError("'content' value must be string"); | ||||||
throw e; | ||||||
} | ||||||
|
||||||
const count = await db('notes').where('id', id).update(note); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a good time to have a `try/catch block to organize your code
|
||||||
if (count) { | ||||||
const n = await get(id); | ||||||
return n; | ||||||
} else { | ||||||
const e = new Error("id does not exist"); | ||||||
e.name = "InvalidID"; | ||||||
throw e; | ||||||
} | ||||||
}; | ||||||
|
||||||
const remove = async (id) => { | ||||||
|
||||||
// check for missing id | ||||||
if (typeof id === 'undefined') { | ||||||
const e = new Error("note id"); | ||||||
e.name = "MissingParam"; | ||||||
throw e; | ||||||
} | ||||||
|
||||||
const count = await db('notes').where('id', id).del(); | ||||||
if (count) { | ||||||
return count; | ||||||
} else { | ||||||
const e = new Error("id does not exist"); | ||||||
e.name = "InvalidID"; | ||||||
throw e; | ||||||
} | ||||||
}; | ||||||
|
||||||
module.exports = { | ||||||
insert, get, update, remove | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Update with your config settings. | ||
|
||
const localPgConnection = { | ||
host: 'localhost', | ||
database: 'prod', | ||
user: 'notes', | ||
password: 'blah1234', | ||
} | ||
|
||
const dbConnection = process.env.DATABASE_URL || localPgConnection; | ||
|
||
module.exports = { | ||
|
||
development: { | ||
client: 'sqlite3', | ||
connection: { | ||
filename: './data/dev.sqlite3' | ||
}, | ||
useNullAsDefault: true, | ||
migrations: { | ||
directory: './data/migrations', | ||
}, | ||
seeds: { | ||
directory: './data/seeds', | ||
}, | ||
}, | ||
|
||
production: { | ||
client: 'pg', | ||
connection: dbConnection, | ||
pool: { | ||
min: 2, | ||
max: 10 | ||
}, | ||
migrations: { | ||
directory: './data/migrations', | ||
}, | ||
seeds: { | ||
directory: './data/seeds', | ||
}, | ||
}, | ||
|
||
testing: { | ||
client: 'sqlite3', | ||
connection: { | ||
filename: './data/test.sqlite3' | ||
}, | ||
useNullAsDefault: true, | ||
migrations: { | ||
directory: './data/migrations', | ||
}, | ||
seeds: { | ||
directory: './data/seeds', | ||
}, | ||
}, | ||
|
||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"name": "back-end-project-week", | ||
"version": "1.0.0", | ||
"main": "server.js", | ||
"repository": "https://github.com/ericwhitcomb/back-end-project-week.git", | ||
"author": "Eric Whitcomb <[email protected]>", | ||
"license": "MIT", | ||
"dependencies": { | ||
"cors": "^2.8.5", | ||
"dotenv": "^6.2.0", | ||
"express": "^4.16.4", | ||
"knex": "^0.16.3", | ||
"passport": "^0.4.0", | ||
"passport-github2": "^0.1.11", | ||
"pg": "^7.8.0", | ||
"sqlite3": "^4.0.6" | ||
}, | ||
"devDependencies": { | ||
"cross-env": "^5.2.0", | ||
"jest": "^24.1.0", | ||
"nodemon": "^1.18.10", | ||
"supertest": "^3.4.2" | ||
}, | ||
"scripts": { | ||
"server": "nodemon server.js", | ||
"test": "cross-env DB_ENV=testing jest --watch --verbose" | ||
}, | ||
"jest": { | ||
"testEnvironment": "node" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require('dotenv').config(); | ||
|
||
const app = require('./app'); | ||
|
||
const PORT = process.env.PORT || '3300'; | ||
|
||
app.listen(PORT, () => { | ||
console.log(`\nListening on port ${PORT}\n`); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure you can use
.first()
? instead of having that if statement