mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 06:34:54 +08:00
871 lines
25 KiB
Go
871 lines
25 KiB
Go
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/releases:
|
|
get:
|
|
summary: Rust-owned official and localized release history
|
|
parameters:
|
|
- name: channel
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [official, localized]
|
|
responses:
|
|
"200":
|
|
description: Release history and manifest/artifact integrity summaries.
|
|
"503":
|
|
description: Rust bat release backend is unavailable.
|
|
/v1/distribution:
|
|
get:
|
|
summary: Select a verified official or localized release for distribution
|
|
parameters:
|
|
- name: channel
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [official, localized]
|
|
default: official
|
|
- name: release_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: destination
|
|
in: query
|
|
description: Optional release-relative path for single-entry lookup; Rust returns exactly one entry and revalidates the selected channel's actual bytes and BLAKE3.
|
|
schema:
|
|
type: string
|
|
- name: offset
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 0
|
|
- name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 1000
|
|
responses:
|
|
"200":
|
|
description: Rust-verified selected release and resource manifest page.
|
|
"409":
|
|
description: Selected release is missing, stale, damaged, or not distributable.
|
|
"503":
|
|
description: Rust bat release backend is unavailable.
|
|
/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/dashboard/:
|
|
get:
|
|
summary: Embedded bat-api dashboard
|
|
security: []
|
|
responses:
|
|
"200":
|
|
description: Static dashboard HTML.
|
|
/admin/:
|
|
get:
|
|
summary: Admin control entry
|
|
responses:
|
|
"200":
|
|
description: Admin links and allowlisted control actions.
|
|
/admin/diagnostics:
|
|
get:
|
|
summary: Read Rust daemon doctor diagnostics
|
|
responses:
|
|
"200":
|
|
description: Current daemon.doctor report.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat diagnostics backend is unavailable.
|
|
/admin/logs:
|
|
get:
|
|
summary: Read Rust daemon log tail
|
|
parameters:
|
|
- name: tail
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 2000
|
|
responses:
|
|
"200":
|
|
description: Current daemon.logs report.
|
|
"400":
|
|
description: Invalid log query.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat log backend is unavailable.
|
|
/admin/tasks:
|
|
get:
|
|
summary: List Rust-owned async daemon tasks
|
|
responses:
|
|
"200":
|
|
description: Current task.list report.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat task backend is unavailable.
|
|
/admin/tasks/status:
|
|
get:
|
|
summary: Read one Rust-owned async daemon task
|
|
parameters:
|
|
- name: task_id
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Current task.status report.
|
|
"400":
|
|
description: Missing or invalid task_id.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat task backend is unavailable.
|
|
/admin/tasks/logs:
|
|
get:
|
|
summary: Read one Rust-owned async daemon task log
|
|
parameters:
|
|
- name: task_id
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Current task.logs report.
|
|
"400":
|
|
description: Missing or invalid task_id.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat task backend is unavailable.
|
|
/admin/parse/status:
|
|
get:
|
|
summary: Read Rust-owned parse/TextUnit index status
|
|
responses:
|
|
"200":
|
|
description: Current parse.status report.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat parse backend is unavailable.
|
|
/admin/parse/text-units:
|
|
get:
|
|
summary: Query Rust-owned TextUnit index entries
|
|
parameters:
|
|
- name: offset
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 0
|
|
- name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 1000
|
|
- name: destination
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: path_pattern
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: archive_entry
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: path_id
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
- name: class_id
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
- name: field_path
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: format
|
|
in: query
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Current parse.text_units report.
|
|
"400":
|
|
description: Invalid TextUnit query.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat parse backend is unavailable.
|
|
/admin/parse/errors:
|
|
get:
|
|
summary: Query Rust-owned TextUnit extraction diagnostics
|
|
parameters:
|
|
- name: offset
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 0
|
|
- name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 1000
|
|
- name: destination
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: path_pattern
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: archive_entry
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: path_id
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
- name: class_id
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
- name: field_path
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: format
|
|
in: query
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Current parse.errors report.
|
|
"400":
|
|
description: Invalid parse error query.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat parse backend is unavailable.
|
|
/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/translation/tasks:
|
|
get:
|
|
summary: List Rust-owned translation task worker status
|
|
parameters:
|
|
- name: offset
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 0
|
|
- name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 1000
|
|
- name: task_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: release_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: destination
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: archive_entry
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: worker_status
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: parse_status
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: format
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: has_reason
|
|
in: query
|
|
schema:
|
|
type: boolean
|
|
- name: has_failure_reason
|
|
in: query
|
|
schema:
|
|
type: boolean
|
|
responses:
|
|
"200":
|
|
description: Current translation task JSON report from Rust bat.
|
|
"400":
|
|
description: Invalid translation task query.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat translation backend is unavailable.
|
|
/admin/translation/handoff:
|
|
get:
|
|
summary: Read Rust-owned translation handoff state
|
|
responses:
|
|
"200":
|
|
description: Current translation handoff JSON report from Rust bat.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat translation backend is unavailable.
|
|
/admin/translation/memory/summary:
|
|
get:
|
|
summary: Read Rust-owned Translation Memory summary
|
|
parameters:
|
|
- name: translation_memory_path
|
|
in: query
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Translation Memory availability and candidate/trusted counts.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat Translation Memory backend is unavailable.
|
|
/admin/translation/memory/query:
|
|
get:
|
|
summary: Query Rust-owned Translation Memory records
|
|
parameters:
|
|
- name: source_text
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: source_context
|
|
in: query
|
|
description: JSON object whose values are strings.
|
|
schema:
|
|
type: string
|
|
- name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
maximum: 1000
|
|
default: 100
|
|
- name: translation_memory_path
|
|
in: query
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Translation Memory matches with reuse decision and provenance.
|
|
"400":
|
|
description: Missing source text or invalid context/limit.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat Translation Memory backend is unavailable.
|
|
/admin/translation/glossary/summary:
|
|
get:
|
|
summary: Read Rust-owned Glossary summary
|
|
parameters:
|
|
- name: glossary_path
|
|
in: query
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Glossary availability and review-state counts.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat Glossary backend is unavailable.
|
|
/admin/translation/glossary/query:
|
|
get:
|
|
summary: Query Rust-owned Glossary terms
|
|
parameters:
|
|
- name: source_text
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: category
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: review_status
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [draft, approved, deprecated, rejected]
|
|
- name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
maximum: 1000
|
|
default: 100
|
|
- name: glossary_path
|
|
in: query
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Glossary terms with source and review history.
|
|
"400":
|
|
description: Invalid Glossary query.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat Glossary backend is unavailable.
|
|
/admin/translation/glossary/diagnose:
|
|
get:
|
|
summary: Run deterministic Glossary diagnostics
|
|
parameters:
|
|
- name: source_text
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: context
|
|
in: query
|
|
description: JSON object whose values are strings.
|
|
schema:
|
|
type: string
|
|
- name: glossary_path
|
|
in: query
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Glossary constraints, diagnostics, blocked decision, and stable qa_identity.
|
|
"400":
|
|
description: Missing source text or invalid context.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat Glossary backend is unavailable.
|
|
/admin/translation/status:
|
|
get:
|
|
summary: Read Rust-owned localized release status
|
|
responses:
|
|
"200":
|
|
description: Current localized status JSON report from Rust bat.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat localized backend is unavailable.
|
|
/admin/releases/status:
|
|
get:
|
|
summary: Read the unified Rust-owned release status view
|
|
responses:
|
|
"200":
|
|
description: Official/localized current relation and integrity status.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat release backend is unavailable.
|
|
/admin/releases:
|
|
get:
|
|
summary: Read Rust-owned historical release summaries
|
|
parameters:
|
|
- name: channel
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [official, localized]
|
|
responses:
|
|
"200":
|
|
description: Historical release summaries.
|
|
"401":
|
|
description: Missing or invalid admin token.
|
|
"503":
|
|
description: Rust bat release 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, task-cancel, translation-task-update, translation-worker-run, translation-proofread, translation-memory-confirm, translation-glossary-add, translation-glossary-update, translation-glossary-approve, translation-glossary-deprecate, translation-glossary-delete, localized-publish, localized-rollback, release-cleanup]
|
|
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
|
|
task_id:
|
|
type: string
|
|
status:
|
|
type: string
|
|
failure_reason:
|
|
type: string
|
|
provider_run_id:
|
|
type: string
|
|
provider:
|
|
type: string
|
|
translation_results:
|
|
type: array
|
|
items:
|
|
type: object
|
|
required: [unit_id, source_text, translated_text]
|
|
additionalProperties: false
|
|
properties:
|
|
unit_id:
|
|
type: string
|
|
source_text:
|
|
type: string
|
|
translated_text:
|
|
type: string
|
|
glossary_override:
|
|
type: object
|
|
required: [qa_identity, reviewer, reason, provenance, confirmed_unix_seconds]
|
|
additionalProperties: false
|
|
properties:
|
|
qa_identity:
|
|
type: string
|
|
minLength: 1
|
|
reviewer:
|
|
type: string
|
|
reason:
|
|
type: string
|
|
provenance:
|
|
type: string
|
|
confirmed_unix_seconds:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
fixture_path:
|
|
type: string
|
|
concurrency:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
maximum: 256
|
|
max_attempts:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
lease_seconds:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
retry_backoff_seconds:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
max_tasks:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
worker_id:
|
|
type: string
|
|
translation_memory_path:
|
|
type: string
|
|
glossary_path:
|
|
type: string
|
|
record_id:
|
|
type: string
|
|
term_id:
|
|
type: string
|
|
source_term:
|
|
type: string
|
|
aliases:
|
|
type: array
|
|
items:
|
|
type: string
|
|
recommended_translation:
|
|
type: string
|
|
allowed_translations:
|
|
type: array
|
|
items:
|
|
type: string
|
|
source_language:
|
|
type: string
|
|
target_language:
|
|
type: string
|
|
category:
|
|
type: string
|
|
priority:
|
|
type: integer
|
|
format: int64
|
|
scope:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
review_status:
|
|
type: string
|
|
enum: [draft, approved, deprecated, rejected]
|
|
source:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [source_kind, observed_unix_seconds]
|
|
properties:
|
|
source_kind:
|
|
type: string
|
|
enum: [manual, imported]
|
|
source_ref:
|
|
type: string
|
|
source_author:
|
|
type: string
|
|
source_note:
|
|
type: string
|
|
observed_unix_seconds:
|
|
type: integer
|
|
format: int64
|
|
reviewer:
|
|
type: string
|
|
reason:
|
|
type: string
|
|
translation_file:
|
|
type: string
|
|
from_worker:
|
|
type: boolean
|
|
patch_manifest:
|
|
type: string
|
|
localized_release_id:
|
|
type: string
|
|
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))
|
|
}
|