Skip to content
This repository has been archived by the owner on Jun 25, 2024. It is now read-only.

Commit

Permalink
📝 Document one endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Dlurak committed Nov 11, 2023
1 parent cd7d84b commit af7fb5b
Show file tree
Hide file tree
Showing 13 changed files with 466 additions and 29 deletions.
8 changes: 7 additions & 1 deletion src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,13 @@ const de = {
'toc.collapse': 'Inhaltsverzeichnis verstecken',
'toc.expand': 'Inhaltsverzeichnis anzeigen',

'documentation.editOnGitHub': 'Bearbeite diese Seite auf GitHub'
'documentation.editOnGitHub': 'Bearbeite diese Seite auf GitHub',

'documentation.client.method': 'HTTP Methode',
'documentation.client.send': 'Senden',
'documentation.client.query.table.header.key': 'Schlüssel',
'documentation.client.query.table.header.value': 'Wert',
'documentation.client.query.table.header.active': 'Aktiv'
} as const;

export type DeToken = keyof typeof de;
Expand Down
8 changes: 7 additions & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,13 @@ const en = {
'toc.collapse': 'Collapse table of contents',
'toc.expand': 'Expand table of contents',

'documentation.editOnGitHub': 'Edit this page on GitHub'
'documentation.editOnGitHub': 'Edit this page on GitHub',

'documentation.client.method': 'HTTP Methode',
'documentation.client.send': 'Send',
'documentation.client.query.table.header.key': 'Key',
'documentation.client.query.table.header.value': 'Value',
'documentation.client.query.table.header.active': 'Active'
} as const;

export type EnToken = keyof typeof en;
Expand Down
19 changes: 0 additions & 19 deletions src/lib/MarkdownLayout.svelte

This file was deleted.

10 changes: 10 additions & 0 deletions src/lib/documentation/Information.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="py-3 px-1">
<div
class="border-blue-600 dark:border-blue-400 bg-blue-300 bg-opacity-20 border-2 border-solid rounded-md flex gap-2 items-center px-3 py-2 info-box"
>
<i class="bx bx-info-circle text-4xl" />
<span class="w-full">
<slot />
</span>
</div>
</div>
124 changes: 124 additions & 0 deletions src/lib/documentation/Request.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<script lang="ts">
import Switch from '$lib/utils/Switch.svelte';
import { backendUrl } from '../../stores';
import { i } from '../../languages/i18n';
import I18n from '$lib/I18n.svelte';
// const methods = ['GET', 'POST', 'PUT', 'DELETE'] as const;
const methods = ['GET'] as const;
type Method = (typeof methods)[number];
export let uri: string;
export let method: Method = 'GET';
export let urlParams: Record<
string,
{
value: string;
active: boolean;
}
> = {};
const urlParamsToString = () => {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(urlParams)) {
if (value.active) params.append(key, value.value);
}
return params.toString();
};
const genFullUrlString = () =>
`${$backendUrl}/${uri}${urlParamsToString() ? '?' : ''}${urlParamsToString()}`;
let fullUrlString = genFullUrlString();
let jsonRes = '';
</script>

<div class="py-3 px-1">
<div
class="border-green-600 dark:border-green-400 bg-green-300 bg-opacity-20 border-2 border-solid rounded-md flex flex-col gap-2 items-start px-3 py-2"
>
<div class="flex flex-col justify-between w-full gap-2">
<span
class="rounded-md px-3 py-1 bg-gray-200 dark:bg-gray-600 bg-opacity-50 dark:bg-opacity-50 w-full"
>
{fullUrlString}
</span>

