atproto pds in zig pds.zat.dev
pds atproto
24

Configure Feed

Select the types of activity you want to include in your feed.

Align API reference with landing page

zzstoatzz (Jun 1, 2026, 10:32 PM -0500) 17e2914d e3105f18

+23 -14
+1
src/http/landing/mod.zig
··· 181 181 \\ <div class="client-body"> 182 182 \\ <p class="hint">public endpoints exposed by this PDS.</p> 183 183 \\ <div class="system-links"> 184 + \\ <a href="/api"><strong>api reference</strong><span>/api</span></a> 184 185 \\ <a href="/xrpc/_health"><strong>health</strong><span>/xrpc/_health</span></a> 185 186 \\ <a href="/xrpc/com.atproto.server.describeServer"><strong>server</strong><span>describeServer</span></a> 186 187 \\ <a href="/.well-known/did.json"><strong>did document</strong><span>/.well-known/did.json</span></a>
+22 -14
src/internal/api_reference/html.zig
··· 25 25 } 26 26 27 27 const public_url = config.publicUrl(); 28 + const public_host = displayHost(public_url); 28 29 return std.fmt.allocPrint(allocator, 29 30 \\<!doctype html> 30 31 \\<html lang="en"> ··· 33 34 \\ <meta name="viewport" content="width=device-width, initial-scale=1"> 34 35 \\ <meta name="color-scheme" content="dark light"> 35 36 \\ <title>zds api</title> 37 + \\ <meta name="description" content="endpoint reference for this zds pds"> 36 38 \\ <link rel="canonical" href="{s}/api"> 37 39 \\ <link rel="icon" href="/favicon.svg" type="image/svg+xml"> 38 40 \\ <style>{s}</style> ··· 42 44 \\ <header> 43 45 \\ <a class="brand" href="/">zds</a> 44 46 \\ <nav aria-label="api links"> 45 - \\ <a href="/api/openapi.json">OpenAPI JSON</a> 46 - \\ <a href="/xrpc/com.atproto.server.describeServer">describeServer</a> 47 + \\ <a class="nav-link" href="/api/openapi.json">openapi</a> 48 + \\ <a class="nav-link" href="/xrpc/com.atproto.server.describeServer">describe</a> 47 49 \\ </nav> 48 50 \\ </header> 49 51 \\ <section class="intro"> 50 - \\ <p class="eyebrow">endpoint reference</p> 51 - \\ <h1>{s}</h1> 52 - \\ <p class="lede">This PDS exposes {d} documented HTTP operations, including XRPC methods at <code>/xrpc/{{NSID}}</code>.</p> 52 + \\ <p class="eyebrow">{s}</p> 53 + \\ <h1>api reference</h1> 54 + \\ <p class="lede">this pds exposes {d} documented http operations, including xrpc methods at <span class="route-expression"><code>/xrpc/</code><code>{{NSID}}</code></span>.</p> 53 55 \\ <div class="stats" aria-label="endpoint summary"> 54 56 \\ <span><strong>{d}</strong> operations</span> 55 57 \\ <span><strong>{d}</strong> groups</span> 56 - \\ <span><strong>{d}</strong> XRPC methods</span> 58 + \\ <span><strong>{d}</strong> xrpc methods</span> 57 59 \\ </div> 58 60 \\ </section> 59 61 \\ <section class="tools" aria-label="filters"> ··· 71 73 , .{ 72 74 try model.escapeHtml(allocator, public_url), 73 75 css, 74 - try model.escapeHtml(allocator, public_url), 76 + try model.escapeHtml(allocator, public_host), 75 77 endpoints.len, 76 78 endpoints.len, 77 79 model.groupCountTotal(), ··· 80 82 cards.written(), 81 83 script, 82 84 }); 85 + } 86 + 87 + fn displayHost(url: []const u8) []const u8 { 88 + if (std.mem.startsWith(u8, url, "https://")) return url["https://".len..]; 89 + if (std.mem.startsWith(u8, url, "http://")) return url["http://".len..]; 90 + return url; 83 91 } 84 92 85 93 fn renderEndpointCard(allocator: std.mem.Allocator, writer: *std.Io.Writer, endpoint: Endpoint, open: bool) !void { ··· 152 160 } 153 161 154 162 const css = 155 - \\:root{color-scheme:dark light;--bg:#111411;--panel:#171b18;--text:#eef4ed;--muted:#98a69b;--line:#2d352f;--accent:#7ee787;--cyan:#7dd3fc;--rose:#f0a6ca;--gold:#e6c36a;--shadow:0 14px 38px rgba(0,0,0,.24);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif} 156 - \\*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text)}a{color:inherit}.shell{width:min(1180px,calc(100% - 32px));margin:0 auto;padding:24px 0 56px}header{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:54px}.brand{font-weight:800;text-decoration:none;font-size:1.25rem}nav{display:flex;gap:10px;flex-wrap:wrap}nav a{border:1px solid var(--line);border-radius:8px;padding:9px 12px;text-decoration:none;color:var(--muted);background:rgba(255,255,255,.02)} 157 - \\.intro{display:grid;gap:14px;margin-bottom:28px}.eyebrow{text-transform:uppercase;letter-spacing:.08em;color:var(--accent);font-size:.78rem;font-weight:800;margin:0}h1{font-size:clamp(2.4rem,8vw,5.8rem);line-height:.9;margin:0;letter-spacing:0}.lede{max-width:760px;color:var(--muted);font-size:1.12rem;line-height:1.6;margin:0}.lede code{color:var(--cyan)}.stats{display:flex;gap:10px;flex-wrap:wrap;margin-top:6px}.stats span{border:1px solid var(--line);border-radius:8px;padding:10px 12px;color:var(--muted);background:rgba(255,255,255,.025)}.stats strong{color:var(--text)} 158 - \\.tools{position:sticky;top:0;z-index:5;background:color-mix(in srgb,var(--bg) 90%,transparent);backdrop-filter:blur(16px);padding:12px 0 16px;margin-bottom:12px;border-bottom:1px solid var(--line)}.search{display:grid;gap:7px;margin-bottom:12px}.search span{font-size:.78rem;text-transform:uppercase;color:var(--muted);font-weight:800}.search input{width:100%;border:1px solid var(--line);border-radius:8px;background:var(--panel);color:var(--text);padding:13px 14px;font:inherit;outline:none}.search input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(126,231,135,.15)}.chips{display:flex;flex-wrap:wrap;gap:8px}.chip{border:1px solid var(--line);border-radius:999px;background:transparent;color:var(--muted);padding:8px 11px;font:inherit;cursor:pointer}.chip.active{background:var(--text);border-color:var(--text);color:var(--bg)}.chip span{opacity:.72} 159 - \\.endpoints{display:grid;gap:10px}.endpoint{border:1px solid var(--line);border-radius:8px;background:var(--panel);box-shadow:var(--shadow);overflow:hidden}.endpoint[hidden]{display:none}.endpoint summary{list-style:none;display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:12px;align-items:center;padding:15px;cursor:pointer}.endpoint summary::-webkit-details-marker{display:none}.endpoint code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere}.method{font-size:.76rem;font-weight:900;border-radius:6px;padding:5px 7px;color:#071008}.method.get{background:var(--cyan)}.method.post{background:var(--accent)}.method.head{background:var(--gold)}.auth{font-size:.78rem;color:var(--muted);border:1px solid var(--line);border-radius:999px;padding:5px 8px;white-space:nowrap}.body{border-top:1px solid var(--line);padding:16px;display:grid;gap:15px}.body p{margin:0;color:var(--muted);line-height:1.55}.nsid{display:flex;gap:10px;align-items:center;color:var(--muted)}.nsid span{font-size:.75rem;text-transform:uppercase;font-weight:900;color:var(--rose)}.meta-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.meta-grid>div{border:1px solid var(--line);border-radius:8px;padding:12px;background:rgba(255,255,255,.018)}h2{font-size:.78rem;text-transform:uppercase;color:var(--muted);margin:0 0 8px}ul{margin:0;padding-left:18px}.muted{color:var(--muted)}.compact{font-size:.9rem}.note{border-left:3px solid var(--rose);padding-left:12px}.snippet{position:relative}.copy{position:absolute;right:8px;top:8px;border:1px solid var(--line);border-radius:6px;background:var(--panel);color:var(--text);font:inherit;font-size:.75rem;font-weight:800;padding:6px 9px;cursor:pointer}.copy:hover,.copy:focus{border-color:var(--accent);outline:none}.copy.done{background:var(--accent);border-color:var(--accent);color:#071008}pre{margin:0;white-space:pre-wrap;background:#090b09;color:#d6ead8;border-radius:8px;border:1px solid var(--line);padding:42px 12px 12px;overflow:auto} 160 - \\@media (max-width:720px){.shell{width:min(100% - 20px,1180px);padding-top:16px}header{align-items:flex-start;margin-bottom:32px}.endpoint summary{grid-template-columns:auto minmax(0,1fr);}.endpoint summary .auth{grid-column:2}.meta-grid{grid-template-columns:1fr}nav{justify-content:flex-end}} 161 - \\@media (prefers-color-scheme:light){:root{--bg:#f6f7f3;--panel:#ffffff;--text:#111411;--muted:#5b665f;--line:#d9dfd8;--shadow:0 12px 34px rgba(33,45,36,.09)}pre{background:#101510;color:#ecf7ec}} 163 + \\:root{--bg:#070807;--panel:#101210;--panel-2:#151915;--line:#273026;--text:#f0f1ec;--muted:#aaa69b;--dim:#69645c;--accent:#91adff;--green:#39c178;--pink:#f05f8e;--focus:#c9d7ff;--glass:rgba(255,255,255,.085);--accent-bg:color-mix(in srgb,var(--green) 13%,var(--bg));--accent-panel:color-mix(in srgb,var(--green) 9%,var(--panel));--accent-panel-2:color-mix(in srgb,var(--accent) 8%,var(--panel-2));color-scheme:dark} 164 + \\*{box-sizing:border-box}html{min-height:100%;background:var(--accent-bg);overflow-x:hidden}body{position:relative;margin:0;min-height:100vh;overflow-x:hidden;background:radial-gradient(circle at 20% 0%,color-mix(in srgb,var(--green) 15%,transparent),transparent 35%),radial-gradient(circle at 94% 18%,color-mix(in srgb,var(--accent) 13%,transparent),transparent 32%),linear-gradient(135deg,var(--accent-bg),var(--bg) 58%);color:var(--text);font:15px/1.55 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono",monospace}body::before,body::after{content:"";position:fixed;inset:-18vmax;z-index:0;pointer-events:none}body::before{background:linear-gradient(108deg,transparent 0 22%,rgba(255,255,255,.10) 24%,transparent 27% 52%,rgba(255,255,255,.055) 54%,transparent 58%),linear-gradient(72deg,transparent 0 38%,color-mix(in srgb,var(--accent) 11%,transparent) 44%,transparent 52%);filter:blur(20px) saturate(1.15);opacity:.58;transform:rotate(-4deg)}body::after{background:radial-gradient(ellipse at 22% 32%,rgba(255,255,255,.09),transparent 28%),radial-gradient(ellipse at 72% 18%,color-mix(in srgb,var(--green) 14%,transparent),transparent 31%),radial-gradient(ellipse at 66% 78%,color-mix(in srgb,var(--pink) 12%,transparent),transparent 30%);filter:blur(34px);opacity:.44}a{color:inherit}.shell{position:relative;z-index:1;width:min(100%,920px);margin:0 auto;padding:18px 16px 46px}header{position:relative;z-index:10;display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:50px;margin:0 0 38px;padding:8px 0;color:var(--muted);font-size:12px}.brand{flex:0 0 auto;display:inline-flex;align-items:center;color:var(--text);text-decoration:none;font-weight:700;font-size:14px;letter-spacing:0}.brand:hover{opacity:.82}nav{min-width:0;display:flex;align-items:center;justify-content:flex-end;gap:7px;padding:4px;border:1px solid color-mix(in srgb,var(--line) 58%,white 14%);border-radius:18px;background:linear-gradient(110deg,rgba(255,255,255,.16),transparent 22% 76%,rgba(255,255,255,.08)),radial-gradient(circle at 20% 0%,color-mix(in srgb,var(--green) 12%,transparent),transparent 46%),color-mix(in srgb,var(--accent-panel) 72%,transparent);box-shadow:inset 0 1px 0 rgba(255,255,255,.22),inset 0 -18px 42px rgba(255,255,255,.035),0 8px 28px rgba(0,0,0,.12);backdrop-filter:blur(26px) saturate(1.26);-webkit-backdrop-filter:blur(26px) saturate(1.26)}.nav-link{min-height:34px;display:inline-grid;place-items:center;border:1px solid color-mix(in srgb,var(--line) 74%,white 10%);border-radius:12px;padding:0 11px;background:radial-gradient(circle at 30% 18%,rgba(255,255,255,.20),transparent 32%),linear-gradient(145deg,rgba(255,255,255,.12),rgba(255,255,255,.03)),color-mix(in srgb,var(--accent-panel) 74%,transparent);color:var(--muted);text-decoration:none;box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 10px 28px rgba(0,0,0,.14)}.nav-link:hover{color:var(--text);border-color:color-mix(in srgb,var(--green) 55%,var(--line));background:color-mix(in srgb,var(--accent-panel-2) 86%,transparent)} 165 + \\.intro{display:grid;gap:13px;margin:52px 0 26px}.eyebrow{margin:0;color:var(--green);font-size:12px;font-weight:700;text-transform:lowercase}.eyebrow::before{content:"/";color:var(--dim);margin-right:2px}h1{margin:0;color:var(--text);font-size:clamp(42px,10vw,82px);line-height:.95;letter-spacing:0;text-transform:lowercase}.lede{max-width:68ch;margin:0;color:var(--muted);font-size:15px}.lede code{color:#7dd3fc}.route-expression{display:inline-flex;white-space:nowrap}.stats{display:flex;gap:9px;flex-wrap:wrap;margin-top:5px}.stats span{border:1px solid color-mix(in srgb,var(--line) 70%,white 8%);border-radius:12px;padding:9px 11px;color:var(--muted);background:color-mix(in srgb,var(--accent-panel) 64%,transparent);box-shadow:inset 0 1px 0 rgba(255,255,255,.10)}.stats strong{color:var(--text)} 166 + \\.tools{position:relative;z-index:5;padding:12px 0 15px;margin-bottom:12px;border-bottom:1px solid color-mix(in srgb,var(--line) 58%,transparent)}.search{display:grid;gap:7px;margin-bottom:11px}.search span{font-size:11px;text-transform:lowercase;color:var(--dim)}.search input{width:100%;border:1px solid color-mix(in srgb,var(--line) 76%,white 6%);border-radius:12px;background:color-mix(in srgb,var(--panel) 86%,transparent);color:var(--text);padding:12px 13px;font:inherit;outline:none;box-shadow:inset 0 1px 0 rgba(255,255,255,.08)}.search input:focus{border-color:var(--focus)}.chips{display:flex;flex-wrap:wrap;gap:7px}.chip{border:1px solid color-mix(in srgb,var(--line) 78%,white 6%);border-radius:999px;background:color-mix(in srgb,var(--accent-panel) 50%,transparent);color:var(--muted);padding:7px 10px;font:inherit;font-size:12px;cursor:pointer;text-transform:lowercase}.chip.active{background:var(--text);border-color:var(--text);color:var(--bg)}.chip span{opacity:.68} 167 + \\.endpoints{display:grid;gap:9px}.endpoint{border:1px solid color-mix(in srgb,var(--line) 76%,white 6%);border-radius:12px;background:color-mix(in srgb,var(--panel) 88%,transparent);box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 14px 38px rgba(0,0,0,.16);overflow:hidden}.endpoint[hidden]{display:none}.endpoint summary{list-style:none;display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:11px;align-items:center;padding:13px 14px;cursor:pointer}.endpoint summary::-webkit-details-marker{display:none}.endpoint code{font-family:inherit;overflow-wrap:anywhere}.method{font-size:11px;font-weight:700;border-radius:8px;padding:4px 6px;color:#071008;text-transform:lowercase}.method.get{background:#7dd3fc}.method.post{background:var(--green)}.method.head{background:#f5d85d}.auth{font-size:11px;color:var(--muted);border:1px solid color-mix(in srgb,var(--line) 76%,white 5%);border-radius:999px;padding:4px 7px;white-space:nowrap;text-transform:lowercase}.body{border-top:1px solid color-mix(in srgb,var(--line) 78%,transparent);padding:14px;display:grid;gap:14px}.body p{margin:0;color:var(--muted);line-height:1.55}.nsid{display:flex;gap:8px;align-items:center;color:var(--muted);min-width:0}.nsid span{font-size:10px;text-transform:lowercase;color:var(--pink)}.nsid code{color:var(--text);min-width:0}.meta-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px}.meta-grid>div{border:1px solid color-mix(in srgb,var(--line) 78%,white 4%);border-radius:10px;padding:10px;background:rgba(255,255,255,.018)}h2{font-size:11px;text-transform:lowercase;color:var(--dim);font-weight:400;margin:0 0 7px}ul{margin:0;padding-left:18px}.muted{color:var(--dim)}.compact{font-size:12px}.note{border-left:2px solid var(--pink);padding-left:10px}.snippet{position:relative}.copy{position:absolute;right:8px;top:8px;border:1px solid color-mix(in srgb,var(--line) 78%,white 6%);border-radius:10px;background:color-mix(in srgb,var(--panel) 88%,transparent);color:var(--muted);font:inherit;font-size:11px;padding:5px 8px;cursor:pointer;text-transform:lowercase}.copy:hover,.copy:focus{color:var(--text);border-color:color-mix(in srgb,var(--green) 55%,var(--line));outline:none}.copy.done{background:var(--green);border-color:var(--green);color:#071008}pre{margin:0;white-space:pre-wrap;background:#090b09;color:#d6ead8;border-radius:10px;border:1px solid color-mix(in srgb,var(--line) 78%,white 4%);padding:38px 11px 11px;overflow:auto;font:inherit;font-size:13px} 168 + \\@media (max-width:720px){.shell{width:min(100% - 20px,920px);padding-top:14px}header{align-items:flex-start;margin-bottom:28px}.intro{margin-top:34px}.endpoint summary{grid-template-columns:auto minmax(0,1fr)}.endpoint summary .auth{grid-column:2}.meta-grid{grid-template-columns:1fr}nav{justify-content:flex-end}.lede{font-size:14px}} 169 + \\@media (prefers-color-scheme:light){:root{--bg:#f6f4ed;--panel:#fffdf7;--panel-2:#ece8dd;--line:#d8d0c0;--text:#161412;--muted:#625c53;--dim:#8f8679;--accent:#315dcb;--green:#1b7340;--pink:#b72e5c;--focus:#163f9f;--glass:rgba(255,255,255,.72);--accent-bg:color-mix(in srgb,var(--green) 11%,var(--bg));--accent-panel:color-mix(in srgb,var(--green) 5%,var(--panel));--accent-panel-2:color-mix(in srgb,var(--accent) 5%,var(--panel-2));color-scheme:light}pre{background:#101510;color:#ecf7ec}} 162 170 ; 163 171 164 172 const script =