Skip to content

Commit

Permalink
Added clip crud api
Browse files Browse the repository at this point in the history
  • Loading branch information
dioveath committed May 25, 2022
1 parent adad122 commit f10d0be
Show file tree
Hide file tree
Showing 20 changed files with 562 additions and 9 deletions.
32 changes: 32 additions & 0 deletions controllers/clip/create-clip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module.exports = function makeCreateClip(clipAccess){

return async function createClip(httpRequest){
const headers = {
'Content-Type': 'application/json'
};
try {
const newClip = await clipAccess.addClip(httpRequest.body);
return {
headers,
statusCode: 200,
body: {
status: 'success',
newClip
}
};
} catch(error){
// TODO: Error Logging
console.log(error);

return {
headers,
statusCode: 400,
body: {
status: 'fail',
errorList: error.message.split(',')
}
};
}
};

}
35 changes: 35 additions & 0 deletions controllers/clip/delete-clip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

module.exports = function makeDeleteClip(clipAccess){

return async function deleteClip(httpRequest){

const headers = {
'Content-Type': 'application/json'
};

try {
const deleteResult = await clipAccess.deleteClip(httpRequest.params.id);
return {
headers,
statusCode: 200,
body: {
status: 'success',
deleted: deleteResult
}
};
} catch(error){
// TODO: error logging
console.log(error);
return {
headers,
statusCode: 400,
body: {
status: 'fail',
errorList: error.message.split(',')
}
};
};

};

};
36 changes: 36 additions & 0 deletions controllers/clip/get-clip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module.exports = function makeGetClip(clipAccess) {
return async function getClip(httpRequest){ // Custom Httprequest (Made from express default requests)
const headers = {
'Content-Type': 'application/json'
};
try {
const clip = await clipAccess.findClipById(httpRequest.params.id);

if(clip == null) {
throw new Error("No Clip with id: " + httpRequest.params.id);
}

return { // this is response model
headers,
statusCode: 200,
body: {
status: 'success',
clip
}
};

} catch(error){
// TODO: Error logging
// console.log(error);

return {
headers,
statusCode: 400,
body: {
status: 'fail',
errorList: error.message.split(',')
}
};
}
};
};
22 changes: 22 additions & 0 deletions controllers/clip/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const clipAccess = require('../../data-access/clip-db/index');
const makeGetClip = require('./get-clip');
const makeCreateClip = require('./create-clip');
const makeDeleteClip = require('./delete-clip');
const makeListClips = require('./list-clips');
const makeUpdateClip = require('./update-clip');

const getClip = makeGetClip(clipAccess);
const createClip = makeCreateClip(clipAccess);
const deleteClip = makeDeleteClip(clipAccess);
const listClips = makeListClips(clipAccess);
const updateClip = makeUpdateClip(clipAccess);

const clipController = {
getClip,
createClip,
updateClip,
deleteClip,
listClips,
};

module.exports = clipController;
34 changes: 34 additions & 0 deletions controllers/clip/list-clips.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module.exports = function makeListClips(clipAccess){

return async function listClips(httpRequest){

const headers = {
'Content-Type': 'application/json'
};
try {
const clips = await clipAccess.listClips();
return {
headers,
statusCode: 200,
body: {
status: 'success',
clips
}
};
} catch (error){
// Error logging
console.log(error);
return {
headers,
statusCode: 400,
body: {
status: 'fail',
errorList: error.message.split(',')
}
};

};

};

}
36 changes: 36 additions & 0 deletions controllers/clip/update-clip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module.exports = function makeUpdateUsser(clipAccess){

return async function updateClip(httpRequest){

const headers = {
'Content-Type': 'application/json'
};

try {
const updatedClip = await clipAccess.updateClip(httpRequest.params.id, httpRequest.body);
return {
headers,
statusCode: 200,
body: {
status: 'success',
updatedClip
}
};

} catch(error){
// TODO: Error logging
// console.log(error);

return {
headers,
statusCode: 400,
body: {
status: 'fail',
errorList: error.message.split(',')
}
};
}

};

}
18 changes: 18 additions & 0 deletions data-access/clip-db/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { listClips,
findClipBy,
findClipById,
addClip,
updateClip,
deleteClip,
dropClips
} = require('./mongodb'); // Gateway to actual database, mongodb here

module.exports = {
listClips,
findClipBy,
findClipById,
addClip,
updateClip,
deleteClip,
dropClips,
};
46 changes: 46 additions & 0 deletions data-access/clip-db/mongodb/errorFormatter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// throws appropriate business frontend error for mongoose error and mongoose-unique-validator errors

module.exports = (error) => {
if (error.name == "ValidationError") {
// from mongoose-unique-validator

let props = Object.keys(error.errors);
let messages = [];
console.log(props);

for (let prop of props) {
// error.errors.message gives us: Error, 'gaming_name' to be unique
// gets the errors.message exact message removing Error, from it
let message = `${error.errors[`${prop}`].message}`
.split(",")[1]
.substring(1);
messages.push(message.charAt(0).toUpperCase() + message.slice(1));
}

throw new Error(messages.join(","));
} else if (error.name == "CastError") {
throw new Error(
`Casting error with ${error.path} of value type '${error.valueType}' to type of '${error.kind}'`
);
} else if (error.code === 11000) {
// duplicates in db:
// NOTE: this will never be reached, above unique validation will catch first, here is for reference only
let props = Object.keys(error.keyValue);
let messages = [];

for (let prop of props) {
messages.push(
`"'${prop}' : '${error.keyValue[`${prop}`]}'" is already in use`
);
}

throw new Error(messages.join(","));
} else if (error.code == 11011 || error.name == "CastError") {
throw new Error(`Clip not found with "id : '${error._id}'"`);
} else if (error.name === "CastError") {
throw new Error(error.reason);
} else {
console.log(error);
throw new Error("Error in database!");
}
};
87 changes: 87 additions & 0 deletions data-access/clip-db/mongodb/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// uses mongoose implementation of findClip, listClips, dropAll, etc.
// Gateway -- Implementation
// Data-Access and Use-Cases as well

const Clip = require('../../../db/mongodb/models/clip');
const serialize = require('./serializer');
const makeClip = require('../../../models/clip/index').makeClip;
const makeUpdateClip = require('../../../models/clip/index').makeUpdateClip;
const errorFormatter = require('./errorFormatter');


function listClips(){
return Clip.find({}).then(serialize).catch(errorFormatter);
}

function findClipBy(prop, val){
if(prop === 'id') prop = '_id';
return Clip.find({[prop]: val}).then(res => serialize(res[0])).catch(errorFormatter);
}

function findClipById(id){
return Clip.findById(id).then(serialize).catch(errorFormatter);
}

async function addClip(clipInfo){
// defaults
var clip = await makeClip(clipInfo);

var newClip = {
title: clip.getTitle(),
author: clip.getAuthor(),
privacy: clip.getPrivacy(),
video_url: clip.getVideoUrl(),
meta_data: clip.getVideoMeta(),
likes: clip.getLikes(),
comments: clip.getComments()
};

return Clip.create(newClip).then(serialize).catch(errorFormatter);
}


async function updateClip(id, updateClipInfo){
if(!id)
throw new Error("You must supply id!");

var clipData = await Clip.findById(id);
if(clipData === null) throw new Error("No Clip with id: " + id);

// validate the update info
await makeUpdateClip(updateClipInfo);

// if error is not thrown, then we can update with updateClipInfo in database
return Clip.findByIdAndUpdate(id, updateClipInfo, { new: true }).then(serialize).catch(errorFormatter);
}


function deleteClip(id){
return Clip.findByIdAndDelete(id)
.then(res => {
if(!res)
throw {
name: 'Error',
code: 11011, // custom error code
_id: id,
};
return {
id: res._id.toString(),
};
}).catch(errorFormatter);
}


function dropClips(){
return Clip.deleteMany().catch(errorFormatter);
}


module.exports = {
listClips,
findClipBy,
findClipById,
addClip,
updateClip,
deleteClip,
dropClips
};
25 changes: 25 additions & 0 deletions data-access/clip-db/mongodb/serializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// serializes db model to business model
// for, e.g.- _id to id

const _serializeSingle = (clip) => {
return {
"id": clip._id,
"title": clip.title,
"author": clip.author,
"privacy": clip.privacy,
"video_url": clip.video_url,
"video_meta": clip.video_meta,
"likes": clip.likes,
"comments": clip.comments
};
};


function serializer(data){
if(!data) return null;
if(Array.isArray(data))
return data.map(_serializeSingle);
return _serializeSingle(data);
}

module.exports = serializer;
3 changes: 1 addition & 2 deletions data-access/user-db/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@

// other controllers and drivers that rely on this API (findUser, listUsers, addUser)
// FIXME: Gateway | Interactor --
// TODO: Learn more about Gateway | Interactor --

const { listUsers,
findUserBy,
Expand Down
Loading

0 comments on commit f10d0be

Please sign in to comment.