Code reviewWeb development
PRPRPRPRPRPRP
Contestststst
Published snippet
typeof value === "string" &&
value.length <= 1000 &&
(!value || ["https:", "http:"].includes(new URL(value).protocol))
);
} catch {
return false;
}
};
export function registerCatalog(app, db, required) {
function project(id, user) {
const row = db
.prepare(
"SELECT pr.*,u.name founder_name,u.role founder_role,(SELECT COUNT(*) FROM replies r WHERE r.post_id=pr.post_id) feedback_count FROM projects pr JOIN users u ON u.id=pr.user_id WHERE pr.id=?",
)
.get(id);
const post =
row && db.prepare("SELECT * FROM posts WHERE id=?").get(row.post_id);
if (!post || post.community_id || !canRead(db, user, post)) return null;
const metadata =
db
.prepare(
"SELECT data FROM entity_details WHERE kind='project' AND entity_id=?",
)
.get(String(row.id))?.data || "{}";
return {
...row,
revision: createHash("sha256")
.update(
JSON.stringify([
fields.map((key) => row[key]),
post.revision,
metadata,
]),
)
.digest("hex"),
};
}
app.get("/api/projects/:id", (req, res) => {
const row = project(req.params.id, req.user);
if (!row) return res.status(404).json({ error: "Project not found." });
res.json(row);
});
app.patch("/api/projects/:id", required, (req, res) => {
const row = project(req.params.id, req.user);
if (!row) return res.status(404).json({ error: "Project not found." });
if (row.user_id !== req.user.id)
return res
.status(403)
.json({ error: "Only the founder can edit this project." });
const b = req.body;
if (
!text(b.name, 2, 80) ||
!text(b.description, 20, 5000) ||
!text(b.help, 10, 1500) ||
!text(b.stack, 0, 150) ||
!link(b.url) ||
!link(b.repo) ||
!["Idea", "Prototype", "Beta", "Live"].includes(b.stage) ||GitHub contextLocal file
Branch main
File catalog-api.mjs · lines 20–77