diff --git a/database/connection.js b/database/bookshelf.js similarity index 100% rename from database/connection.js rename to database/bookshelf.js diff --git a/index.js b/index.js index a6b9cc1..4ae5ffd 100644 --- a/index.js +++ b/index.js @@ -8,7 +8,7 @@ const morgan = require('morgan') const cors = require('cors') // module to format the json response // Creates instances of database connections -const connection = require('./database/connection') +const connection = require('./database/bookshelf') const db = connection.db // CONSTANTS @@ -30,4 +30,7 @@ const server = app.listen( port, () => {console.log(`App listening on port ${por // Routing app.use('/api/spells', routes.spells) app.use('/api/schools', routes.schools) -app.use('/api/users', routes.users) \ No newline at end of file +app.use('/api/meta_schools', routes.meta_schools) +app.use('/api/variables', routes.variables) +app.use('/api/ingredients', routes.ingredients) +app.use('/api/users', routes.users) diff --git a/models/ingredient-model.js b/models/ingredient-model.js new file mode 100644 index 0000000..cdb8ded --- /dev/null +++ b/models/ingredient-model.js @@ -0,0 +1,13 @@ +'use strict' +const bookshelf = require('../database/bookshelf').bookshelf + +require('./spell-model') + +let Ingredient = bookshelf.Model.extend({ + tableName: 'ingredient', + spells() { + return this.belongsToMany( 'Spell', 'spell_ingredient') + } +}) + +module.exports = bookshelf.model('Ingredient', Ingredient) \ No newline at end of file diff --git a/models/meta-school-model.js b/models/meta-school-model.js new file mode 100644 index 0000000..e52ea7e --- /dev/null +++ b/models/meta-school-model.js @@ -0,0 +1,13 @@ +'use strict' +const bookshelf = require('../database/bookshelf').bookshelf + +require('./school-model') + +let MetaSchool = bookshelf.Model.extend({ + tableName: 'meta_school', + schools() { + return this.hasMany( 'School' ) + } +}) + +module.exports = bookshelf.model('MetaSchool', MetaSchool) \ No newline at end of file diff --git a/models/school-model.js b/models/school-model.js new file mode 100644 index 0000000..2d3ef63 --- /dev/null +++ b/models/school-model.js @@ -0,0 +1,17 @@ +'use strict' +const bookshelf = require('../database/bookshelf').bookshelf + +require('./spell-model') +require('./meta-school-model') + +let School = bookshelf.Model.extend({ + tableName: 'school', + spells() { + return this.belongsToMany( 'Spell', 'spell_school') + }, + meta_schools() { + return this.belongsTo( 'MetaSchool', 'meta_school_id') + } +}) + +module.exports = bookshelf.model('School', School) \ No newline at end of file diff --git a/models/spell-model.js b/models/spell-model.js new file mode 100644 index 0000000..96100a5 --- /dev/null +++ b/models/spell-model.js @@ -0,0 +1,21 @@ +'use strict' +const bookshelf = require('../database/bookshelf').bookshelf + +require('./school-model') +require('./variable-model') +require('./ingredient-model') + +let Spell = bookshelf.Model.extend({ + tableName: 'spell', + schools() { + return this.belongsToMany( 'School', 'spell_school' ) + }, + variables() { + return this.belongsToMany( 'Variable', 'spell_variable' ) + }, + ingredients() { + return this.belongsToMany( 'Ingredient', 'spell_ingredient' ) + } +}) + +module.exports = bookshelf.model('Spell', Spell) \ No newline at end of file diff --git a/models/user-model.js b/models/user-model.js new file mode 100644 index 0000000..60b5c64 --- /dev/null +++ b/models/user-model.js @@ -0,0 +1,8 @@ +'use strict' +const bookshelf = require('../database/bookshelf').bookshelf + +let User = bookshelf.Model.extend({ + tableName: 'user', +}) + +module.exports = bookshelf.model('User', User) \ No newline at end of file diff --git a/models/variable-model.js b/models/variable-model.js new file mode 100644 index 0000000..ba020c9 --- /dev/null +++ b/models/variable-model.js @@ -0,0 +1,13 @@ +'use strict' +const bookshelf = require('../database/bookshelf').bookshelf + +require('./spell-model') + +let Variable = bookshelf.Model.extend({ + tableName: 'variable', + spells() { + return this.belongsToMany( 'Spell', 'spell_variable') + } +}) + +module.exports = bookshelf.model('Variable', Variable) \ No newline at end of file diff --git a/repositories/ingredient-repository.js b/repositories/ingredient-repository.js index 285d539..a24a30f 100644 --- a/repositories/ingredient-repository.js +++ b/repositories/ingredient-repository.js @@ -1,27 +1,55 @@ 'use strict' // Bookshelf -const bookshelf = require('../database/connection').bookshelf +const bookshelf = require('../database/bookshelf').bookshelf +const model = require('../models/ingredient-model') -const Spells = require('./spell-repository') +// Model validation +const Validator = require('jsonschema').Validator +const v = new Validator() +const IngredientValidation = require("../validations/IngredientValidation") +v.addSchema(IngredientValidation, "/IngredientValidation") + +// Validations +const regexXSS = RegExp(/<[^>]*script/) + +// Error handling +const { HttpError } = require('../validations/Errors') class IngredientRepository { constructor() { - this.model = bookshelf.Model.extend({ - tableName: 'ingredient', - spells() { - return this.belongsToMany( Spells._model, 'spell_ingredient', 'ingredient_id', 'spell_id') - } + } + + getAll() { + return new Promise((resolve, reject) => { + model.forge() + .fetchAll({ withRelated: ['spells'] }) + .then(v => { + resolve(v.toJSON({ omitPivot: true })) + }) + .catch(err => { + console.log(err) + reject(new HttpError(500, "Couldn't get ingredients")) + }) }) } - set model(model) { - this._model = model + + getOne(id) { + return new Promise((resolve, reject) => { + model.forge() + .where({ 'id' : id }) + .fetch({ withRelated: ['spells']}) + .then(v => { + resolve(v.toJSON({ omitPivot: true })) + }) + .catch(err => { + console.log(err) + reject(new HttpError(500, "Couldn't get ingredient")) + }) + }) } - get model() { - return this._model - } } module.exports = IngredientRepository \ No newline at end of file diff --git a/repositories/meta-school-repository.js b/repositories/meta-school-repository.js index c8f8960..f2eb7bc 100644 --- a/repositories/meta-school-repository.js +++ b/repositories/meta-school-repository.js @@ -1,27 +1,72 @@ 'use strict' // Bookshelf -const bookshelf = require('../database/connection').bookshelf +const bookshelf = require('../database/bookshelf').bookshelf +const model = require('../models/meta-school-model') -const Schools = require('./school-repository') +// Model validation +const Validator = require('jsonschema').Validator +const v = new Validator() +const MetaSchoolValidation = require("../validations/MetaSchoolValidation") +v.addSchema(MetaSchoolValidation, "/MetaSchoolValidation") + +// Validations +const regexXSS = RegExp(/<[^>]*script/) + +// Error handling +const { HttpError } = require('../validations/Errors') class MetaSchoolRepository { constructor() { - this.model = bookshelf.Model.extend({ - tableName: 'meta_school', - schools() { - return this.hasMany( Schools._model ) - } + } + + getAll() { + return new Promise((resolve, reject) => { + model.forge() + .fetchAll({ withRelated: ['schools'] }) + .then(v => { + resolve(v.toJSON({ omitPivot: true })) + }) + .catch(err => { + console.log(err) + reject(new HttpError(500, "Couldn't get meta schools")) + }) }) } - set model(model) { - this._model = model + getOne(id) { + return new Promise((resolve, reject) => { + model.forge() + .where({ 'id' : id }) + .fetch({ withRelated: ['schools']}) + .then(v => { + resolve(v.toJSON({ omitPivot: true })) + }) + .catch(err => { + console.log(err) + reject(new HttpError(500, "Couldn't get meta school")) + }) + }) } - get model() { - return this._model + // Check if object is null + isEmptyObject = (obj) => { + if (Object.keys(obj).length === 0 && obj.constructor === Object) { + return true + } else { + return false + } } + + // Check if script injection attempt + isXSSAttempt = (string) => { + if (regexXSS.test(string)) { + return true + } else { + return false + } + } + } module.exports = MetaSchoolRepository \ No newline at end of file diff --git a/repositories/school-repository.js b/repositories/school-repository.js index 477d45b..2ffa311 100644 --- a/repositories/school-repository.js +++ b/repositories/school-repository.js @@ -1,49 +1,28 @@ 'use strict' // Bookshelf -const bookshelf = require('../database/connection').bookshelf - -const Spells = require('./spell-repository') - -const MetaSchoolRepository = require('./meta-school-repository') -const MetaSchools = new MetaSchoolRepository() +const bookshelf = require('../database/bookshelf').bookshelf +const model = require('../models/school-model') // Model validation const Validator = require('jsonschema').Validator const v = new Validator() -const SchoolModel = require("../models/SchoolValidation") -v.addSchema(SchoolModel, "/SchoolModel") +const SchoolValidation = require("../validations/SchoolValidation") +v.addSchema(SchoolValidation, "/SchoolValidation") // Validations const regexXSS = RegExp(/<[^>]*script/) // Error handling -const { HttpError } = require('../models/Errors') +const { HttpError } = require('../validations/Errors') class SchoolRepository { constructor() { - this.model = bookshelf.Model.extend({ - tableName: 'school', - spells() { - return this.belongsToMany( Spells._model, 'spell_school', 'school_id', 'spell_id') - }, - meta_schools() { - return this.belongsTo( MetaSchools._model, 'meta_school_id') - } - }) - } - - set model(model) { - this._model = model - } - - get model() { - return this._model } getAll() { return new Promise((resolve, reject) => { - this._model.forge() + model.forge() .fetchAll({ withRelated: ['meta_schools'] }) .then(v => { resolve(v.toJSON({ omitPivot: true })) @@ -57,7 +36,7 @@ class SchoolRepository { getOne(id) { return new Promise((resolve, reject) => { - this._model.forge() + model.forge() .where({ 'id' : id }) .fetch({ withRelated: ['meta_schools']}) .then(v => { @@ -75,13 +54,13 @@ class SchoolRepository { // Checks if body exists and if the model fits, and throws errors if it doesn't if (this.isEmptyObject(s)) { reject(new HttpError(403, "Error: School cannot be nothing !")) - } else if (!v.validate(s, SchoolModel).valid) { - reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SchoolModel).errors)) + } else if (!v.validate(s, SchoolValidation).valid) { + reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SchoolValidation).errors)) } else if (this.isXSSAttempt(s.name) || this.isXSSAttempt(s.description)) { reject(new HttpError(403, 'Injection attempt detected, aborting the request.')) } else { bookshelf.transaction(t => { - return this._model.forge({ + return model.forge({ 'name': s.name, 'description': s.description, 'meta_school_id': s.meta_school_id, @@ -111,12 +90,12 @@ class SchoolRepository { // Checks if body exists and if the model fits, and throws errors if it doesn't if (this.isEmptyObject(s)) { reject(new HttpError(403, "Error: School cannot be nothing !")) - } else if (!v.validate(s, SchoolModel).valid) { - reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SchoolModel).errors)) + } else if (!v.validate(s, SchoolValidation).valid) { + reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SchoolValidation).errors)) } else if (this.isXSSAttempt(s.name) || this.isXSSAttempt(s.description)) { reject(new HttpError(403, 'Injection attempt detected, aborting the request.')) } else { - this._model.forge({id: id}) + model.forge({id: id}) .fetch({require: true, withRelated: ['meta_schools']}) .then(v => { bookshelf.transaction(t => { @@ -154,11 +133,12 @@ class SchoolRepository { deleteOne(id) { return new Promise((resolve, reject) => { - this._model.forge() + model.forge() .where({ 'id' : id }) .fetch({require: true, withRelated: ['spells', 'meta_schools']}) .then(v => { - + v.spells().detach() + v.destroy() }) .then(() => { resolve({ diff --git a/repositories/spell-repository.js b/repositories/spell-repository.js index b49ac45..cc14d8f 100644 --- a/repositories/spell-repository.js +++ b/repositories/spell-repository.js @@ -1,57 +1,28 @@ 'use strict' - // Bookshelf -const bookshelf = require('../database/connection').bookshelf - -const SchoolRepository = require('./school-repository') -const Schools = new SchoolRepository() - -const IngredientRepository = require('./ingredient-repository') -const Ingredients = new IngredientRepository() - -const VariableRepository = require('./variable-repository') -const Variables = new VariableRepository() +const bookshelf = require('../database/bookshelf').bookshelf +const model = require('../models/spell-model') // Model validation const Validator = require('jsonschema').Validator const v = new Validator() -const SpellModel = require("../models/SpellValidation") -v.addSchema(SpellModel, "/SpellModel") +const SpellValidation = require("../validations/SpellValidation") +v.addSchema(SpellValidation, "/SpellValidation") // Validations const regexXSS = RegExp(/<[^>]*script/) // Error handling -const { HttpError } = require('../models/Errors') +const { HttpError } = require('../validations/Errors') class SpellRepository { constructor() { - this.model = bookshelf.Model.extend({ - tableName: 'spell', - schools() { - return this.belongsToMany( Schools._model, 'spell_school', 'spell_id', 'school_id' ) - }, - variables() { - return this.belongsToMany( Variables._model, 'spell_variable', 'spell_id', 'variable_id' ) - }, - ingredients() { - return this.belongsToMany( Ingredients._model, 'spell_ingredient', 'spell_id', 'ingredient_id' ) - } - }) - } - - set model(model) { - this._model = model - } - - get model() { - return this._model } getAll() { return new Promise((resolve, reject) => { - this._model.forge() + model.forge() .fetchAll({ withRelated: ['schools.meta_schools', 'variables', 'ingredients'] }) .then(v => { resolve(v.toJSON({ omitPivot: true })) @@ -65,7 +36,7 @@ class SpellRepository { getOne(id) { return new Promise((resolve, reject) => { - this._model.forge() + model.forge() .where({ 'id' : id }) .fetch({ withRelated: ['schools.meta_schools', 'variables', 'ingredients']}) .then(v => { @@ -83,13 +54,13 @@ class SpellRepository { // Checks if body exists and if the model fits, and throws errors if it doesn't if (this.isEmptyObject(s)) { reject(new HttpError(403, "Error: Spell cannot be nothing !")) - } else if (!v.validate(s, SpellModel).valid) { - reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SpellModel).errors)) + } else if (!v.validate(s, SpellValidation).valid) { + reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SpellValidation).errors)) } else if (this.isXSSAttempt(s.name) || this.isXSSAttempt(s.description) || this.isXSSAttempt(s.cost)) { reject(new HttpError(403, 'Injection attempt detected, aborting the request.')) } else { bookshelf.transaction(t => { - return this._model.forge({ + return model.forge({ 'name': s.name, 'description': s.description, 'level': s.level, @@ -143,12 +114,12 @@ class SpellRepository { // Checks if body exists and if the model fits, and throws errors if it doesn't if (this.isEmptyObject(s)) { reject(new HttpError(403, "Error: Spell cannot be nothing !")) - } else if (!v.validate(s, SpellModel).valid) { - reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SpellModel).errors)) + } else if (!v.validate(s, SpellValidation).valid) { + reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SpellValidation).errors)) } else if (this.isXSSAttempt(s.name) || this.isXSSAttempt(s.description) || this.isXSSAttempt(s.cost)) { reject(new HttpError(403, 'Injection attempt detected, aborting the request.')) } else { - this._model.forge({id: id}) + model.forge({id: id}) .fetch({require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients']}) .then(v => { bookshelf.transaction(t => { @@ -231,14 +202,14 @@ class SpellRepository { deleteOne(id) { return new Promise((resolve, reject) => { - this._model.forge() + model.forge() .where({ 'id' : id }) .fetch({require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients']}) .then(v => { - v.schools().detach(); - v.variables().detach(); - v.ingredients().detach(); - v.destroy(); + v.schools().detach() + v.variables().detach() + v.ingredients().detach() + v.destroy() }) .then(() => { resolve({ diff --git a/repositories/user-repository.js b/repositories/user-repository.js index b6d1abc..292e5fa 100644 --- a/repositories/user-repository.js +++ b/repositories/user-repository.js @@ -1,7 +1,7 @@ 'use strict' - // Bookshelf -const bookshelf = require('../database/connection').bookshelf +const bookshelf = require('../database/bookshelf').bookshelf +const model = require('../models/user-model') // Hashing and passwords const bcrypt = require('bcrypt') @@ -9,29 +9,18 @@ const bcrypt = require('bcrypt') // Model validation const Validator = require('jsonschema').Validator const v = new Validator() -const UserModel = require("../models/UserValidation") -v.addSchema(UserModel, "/UserModel") +const UserValidation = require("../validations/UserValidation") +v.addSchema(UserValidation, "/UserValidation") // Validations -const regexInt = RegExp(/^[1-9]\d*$/) const regexXSS = RegExp(/<[^>]*script/) // Error handling -const { HttpError } = require('../models/Errors') +const { HttpError } = require('../validations/Errors') class UserRepository { - constructor() { - this.model = bookshelf.Model.extend({ - tableName: 'user', - }) - } - - set model(model) { - this._model = model - } - get model() { - return this._model + constructor() { } getAll() { diff --git a/repositories/variable-repository.js b/repositories/variable-repository.js index 2be3ca1..549f1ca 100644 --- a/repositories/variable-repository.js +++ b/repositories/variable-repository.js @@ -1,26 +1,47 @@ 'use strict' // Bookshelf -const bookshelf = require('../database/connection').bookshelf +const bookshelf = require('../database/bookshelf').bookshelf +const model = require('../models/variable-model') -const Spells = require('./spell-repository') +// Model validation +const Validator = require('jsonschema').Validator +const v = new Validator() +const VariableValidation = require("../validations/VariableValidation") +v.addSchema(VariableValidation, "/VariableValidation") class VariableRepository { constructor() { - this.model = bookshelf.Model.extend({ - tableName: 'variable', - spells() { - return this.belongsToMany( Spells._model, 'spell_variable', 'variable_id', 'spell_id') - } + } + + getAll() { + return new Promise((resolve, reject) => { + model.forge() + .fetchAll({ withRelated: ['spells'] }) + .then(v => { + resolve(v.toJSON({ omitPivot: true })) + }) + .catch(err => { + console.log(err) + reject(new HttpError(500, "Couldn't get variables")) + }) }) } - set model(model) { - this._model = model - } - - get model() { - return this._model + + getOne(id) { + return new Promise((resolve, reject) => { + model.forge() + .where({ 'id' : id }) + .fetch({ withRelated: ['spells']}) + .then(v => { + resolve(v.toJSON({ omitPivot: true })) + }) + .catch(err => { + console.log(err) + reject(new HttpError(500, "Couldn't get variable")) + }) + }) } } diff --git a/routes/index.js b/routes/index.js index 021e2b2..f2a3aa5 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,9 +1,15 @@ -const users = require('./users') const spells = require('./spells') const schools = require('./schools') +const meta_schools = require('./meta_schools') +const variables = require('./variables') +const ingredients = require('./ingredients') +const users = require('./users') module.exports = { spells, schools, - users + meta_schools, + ingredients, + variables, + users, } \ No newline at end of file diff --git a/routes/ingredients.js b/routes/ingredients.js new file mode 100644 index 0000000..ea5c36d --- /dev/null +++ b/routes/ingredients.js @@ -0,0 +1,90 @@ +'use strict' + +// Router +const express = require('express') +let router = express.Router() + +// Connection +const connection = require('../database/bookshelf') +const db = connection.db + +// Repository +const IngredientRepository = require('../repositories/ingredient-repository'); +const Ingredients = new IngredientRepository(); + +const regexInt = RegExp(/^[1-9]\d*$/) + +// Error handling +const { HttpError } = require('../validations/Errors') + +// ROUTES +// GET ALL ------------------ +const getIngredients = () => { + return Ingredients.getAll() + .catch(err => { + console.log(err) + throw err + }) +} +router.get('/', async (req, res) => { + getIngredients() + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.end(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + + +// GET ONE ------------------ +const getIngredient = (id) => { + return Ingredients.getOne(id) + .catch(err => { + console.log(err) + throw err + }) +} +router.get('/:id/', async (req, res) => { + getIngredient(req.params.id) + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.end(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + +// Param validation for ID +// (check if id is int) (could be refactored) +router.param('id', (req, res, next, id) => { + try { + if (regexInt.test(id)) { + next() + } else { + throw new Error; + } + } catch (err) { + err = new HttpError(403, 'Provided ID must be an integer and not zero') + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + } +}) + +module.exports = router \ No newline at end of file diff --git a/routes/meta_schools.js b/routes/meta_schools.js new file mode 100644 index 0000000..4639c36 --- /dev/null +++ b/routes/meta_schools.js @@ -0,0 +1,91 @@ +'use strict' + +// Router +const express = require('express') +let router = express.Router() + +// Connection +const connection = require('../database/bookshelf') +const db = connection.db + +// Repository +const MetaSchoolRepository = require('../repositories/meta-school-repository'); +const MetaSchools = new MetaSchoolRepository(); + +const regexInt = RegExp(/^[1-9]\d*$/) + +// Error handling +const { HttpError } = require('../validations/Errors') + +// ROUTES +// GET ALL ------------------ +const getMetaSchools = () => { + return MetaSchools.getAll() + .catch(err => { + console.log(err) + throw err + }) +} +router.get('/', async (req, res) => { + getMetaSchools() + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.end(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + + +// GET ONE ------------------ +const getMetaSchool = (id) => { + return MetaSchools.getOne(id) + .catch(err => { + console.log(err) + throw err + }) +} +router.get('/:id/', async (req, res) => { + getMetaSchool(req.params.id) + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.end(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + + +// Param validation for ID +// (check if id is int) (could be refactored) +router.param('id', (req, res, next, id) => { + try { + if (regexInt.test(id)) { + next() + } else { + throw new Error; + } + } catch (err) { + err = new HttpError(403, 'Provided ID must be an integer and not zero') + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + } +}) + +module.exports = router \ No newline at end of file diff --git a/routes/schools.js b/routes/schools.js index 502e303..4b228e0 100644 --- a/routes/schools.js +++ b/routes/schools.js @@ -5,7 +5,7 @@ const express = require('express') let router = express.Router() // Connection -const connection = require('../database/connection') +const connection = require('../database/bookshelf') const db = connection.db // Repository @@ -15,7 +15,7 @@ const Schools = new SchoolRepository(); const regexInt = RegExp(/^[1-9]\d*$/) // Error handling -const { HttpError } = require('../models/Errors') +const { HttpError } = require('../validations/Errors') // ROUTES // GET ALL ------------------ @@ -142,24 +142,23 @@ router.delete('/:id/', async (req, res) => { }) // Param validation for ID - // (check if id is int) (could be refactored) - router.param('id', (req, res, next, id) => { - try { - if (regexInt.test(id)) { - next() - } else { - throw new Error; - } - } catch (err) { - err = new HttpError(403, 'Provided ID must be an integer and not zero') - res.status(err.code).send(JSON.stringify( - { - "error": err.message, - "code": err.code - }) - ) +// (check if id is int) (could be refactored) +router.param('id', (req, res, next, id) => { + try { + if (regexInt.test(id)) { + next() + } else { + throw new Error; } - }) - - module.exports = router - \ No newline at end of file + } catch (err) { + err = new HttpError(403, 'Provided ID must be an integer and not zero') + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + } +}) + +module.exports = router \ No newline at end of file diff --git a/routes/spells.js b/routes/spells.js index f032da8..2d3ea4f 100644 --- a/routes/spells.js +++ b/routes/spells.js @@ -5,7 +5,7 @@ const express = require('express') let router = express.Router() // Connection -const connection = require('../database/connection') +const connection = require('../database/bookshelf') const db = connection.db // Repository @@ -15,7 +15,7 @@ const Spells = new SpellReposity(); const regexInt = RegExp(/^[1-9]\d*$/) // Error handling -const { HttpError } = require('../models/Errors') +const { HttpError } = require('../validations/Errors') // ROUTES // GET ALL ------------------ diff --git a/routes/users.js b/routes/users.js index 26ed9d2..951aab9 100644 --- a/routes/users.js +++ b/routes/users.js @@ -5,7 +5,7 @@ const express = require('express') let router = express.Router() // Connection -const connection = require('../database/connection') +const connection = require('../database/bookshelf') const db = connection.db // Repository @@ -15,7 +15,7 @@ const Users = new UserRepository(); const regexInt = RegExp(/^[1-9]\d*$/) // Error handling -const { HttpError } = require('../models/Errors') +const { HttpError } = require('../validations/Errors') // ROUTES // GET ALL ------------------ diff --git a/routes/variables.js b/routes/variables.js new file mode 100644 index 0000000..1814b18 --- /dev/null +++ b/routes/variables.js @@ -0,0 +1,91 @@ +'use strict' + +// Router +const express = require('express') +let router = express.Router() + +// Connection +const connection = require('../database/bookshelf') +const db = connection.db + +// Repository +const VariableRepository = require('../repositories/variable-repository'); +const Variables = new VariableRepository(); + +const regexInt = RegExp(/^[1-9]\d*$/) + +// Error handling +const { HttpError } = require('../validations/Errors') + +// ROUTES +// GET ALL ------------------ +const getvariables = () => { + return Variables.getAll() + .catch(err => { + console.log(err) + throw err + }) +} +router.get('/', async (req, res) => { + getvariables() + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.end(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + + +// GET ONE ------------------ +const getVariable = (id) => { + return Variables.getOne(id) + .catch(err => { + console.log(err) + throw err + }) +} +router.get('/:id/', async (req, res) => { + getVariable(req.params.id) + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.end(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + + +// Param validation for ID +// (check if id is int) (could be refactored) +router.param('id', (req, res, next, id) => { + try { + if (regexInt.test(id)) { + next() + } else { + throw new Error; + } + } catch (err) { + err = new HttpError(403, 'Provided ID must be an integer and not zero') + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + } +}) + +module.exports = router \ No newline at end of file diff --git a/models/Errors.js b/validations/Errors.js similarity index 100% rename from models/Errors.js rename to validations/Errors.js diff --git a/validations/IngredientValidation.js b/validations/IngredientValidation.js new file mode 100644 index 0000000..7bd1cef --- /dev/null +++ b/validations/IngredientValidation.js @@ -0,0 +1,10 @@ +const Ingredient = { + "id": "/IngredientValidation", + "type": Object, + "properties": { + "name": { "type": "string" }, + }, + "required": ["name"] +} + +module.exports = Ingredient \ No newline at end of file diff --git a/validations/MetaSchoolValidation.js b/validations/MetaSchoolValidation.js new file mode 100644 index 0000000..0bbcf23 --- /dev/null +++ b/validations/MetaSchoolValidation.js @@ -0,0 +1,12 @@ +const MetaSchool = { + "id": "/MetaSchoolValidation", + "type": Object, + "properties": { + "name": { "type": "string" }, + "description": { "type": "string" }, + "schools": { "type": "array" } + }, + "required": ["name", "description"] +} + +module.exports = MetaSchool \ No newline at end of file diff --git a/models/SchoolValidation.js b/validations/SchoolValidation.js similarity index 90% rename from models/SchoolValidation.js rename to validations/SchoolValidation.js index 8b48344..f2dd21d 100644 --- a/models/SchoolValidation.js +++ b/validations/SchoolValidation.js @@ -1,5 +1,5 @@ const School = { - "id": "/SchoolModel", + "id": "/SchoolValidation", "type": Object, "properties": { "name": { "type": "string" }, diff --git a/models/SpellValidation.js b/validations/SpellValidation.js similarity index 92% rename from models/SpellValidation.js rename to validations/SpellValidation.js index da0167e..4ae434b 100644 --- a/models/SpellValidation.js +++ b/validations/SpellValidation.js @@ -1,5 +1,5 @@ -const SpellModel = { - "id": "/SpellModel", +const Spell = { + "id": "/SpellValidation", "type": Object, "properties": { "name": { "type": "string" }, @@ -36,4 +36,4 @@ const SpellModel = { "required": ["name", "description"] } -module.exports = SpellModel \ No newline at end of file +module.exports = Spell \ No newline at end of file diff --git a/models/UserValidation.js b/validations/UserValidation.js similarity index 90% rename from models/UserValidation.js rename to validations/UserValidation.js index 451adad..1dc9290 100644 --- a/models/UserValidation.js +++ b/validations/UserValidation.js @@ -1,5 +1,5 @@ const User = { - "id": "/UserModel", + "id": "/UserValidation", "type": Object, "properties": { "name": { "type": "string" }, diff --git a/validations/VariableValidation.js b/validations/VariableValidation.js new file mode 100644 index 0000000..29cf829 --- /dev/null +++ b/validations/VariableValidation.js @@ -0,0 +1,10 @@ +const Variable = { + "id": "/VariableValidation", + "type": Object, + "properties": { + "description": { "type": "string" }, + }, + "required": ["description"] +} + +module.exports = Variable \ No newline at end of file