OpenAPI spec at /api/docs with a Scalar viewer, opt-in via FEAT_API_DOCS

This commit is contained in:
jarek committed 2026-08-17 09:50:34 +02:00
1 parent ba8670af66
commit da26f7f764
251 files changed
+32497 -66

No files matched your search

+20
View File
@@ -4,6 +4,14 @@ import { getConfigSets, createConfigSet } from '$lib/server/db';
import { authorize } from '$lib/server/authorize';
import { auditConfigSet } from '$lib/server/audit';
/**
* @openapi
* summary: List all config sets (reusable bundles of env vars, labels, ports, volumes, and runtime defaults)
* resp-200: array<{id:integer!, name:string!, description:string, envVars:array<{key:string!, value:string!}>, labels:array<{key:string!, value:string!}>, ports:array<{hostPort:string!, containerPort:string!, protocol:string!}>, volumes:array<{hostPath:string!, containerPath:string!, mode:string!}>, networkMode:string!, restartPolicy:string!, createdAt:string!, updatedAt:string!}>
* resp-200-example: [{"id":1,"name":"web-defaults","description":"Defaults for web stacks","envVars":[{"key":"TZ","value":"UTC"}],"labels":[],"ports":[],"volumes":[],"networkMode":"bridge","restartPolicy":"unless-stopped","createdAt":"2026-06-01T10:00:00Z","updatedAt":"2026-06-01T10:00:00Z"}]
* resp-403: Permission denied (requires configsets:view)
* resp-500: Failed to fetch config sets
*/
export const GET: RequestHandler = async ({ cookies }) => {
const auth = await authorize(cookies);
if (auth.authEnabled && !await auth.can('configsets', 'view')) {
@@ -19,6 +27,18 @@ export const GET: RequestHandler = async ({ cookies }) => {
}
};
/**
* @openapi
* summary: Create a new config set
* body: {name:string!, description:string, envVars:array<{key:string!, value:string!}>, labels:array<{key:string!, value:string!}>, ports:array<{hostPort:string!, containerPort:string!, protocol:string!}>, volumes:array<{hostPath:string!, containerPath:string!, mode:string!}>, networkMode:string, restartPolicy:string}
* body-example: {"name":"web-defaults","description":"Defaults for web stacks","envVars":[{"key":"TZ","value":"UTC"}],"networkMode":"bridge","restartPolicy":"unless-stopped"}
* resp-201: {id:integer!, name:string!, description:string, envVars:array<{key:string!, value:string!}>, labels:array<{key:string!, value:string!}>, ports:array<{hostPort:string!, containerPort:string!, protocol:string!}>, volumes:array<{hostPath:string!, containerPath:string!, mode:string!}>, networkMode:string!, restartPolicy:string!, createdAt:string!, updatedAt:string!}
* resp-201-desc: Config set created
* resp-201-example: {"id":1,"name":"web-defaults","description":"Defaults for web stacks","envVars":[{"key":"TZ","value":"UTC"}],"labels":[],"ports":[],"volumes":[],"networkMode":"bridge","restartPolicy":"unless-stopped","createdAt":"2026-06-01T10:00:00Z","updatedAt":"2026-06-01T10:00:00Z"}
* resp-400: Name is required, or a config set with this name already exists
* resp-403: Permission denied (requires configsets:create)
* resp-500: Failed to create config set
*/
export const POST: RequestHandler = async (event) => {
const { request, cookies } = event;
const auth = await authorize(cookies);
@@ -5,6 +5,17 @@ import { authorize } from '$lib/server/authorize';
import { auditConfigSet } from '$lib/server/audit';
import { computeAuditDiff } from '$lib/utils/diff';
/**
* @openapi
* summary: Fetch a single config set by its numeric ID
* path: id:integer! Config set ID (from GET /api/config-sets)
* resp-200: {id:integer!, name:string!, description:string, envVars:array<{key:string!, value:string!}>, labels:array<{key:string!, value:string!}>, ports:array<{hostPort:string!, containerPort:string!, protocol:string!}>, volumes:array<{hostPath:string!, containerPath:string!, mode:string!}>, networkMode:string!, restartPolicy:string!, createdAt:string!, updatedAt:string!}
* resp-200-example: {"id":1,"name":"web-defaults","description":"Defaults for web stacks","envVars":[{"key":"TZ","value":"UTC"}],"labels":[],"ports":[],"volumes":[],"networkMode":"bridge","restartPolicy":"unless-stopped","createdAt":"2026-06-01T10:00:00Z","updatedAt":"2026-06-01T10:00:00Z"}
* resp-400: Invalid ID
* resp-403: Permission denied (requires configsets:view)
* resp-404: Config set not found
* resp-500: Failed to fetch config set
*/
export const GET: RequestHandler = async ({ params, cookies }) => {
const auth = await authorize(cookies);
if (auth.authEnabled && !await auth.can('configsets', 'view')) {
@@ -29,6 +40,19 @@ export const GET: RequestHandler = async ({ params, cookies }) => {
}
};
/**
* @openapi
* summary: Update an existing config set by ID
* path: id:integer! Config set ID (from GET /api/config-sets)
* body: {name:string, description:string, envVars:array<{key:string!, value:string!}>, labels:array<{key:string!, value:string!}>, ports:array<{hostPort:string!, containerPort:string!, protocol:string!}>, volumes:array<{hostPath:string!, containerPath:string!, mode:string!}>, networkMode:string, restartPolicy:string}
* body-example: {"name":"web-defaults","networkMode":"host","restartPolicy":"always"}
* resp-200: {id:integer!, name:string!, description:string, envVars:array<{key:string!, value:string!}>, labels:array<{key:string!, value:string!}>, ports:array<{hostPort:string!, containerPort:string!, protocol:string!}>, volumes:array<{hostPath:string!, containerPath:string!, mode:string!}>, networkMode:string!, restartPolicy:string!, createdAt:string!, updatedAt:string!}
* resp-200-example: {"id":1,"name":"web-defaults","description":"Defaults for web stacks","envVars":[],"labels":[],"ports":[],"volumes":[],"networkMode":"host","restartPolicy":"always","createdAt":"2026-06-01T10:00:00Z","updatedAt":"2026-06-02T12:00:00Z"}
* resp-400: Invalid ID, or a config set with this name already exists
* resp-403: Permission denied (requires configsets:edit)
* resp-404: Config set not found
* resp-500: Failed to update config set
*/
export const PUT: RequestHandler = async (event) => {
const { params, request, cookies } = event;
const auth = await authorize(cookies);
@@ -81,6 +105,17 @@ export const PUT: RequestHandler = async (event) => {
}
};
/**
* @openapi
* summary: Delete a config set by ID
* path: id:integer! Config set ID (from GET /api/config-sets)
* resp-200: {success:boolean!}
* resp-200-example: {"success":true}
* resp-400: Invalid ID
* resp-403: Permission denied (requires configsets:delete)
* resp-404: Config set not found
* resp-500: Failed to delete config set
*/
export const DELETE: RequestHandler = async (event) => {
const { params, cookies } = event;
const auth = await authorize(cookies);