wasp/examples/realworld/ext/queries.js

101 lines
3.1 KiB
JavaScript
Raw Normal View History

import HttpError from '@wasp/core/HttpError.js'
2020-11-24 22:39:36 +03:00
const userPublicSelection = {
id: true,
username: true,
email: true,
bio: true,
profilePictureUrl: true
}
export const getUser = async ({ username }, context) => {
// TODO: Do some error handling?
2020-11-27 00:48:35 +03:00
const user = await context.entities.User.findUnique({
2020-11-24 22:39:36 +03:00
where: { username },
// TODO: Tricky, if you forget this you could return unwanted fields
// like hashed password!
// It would be cool if we had some protection against making this mistake easily.
select: userPublicSelection
})
if (!user) throw new HttpError(404, 'No user with username ' + username)
return user
}
2020-11-20 20:22:49 +03:00
2020-11-27 00:48:35 +03:00
// TODO: I extracted this articleInclude and articleSetFavoritedFields to enable
// reusing of logic that shapes articles as they come out of the server,
// but I wonder if there is a more elegant way - here there are a lot of assumptions,
// and it is easy to not use where it should be used or use it in wrong setting.
const articleInclude = {
user: {
// TODO: Tricky, if you forget this you could return unwanted fields
// like hashed password!
// It would be cool if we had some protection against making this mistake easily.
select: userPublicSelection
},
2020-11-27 16:25:47 +03:00
tags: true,
2020-11-27 00:48:35 +03:00
favoritedBy: {
select: {
// TODO: Tricky, if I forgot this select here, sensitive data could leak out (hashed password).
username: true
}
}
}
const articleSetFavoritedFields = (article, user) => {
article.favorited = user && article.favoritedBy.find(f => f.username === user.username)
article.favoritesCount = article.favoritedBy.length
delete article.favoritedBy
}
const getArticles = async ({ where }, context) => {
2020-11-20 20:22:49 +03:00
// TODO: Do some error handling?
const articles = await context.entities.Article.findMany({
2020-11-27 00:48:35 +03:00
where,
include: articleInclude
2020-11-20 20:22:49 +03:00
})
2020-11-27 00:48:35 +03:00
for (const article of articles) {
articleSetFavoritedFields(article, context.user)
}
2020-11-20 20:22:49 +03:00
return articles
}
2020-11-27 00:48:35 +03:00
export const getArticlesByUser = async ({ username }, context) => {
return await getArticles({ where: { user: { username } } }, context)
}
export const getFavoritedArticles = async (args, context) => {
if (!context.user) { throw new HttpError(403) }
return await getArticles({
where: { favoritedBy: { some: { username: context.user.username } } },
}, context)
}
2020-11-24 23:10:26 +03:00
export const getArticle = async ({ slug }, context) => {
2020-11-20 20:22:49 +03:00
// TODO: Do some error handling?
2020-11-27 00:48:35 +03:00
const article = await context.entities.Article.findUnique({
where: { slug },
include: articleInclude
})
articleSetFavoritedFields(article, context.user)
2020-11-20 20:22:49 +03:00
return article
}
2020-11-25 00:57:14 +03:00
export const getArticleComments = async ({ slug }, context) => {
// TODO: Do some error handling?
const comments = await context.entities.Comment.findMany({
where: { article: { slug } },
include: {
user: {
// TODO: Tricky, if you forget this you could return unwanted fields
// like hashed password!
// It would be cool if we had some protection against making this mistake easily.
select: userPublicSelection
}
}
})
return comments
}