documentation server and /doc route

Signed-off-by: ngn <ngn@ngn.tf>
This commit is contained in:
ngn
2025-01-16 07:46:27 +03:00
parent 5fb3c03e40
commit e87764a4c2
40 changed files with 1313 additions and 301 deletions

View File

@ -1,13 +1,13 @@
import { urljoin } from "$lib/util.js";
const version = "v1";
const url = urljoin(import.meta.env.APP_API_URL, version);
const api_version = "v1";
const api_url = urljoin(import.meta.env.APP_API_URL, api_version);
function api_url(path = null, query = {}) {
return urljoin(url, path, query);
function api_urljoin(path = null, query = {}) {
return urljoin(api_url, path, query);
}
function check_err(json) {
function api_check_err(json) {
if (!("error" in json)) throw new Error('API response is missing the "error" key');
if (json["error"] != "") throw new Error(`API returned an error: ${json["error"]}`);
@ -15,23 +15,23 @@ function check_err(json) {
if (!("result" in json)) throw new Error('API response is missing the "result" key');
}
async function GET(fetch, url) {
async function api_http_get(fetch, url) {
const res = await fetch(url);
const json = await res.json();
check_err(json);
api_check_err(json);
return json["result"];
}
async function get_metrics(fetch) {
return GET(fetch, api_url("/metrics"));
async function api_get_metrics(fetch) {
return await api_http_get(fetch, api_urljoin("/metrics"));
}
async function get_services(fetch) {
return GET(fetch, api_url("/services"));
async function api_get_services(fetch) {
return await api_http_get(fetch, api_urljoin("/services"));
}
async function get_projects(fetch) {
return GET(fetch, api_url("/projects"));
async function api_get_projects(fetch) {
return await api_http_get(fetch, api_urljoin("/projects"));
}
export { version, api_url, get_metrics, get_services, get_projects };
export { api_version, api_urljoin, api_get_metrics, api_get_services, api_get_projects };

28
app/src/lib/doc.js Normal file
View File

@ -0,0 +1,28 @@
import { urljoin } from "$lib/util.js";
function doc_urljoin(path = null, query = {}) {
return urljoin(import.meta.env.APP_DOC_URL, path, query);
}
function doc_check_err(json) {
if ("error" in json) throw new Error(`Documentation server returned an error: ${json["error"]}`);
}
async function doc_http_get(fetch, url) {
const res = await fetch(url);
const json = await res.json();
doc_check_err(json);
return json;
}
async function doc_get_list(fetch) {
return (await doc_http_get(fetch, doc_urljoin("/list")))["list"];
}
async function doc_get(fetch, name) {
let url = doc_urljoin("/get");
url = urljoin(url, name);
return await doc_http_get(fetch, url);
}
export { doc_urljoin, doc_get, doc_get_list };

View File

@ -34,6 +34,7 @@
display: flex;
flex-direction: column;
justify-content: end;
align-items: flex-start;
gap: 10px;
padding: 50px;

View File

@ -1,6 +1,6 @@
<script>
import { urljoin, color, date_from_ts, language } from "$lib/util.js";
import { get_metrics } from "$lib/api.js";
import { urljoin, color, date_from_ts } from "$lib/util.js";
import { api_get_metrics } from "$lib/api.js";
import Link from "$lib/link.svelte";
import { onMount } from "svelte";
@ -9,7 +9,7 @@
let data = {};
onMount(async () => {
data = await get_metrics(fetch);
data = await api_get_metrics(fetch);
});
</script>
@ -21,16 +21,14 @@
</span>
<span>/</span>
<span>
<Link
link={urljoin(import.meta.env.APP_DOC_URL, "license", { lang: $language })}
bold={true}>{$_("footer.license")}</Link
<Link link={urljoin(import.meta.env.APP_URL, "doc/license")} bold={true}
>{$_("footer.license")}</Link
>
</span>
<span>/</span>
<span>
<Link
link={urljoin(import.meta.env.APP_DOC_URL, "privacy", { lang: $language })}
bold={true}>{$_("footer.privacy")}</Link
<Link link={urljoin(import.meta.env.APP_URL, "doc/privacy")} bold={true}
>{$_("footer.privacy")}</Link
>
</span>
</div>

View File

@ -1,6 +1,6 @@
<script>
import { frontend_url } from "$lib/util.js";
import { api_url } from "$lib/api.js";
import { api_urljoin } from "$lib/api.js";
export let desc, title;
</script>
@ -13,5 +13,10 @@
<meta content={frontend_url()} property="og:url" />
<meta content="#000000" data-react-helmet="true" name="theme-color" />
<link rel="alternate" type="application/atom+xml" href={api_url("/news/en")} title="Atom Feed" />
<link
rel="alternate"
type="application/atom+xml"
href={api_urljoin("/news/en")}
title="Atom Feed"
/>
</svelte:head>

View File

@ -8,9 +8,7 @@
<header>
<div>
<h1 class="title" style="color: var(--{color()})">
{title.toLowerCase()}
</h1>
<h1 class="title" style="color: var(--{color()})">{title.toLowerCase()}</h1>
<h1 class="cursor" style="color: var(--{color()})">_</h1>
</div>
<img src="/profile/{picture}.png" alt="" />

View File

@ -73,11 +73,13 @@
main .info .title h1 {
font-size: var(--size-5);
margin-bottom: 8px;
font-weight: 900;
}
main .info .title p {
font-size: var(--size-4);
color: var(--white-2);
font-weight: 100;
}
main .info .links {