Skip to content

Convert project.controller to async/await syntax #3025

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

Merged
merged 3 commits into from
Mar 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 102 additions & 106 deletions server/controllers/project.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,16 @@ export {
apiGetProjectsForUser
} from './project.controller/getProjectsForUser';

export function updateProject(req, res) {
Project.findById(req.params.project_id, (findProjectErr, project) => {
export async function updateProject(req, res) {
try {
const project = await Project.findById(req.params.project_id).exec();
if (!project) {
res.status(404).send({
success: false,
message: 'Project with that id does not exist.'
});
return;
}
if (!project.user.equals(req.user._id)) {
res.status(403).send({
success: false,
Expand All @@ -39,7 +47,7 @@ export function updateProject(req, res) {
});
return;
}
Project.findByIdAndUpdate(
const updatedProject = await Project.findByIdAndUpdate(
req.params.project_id,
{
$set: req.body
Expand All @@ -50,119 +58,91 @@ export function updateProject(req, res) {
}
)
.populate('user', 'username')
.exec((updateProjectErr, updatedProject) => {
if (updateProjectErr) {
console.log(updateProjectErr);
res.status(400).json({ success: false });
return;
}
if (
req.body.files &&
updatedProject.files.length !== req.body.files.length
) {
const oldFileIds = updatedProject.files.map((file) => file.id);
const newFileIds = req.body.files.map((file) => file.id);
const staleIds = oldFileIds.filter(
(id) => newFileIds.indexOf(id) === -1
);
staleIds.forEach((staleId) => {
updatedProject.files.id(staleId).remove();
});
updatedProject.save((innerErr, savedProject) => {
if (innerErr) {
console.log(innerErr);
res.status(400).json({ success: false });
return;
}
res.json(savedProject);
});
} else {
res.json(updatedProject);
}
.exec();
if (
req.body.files &&
updatedProject.files.length !== req.body.files.length
) {
const oldFileIds = updatedProject.files.map((file) => file.id);
const newFileIds = req.body.files.map((file) => file.id);
const staleIds = oldFileIds.filter((id) => newFileIds.indexOf(id) === -1);
staleIds.forEach((staleId) => {
updatedProject.files.id(staleId).remove();
});
});
const savedProject = await updatedProject.save();
res.json(savedProject);
} else {
res.json(updatedProject);
}
} catch (error) {
console.error(error);
res.status(500).json({ success: false });
}
}

export function getProject(req, res) {
export async function getProject(req, res) {
const { project_id: projectId, username } = req.params;
User.findByUsername(username, (err, user) => { // eslint-disable-line
if (!user) {
return res
.status(404)
.send({ message: 'Project with that username does not exist' });
}
Project.findOne({
user: user._id,
$or: [{ _id: projectId }, { slug: projectId }]
})
.populate('user', 'username')
.exec((err, project) => { // eslint-disable-line
if (err) {
console.log(err);
return res
.status(404)
.send({ message: 'Project with that id does not exist' });
}
return res.json(project);
});
});
const user = await User.findByUsername(username);
if (!user) {
return res
.status(404)
.send({ message: 'User with that username does not exist' });
}
const project = await Project.findOne({
user: user._id,
$or: [{ _id: projectId }, { slug: projectId }]
}).populate('user', 'username');
if (!project) {
return res
.status(404)
.send({ message: 'Project with that id does not exist' });
}
return res.json(project);
}

export function getProjectsForUserId(userId) {
return new Promise((resolve, reject) => {
Project.find({ user: userId })
.sort('-createdAt')
.select('name files id createdAt updatedAt')
.exec((err, projects) => {
if (err) {
console.log(err);
}
resolve(projects);
});
});
return Project.find({ user: userId })
.sort('-createdAt')
.select('name files id createdAt updatedAt')
.exec();
}

export function getProjectAsset(req, res) {
export async function getProjectAsset(req, res) {
const projectId = req.params.project_id;
Project.findOne({ $or: [{ _id: projectId }, { slug: projectId }] })
const project = await Project.findOne({
$or: [{ _id: projectId }, { slug: projectId }]
})
.populate('user', 'username')
.exec(async (err, project) => { // eslint-disable-line
if (err) {
return res
.status(404)
.send({ message: 'Project with that id does not exist' });
}
if (!project) {
return res
.status(404)
.send({ message: 'Project with that id does not exist' });
}
.exec();
if (!project) {
return res
.status(404)
.send({ message: 'Project with that id does not exist' });
}

const filePath = req.params[0];
const resolvedFile = resolvePathToFile(filePath, project.files);
if (!resolvedFile) {
return res.status(404).send({ message: 'Asset does not exist' });
}
if (!resolvedFile.url) {
return res.send(resolvedFile.content);
}
const filePath = req.params[0];
const resolvedFile = resolvePathToFile(filePath, project.files);
if (!resolvedFile) {
return res.status(404).send({ message: 'Asset does not exist' });
}
if (!resolvedFile.url) {
return res.send(resolvedFile.content);
}

try {
const { data } = await axios.get(resolvedFile.url, {
responseType: 'arraybuffer'
});
res.send(data);
} catch (error) {
res.status(404).send({ message: 'Asset does not exist' });
}
try {
const { data } = await axios.get(resolvedFile.url, {
responseType: 'arraybuffer'
});
return res.send(data);
} catch (error) {
return res.status(404).send({ message: 'Asset does not exist' });
}
}

export function getProjects(req, res) {
export async function getProjects(req, res) {
if (req.user) {
getProjectsForUserId(req.user._id).then((projects) => {
res.json(projects);
});
const projects = await getProjectsForUserId(req.user._id);
res.json(projects);
} else {
// could just move this to client side
res.json([]);
Expand All @@ -180,7 +160,7 @@ export async function projectExists(projectId) {

/**
* @param {string} username
* @param {string} projectId
* @param {string} projectId - the database id or the slug or the project
* @return {Promise<boolean>}
*/
export async function projectForUserExists(username, projectId) {
Expand All @@ -193,12 +173,18 @@ export async function projectForUserExists(username, projectId) {
return project != null;
}

/**
* Adds URLs referenced in <script> tags to the `files` array of the project
* so that they can be downloaded along with other remote files from S3.
* @param {object} project
* @void - modifies the `project` parameter
*/
function bundleExternalLibs(project) {
const indexHtml = project.files.find((file) => file.name === 'index.html');
const { window } = new JSDOM(indexHtml.content);
const scriptTags = window.document.getElementsByTagName('script');

Object.values(scriptTags).forEach(async ({ src }, i) => {
Object.values(scriptTags).forEach(({ src }) => {
if (!isUrl(src)) return;

const path = src.split('/');
Expand All @@ -214,6 +200,13 @@ function bundleExternalLibs(project) {
});
}

/**
* Recursively adds a file and all of its children to the JSZip instance.
* @param {object} file
* @param {Array<object>} files
* @param {JSZip} zip
* @return {Promise<void>} - modifies the `zip` parameter
*/
async function addFileToZip(file, files, zip) {
if (file.fileType === 'folder') {
const folderZip = file.name === 'root' ? zip : zip.folder(file.name);
Expand Down Expand Up @@ -264,9 +257,12 @@ async function buildZip(project, req, res) {
}
}

export function downloadProjectAsZip(req, res) {
Project.findById(req.params.project_id, (err, project) => {
// save project to some path
buildZip(project, req, res);
});
export async function downloadProjectAsZip(req, res) {
Copy link
Contributor

@Swarnendu0123 Swarnendu0123 Feb 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

downloadProjectAsZip, if the project with the given ID doesn't exist, the function sends a response with a 404 status code but doesn't return or terminate the function. We can consider using return or else to prevent further execution if the project doesn't exist.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. Good catch!

const project = await Project.findById(req.params.project_id).exec();
if (!project) {
res.status(404).send({ message: 'Project with that id does not exist' });
return;
}
// save project to some path
buildZip(project, req, res);
}