diff --git a/docs/.vitepress/.gitignore b/docs/.vitepress/.gitignore new file mode 100644 index 0000000..6e25fa8 --- /dev/null +++ b/docs/.vitepress/.gitignore @@ -0,0 +1 @@ +cache/ \ No newline at end of file diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 0000000..47d4ba6 --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,41 @@ +import { defineConfig } from "vitepress"; + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: "pronouns.cc documentation", + description: "pronouns.cc documentation", + markdown: { + anchor: { level: [2, 3] }, + }, + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + siteTitle: "pronouns.cc", + logo: "/logo.svg", + nav: [ + { text: "Home", link: "/" }, + { text: "Back to pronouns.cc", link: "https://pronouns.cc/" }, + ], + outline: { + level: [2, 3], + }, + sidebar: [ + { + text: "API", + items: [ + { text: "API reference", link: "/api/" }, + { text: "Rate limits", link: "/api/ratelimits" }, + { text: "Error messages", link: "/api/errors" }, + ], + }, + { + text: "Endpoints", + items: [ + { text: "Object reference", link: "/api/endpoints/" }, + { text: "Users", link: "/api/endpoints/users" }, + { text: "Members", link: "/api/endpoints/members" }, + { text: "Other", link: "/api/endpoints/other" }, + ], + }, + ], + }, +}); diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 0000000..8f8b0a9 --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,4 @@ +:root { + --vp-font-family-base: "FiraGO", sans-serif; + --vp-font-family-mono: "Fira Mono", monospace; +} diff --git a/docs/.vitepress/theme/index.mts b/docs/.vitepress/theme/index.mts new file mode 100644 index 0000000..faafd9e --- /dev/null +++ b/docs/.vitepress/theme/index.mts @@ -0,0 +1,9 @@ +import DefaultTheme from 'vitepress/theme-without-fonts' +import "@fontsource/firago/400.css"; +import "@fontsource/firago/400-italic.css"; +import "@fontsource/firago/700.css"; +import "@fontsource/firago/700-italic.css"; +import "@fontsource/fira-mono"; +import "./custom.css"; + +export default DefaultTheme diff --git a/docs/api/endpoints/index.md b/docs/api/endpoints/index.md new file mode 100644 index 0000000..0b14002 --- /dev/null +++ b/docs/api/endpoints/index.md @@ -0,0 +1,53 @@ +# Object reference + +These are some of the objects shared by multiple types of endpoints. +For other objects, such as [users](./users) or [members](./members), check their respective pages. + +## Field + +| Field | Type | Description | +| ------- | ------------------------------- | --------------------------- | +| name | string | the field's name or heading | +| entries | [field_entry](./#field-entry)[] | the field's entries | + +## Field entry + +| Field | Type | Description | +| ------ | ------ | -------------------------------- | +| value | string | this entry's value or key | +| status | string | this entry's [status](./#status) | + +## Pronoun entry + +| Field | Type | Description | +| ------------ | ------- | ----------------------------------------------------------------------------------------------------- | +| pronouns | string | this entry's raw pronouns. This can be any user-inputted value and does not have to be a complete set | +| display_text | string? | the text shown in the pronoun list, if `pronouns` is a valid 5-member set | +| status | string | this entry's [status](./#status) | + +## Status + +A name, pronoun, or field entry's **status** is how the user or member feels about that entry. +This can be any of `favourite`, `okay`, `jokingly`, `friends_only`, `avoid`, +as well as the UUID of any [custom preferences](./#custom-preference) the user has set. + +## Custom preference + +A user can set custom word preferences, which can have custom icons and tooltips. These are identified by a UUID. + +| Field | Type | Description | +| --------- | ------ | ---------------------------------------------------------------------------------------------------- | +| icon | string | the [Bootstrap icon](https://icons.getbootstrap.com/) associated with this preference | +| tooltip | string | the description shown in the tooltip on hover or tap | +| size | string | the size at which any entry with this preference will be shown, can be `large`, `normal`, or `small` | +| muted | bool | whether the preference is shown in a muted grey colour | +| favourite | bool | whether the preference is treated the same as `favourite` when building embeds | + +## Pride flag + +| Field | Type | Description | +| ----------- | ------- | ------------------------------------- | +| id | string | the flag's unique ID | +| hash | string | the flag's [image hash](/api/#images) | +| name | string | the flag's name | +| description | string? | the flag's description or alt text | diff --git a/docs/api/endpoints/members.md b/docs/api/endpoints/members.md new file mode 100644 index 0000000..2a41a4c --- /dev/null +++ b/docs/api/endpoints/members.md @@ -0,0 +1,123 @@ +# Member endpoints + +## Member object + +| Field | Type | Description | +| ------------ | ---------------------------------------------------- | --------------------------------------------------------------------------------- | +| id | string | the member's unique ID | +| sid | string | the member's 6-letter short ID | +| name | string | the member's name | +| display_name | string? | the member's display name or nickname | +| bio | string? | the member's description | +| avatar | string? | the member's [avatar hash](/api/#images) | +| links | string[] | the member's profile links | +| names | [field_entry](./#field-entry)[] | the member's preferred names | +| pronouns | [pronoun_entry](./#pronoun-entry)[] | the member's preferred pronouns | +| fields | ?[field](./#field)[] | the member's term fields. Not returned in member list endpoints. | +| flags | [flag](./#pride-flag)[] | the member's pride flags | +| user | partial [user](./members#partial-user-object) object | the user associated with this member | +| unlisted | ?bool | _only returned for your own members_, whether the member is shown in member lists | + +## Partial user object + +| Field | Type | Description | +| ------------------ | ---------------------------------------------------- | -------------------------------------- | +| id | string | the user's unique ID | +| name | string | the user's username | +| display_name | string? | the user's display name or nickname | +| avatar | string? | the user's [avatar hash](/api/#images) | +| custom_preferences | map\[uuid\][custom_preference](./#custom-preference) | the user's custom preferences | + +## Endpoints + +### Get member + +#### `GET /members/{member.id}` + +Gets a member by their ID. Returns a [member](./members#member-object) object. +If authenticated and the authenticated user is the owner of the requested member, +also returns the `unlisted` field. + +### Get user member + +#### `GET /users/{user.id}/members/{member.id} | GET /users/{user.name}/members/{member.name}` + +Gets a member by their ID or name. Returns a [member](./members#member-object) object. +If authenticated and the authenticated user is the owner of the requested member, +also returns the `unlisted` field. + +### Get user members + +#### `GET /users/{user.id}/members | GET /users/{user.name}/members` + +Get a user's members. Returns an array of [member](./members#member-object) objects. + +### Get current user member + +#### `GET /users/@me/members/{member.id} | GET /users/@me/members/{member.name}` + +**Requires authentication.** Get one of the currently authenticated user's members by ID or name. +Returns a [member](./members#member-object) object. + +### Get current user members + +#### `GET /users/@me/members` + +**Requires authentication.** Get the currently authenticated user's members. +Returns an array of [member](./members#member-object) objects. + +### Create member + +#### `POST /members` + +**Requires authentication**. Creates a new member. +Returns the newly created [member](./members#member-object) on success. + +#### Request body parameters + +| Field | Type | Description | +| ------------ | --------------- | --------------------------------------------------------------------------------------------------- | +| name | string | the new member's name. Must be unique per user, and be between 1 and 100 characters. **Required** | +| display_name | string? | the new member's display name. Must be between 1 and 100 characters | +| bio | string? | the new member's bio. Must be between 1 and 1000 characters | +| avatar | string | the new member's avatar. This must be a PNG, JPEG, or WebP image, encoded in base64 data URI format | +| links | string[] | the new member's profile links. Maximum 25 links, and links must be between 1 and 256 characters | +| names | field_entry[] | the new member's preferred names | +| pronouns | pronoun_entry[] | the new member's preferred pronouns | +| fields | field[] | the new member's profile fields | + +### Update member + +#### `PATCH /members/{member.id}` + +**Requires authentication.** Updates the given member. +Returns the updated [member](./members#member-object) on success. + +#### Request body parameters + +| Field | Type | Description | +| ------------------ | -------------------- | --------------------------------------------------------------------------------------------------- | +| name | string | the member's new name. Must be unique per user, and be between 1 and 100 characters. | +| display_name | string | the member's new display name. Must be between 1 and 100 characters | +| bio | string | the member's new bio. Must be between 1 and 1000 characters | +| links | string[] | the member's new profile links. Maximum 25 links, and links must be between 1 and 256 characters | +| names | field_entry[] | the member's new preferred names | +| pronouns | pronoun_entry[] | the member's new preferred pronouns | +| fields | field[] | the member's new profile fields | +| flags | string[] | the member's new flags. This must be an array of [pride flag](./#pride-flag) IDs. | +| avatar | string | the member's new avatar. This must be a PNG, JPEG, or WebP image, encoded in base64 data URI format | +| unlisted | bool | whether or not the member should be hidden from the member list | + +### Delete member + +#### `DELETE /members/{member.id}` + +**Requires authentication.** Deletes the given member. Returns `204 No Content` on success. + +### Reroll short ID + +#### `GET /members/{member.id}/reroll` + +**Requires authentication.** Rerolls the member's short ID. +Returns the updated [member](./members#member-object) on success. +If the user has already rerolled a short ID in the past hour, returns `403 Forbidden`. diff --git a/docs/api/endpoints/other.md b/docs/api/endpoints/other.md new file mode 100644 index 0000000..f6d51d2 --- /dev/null +++ b/docs/api/endpoints/other.md @@ -0,0 +1,46 @@ +# Other endpoints + +There are some endpoints that are neither user or member related: + +### Get statistics + +#### `GET /meta` + +Get aggregate statistics for pronouns.cc. +Note: a user is considered active if they have updated their profile, created a member, deleted a member, +or updated a member's profile in the given time period. + +#### Response body + +| Field | Type | Description | +| -------------- | ----------------- | ------------------------------------------------------------------------- | +| git_repository | string | link to the project's Git repository | +| git_commit | string | the commit the backend is built from | +| users | user count object | the total number of users | +| members | int | the total number of non-hidden members | +| require_invite | bool | whether invites are required to sign up. _Always `false` for pronouns.cc_ | + +#### User count object + +| Field | Type | Description | +| ------------ | ---- | ------------------------------------------- | +| total | int | total number of users | +| active_month | int | number of users active in the last month | +| active_week | int | number of users active in the last week | +| active_day | int | number of users active in the last 24 hours | + +### Get warnings + +#### `GET /auth/warnings` + +**Requires authentication.** Returns an array of warnings the currently authenticated user has. +Add `?all=true` query parameter to return all warnings, not just unread ones. + +#### Response body + +| Field | Type | Description | +| ---------- | -------- | ---------------------------------------------- | +| id | int | the warning ID | +| reason | string | the reason for the warning | +| created_at | datetime | when the warning was created | +| read | bool | whether the warning has been read/acknowledged | diff --git a/docs/api/endpoints/users.md b/docs/api/endpoints/users.md new file mode 100644 index 0000000..961a0b2 --- /dev/null +++ b/docs/api/endpoints/users.md @@ -0,0 +1,143 @@ +# User endpoints + +## User object + +| Field | Type | Description | +| ------------------ | ---------------------------------------------------- | --------------------------------------------------------------------------- | +| id | string | the user's unique ID | +| sid | string | the user's 5 letter short ID | +| name | string | the user's username | +| display_name | string? | the user's display name or nickname | +| bio | string? | the user's description or bio | +| member_title | string? | the heading used for the user's member list. If null, defaults to "Members" | +| avatar | string? | the user's [avatar hash](/api/#images) | +| links | string[] | the user's profile links | +| names | [field_entry](./#field-entry)[] | the user's preferred names | +| pronouns | [pronoun_entry](./#pronoun-entry)[] | the user's preferred pronouns | +| fields | [field](./#field)[] | the user's term fields | +| flags | [flag](./#pride-flag)[] | the user's pride flags | +| members | [partial](./users#partial-member-object) member[] | the user's non-hidden members | +| badges | int | the user's badges, represented as a bitmask field | +| utc_offset | int? | the user's current offset from UTC, in seconds | +| custom_preferences | map\[uuid\][custom_preference](./#custom-preference) | the user's custom preferences | + +### Additional fields for the currently authenticated user {#additional-user-fields} + +| Field | Type | Description | +| ------------------ | -------- | ------------------------------------------------ | +| created_at | datetime | the user's creation date and time | +| timezone | string? | the user's timezone in IANA timezone format | +| is_admin | bool | whether or not the user is an administrator | +| list_private | bool | whether or not the user's member list is private | +| last_sid_reroll | datetime | the last time the user rerolled a short ID | +| discord | string? | the user's Discord ID | +| discord_username | string? | the user's Discord username | +| tumblr | string? | the user's Tumblr ID | +| tumblr_username | string? | the user's Tumblr username | +| google | string? | the user's Google ID | +| google_username | string? | the user's Google username | +| fediverse | string? | the user's fediverse user ID | +| fediverse_username | string? | the user's fediverse username, without instance | +| fediverse_instance | string? | the user's fediverse instance | + +## Partial member object + +| Field | Type | Description | +| ------------ | ----------------------------------- | ---------------------------------------- | +| id | string | the member's unique ID | +| sid | string | the member's 6-letter short ID | +| name | string | the member's name | +| display_name | string? | the member's display name or nickname | +| bio | string? | the member's description | +| avatar | string? | the member's [avatar hash](/api/#images) | +| links | string[] | the member's profile links | +| names | [field_entry](./#field-entry)[] | the member's preferred names | +| pronouns | [pronoun_entry](./#pronoun-entry)[] | the member's preferred pronouns | + +## Endpoints + +### Get user + +#### `GET /users/{user.id} | GET /users/{user.name}` + +Gets a user by their ID or username. Returns a [user](./users#user-object) object. +If authenticated and the authenticated user is the requested user, also returns the [additional user fields](./users#additional-user-fields). + +### Get current user + +#### `GET /users/@me` + +**Requires authentication.** Gets the currently authenticated [user](./users#user-object), +with all [additional user fields](./users#additional-user-fields). + +### Update current user + +#### `PATCH /users/@me` + +**Requires authentication.** Updates the currently authenticated user. +Returns the updated [user](./users#user-object) object on success. + +#### Request body parameters + +| Field | Type | Description | +| ------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------- | +| name | string | the user's new name. Must be between 2 and 40 characters and only consist of ASCII letters, `_`, `.`, and `-` | +| display_name | string | the user's new display name. Must be between 1 and 100 characters | +| bio | string | the user's new bio. Must be between 1 and 1000 characters | +| member_title | string | the user's new member title. Must be between 1 and 150 characters | +| links | string[] | the user's new profile links. Maximum 25 links, and links must be between 1 and 256 characters | +| names | field_entry[] | the user's new preferred names | +| pronouns | pronoun_entry[] | the user's new preferred pronouns | +| fields | field[] | the user's new profile fields | +| flags | string[] | the user's new flags. This must be an array of [pride flag](./#pride-flag) IDs. | +| avatar | string | the user's new avatar. This must be a PNG, JPEG, or WebP image, encoded in base64 data URI format | +| timezone | string | the user's new timezone. Must be in IANA timezone database format | +| list_private | bool | whether or not the user's member list should be hidden | +| custom_preferences | _custom preferences_ | the user's new custom preferences | + +### Get pride flags + +#### `GET /users/@me/flags` + +**Requires authentication.** Returns an array of the currently authenticated user's [pride flags](./#pride-flag). + +### Create pride flag + +#### `POST /users/@me/flags` + +**Requires authentication.** Creates a new pride flag. Returns a [pride flag](./#pride-flag) object on success. + +#### Request body parameters + +| Field | Type | Description | +| ----------- | ------ | -------------------------------------------------------------------------------------------------------- | +| flag | string | the flag image. This must be a PNG, JPEG, or WebP image, encoded in base64 data URI format. **Required** | +| name | string | the flag name. Must be between 1 and 100 characters. **Required** | +| description | string | the flag description or alt text. | + +### Edit pride flag + +#### `PATCH /users/@me/flags/{flag.id}` + +**Requires authentication.** Edits an existing pride flag. +Returns the updated [pride flag](./#pride-flag) object on success. + +#### Request body parameters + +| Field | Type | Description | +| ----------- | ------ | ---------------------------------------------------------------- | +| name | string | the flag's new name. Must be between 1 and 100 characters | +| description | string | the flag's new description. Must be between 1 and 500 characters | + +### Delete pride flag + +#### `DELETE /users/@me/flags/{flag.id}` + +**Requires authentication.** Deletes an existing pride flag. Returns `204 No Content` on success. + +### Reroll short ID + +#### `GET /users/@me/reroll` + +**Requires authentication.** Rerolls the user's short ID. Returns the updated [user](./users#user-object) on success. +If the user has already rerolled a short ID in the past hour, returns `403 Forbidden`. diff --git a/docs/api/errors.md b/docs/api/errors.md new file mode 100644 index 0000000..afb5245 --- /dev/null +++ b/docs/api/errors.md @@ -0,0 +1,33 @@ +# Error messages + +If there is an error in your request, or the server encounters an error while processing it, an error object will be returned. + +| Field | Type | Description | +| --------------- | ------- | --------------------------------------------------------------- | +| code | int | an [error code](./errors#error-codes) | +| message | ?string | a human-readable description of the error | +| details | ?string | more details about the error, most often for bad request errors | +| ratelimit_reset | ?int | the unix time when an expired rate limit will reset | + +### Error codes + +| Code | Description | +| ---- | ----------------------------------------------------------------------------------- | +| 400 | One or more fields in your requests was invalid, or some required field is missing. | +| 403 | You are not authorized to use this endpoint. | +| 404 | The endpoint was not found. | +| 405 | The method you are trying to use is not suported for this endpoint. | +| 429 | You have made too many requests in the last minute. | +| 500 | An internal server error occurred. | +| 1006 | That username is invalid. | +| 1007 | That username is already taken. | +| 2001 | User not found. | +| 2002 | This user's member list is private. | +| 2003 | You have reached the maximum number of pride flags. | +| 2004 | You are trying to reroll short IDs too quickly. | +| 3001 | Member not found. | +| 3002 | You have reached the maximum number of members. | +| 3003 | That member name is already in use. | +| 3004 | You can only edit your own members. | +| 4001 | Your request is too big (maximum 2 megabytes) | +| 4002 | This endpoint is unavailable to your account or the current token. | diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 0000000..0db8486 --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,91 @@ +# API reference + +pronouns.cc has a HTTP REST API to query and edit profiles, available at `https://pronouns.cc/api`. + +## Versioning + +The API is versioned, and versions must be explicitly specified for all endpoints. +The current, and only, available version is **1**. +The version is specified in the request path, like `https://pronouns.cc/api/v{version}`. + +| Version | Status | +| ------- | ---------- | +| 1 | Default | +| 2 | _Upcoming_ | + +The API version will be incremented for any breaking changes, including: + +- Removing entire endpoints +- Removing fields from responses +- Changing the behaviour of fields (in some situations, see below) + +However, the following types of changes are **not** considered breaking: + +- Adding new endpoints +- Adding new fields to requests or responses (your JSON serializer/deserializer should ignore unknown fields) +- Forcing fields related to removed features to their default value + +## Authentication + +Tokens can be created [here](https://pronouns.cc/settings/tokens). +Not all endpoints require authentication. For those that do, a token must be provided in the `Authorization` header. +The token _may_ be prefixed with `Bearer `, but this is not required. + +::: info +You are allowed to use site tokens (those stored in your browser's local storage) to access endpoints not available to API tokens, +however, these endpoints are not available to API tokens *for a reason*: +site tokens can take destructive actions such as deleting your account. +Additionally, endpoints that are not available to API tokens may have breaking changes without a major version bump. +::: + +## Request bodies + +::: info +The current API version doesn't distinguish between omitted and `null` keys yet. +However, the next version of the API will use `null` to unset keys, so clients should not rely on this behaviour. +::: + +Request bodies should be in JSON format. +For PATCH requests, **all keys are optional**. Omitted keys will not be updated, +and keys set to the zero value of their respective types (for strings: `""`, for numbers: `0`, for arrays: `[]`, etc.) +will be unset. + +## Documentation formatting + +The "type" column in tables is formatted as follows: + +- The type used is the _Go_ type, not the _JSON_ type. + For example, the documentation will use `int` for integers and `float` for floats, + even though they are both represented with JSON numbers. +- A _leading_ `?` signifies that the field may be omitted. +- A _trailing_ `?` signifies that the field may be null. + +## IDs + +::: info +pronouns.cc is [planning a transition](https://codeberg.org/pronounscc/pronouns.cc/issues/89) +to [Snowflake IDs](https://en.wikipedia.org/wiki/Snowflake_ID). +The information below pertains to the current ID format. +::: + +The API uses [xid](https://github.com/rs/xid) for unique IDs. These are always serialized as strings. +Although xids have timestamp information embedded in them, this is non-trivial to extract. +xids are unique across _all_ resources, they are never shared (for example, a user and a member cannot share the same ID). + +Users and members also have an additional ID type, `sid`. +These are randomly generated 5 or 6 letter strings, and are used for the prns.cc URL shortener. +They can be rerolled once per hour. + +## Images + +The API does not return full URLs to images such as avatars and pride flags. +Instead, the URL must be constructed manually using the `avatar` or `hash` fields. + +The default user and member avatar is served at `https://pronouns.cc/default/512.webp`. +All custom images are served on the base URL `https://cdn.pronouns.cc`, and are only available in WebP format. + +| Type | Format | +| ------------- | ------------------------------------------- | +| User avatar | `/users/{user.id}/{user.avatar}.webp` | +| Member avatar | `/members/{member.id}/{member.avatar}.webp` | +| Pride flag | `/flags/{flag.hash}.webp` | diff --git a/docs/api/ratelimits.md b/docs/api/ratelimits.md new file mode 100644 index 0000000..54b0d2d --- /dev/null +++ b/docs/api/ratelimits.md @@ -0,0 +1,31 @@ +# Rate limits + +The API has rate limits, generally separated by groups of endpoints. +If you exceed a rate limit, the API will start to return 429 errors. + +## Headers + +- `X-RateLimit-Bucket`: the bucket the rate limit is for (listed below) +- `X-RateLimit-Limit`: the total number of requests you can make per minute +- `X-RateLimit-Remaining`: the number of requests remaining in the current timeframe +- `X-RateLimit-Reset`: the unix timestamp that the number of requests resets at +- `Retry-After`: only if you hit a rate limit, the number of seconds until you can make requests again + +## Buckets + +Note that only the most specific matching bucket is used for rate limits. + +| Bucket | Rate limit per minute | Notes | +| ------------------------ | --------------------- | ----------------------------------------------------------- | +| / | 120 | Used as fallback if no other bucket exists for the endpoint | +| GET /users/\* | 60 | | +| GET /users/\*/members | 60 | | +| GET /users/\*/members/\* | 60 | | +| PATCH /users/@me | 10 | | +| POST /members | 10 | | +| GET /members/\* | 60 | | +| PATCH /members/\* | 20 | | +| DELETE /members/\* | 5 | | +| /auth/\* | 20 | | +| /auth/tokens | 10 | | +| /auth/invites | 10 | | diff --git a/docs/Caddyfile b/docs/config-examples/Caddyfile similarity index 100% rename from docs/Caddyfile rename to docs/config-examples/Caddyfile diff --git a/docs/pronouns-api.service b/docs/config-examples/pronouns-api.service similarity index 100% rename from docs/pronouns-api.service rename to docs/config-examples/pronouns-api.service diff --git a/docs/pronouns-clean.service b/docs/config-examples/pronouns-clean.service similarity index 100% rename from docs/pronouns-clean.service rename to docs/config-examples/pronouns-clean.service diff --git a/docs/pronouns-clean.timer b/docs/config-examples/pronouns-clean.timer similarity index 100% rename from docs/pronouns-clean.timer rename to docs/config-examples/pronouns-clean.timer diff --git a/docs/pronouns-exporter.service b/docs/config-examples/pronouns-exporter.service similarity index 100% rename from docs/pronouns-exporter.service rename to docs/config-examples/pronouns-exporter.service diff --git a/docs/pronouns-fe.service b/docs/config-examples/pronouns-fe.service similarity index 100% rename from docs/pronouns-fe.service rename to docs/config-examples/pronouns-fe.service diff --git a/docs/pronounscc.nginx b/docs/config-examples/pronounscc.nginx similarity index 100% rename from docs/pronounscc.nginx rename to docs/config-examples/pronounscc.nginx diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..48d671f --- /dev/null +++ b/docs/index.md @@ -0,0 +1,5 @@ +# pronouns.cc + +pronouns.cc is a service where you can create a list of your preferred names, pronouns, and other terms, and share it with other people. + +*Note: this documentation site is a work in progress, and currently only contains (partial) API documentation.* diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 0000000..ec26c6b --- /dev/null +++ b/docs/package.json @@ -0,0 +1,14 @@ +{ + "devDependencies": { + "vitepress": "1.0.0-rc.4" + }, + "scripts": { + "docs:dev": "vitepress dev", + "docs:build": "vitepress build", + "docs:preview": "vitepress preview" + }, + "dependencies": { + "@fontsource/fira-mono": "^5.0.8", + "@fontsource/firago": "^5.0.7" + } +} diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml new file mode 100644 index 0000000..a29277a --- /dev/null +++ b/docs/pnpm-lock.yaml @@ -0,0 +1,876 @@ +lockfileVersion: '6.0' + +dependencies: + '@fontsource/fira-mono': + specifier: ^5.0.8 + version: 5.0.8 + '@fontsource/firago': + specifier: ^5.0.7 + version: 5.0.7 + +devDependencies: + vitepress: + specifier: 1.0.0-rc.4 + version: 1.0.0-rc.4(@algolia/client-search@4.19.1)(search-insights@2.7.0) + +packages: + + /@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)(search-insights@2.7.0): + resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)(search-insights@2.7.0) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + dev: true + + /@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)(search-insights@2.7.0): + resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} + peerDependencies: + search-insights: '>= 1 < 3' + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1) + search-insights: 2.7.0 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + dev: true + + /@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1): + resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1) + '@algolia/client-search': 4.19.1 + algoliasearch: 4.19.1 + dev: true + + /@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1): + resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + dependencies: + '@algolia/client-search': 4.19.1 + algoliasearch: 4.19.1 + dev: true + + /@algolia/cache-browser-local-storage@4.19.1: + resolution: {integrity: sha512-FYAZWcGsFTTaSAwj9Std8UML3Bu8dyWDncM7Ls8g+58UOe4XYdlgzXWbrIgjaguP63pCCbMoExKr61B+ztK3tw==} + dependencies: + '@algolia/cache-common': 4.19.1 + dev: true + + /@algolia/cache-common@4.19.1: + resolution: {integrity: sha512-XGghi3l0qA38HiqdoUY+wvGyBsGvKZ6U3vTiMBT4hArhP3fOGLXpIINgMiiGjTe4FVlTa5a/7Zf2bwlIHfRqqg==} + dev: true + + /@algolia/cache-in-memory@4.19.1: + resolution: {integrity: sha512-+PDWL+XALGvIginigzu8oU6eWw+o76Z8zHbBovWYcrtWOEtinbl7a7UTt3x3lthv+wNuFr/YD1Gf+B+A9V8n5w==} + dependencies: + '@algolia/cache-common': 4.19.1 + dev: true + + /@algolia/client-account@4.19.1: + resolution: {integrity: sha512-Oy0ritA2k7AMxQ2JwNpfaEcgXEDgeyKu0V7E7xt/ZJRdXfEpZcwp9TOg4TJHC7Ia62gIeT2Y/ynzsxccPw92GA==} + dependencies: + '@algolia/client-common': 4.19.1 + '@algolia/client-search': 4.19.1 + '@algolia/transporter': 4.19.1 + dev: true + + /@algolia/client-analytics@4.19.1: + resolution: {integrity: sha512-5QCq2zmgdZLIQhHqwl55ZvKVpLM3DNWjFI4T+bHr3rGu23ew2bLO4YtyxaZeChmDb85jUdPDouDlCumGfk6wOg==} + dependencies: + '@algolia/client-common': 4.19.1 + '@algolia/client-search': 4.19.1 + '@algolia/requester-common': 4.19.1 + '@algolia/transporter': 4.19.1 + dev: true + + /@algolia/client-common@4.19.1: + resolution: {integrity: sha512-3kAIVqTcPrjfS389KQvKzliC559x+BDRxtWamVJt8IVp7LGnjq+aVAXg4Xogkur1MUrScTZ59/AaUd5EdpyXgA==} + dependencies: + '@algolia/requester-common': 4.19.1 + '@algolia/transporter': 4.19.1 + dev: true + + /@algolia/client-personalization@4.19.1: + resolution: {integrity: sha512-8CWz4/H5FA+krm9HMw2HUQenizC/DxUtsI5oYC0Jxxyce1vsr8cb1aEiSJArQT6IzMynrERif1RVWLac1m36xw==} + dependencies: + '@algolia/client-common': 4.19.1 + '@algolia/requester-common': 4.19.1 + '@algolia/transporter': 4.19.1 + dev: true + + /@algolia/client-search@4.19.1: + resolution: {integrity: sha512-mBecfMFS4N+yK/p0ZbK53vrZbL6OtWMk8YmnOv1i0LXx4pelY8TFhqKoTit3NPVPwoSNN0vdSN9dTu1xr1XOVw==} + dependencies: + '@algolia/client-common': 4.19.1 + '@algolia/requester-common': 4.19.1 + '@algolia/transporter': 4.19.1 + dev: true + + /@algolia/logger-common@4.19.1: + resolution: {integrity: sha512-i6pLPZW/+/YXKis8gpmSiNk1lOmYCmRI6+x6d2Qk1OdfvX051nRVdalRbEcVTpSQX6FQAoyeaui0cUfLYW5Elw==} + dev: true + + /@algolia/logger-console@4.19.1: + resolution: {integrity: sha512-jj72k9GKb9W0c7TyC3cuZtTr0CngLBLmc8trzZlXdfvQiigpUdvTi1KoWIb2ZMcRBG7Tl8hSb81zEY3zI2RlXg==} + dependencies: + '@algolia/logger-common': 4.19.1 + dev: true + + /@algolia/requester-browser-xhr@4.19.1: + resolution: {integrity: sha512-09K/+t7lptsweRTueHnSnmPqIxbHMowejAkn9XIcJMLdseS3zl8ObnS5GWea86mu3vy4+8H+ZBKkUN82Zsq/zg==} + dependencies: + '@algolia/requester-common': 4.19.1 + dev: true + + /@algolia/requester-common@4.19.1: + resolution: {integrity: sha512-BisRkcWVxrDzF1YPhAckmi2CFYK+jdMT60q10d7z3PX+w6fPPukxHRnZwooiTUrzFe50UBmLItGizWHP5bDzVQ==} + dev: true + + /@algolia/requester-node-http@4.19.1: + resolution: {integrity: sha512-6DK52DHviBHTG2BK/Vv2GIlEw7i+vxm7ypZW0Z7vybGCNDeWzADx+/TmxjkES2h15+FZOqVf/Ja677gePsVItA==} + dependencies: + '@algolia/requester-common': 4.19.1 + dev: true + + /@algolia/transporter@4.19.1: + resolution: {integrity: sha512-nkpvPWbpuzxo1flEYqNIbGz7xhfhGOKGAZS7tzC+TELgEmi7z99qRyTfNSUlW7LZmB3ACdnqAo+9A9KFBENviQ==} + dependencies: + '@algolia/cache-common': 4.19.1 + '@algolia/logger-common': 4.19.1 + '@algolia/requester-common': 4.19.1 + dev: true + + /@babel/helper-string-parser@7.22.5: + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.5: + resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/parser@7.22.10: + resolution: {integrity: sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.22.10 + dev: true + + /@babel/types@7.22.10: + resolution: {integrity: sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + to-fast-properties: 2.0.0 + dev: true + + /@docsearch/css@3.5.2: + resolution: {integrity: sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==} + dev: true + + /@docsearch/js@3.5.2(@algolia/client-search@4.19.1)(search-insights@2.7.0): + resolution: {integrity: sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==} + dependencies: + '@docsearch/react': 3.5.2(@algolia/client-search@4.19.1)(search-insights@2.7.0) + preact: 10.17.1 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + dev: true + + /@docsearch/react@3.5.2(@algolia/client-search@4.19.1)(search-insights@2.7.0): + resolution: {integrity: sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + dependencies: + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)(search-insights@2.7.0) + '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1) + '@docsearch/css': 3.5.2 + algoliasearch: 4.19.1 + search-insights: 2.7.0 + transitivePeerDependencies: + - '@algolia/client-search' + dev: true + + /@esbuild/android-arm64@0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@fontsource/fira-mono@5.0.8: + resolution: {integrity: sha512-8OJiUK2lzJjvDlkmamEfhtpL1cyFApg1Pk4kE5Pw5UTf1ETF3Yy/pprgwV5I+LQPDjuFvinsinT9xSUZ2b/zuQ==} + dev: false + + /@fontsource/firago@5.0.7: + resolution: {integrity: sha512-xuTYVOBSwev2IVp2dqgrnq3gABUnehn91Ii+R1TM5Jpvr86gCPrMxmqfL9fgpUb5r12u7U1LBVC20GypIy8jeg==} + dev: false + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@types/web-bluetooth@0.0.17: + resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==} + dev: true + + /@vitejs/plugin-vue@4.3.1(vite@4.4.9)(vue@3.3.4): + resolution: {integrity: sha512-tUBEtWcF7wFtII7ayNiLNDTCE1X1afySEo+XNVMNkFXaThENyCowIEX095QqbJZGTgoOcSVDJGlnde2NG4jtbQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 + vue: ^3.2.25 + dependencies: + vite: 4.4.9 + vue: 3.3.4 + dev: true + + /@vue/compiler-core@3.3.4: + resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} + dependencies: + '@babel/parser': 7.22.10 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + source-map-js: 1.0.2 + dev: true + + /@vue/compiler-dom@3.3.4: + resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} + dependencies: + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + dev: true + + /@vue/compiler-sfc@3.3.4: + resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} + dependencies: + '@babel/parser': 7.22.10 + '@vue/compiler-core': 3.3.4 + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-ssr': 3.3.4 + '@vue/reactivity-transform': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.2 + postcss: 8.4.28 + source-map-js: 1.0.2 + dev: true + + /@vue/compiler-ssr@3.3.4: + resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/shared': 3.3.4 + dev: true + + /@vue/devtools-api@6.5.0: + resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} + dev: true + + /@vue/reactivity-transform@3.3.4: + resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==} + dependencies: + '@babel/parser': 7.22.10 + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.2 + dev: true + + /@vue/reactivity@3.3.4: + resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} + dependencies: + '@vue/shared': 3.3.4 + dev: true + + /@vue/runtime-core@3.3.4: + resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} + dependencies: + '@vue/reactivity': 3.3.4 + '@vue/shared': 3.3.4 + dev: true + + /@vue/runtime-dom@3.3.4: + resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} + dependencies: + '@vue/runtime-core': 3.3.4 + '@vue/shared': 3.3.4 + csstype: 3.1.2 + dev: true + + /@vue/server-renderer@3.3.4(vue@3.3.4): + resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} + peerDependencies: + vue: 3.3.4 + dependencies: + '@vue/compiler-ssr': 3.3.4 + '@vue/shared': 3.3.4 + vue: 3.3.4 + dev: true + + /@vue/shared@3.3.4: + resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} + dev: true + + /@vueuse/core@10.3.0(vue@3.3.4): + resolution: {integrity: sha512-BEM5yxcFKb5btFjTSAFjTu5jmwoW66fyV9uJIP4wUXXU8aR5Hl44gndaaXp7dC5HSObmgbnR2RN+Un1p68Mf5Q==} + dependencies: + '@types/web-bluetooth': 0.0.17 + '@vueuse/metadata': 10.3.0 + '@vueuse/shared': 10.3.0(vue@3.3.4) + vue-demi: 0.14.5(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /@vueuse/integrations@10.3.0(focus-trap@7.5.2)(vue@3.3.4): + resolution: {integrity: sha512-Jgiv7oFyIgC6BxmDtiyG/fxyGysIds00YaY7sefwbhCZ2/tjEx1W/1WcsISSJPNI30in28+HC2J4uuU8184ekg==} + peerDependencies: + async-validator: '*' + axios: '*' + change-case: '*' + drauu: '*' + focus-trap: '*' + fuse.js: '*' + idb-keyval: '*' + jwt-decode: '*' + nprogress: '*' + qrcode: '*' + sortablejs: '*' + universal-cookie: '*' + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + dependencies: + '@vueuse/core': 10.3.0(vue@3.3.4) + '@vueuse/shared': 10.3.0(vue@3.3.4) + focus-trap: 7.5.2 + vue-demi: 0.14.5(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /@vueuse/metadata@10.3.0: + resolution: {integrity: sha512-Ema3YhNOa4swDsV0V7CEY5JXvK19JI/o1szFO1iWxdFg3vhdFtCtSTP26PCvbUpnUtNHBY2wx5y3WDXND5Pvnw==} + dev: true + + /@vueuse/shared@10.3.0(vue@3.3.4): + resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} + dependencies: + vue-demi: 0.14.5(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /algoliasearch@4.19.1: + resolution: {integrity: sha512-IJF5b93b2MgAzcE/tuzW0yOPnuUyRgGAtaPv5UUywXM8kzqfdwZTO4sPJBzoGz1eOy6H9uEchsJsBFTELZSu+g==} + dependencies: + '@algolia/cache-browser-local-storage': 4.19.1 + '@algolia/cache-common': 4.19.1 + '@algolia/cache-in-memory': 4.19.1 + '@algolia/client-account': 4.19.1 + '@algolia/client-analytics': 4.19.1 + '@algolia/client-common': 4.19.1 + '@algolia/client-personalization': 4.19.1 + '@algolia/client-search': 4.19.1 + '@algolia/logger-common': 4.19.1 + '@algolia/logger-console': 4.19.1 + '@algolia/requester-browser-xhr': 4.19.1 + '@algolia/requester-common': 4.19.1 + '@algolia/requester-node-http': 4.19.1 + '@algolia/transporter': 4.19.1 + dev: true + + /ansi-sequence-parser@1.1.1: + resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} + dev: true + + /body-scroll-lock@4.0.0-beta.0: + resolution: {integrity: sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==} + dev: true + + /csstype@3.1.2: + resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + dev: true + + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /focus-trap@7.5.2: + resolution: {integrity: sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==} + dependencies: + tabbable: 6.2.0 + dev: true + + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + + /magic-string@0.30.2: + resolution: {integrity: sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + dev: true + + /minisearch@6.1.0: + resolution: {integrity: sha512-PNxA/X8pWk+TiqPbsoIYH0GQ5Di7m6326/lwU/S4mlo4wGQddIcf/V//1f9TB0V4j59b57b+HZxt8h3iMROGvg==} + dev: true + + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /postcss@8.4.28: + resolution: {integrity: sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /preact@10.17.1: + resolution: {integrity: sha512-X9BODrvQ4Ekwv9GURm9AKAGaomqXmip7NQTZgY7gcNmr7XE83adOMJvd3N42id1tMFU7ojiynRsYnY6/BRFxLA==} + dev: true + + /rollup@3.28.0: + resolution: {integrity: sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /search-insights@2.7.0: + resolution: {integrity: sha512-GLbVaGgzYEKMvuJbHRhLi1qoBFnjXZGZ6l4LxOYPCp4lI2jDRB3jPU9/XNhMwv6kvnA9slTreq6pvK+b3o3aqg==} + engines: {node: '>=8.16.0'} + dev: true + + /shiki@0.14.3: + resolution: {integrity: sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==} + dependencies: + ansi-sequence-parser: 1.1.1 + jsonc-parser: 3.2.0 + vscode-oniguruma: 1.7.0 + vscode-textmate: 8.0.0 + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /vite@4.4.9: + resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.18.20 + postcss: 8.4.28 + rollup: 3.28.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitepress@1.0.0-rc.4(@algolia/client-search@4.19.1)(search-insights@2.7.0): + resolution: {integrity: sha512-JCQ89Bm6ECUTnyzyas3JENo00UDJeK8q1SUQyJYou+4Yz5BKEc/F3O21cu++DnUT2zXc0kvQ2Aj4BZCc/nioXQ==} + hasBin: true + dependencies: + '@docsearch/css': 3.5.2 + '@docsearch/js': 3.5.2(@algolia/client-search@4.19.1)(search-insights@2.7.0) + '@vitejs/plugin-vue': 4.3.1(vite@4.4.9)(vue@3.3.4) + '@vue/devtools-api': 6.5.0 + '@vueuse/core': 10.3.0(vue@3.3.4) + '@vueuse/integrations': 10.3.0(focus-trap@7.5.2)(vue@3.3.4) + body-scroll-lock: 4.0.0-beta.0 + focus-trap: 7.5.2 + mark.js: 8.11.1 + minisearch: 6.1.0 + shiki: 0.14.3 + vite: 4.4.9 + vue: 3.3.4 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - react + - react-dom + - sass + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - universal-cookie + dev: true + + /vscode-oniguruma@1.7.0: + resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} + dev: true + + /vscode-textmate@8.0.0: + resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} + dev: true + + /vue-demi@0.14.5(vue@3.3.4): + resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + dependencies: + vue: 3.3.4 + dev: true + + /vue@3.3.4: + resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-sfc': 3.3.4 + '@vue/runtime-dom': 3.3.4 + '@vue/server-renderer': 3.3.4(vue@3.3.4) + '@vue/shared': 3.3.4 + dev: true diff --git a/docs/public/logo.svg b/docs/public/logo.svg new file mode 100644 index 0000000..c04193b --- /dev/null +++ b/docs/public/logo.svg @@ -0,0 +1 @@ + diff --git a/docs/production.md b/docs/self-hosting.md similarity index 98% rename from docs/production.md rename to docs/self-hosting.md index 9afe530..a658d67 100644 --- a/docs/production.md +++ b/docs/self-hosting.md @@ -1,6 +1,6 @@ # Running pronouns.cc in production -The configuration files in this directory are the same files used to run pronouns.cc in production. +The configuration files in this directory are the same files used to run pronouns.cc in production. You might have to change paths and ports, but they should work fine as-is. ## Building pronouns.cc