<div class="flex gap-2 w-full">
<I18n>
<select
bind:value={method}
class="rounded-sm px-2 py-1 bg-gray-200 dark:bg-gray-600 w-full"
title={i('documentation.client.method')}
>
{#each methods as method}
<option value={method}>{method}</option>
{/each}
</select>
<button
class="bg-emerald-300 dark:bg-emerald-700 px-3 py-1 text-lg rounded-md w-full shadow-md hover:shadow-xl focus:shadow-xl transition-all duration-300 active:shadow-2xl active:scale-[.98]"
type="submit"
on:click={async () => {
const res = await fetch(fullUrlString, {
method
});
jsonRes = await res.text();
}}
title={i('documentation.client.send')}
>
{i('documentation.client.send')}
</button>
</I18n>
</div>
</div>

<div class="flex gap-3 flex-col w-full">
<table class="border-collapse border border-slate-500">
<thead>
<tr>
{#each [i('documentation.client.query.table.header.key'), i('documentation.client.query.table.header.value'), i('documentation.client.query.table.header.active')] as header}
<th class="border border-slate-600 py-1 px-4">{header}</th>
{/each}
</tr>
</thead>
<tbody>
{#each Object.entries(urlParams) as [key, value]}
<tr>
<td class="border border-slate-600">{key}</td>
<td class="border border-slate-600">
<input
type="text"
bind:value={value.value}
class="bg-gray-200 dark:bg-gray-600 px-2 py-1 w-full h-full"
on:change={() => {
fullUrlString = genFullUrlString();
}}
/>
</td>
<td class="border border-slate-600">
<div class="flex items-center justify-center w-full h-full">
<Switch
bind:checked={value.active}
on:change={() => {
fullUrlString = genFullUrlString();
}}
/>
</div>
</td>
</tr>
{/each}
</tbody>
</table>

{#if jsonRes}
<div>
<h4>Response</h4>
<div class="bg-gray-200 dark:bg-gray-600 p-2 rounded-md line-clamp-[15] overflow-scroll">
<pre class="text-sm max-w-3xl">{JSON.stringify(JSON.parse(jsonRes), null, 4)}</pre>
</div>
</div>
{/if}
</div>
</div>
</div>
41 changes: 41 additions & 0 deletions src/lib/documentation/response/Response.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script lang="ts">
import { mergeObjects } from '$lib/utils/mergeObjects';
import { setNestedProperty } from '$lib/utils/setMultipleKeys';
import ResponseRow from './ResponseRow.svelte';
import type { Response } from './types';
const statusCodes = {
200: 'OK'
};
type StatusCode = keyof typeof statusCodes;
export let status: StatusCode;
export let response: Response[];
const responseKeys = response.map((res) => res.field.split('.'));
const responseTrees = responseKeys.map((r) =>
setNestedProperty(
r,
response.find((res) => res.field === r.join('.'))
)
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const responseTree = mergeObjects(responseTrees) as Record<string, any>;
</script>

<h4>{status} {statusCodes[status]}</h4>
<table>
<thead>
<tr>
<th>Field</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{#each Object.keys(responseTree) as field}
<ResponseRow {field} tree={responseTree[field]} />
{/each}
</tbody>
</table>
60 changes: 60 additions & 0 deletions src/lib/documentation/response/ResponseRow.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<script lang="ts">
import type { Response } from './types';
interface TreeType extends Response {
[key: string]: unknown;
}
export let field: string;
export let tree: TreeType;
export let indent = 0;
const treeKeys = Object.keys(tree);
const normalKeys = ['field', 'type', 'description', 'allowedValues', 'max', 'min'];
const childrenKeys = treeKeys.filter((key) => !normalKeys.includes(key));
</script>

<tr>
<td style="--indent: {indent}rem">{field}</td>
<td>{tree.type}</td>
<td>
<div>
{tree.description}
<div class="empty:hidden flex gap-3 text-xs">
{#if tree.allowedValues}
<div>
Possible Values:
{#each tree.allowedValues as value}
<span class="rounded-sm px-1 py-0.5 bg-gray-200 dark:bg-gray-800">{value}</span>
{/each}
</div>
{/if}
{#if tree.max}
<div>
Max: {tree.max}
</div>
{/if}
{#if tree.min}
<div>
Min: {tree.min}
</div>
{/if}
</div>
</div>
</td>
</tr>

{#each childrenKeys as childKey}
<svelte:self field={childKey} tree={tree[childKey]} indent={indent + 1} />
{/each}

<style>
td {
--base-padding-x: 0.5rem;
padding-left: var(--base-padding-x);
padding-right: var(--base-padding-x);
}
tr td:first-child {
padding-left: calc(var(--base-padding-x) + var(--indent));
}
</style>
12 changes: 12 additions & 0 deletions src/lib/documentation/response/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
type BaseTypes = 'string' | 'number' | 'object';
type ArrayTypes = `${BaseTypes}[]`;
export type Type = BaseTypes | ArrayTypes;

export type Response = {
field: string;
type: Type;
description: string;
allowedValues?: string[];
max?: number;
min?: number;
};
11 changes: 11 additions & 0 deletions src/lib/markdown/layout/Docs.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#wrapper > table {
@apply border-collapse border-slate-500 border;
}

#wrapper > table th {
@apply border-slate-500 border py-0.5 px-4;
}

#wrapper > table td {
@apply border-slate-500 border py-0.5 pr-4;
}
3 changes: 2 additions & 1 deletion src/lib/markdown/layout/Docs.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script>
import './Docs.css';
import { page } from '$app/stores';
import I18n from '$lib/I18n.svelte';
Expand All @@ -21,7 +22,7 @@
<title>Dlool | Documentation{title ? ` | ${title}` : ''}</title>
</svelte:head>
<div>
<div id="wrapper">
<slot />
</div>
Expand Down
9 changes: 2 additions & 7 deletions src/lib/utils/setMultipleKeys.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
type Primitives = string | boolean | number;

type NestedObject<FinalValue extends Primitives, Keys extends string[]> = Keys extends [
type NestedObject<FinalValue, Keys extends string[]> = Keys extends [
infer FirstKey,
...infer RestKeys
]
Expand All @@ -11,10 +9,7 @@ type NestedObject<FinalValue extends Primitives, Keys extends string[]> = Keys e
: never
: Record<string, unknown>;

export const setNestedProperty = <V extends Primitives, K extends string[]>(
keys: K,
value: V
): NestedObject<V, K> => {
export const setNestedProperty = <V, K extends string[]>(keys: K, value: V): NestedObject<V, K> => {
// any makes it waaaaaay easier to work with
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const obj: Record<string, any> = {};
Expand Down
13 changes: 13 additions & 0 deletions src/routes/documentation/api/homework/+page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: API - Homework
author:
name: Dlurak
link: https://github.com/Dlurak
date: 2023-11-11
---

## Homework

Homework was the first feature of Dlool and is still the most important one. It is the core of the platform and the reason why it was created.

Read operations are available to everyone, but write operations require [authentication](/documentation/api/authentication).
Loading

0 comments on commit af7fb5b

Please sign in to comment.