mirror of
https://github.com/versia-pub/docs.git
synced 2025-12-06 06:18:19 +01:00
feat: ✨ Add unique ID to every property on docs
This commit is contained in:
parent
f27f206e2d
commit
9db7cfccda
|
|
@ -19,7 +19,7 @@ Having the authorization is defined as:
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Delete">
|
||||
<Property name="uri" type="null" required={false}>
|
||||
This is a [**Transient Entity**](/entities#transient-entities) and does not have a URI.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export const metadata = {
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="FollowAccept">
|
||||
<Property name="uri" type="null" required={false}>
|
||||
This is a [**Transient Entity**](/entities#transient-entities) and does not have a URI.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ But it can also be used when Bob is already following Alice, in the case that:
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="FollowReject">
|
||||
<Property name="uri" type="null" required={false}>
|
||||
This is a [**Transient Entity**](/entities#transient-entities) and does not have a URI.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ Once a follow relationship is established, the **followee**'s instance should se
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Follow">
|
||||
<Property name="uri" type="null" required={false}>
|
||||
This is a [**Transient Entity**](/entities#transient-entities) and does not have a URI.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ Check the entity's documentation page to see if it supports this (it will be not
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="InstanceMetadata">
|
||||
<Property name="id" type="null">
|
||||
This entity does not have an ID.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Notes represent a piece of content on a Versia instance. They can be posted by [
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Note">
|
||||
<Property name="attachments" type="ContentFormat[]" required={false} typeLink="/structures/content-format">
|
||||
Media attachments to the note. May be any format. **Must** be remote.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ Any field in an entity not marked as `required` may be omitted or set to `null`.
|
|||
<Row>
|
||||
<Col>
|
||||
|
||||
<Properties>
|
||||
<Properties name="Entity">
|
||||
<Property name="id" type="string" required={true}>
|
||||
Unique identifier for the entity. Must be unique within the instance. Can be any string. Max of 512 UTF-8 characters.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Sometimes, [Users](/entities/user) want to unsubscribe from each other to stop s
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Unfollow">
|
||||
<Property name="uri" type="null" required={false}>
|
||||
This is a [**Transient Entity**](/entities#transient-entities) and does not have a URI.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ Instance **must** be the host of the instance the user is on (hostname with opti
|
|||
<Row>
|
||||
<Col>
|
||||
|
||||
<Properties>
|
||||
<Properties name="User">
|
||||
<Property name="avatar" type="ContentFormat" required={false} typeLink="/structures/content-format">
|
||||
The user's avatar. Must be an image format (`image/*`).
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ The Custom Emojis extension adds support for adding personalized emojis to feder
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="CustomEmoji">
|
||||
<Property name="name" type="string" required={true}>
|
||||
Emoji name, surrounded by identification characters (for example, colons: `:happy_face:`).
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ Custom Emojis can be added to any entity with text content. The extension ID is
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="CustomEmojisExtension">
|
||||
<Property name="emojis" type="CustomEmoji[]" required={true} typeLink="/extensions/custom-emoji#structure-definition">
|
||||
[Custom emojis](/extensions/custom-emoji#structure-definition) to be added to the note.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Refer to [Note](/entities/note#entity-definition)'s `group` property for how not
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Group">
|
||||
<Property name="type" type="string" required={true}>
|
||||
Must be `pub.versia:groups/Group`.
|
||||
</Property>
|
||||
|
|
@ -84,7 +84,7 @@ Indicates that a [User](/entities/user) wishes to subscribe to a group.
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="GroupSubscribe">
|
||||
<Property name="type" type="string" required={true}>
|
||||
Must be `pub.versia:groups/Subscribe`.
|
||||
</Property>
|
||||
|
|
@ -121,7 +121,7 @@ Indicates that a [User](/entities/user) wishes to unsubscribe from a group.
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="GroupUnsubscribe">
|
||||
<Property name="type" type="string" required={true}>
|
||||
Must be `pub.versia:groups/Unsubscribe`.
|
||||
</Property>
|
||||
|
|
@ -158,7 +158,7 @@ Indicates that a [Group](#entity-definition) has accepted a [User](/entities/use
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="GroupSubscribeAccept">
|
||||
<Property name="type" type="string" required={true}>
|
||||
Must be `pub.versia:groups/SubscribeAccept`.
|
||||
</Property>
|
||||
|
|
@ -195,7 +195,7 @@ Indicates that a [Group](#entity-definition) has rejected a [User](/entities/use
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="GroupSubscribeReject">
|
||||
<Property name="type" type="string" required={true}>
|
||||
Must be `pub.versia:groups/SubscribeReject`.
|
||||
</Property>
|
||||
|
|
@ -240,7 +240,7 @@ The `GroupFederate` entity allows a group to federate a note to all of its membe
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="GroupFederate">
|
||||
<Property name="type" type="string" required={true}>
|
||||
Must be `pub.versia:groups/Federate`.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ This extension adds the following metadata to instances:
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="InstanceMessagingExtension">
|
||||
<Property name="endpoint" type="string" required={true}>
|
||||
The endpoint to send federation debug messages to.
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ The entity defined in this document must be inserted in the `pub.versia:interact
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="InteractionControls">
|
||||
<Property name="interaction_type">
|
||||
Describes permissions for a specific interaction.
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Likes are a way for users to show appreciation for a note, like Twitter's "heart
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Like">
|
||||
<Property name="type" type="string" required={true}>
|
||||
Must be `pub.versia:likes/Like`.
|
||||
</Property>
|
||||
|
|
@ -55,7 +55,7 @@ Dislikes are a way for users to show disapproval for a note, like YouTube's "dis
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Dislike">
|
||||
<Property name="type" type="string" required={true}>
|
||||
Must be `pub.versia:likes/Dislike`.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ Migration happens in three steps:
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Migration">
|
||||
<Property name="uri" type="null" required={false}>
|
||||
This is a [**Transient Entity**](/entities#transient-entities) and does not have a URI.
|
||||
</Property>
|
||||
|
|
@ -69,7 +69,7 @@ The following extensions to [User](/entities/user) are used by the migration ext
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="MigrationExtension">
|
||||
<Property name="previous" type="URI" required={true} typeLink="/types#uri">
|
||||
If this user has migrated from another instance, this property **MUST** be set to the URI of the user on the previous instance.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ Extensions can be found in two places: an [Entity](/entities#entity-definition)'
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="EntityExtension">
|
||||
<Property name="extensions" type="Record<string, JSONData>" required={false}>
|
||||
Custom extensions to the entity.
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ Extensions can be found in two places: an [Entity](/entities#entity-definition)'
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="CustomEntity">
|
||||
<Property name="type" type="string" required={true}>
|
||||
The extension type. [Must follow naming conventions](#naming).
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Note that there is no `question` field: the question should be included in the `
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Polls">
|
||||
<Property name="options" type="ContentFormat[]" required="true">
|
||||
Array of options for the poll. Each option is a [ContentFormat](/structures/content-format) that can contain the same properties as a Note's `content` (e.g. [Custom Emojis](/extensions/custom-emojis) or HTML hyperlinks).
|
||||
</Property>
|
||||
|
|
@ -98,7 +98,7 @@ If a vote is cast to a poll that is closed, the vote should be rejected with a `
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Vote">
|
||||
<Property name="type" type="string" required="true">
|
||||
Must be `pub.versia:polls/Vote`.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ User reactions are (like every other entity) federated to all followers, and can
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Reaction">
|
||||
<Property name="type" type="string" required>
|
||||
Must be `pub.versia:reactions/Reaction`.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ When an instance receives a report, it *should* be reviewed by a moderator or ad
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Report">
|
||||
<Property name="uri" type="null" required={false}>
|
||||
This is a [**Transient Entity**](/entities#transient-entities) and does not have a URI.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ When a user shares a note, the note's original author **must** receive the entit
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Share">
|
||||
<Property name="type" type="string" required={true}>
|
||||
Must be `pub.versia:share/Share`.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ All properties are optional.
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Vanity">
|
||||
<Property name="avatar_overlays" type="ContentFormat[]" typeLink="/structures/content-format" required={false}>
|
||||
Overlay images to be placed on top of the user's avatar, like this: [example overlay from Discord](https://cdn.discordapp.com/avatar-decoration-presets/a_949a575b693c81ced8f56a7579d0969f.png).
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Messages sent over the WebSocket connection are JSON objects.
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="WebSocketMessage">
|
||||
<Property name="signature" type="string" required={true}>
|
||||
Same as the `Versia-Signature` header in HTTP requests.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ ALL kinds of HTTP requests/responses between instances **MUST** include a [Signa
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="HTTP Request">
|
||||
<Property name="Accept" type="string" required={true}>
|
||||
Must include `application/json`.
|
||||
</Property>
|
||||
|
|
@ -61,7 +61,7 @@ IETF draft [draft-polli-ratelimit-headers-02](https://www.ietf.org/archive/id/dr
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="HTTP Response">
|
||||
<Property name="Content-Type" type="string" required={true}>
|
||||
Must include `application/json; charset=utf-8`.
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Versia Links are a way to reference entities in the Versia Protocol, in a way th
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Versia Link">
|
||||
<Property name="scheme" type="string" required={true}>
|
||||
Must be `web+versia://` so that browsers and applications can recognize it.
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ Pages should be limited to a reasonable number of entities, such as 20 or 80.
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="Collection">
|
||||
<Property name="author" type="URI | null" required={true} typeLink="/types#uri">
|
||||
Author of the collection. Usually the user who owns the collection. [Can be set to `null` to represent the instance](/entities/instance-metadata#the-null-author).
|
||||
</Property>
|
||||
|
|
@ -88,7 +88,7 @@ URI Collections are identical to regular collections, but they contain only URIs
|
|||
|
||||
<Row>
|
||||
<Col>
|
||||
<Properties>
|
||||
<Properties name="URICollection">
|
||||
<Property name="author" type="URI | null" required={true} typeLink="/types#uri">
|
||||
Author of the collection. Usually the user who owns the collection. [Can be set to `null` to represent the instance](/entities/instance-metadata#the-null-author).
|
||||
</Property>
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ It is a good idea to provide at least two versions of an image (if possible): on
|
|||
<Row>
|
||||
<Col>
|
||||
|
||||
<Properties>
|
||||
<Properties name="ContentFormat">
|
||||
<Property name="content" type="string | URI" required={true}>
|
||||
Structure data. If `Content-Type` is a binary format, this field should be a URI to the binary data. Otherwise, it should be the content itself. Refer to the `remote` property for more information.
|
||||
</Property>
|
||||
|
|
|
|||
105
components/Property.tsx
Normal file
105
components/Property.tsx
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { type ReactNode, createContext, useContext } from "react";
|
||||
|
||||
export const PropertyContext = createContext<{
|
||||
name: string;
|
||||
}>({
|
||||
name: "",
|
||||
});
|
||||
|
||||
export function Properties({
|
||||
children,
|
||||
name,
|
||||
}: { children: ReactNode; name: string }) {
|
||||
return (
|
||||
<div className="my-6">
|
||||
<ul className="m-0 max-w-[calc(theme(maxWidth.lg)-theme(spacing.8))] list-none divide-y divide-zinc-900/5 p-0 dark:divide-white/5">
|
||||
<PropertyContext.Provider value={{ name }}>
|
||||
{children}
|
||||
</PropertyContext.Provider>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const numberTypeTooltips = {
|
||||
f64: "64-bit floating-point number",
|
||||
i64: "64-bit signed integer",
|
||||
u64: "64-bit unsigned integer",
|
||||
};
|
||||
|
||||
export function Property({
|
||||
name,
|
||||
children,
|
||||
type,
|
||||
typeLink,
|
||||
numberType,
|
||||
required,
|
||||
}: {
|
||||
name: string;
|
||||
children: ReactNode;
|
||||
type?: string;
|
||||
typeLink?: string;
|
||||
numberType?: "f64" | "i64" | "u64";
|
||||
required?: boolean;
|
||||
}) {
|
||||
const { name: contextName } = useContext(PropertyContext);
|
||||
|
||||
const idFormat = (name: string) =>
|
||||
name
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
.replace(/^-|-$/g, "");
|
||||
|
||||
return (
|
||||
<li className="m-0 px-0 py-4 first:pt-0 last:pb-0">
|
||||
<dl
|
||||
id={`${idFormat(contextName)}-${idFormat(name)}`}
|
||||
className="m-0 flex flex-wrap items-center gap-x-3 gap-y-2"
|
||||
>
|
||||
<dt className="sr-only">Name</dt>
|
||||
<dd>
|
||||
<code>{name}</code>
|
||||
</dd>
|
||||
{required && (
|
||||
<>
|
||||
<dt className="sr-only">Required</dt>
|
||||
<dd className="inline-flex items-center rounded-md bg-brand-50 px-2 py-0 text-xs font-medium text-brand-700 ring-1 ring-inset ring-brand-500/10 dark:bg-brand-500/10 dark:text-brand-100 dark:ring-brand-200/20">
|
||||
Required
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
{numberType && (
|
||||
<>
|
||||
<dt className="sr-only">Type</dt>
|
||||
<dd
|
||||
className="inline-flex items-center rounded-md bg-blue-50 px-2 py-0 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-500/10 dark:bg-blue-500/10 dark:text-blue-100 dark:ring-blue-200/20 hover:cursor-pointer"
|
||||
title={numberTypeTooltips[numberType]}
|
||||
>
|
||||
{numberType}
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
{type && (
|
||||
<>
|
||||
<dt className="sr-only">Type</dt>
|
||||
<dd className="font-mono text-xs text-zinc-400 dark:text-zinc-500">
|
||||
{typeLink ? (
|
||||
<Link href={typeLink}>{type}</Link>
|
||||
) : (
|
||||
type
|
||||
)}
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
<dt className="sr-only">Description</dt>
|
||||
<dd className="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
{children}
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ export const a = Link;
|
|||
// biome-ignore lint/performance/noBarrelFile: <explanation>
|
||||
export { Button } from "./Button";
|
||||
export { CodeGroup, Code as code, Pre as pre } from "./Code";
|
||||
export { Property, Properties } from "./Property";
|
||||
|
||||
export function wrapper({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
|
|
@ -80,81 +81,3 @@ export function Col({
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Properties({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="my-6">
|
||||
<ul className="m-0 max-w-[calc(theme(maxWidth.lg)-theme(spacing.8))] list-none divide-y divide-zinc-900/5 p-0 dark:divide-white/5">
|
||||
{children}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const numberTypeTooltips = {
|
||||
f64: "64-bit floating-point number",
|
||||
i64: "64-bit signed integer",
|
||||
u64: "64-bit unsigned integer",
|
||||
};
|
||||
|
||||
export function Property({
|
||||
name,
|
||||
children,
|
||||
type,
|
||||
typeLink,
|
||||
numberType,
|
||||
required,
|
||||
}: {
|
||||
name: string;
|
||||
children: ReactNode;
|
||||
type?: string;
|
||||
typeLink?: string;
|
||||
numberType?: "f64" | "i64" | "u64";
|
||||
required?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<li className="m-0 px-0 py-4 first:pt-0 last:pb-0">
|
||||
<dl className="m-0 flex flex-wrap items-center gap-x-3 gap-y-2">
|
||||
<dt className="sr-only">Name</dt>
|
||||
<dd>
|
||||
<code>{name}</code>
|
||||
</dd>
|
||||
{required && (
|
||||
<>
|
||||
<dt className="sr-only">Required</dt>
|
||||
<dd className="inline-flex items-center rounded-md bg-brand-50 px-2 py-0 text-xs font-medium text-brand-700 ring-1 ring-inset ring-brand-500/10 dark:bg-brand-500/10 dark:text-brand-100 dark:ring-brand-200/20">
|
||||
Required
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
{numberType && (
|
||||
<>
|
||||
<dt className="sr-only">Type</dt>
|
||||
<dd
|
||||
className="inline-flex items-center rounded-md bg-blue-50 px-2 py-0 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-500/10 dark:bg-blue-500/10 dark:text-blue-100 dark:ring-blue-200/20 hover:cursor-pointer"
|
||||
title={numberTypeTooltips[numberType]}
|
||||
>
|
||||
{numberType}
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
{type && (
|
||||
<>
|
||||
<dt className="sr-only">Type</dt>
|
||||
<dd className="font-mono text-xs text-zinc-400 dark:text-zinc-500">
|
||||
{typeLink ? (
|
||||
<Link href={typeLink}>{type}</Link>
|
||||
) : (
|
||||
type
|
||||
)}
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
<dt className="sr-only">Description</dt>
|
||||
<dd className="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
{children}
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue