package api import ( "net/http" "strconv" ) const openAPISpecYAML = `openapi: 3.0.3 info: title: BlueArchive Toolkit bat-api version: 0.1.0 description: Resource bootstrap, read-only distribution, and authenticated Rust bat control proxy. servers: - url: http://127.0.0.1:18080 security: - bearerAuth: [] - queryToken: [] paths: /healthz: get: summary: Liveness and refresh diagnostics responses: "200": description: Service is alive. /readyz: get: summary: Release readiness responses: "200": description: A distributable release is available. "503": description: No distributable release is available. /v1/bootstrap: get: summary: Startup resource bootstrap responses: "200": description: Resource bootstrap response. "503": description: Release is not ready. /v1/launcher/bootstrap: get: summary: Launcher-shaped resource bootstrap responses: "200": description: Launcher bootstrap response. "503": description: Release is not ready. /api/launcher/game/config: get: summary: Resource-only launcher game config compatibility responses: "200": description: Launcher envelope with resource metadata. /api/launcher/game/config/json: get: summary: Resource-only launcher manifest URL compatibility parameters: - name: version in: query schema: type: string - name: file_path in: query schema: type: string responses: "200": description: Launcher envelope pointing to resource bootstrap JSON. /api/launcher/advanced/game/download/cdn: get: summary: Resource-only launcher CDN compatibility responses: "200": description: Launcher envelope with public base URL as CDN root. /v1/release: get: summary: Current release summary responses: "200": description: Release summary. /v1/resources: get: summary: Paginated resource manifest entries parameters: - name: offset in: query schema: type: integer minimum: 0 - name: limit in: query schema: type: integer minimum: 1 maximum: 1000 responses: "200": description: Resource list page. /v1/server-info: get: summary: Rewritten server-info document responses: "200": description: Server-info JSON with AddressablesCatalogUrlRoot rewritten. /openapi.yaml: get: summary: OpenAPI document responses: "200": description: OpenAPI YAML. /admin/: get: summary: Admin control entry responses: "200": description: Admin links and allowlisted control actions. /admin/schedules: get: summary: List Rust-owned resource workflow schedules parameters: - name: id in: query schema: type: string - name: group in: query schema: type: string enum: [res, parse, i18n] - name: enabled in: query schema: type: boolean responses: "200": description: Current schedule JSON report. "401": description: Missing or invalid admin token. "503": description: Rust bat schedule backend is unavailable. /admin/control/{action}: post: summary: Forward an allowlisted control or schedule action to Rust bat parameters: - name: action in: path required: true schema: type: string enum: [reload, refresh, restart, sync, verify, repair, catalog-refresh, schedule-add, schedule-update, schedule-remove, schedule-run] requestBody: required: false content: application/json: schema: type: object additionalProperties: false properties: force: type: boolean id: type: string group: type: string action: type: string args: type: array items: type: string next_run_unix_seconds: type: integer format: int64 delay_seconds: type: integer format: int64 every_seconds: type: integer format: int64 count: type: integer format: int64 max_runs: type: integer format: int64 minimum: 1 clear_args: type: boolean clear_every: type: boolean enabled: type: boolean responses: "202": description: Rust bat accepted the control request. "400": description: Invalid action parameters. "401": description: Missing or invalid admin token. "403": description: Control is not exposed or no admin token is configured. "501": description: Rust bat does not implement the requested control action. "502": description: Rust bat rejected the control request. /prod-clientpatch.bluearchiveyostar.com/{path}: get: summary: CDN-shaped resource bytes parameters: - name: path in: path required: true schema: type: string responses: "200": description: Resource bytes. "206": description: Partial resource bytes. head: summary: CDN-shaped resource metadata responses: "200": description: Resource headers. components: securitySchemes: bearerAuth: type: http scheme: bearer queryToken: type: apiKey in: query name: bat_token ` func (s *Server) handleOpenAPI(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet && r.Method != http.MethodHead { writeErrorJSON(w, http.StatusMethodNotAllowed, "method_not_allowed", "method not allowed") return } w.Header().Set("Content-Type", "application/yaml; charset=utf-8") w.Header().Set("Cache-Control", "no-store") w.Header().Set("Content-Length", strconv.Itoa(len(openAPISpecYAML))) w.WriteHeader(http.StatusOK) if r.Method == http.MethodHead { return } _, _ = w.Write([]byte(openAPISpecYAML)) }