| 1 | /** |
| 2 | * `/<owner>/<repo>/ref/<number>`: `#12` read in the repository, as the |
| 3 | * work service reads it (lib/refs.ts): its pull request, the work item that |
| 4 | * was its issue before work items, the workspace's work item or another of its repositories' |
| 5 | * pull requests. Followed as a link (Markdown's `#12`), it sends the |
| 6 | * browser on to that page; asked for JSON, it is the card that opens over |
| 7 | * a `#12` in a commit message or on a timeline (components/commit-message.tsx), |
| 8 | * for anyone who may read it, signed in or not. Anything the viewer may not |
| 9 | * read is not found. A card is kept a minute by the browser, and out of |
| 10 | * indexes (lib/robots.ts). |
| 11 | */ |
| 12 | import { data, redirect } from "react-router"; |
| 13 | |
| 14 | import type { Route } from "./+types/ref-card"; |
| 15 | import { refCard, refPath } from "../../lib/refs.server"; |
| 16 | import { getViewer } from "../../lib/session.server"; |
| 17 | |
| 18 | const HEADERS = { |
| 19 | "cache-control": "private, max-age=60", |
| 20 | vary: "Cookie, Accept", |
| 21 | "x-robots-tag": "noindex, nofollow", |
| 22 | }; |
| 23 | |
| 24 | export async function loader({ params, context, request }: Route.LoaderArgs) { |
| 25 | const viewer = getViewer(context); |
| 26 | const repo = { namespace: params.owner.toLowerCase(), name: params.repo }; |
| 27 | const number = Number(params.number); |
| 28 | const card = (request.headers.get("accept") ?? "").startsWith("application/json"); |
| 29 | if (!Number.isInteger(number) || number < 1) { |
| 30 | if (card) return Response.json({ error: "not_found" }, { status: 404, headers: HEADERS }); |
| 31 | throw data(null, { status: 404 }); |
| 32 | } |
| 33 | if (card) { |
| 34 | const found = await refCard(viewer, { repo }, number); |
| 35 | if (!found) return Response.json({ error: "not_found" }, { status: 404, headers: HEADERS }); |
| 36 | return Response.json(found, { headers: HEADERS }); |
| 37 | } |
| 38 | const to = await refPath(viewer, { repo }, number); |
| 39 | if (!to) throw data(null, { status: 404 }); |
| 40 | return redirect(to); |
| 41 | } |