Skip to content
Open
7 changes: 3 additions & 4 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true,
"node": true,
"jest": true
"es2021": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": "latest"
"ecmaVersion": 13
},
"rules": {
}
Expand Down
69 changes: 62 additions & 7 deletions api/cars/cars-middleware.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,70 @@
const checkCarId = (req, res, next) => {
// DO YOUR MAGIC
const Car = require('./cars-model')
const vin = require('vin-validator')

const checkCarId = async (req, res, next) => {
try{
const car = await Car.getById(req.params.id)
if(!car) {
next({status: 404, message: 'not found'})
}else {
req.car = car
next()
}
} catch (error) {
next(error)
}
}

const checkCarPayload = (req, res, next) => {
// DO YOUR MAGIC
if(!req.body.vin) return next({
status:400,
message: 'vin is missing'
})
if(!req.body.make) return next({
status:400,
message: 'make is missing'
})
if(!req.body.model) return next({
status:400,
message: 'model is missing'
})
if(!req.body.mileage) return next({
status:400,
message: 'mileage is missing'
})
next()
}

const checkVinNumberValid = (req, res, next) => {
// DO YOUR MAGIC
const checkVinNumberValid = async (req, res, next) => {
if(vin.validate(req.body.vin)){
next()
}else{
next({
status: 400,
message: `vin ${req.body.vin} is invalid`
})
}

}

const checkVinNumberUnique = (req, res, next) => {
// DO YOUR MAGIC
const checkVinNumberUnique = async (req, res, next) => {
try{
const existing = await Cars.getByVin(req.body.vin)
if(!existing){
next()
}else{
next({
status: 400,
message: `vin ${req.body.vin} already exists`
})
}
}catch (err){
next(err)
}
}
module.exports = {
checkCarId,
checkCarPayload,
checkVinNumberUnique,
checkVinNumberValid,
}
22 changes: 18 additions & 4 deletions api/cars/cars-model.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
const db = require('../../data/db-config')

const getAll = () => {
// DO YOUR MAGIC
return db('cars')
}

const getById = (id) => {
return db('cars').where('id', id).first()
}

const getById = () => {
// DO YOUR MAGIC
const getByVin = (vin) => {
return db('cars').where('vin', vin).first()
}

const create = () => {
// DO YOUR MAGIC
return db('cars').insert(car).then(([id]) => {
return getById(id)
})
}
module.exports = {
getAll,
getById,
create,
getByVin,
}
43 changes: 43 additions & 0 deletions api/cars/cars-router.js
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
// DO YOUR MAGIC
const router = require('express').Router()
const Car = require('./cars-model')
const {
checkCarId,
checkCarPayload,
checkVinNumberUnique,
checkVinNumberValid,
} = require('./cars-middleware')


router.get('/', async (req, res, next) => {
try{
const cars = await Car.getAll()
res.json(cars)
} catch (error) {
next(error)
}
})

router.get('/:id', checkCarId, async (req, res, next) => {
res.json(req.car)
})

router.post('/',
checkCarPayload,
checkVinNumberUnique,
checkVinNumberValid,
async (req, res, next) => {
try{
const newCar = await Car.create(req.body)
res.status(201).json(newCar)
}catch (error) {
next(error)
}
})

router.use((err, req, res, next) => {
res.status(err.status || 500).json({
message: err.message,
stack: err.stack,
});
});
module.exports = router
15 changes: 14 additions & 1 deletion api/server.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
const express = require("express")
const carsRouter = require('./cars/cars-router')

const server = express()

// DO YOUR MAGIC
server.use(express.json())
server.use('/api/cars', carsRouter)

server.use('*', (req, res, next) => {
next({
status: 404,
message: 'not found'
})
})
server.use((err, req, res, next) => { // eslint-diable-line
res.status(err.status || 500).json({
message: err.message
})
})
module.exports = server
Binary file added data/dealer.db3
Binary file not shown.
10 changes: 10 additions & 0 deletions data/migrations/01-make_cars_table.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
exports.up = function (knex) {
// DO YOUR MAGIC
return knex.schema.createTable('cars', (table) => {
table.increments()
table.string('vin', 16).notNullable().unique()
table.string('make', 128).notNullable()
table.string('model', 256).notNullable()
table.integer('mileage').unsigned().notNullable()
table.string('title', 128)
table.string('transmision', 128)
})
};

exports.down = function (knex) {
// DO YOUR MAGIC
return knex.schema.dropTableIfExists('cars')
};
29 changes: 28 additions & 1 deletion data/seeds/01-cars.js
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
// STRETCH
const cars = [
{
vin: 'JTEBU11F670058710',
make: 'toyota',
model: 'yaris',
mileage: 246000,
title: 'clean',
transmision: 'manual'
},
{
vin: '1D7HA18287S191814',
make: 'jeep',
model: 'grand cherokee',
mileage: 115000,
title: 'clean',
},
{
vin: '5UXXW3C58F0M65560',
make: 'ford',
model: 'bronco',
mileage: 250000,
}
]

exports.seed = async function(knex){
await knex('cars').truncate()
await knex('cars').insert(cars)
}
14 changes: 12 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
"main": "index.js",
"scripts": {
"server": "nodemon index.js",
"test": "cross-env NODE_ENV=testing jest --verbose --runInBand"
"test": "cross-env NODE_ENV=testing jest --verbose --runInBand",
"migrate": "knex migrate:latest",
"rollback": "knex migrate:rollback",
"migup": "knex migrate:up",
"migdown": "knex migrate:down",
"seed": "knex seed:run"
},
"devDependencies": {
"@types/jest": "^27.0.2",
Expand All @@ -17,7 +22,8 @@
"dependencies": {
"express": "^4.17.1",
"knex": "^0.95.11",
"sqlite3": "^5.0.2"
"sqlite3": "^5.0.2",
"vin-validator": "^1.0.0"
},
"repository": {
"type": "git",
Expand Down