feat(projects): 설명 마크다운 렌더링 + 저장소 README 가져오기
등록 모달의 '한 줄 설명' input 을 여러 줄 textarea 로 바꾸고, 설명을 markdown-it 로 렌더링한다(html:false 로 raw HTML 이스케이프·javascript: 링크 차단 — XSS 안전). 상세 화면은 마크다운으로, 카드 미리보기는 기호를 걷어낸 순수 텍스트(mdPlain) + 3줄 클램프로 표시. '저장소 README 가져오기' 버튼과 GET /api/readme 라우트를 추가해 repo_url 의 Gitea README 를 설명란으로 불러올 수 있다(gitea.js fetchReadme). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,8 @@ import path from "path";
|
||||
import { config } from "./config.js";
|
||||
import { toolsForUser } from "./sites.js";
|
||||
import { initOidc, loginRedirect, handleCallback, requireAuth, oidcReady, logoutUrl } from "./auth.js";
|
||||
import { icon, identicon, langColor, langFromTags } from "./helpers.js";
|
||||
import { fetchMainLang } from "./gitea.js";
|
||||
import { icon, identicon, langColor, langFromTags, renderMarkdown, mdPlain } from "./helpers.js";
|
||||
import { fetchMainLang, fetchReadme } from "./gitea.js";
|
||||
import * as db from "./db.js";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
@@ -35,6 +35,8 @@ app.use((req, res, next) => {
|
||||
res.locals.icon = icon;
|
||||
res.locals.identicon = identicon;
|
||||
res.locals.langColor = langColor;
|
||||
res.locals.renderMarkdown = renderMarkdown;
|
||||
res.locals.mdPlain = mdPlain;
|
||||
next();
|
||||
});
|
||||
|
||||
@@ -161,6 +163,13 @@ app.post("/projects/:id/visibility", requireAuth, async (req, res) => {
|
||||
res.redirect(back + sep + "toast=" + encodeURIComponent(msg));
|
||||
});
|
||||
|
||||
// --- README 가져오기 (등록 모달) — repo_url 의 Gitea README 를 마크다운 원문으로 반환 ---
|
||||
app.get("/api/readme", requireAuth, async (req, res) => {
|
||||
const content = await fetchReadme((req.query.repo_url || "").toString().trim());
|
||||
if (!content) return res.status(404).json({ ok: false });
|
||||
res.json({ ok: true, content });
|
||||
});
|
||||
|
||||
// --- 프로젝트 삭제 (본인) ---
|
||||
app.post("/projects/:id/delete", requireAuth, async (req, res) => {
|
||||
const n = await db.deleteProject({ id: req.params.id, sabun: req.session.user.sabun });
|
||||
|
||||
Reference in New Issue
Block a user