mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-10-16 06:25:42 -04:00
feat(docs): use parameterized OpenAPI server URL
Replace the static `https://sofa.example.com/api/v1` server entry with a variable-based URL (`{protocol}://{host}:{port}/api/v1`) so the spec works against any instance out of the box. Also move the output path from `docs/openapi.json` to `docs/public/openapi.json` so the file is served as a static asset by the docs site.
This commit is contained in:
58 files changed
+95
-60
No files matched your search
@@ -1,4 +1,7 @@
|
|||||||
import { OpenAPIGenerator } from "@orpc/openapi";
|
import {
|
||||||
|
OpenAPIGenerator,
|
||||||
|
type OpenAPIGeneratorGenerateOptions,
|
||||||
|
} from "@orpc/openapi";
|
||||||
import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
|
import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
|
||||||
import {
|
import {
|
||||||
BackupSchema,
|
BackupSchema,
|
||||||
@@ -214,7 +217,7 @@ export function normalizeOpenApiSpec<T extends OpenApiSpec>(spec: T): T {
|
|||||||
export async function generateOpenApiSpec(options: {
|
export async function generateOpenApiSpec(options: {
|
||||||
title: string;
|
title: string;
|
||||||
version: string;
|
version: string;
|
||||||
servers: Array<{ url: string }>;
|
servers: OpenAPIGeneratorGenerateOptions["servers"];
|
||||||
sessionCookieName: string;
|
sessionCookieName: string;
|
||||||
tags?: Array<{ name: string; description?: string }>;
|
tags?: Array<{ name: string; description?: string }>;
|
||||||
}): Promise<OpenApiSpec> {
|
}): Promise<OpenApiSpec> {
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Delete the current user's profile avatar, reverting to the default.
|
Delete the current user's profile avatar, reverting to the default.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/account/avatar","method":"delete"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/account/avatar","method":"delete"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Change the current user's display name.
|
Change the current user's display name.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/account/name","method":"put"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/account/name","method":"put"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Upload a new profile avatar image. Accepts JPEG, PNG, WebP, or GIF up to 2 MB.
|
Upload a new profile avatar image. Accepts JPEG, PNG, WebP, or GIF up to 2 MB.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/account/avatar","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/account/avatar","method":"post"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Create a new manual database backup. The backup is tagged as a manual backup.
|
Create a new manual database backup. The backup is tagged as a manual backup.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/backups","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/backups","method":"post"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Permanently delete a database backup file by filename.
|
Permanently delete a database backup file by filename.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/backups/{filename}","method":"delete"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/backups/{filename}","method":"delete"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch all database backups with their sizes and creation times.
|
Fetch all database backups with their sizes and creation times.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/backups","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/backups","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Upload a database backup file and restore it. A pre-restore backup is automatically created before overwriting the current database.
|
Upload a database backup file and restore it. A pre-restore backup is automatically created before overwriting the current database.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/backups/restore","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/backups/restore","method":"post"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch the current automated backup schedule configuration.
|
Fetch the current automated backup schedule configuration.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/backups/schedule","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/backups/schedule","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Update the automated backup schedule. Only provided fields are changed; omitted fields keep their current values.
|
Update the automated backup schedule. Only provided fields are changed; omitted fields keep their current values.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/backups/schedule","method":"put"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/backups/schedule","method":"put"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Delete all cached TMDB images from disk. Images will be re-downloaded on demand.
|
Delete all cached TMDB images from disk. Images will be re-downloaded on demand.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/cache/purge-images","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/cache/purge-images","method":"post"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Delete un-enriched stub titles not in any user's library and clean up orphaned person records.
|
Delete un-enriched stub titles not in any user's library and clean up orphaned person records.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/cache/purge-metadata","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/cache/purge-metadata","method":"post"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Check whether new user registration is currently open or closed.
|
Check whether new user registration is currently open or closed.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/registration","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/registration","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch whether anonymous telemetry is enabled and when the last report was sent.
|
Fetch whether anonymous telemetry is enabled and when the last report was sent.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/telemetry","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/telemetry","method":"get"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Open or close new user registration.
|
Open or close new user registration.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/registration","method":"put"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/registration","method":"put"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Enable or disable anonymous telemetry reporting.
|
Enable or disable anonymous telemetry reporting.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/telemetry","method":"put"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/telemetry","method":"put"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Enable or disable automatic update checks against the public API.
|
Enable or disable automatic update checks against the public API.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/update-check","method":"put"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/update-check","method":"put"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Manually trigger a background cron job by name. The job runs asynchronously.
|
Manually trigger a background cron job by name. The job runs asynchronously.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/jobs/trigger","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/jobs/trigger","method":"post"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch whether automatic update checks are enabled, and the latest cached check result if available.
|
Fetch whether automatic update checks are enabled, and the latest cached check result if available.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/admin/update-check","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/admin/update-check","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch TV shows the user is currently watching, with the next unwatched episode and progress for each.
|
Fetch TV shows the user is currently watching, with the next unwatched episode and progress for each.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/dashboard/continue-watching","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/dashboard/continue-watching","method":"get"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch all titles in the user's library with their tracking statuses.
|
Fetch all titles in the user's library with their tracking statuses.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/dashboard/library","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/dashboard/library","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch personalized title recommendations based on the user's library and watch history.
|
Fetch personalized title recommendations based on the user's library and watch history.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/dashboard/recommendations","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/dashboard/recommendations","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch summary counts for the current user: movies watched this month, episodes this week, library size, and completed titles.
|
Fetch summary counts for the current user: movies watched this month, episodes this week, library size, and completed titles.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/dashboard/stats","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/dashboard/stats","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch the user's watch counts grouped by time period. Useful for rendering activity charts.
|
Fetch the user's watch counts grouped by time period. Useful for rendering activity charts.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/dashboard/watch-history","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/dashboard/watch-history","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Browse movies or TV shows filtered by genre, sorted by popularity. Returns user statuses and episode progress.
|
Browse movies or TV shows filtered by genre, sorted by popularity. Returns user statuses and episode progress.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/discover","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/discover","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Record watch events for multiple episodes at once. Useful for marking a range of episodes as watched.
|
Record watch events for multiple episodes at once. Useful for marking a range of episodes as watched.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/episodes/batch-watch","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/episodes/batch-watch","method":"post"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Remove the watch record for a single TV episode.
|
Remove the watch record for a single TV episode.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/episodes/{id}/unwatch","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/episodes/{id}/unwatch","method":"post"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Record a watch event for a single TV episode.
|
Record a watch event for a single TV episode.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/episodes/{id}/watch","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/episodes/{id}/watch","method":"post"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch the list of TMDB genres for movies or TV shows. Used to populate genre filters for discovery.
|
Fetch the list of TMDB genres for movies or TV shows. Used to populate genre filters for discovery.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/explore/genres","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/explore/genres","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch currently popular movies or TV shows from TMDB with the user's tracking statuses.
|
Fetch currently popular movies or TV shows from TMDB with the user's tracking statuses.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/explore/popular","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/explore/popular","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch today's trending movies and/or TV shows from TMDB, including a featured hero title and the user's statuses.
|
Fetch today's trending movies and/or TV shows from TMDB, including a featured hero title and the user's statuses.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/explore/trending","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/explore/trending","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Create a new media server integration or update an existing one. Generates a unique webhook token for the provider.
|
Create a new media server integration or update an existing one. Generates a unique webhook token for the provider.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/integrations","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/integrations","method":"post"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Remove a media server integration and all its event history.
|
Remove a media server integration and all its event history.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/integrations/{provider}","method":"delete"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/integrations/{provider}","method":"delete"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch all configured media server integrations for the current user, including recent webhook/sync events for each.
|
Fetch all configured media server integrations for the current user, including recent webhook/sync events for each.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/integrations","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/integrations","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Generate a new webhook token for an integration. The old token is immediately invalidated.
|
Generate a new webhook token for an integration. The old token is immediately invalidated.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/integrations/{provider}/regenerate-token","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/integrations/{provider}/regenerate-token","method":"post"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch a person's profile and filmography. Imports from TMDB on first access if not yet cached locally.
|
Fetch a person's profile and filmography. Imports from TMDB on first access if not yet cached locally.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/people/{id}","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/people/{id}","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Look up or import a person by their TMDB ID. Returns the internal ID for use with other endpoints.
|
Look up or import a person by their TMDB ID. Returns the internal ID for use with other endpoints.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/people/resolve","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/people/resolve","method":"post"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Full-text search across movies, TV shows, and people via TMDB. Optionally filter by media type.
|
Full-text search across movies, TV shows, and people via TMDB. Optionally filter by media type.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/search","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/search","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Remove all watch records for episodes in a season in a single operation.
|
Remove all watch records for episodes in a season in a single operation.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/seasons/{id}/unwatch","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/seasons/{id}/unwatch","method":"post"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Mark all episodes in a season as watched in a single operation.
|
Mark all episodes in a season as watched in a single operation.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/seasons/{id}/watch","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/seasons/{id}/watch","method":"post"}]} />
|
||||||
@@ -17,4 +17,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch the authentication configuration including OIDC availability, password login status, and registration state. Does not require authentication.
|
Fetch the authentication configuration including OIDC availability, password login status, and registration state. Does not require authentication.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/system/auth-config","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/system/auth-config","method":"get"}]} />
|
||||||
@@ -17,4 +17,4 @@ _openapi:
|
|||||||
|
|
||||||
Comprehensive health check covering database, TMDB connectivity, cron jobs, image cache, backups, and environment. Does not require authentication.
|
Comprehensive health check covering database, TMDB connectivity, cron jobs, image cache, backups, and environment. Does not require authentication.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/system/health","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/system/health","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch public information about this Sofa instance. Does not require authentication. Used by the login screen to display instance details.
|
Fetch public information about this Sofa instance. Does not require authentication. Used by the login screen to display instance details.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/system/public-info","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/system/public-info","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Quick check of whether TMDB is configured. Does not require authentication.
|
Quick check of whether TMDB is configured. Does not require authentication.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/system/status","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/system/status","method":"get"}]} />
|
||||||
@@ -17,4 +17,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch full title metadata including seasons, cast, and streaming availability. Imports from TMDB on first access if not yet cached locally.
|
Fetch full title metadata including seasons, cast, and streaming availability. Imports from TMDB on first access if not yet cached locally.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/{id}","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/{id}","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch full season and episode data from TMDB for a TV show. Required before tracking individual episodes.
|
Fetch full season and episode data from TMDB for a TV show. Required before tracking individual episodes.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/{id}/hydrate-seasons","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/{id}/hydrate-seasons","method":"post"}]} />
|
||||||
@@ -17,4 +17,4 @@ _openapi:
|
|||||||
|
|
||||||
Import a title by TMDB ID and add it to the user's watchlist in one step. If the title already exists in the user's library, returns alreadyAdded: true.
|
Import a title by TMDB ID and add it to the user's watchlist in one step. If the title already exists in the user's library, returns alreadyAdded: true.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/quick-add","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/quick-add","method":"post"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch similar titles based on locally cached recommendation data, along with the user's statuses for each.
|
Fetch similar titles based on locally cached recommendation data, along with the user's statuses for each.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/{id}/recommendations","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/{id}/recommendations","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Look up or import a title by its TMDB ID and media type. Returns the internal ID for use with other endpoints.
|
Look up or import a title by its TMDB ID and media type. Returns the internal ID for use with other endpoints.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/resolve","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/resolve","method":"post"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Set a 0-5 star rating for a title. Use 0 to clear the rating.
|
Set a 0-5 star rating for a title. Use 0 to clear the rating.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/{id}/rating","method":"put"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/{id}/rating","method":"put"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Set the user's tracking status for a title. Use null to remove the title from the library entirely.
|
Set the user's tracking status for a title. Use null to remove the title from the library entirely.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/{id}/status","method":"put"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/{id}/status","method":"put"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Fetch the current user's tracking status, rating, and watched episode IDs for a title.
|
Fetch the current user's tracking status, rating, and watched episode IDs for a title.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/{id}/user-info","method":"get"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/{id}/user-info","method":"get"}]} />
|
||||||
@@ -16,4 +16,4 @@ _openapi:
|
|||||||
|
|
||||||
Mark every episode of a TV show as watched. Requires seasons to be hydrated first.
|
Mark every episode of a TV show as watched. Requires seasons to be hydrated first.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/{id}/watch-all","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/{id}/watch-all","method":"post"}]} />
|
||||||
@@ -14,4 +14,4 @@ _openapi:
|
|||||||
|
|
||||||
Log a watch event for a movie. Automatically sets status to completed.
|
Log a watch event for a movie. Automatically sets status to completed.
|
||||||
|
|
||||||
<APIPage document={"./openapi.json"} operations={[{"path":"/titles/{id}/watch","method":"post"}]} />
|
<APIPage document={"./public/openapi.json"} operations={[{"path":"/titles/{id}/watch","method":"post"}]} />
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
"mobile-app",
|
"mobile-app",
|
||||||
"telemetry",
|
"telemetry",
|
||||||
"---API Reference---",
|
"---API Reference---",
|
||||||
"...api"
|
"...api",
|
||||||
|
"external:[openapi.json](/openapi.json)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,22 @@
|
|||||||
},
|
},
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "https://sofa.example.com/api/v1"
|
"url": "{protocol}://{host}:{port}/api/v1",
|
||||||
|
"variables": {
|
||||||
|
"protocol": {
|
||||||
|
"default": "http",
|
||||||
|
"enum": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"host": {
|
||||||
|
"default": "localhost"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"default": "3000"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createOpenAPI } from "fumadocs-openapi/server";
|
import { createOpenAPI } from "fumadocs-openapi/server";
|
||||||
|
|
||||||
export const openapi = createOpenAPI({
|
export const openapi = createOpenAPI({
|
||||||
input: ["./openapi.json"],
|
input: ["./public/openapi.json"],
|
||||||
});
|
});
|
||||||
@@ -7,7 +7,23 @@ import {
|
|||||||
const spec = await generateOpenApiSpec({
|
const spec = await generateOpenApiSpec({
|
||||||
title: "Sofa API",
|
title: "Sofa API",
|
||||||
version: packageJson.version || "1.0.0",
|
version: packageJson.version || "1.0.0",
|
||||||
servers: [{ url: "https://sofa.example.com/api/v1" }],
|
servers: [
|
||||||
|
{
|
||||||
|
url: "{protocol}://{host}:{port}/api/v1",
|
||||||
|
variables: {
|
||||||
|
protocol: {
|
||||||
|
default: "http",
|
||||||
|
enum: ["http", "https"],
|
||||||
|
},
|
||||||
|
host: {
|
||||||
|
default: "localhost",
|
||||||
|
},
|
||||||
|
port: {
|
||||||
|
default: "3000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
sessionCookieName: "better-auth.session_token",
|
sessionCookieName: "better-auth.session_token",
|
||||||
tags: [...openApiTags],
|
tags: [...openApiTags],
|
||||||
});
|
});
|
||||||
@@ -55,5 +71,5 @@ for (const pathItem of Object.values(spec.paths ?? {})) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Bun.write("docs/openapi.json", JSON.stringify(spec, null, 2));
|
await Bun.write("docs/public/openapi.json", JSON.stringify(spec, null, 2));
|
||||||
console.log("OpenAPI spec written to docs/openapi.json");
|
console.log("OpenAPI spec written to docs/openapi.json");
|
||||||
Reference in new issue
Block a user