Files
libretro/schemas/site-api-envelope.schema.json
T
Abdessamad Derraz 350cd6d600 feat: keep the address of a file that left
files/?sha1= of a file the collection no longer holds answered that no
file the site knows has the hash. generate_db.py now records each sha1 a
rebuild drops in retired.json, with the day and the file in its place,
backfilled from the history since 0d586ef6b (4,139 files). The lookup
answers with it and leads to the successor's card.
2026-11-06 04:24:44 +01:00

580 lines
16 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://abdess.github.io/retrobios/api/v1/schemas/site-api-envelope.schema.json",
"title": "RetroBIOS static API v1 envelope",
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"generated_at",
"kind",
"count",
"items"
],
"properties": {
"schema_version": {
"const": 1
},
"generated_at": {
"type": "string",
"format": "date-time"
},
"commit": {
"type": "string",
"pattern": "^[0-9a-f]{40}$",
"description": "The repository commit the data was read at. Every envelope carries it when the site is built from a git checkout."
},
"license": {
"type": "string",
"description": "The terms the metadata is offered under, from LICENSE. They never cover BIOS or firmware files (NOTICE)."
},
"kind": {
"type": "string",
"enum": [
"catalog",
"platforms",
"emulators",
"systems",
"verification-and-coverage-gaps",
"file-locations",
"file-lookup",
"index",
"system-index",
"core-index"
]
},
"count": {
"type": "integer",
"minimum": 0
},
"items": {
"type": "array",
"items": {
"type": "object"
}
}
},
"description": "Every endpoint shares this envelope. Within v1 an item keeps the fields listed for its kind and their types: fields may be added, never renamed or removed. A breaking change takes a new prefix.",
"allOf": [
{
"if": {
"properties": {
"kind": {
"const": "catalog"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"bytes",
"media_type",
"sha256",
"title",
"url"
],
"properties": {
"title": {
"type": "string"
},
"url": {
"type": "string"
},
"media_type": {
"type": "string"
},
"bytes": {
"type": "integer",
"minimum": 0
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
}
}
}
}
}
},
{
"if": {
"properties": {
"kind": {
"const": "emulators"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"id",
"profile"
],
"properties": {
"id": {
"type": "string"
},
"profile": {
"type": "object",
"description": "The profile as its YAML states it, valid against emulator.schema.json (https://abdess.github.io/retrobios/api/v1/schemas/emulator.schema.json)."
}
}
}
}
}
}
},
{
"if": {
"properties": {
"kind": {
"const": "platforms"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"contract",
"coverage",
"id",
"name"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"contract": {
"type": "object",
"description": "The platform's list as the tools load it, valid against platform.schema.json (https://abdess.github.io/retrobios/api/v1/schemas/platform.schema.json). Entries a shared group adds carry shared_group, and a Recalbox ZIP entry carries zip_digest."
},
"coverage": {
"type": "object"
},
"registry": {
"type": "object",
"description": "The platform's registry entry beside its list: install detection, logo, scraper and schedule. Not part of the list. release_pack is the platform's own entry, never its parent's: true when a release publishes its ZIP."
}
}
}
}
}
}
},
{
"if": {
"properties": {
"kind": {
"const": "verification-and-coverage-gaps"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"destination",
"discrepancy",
"emulator",
"expected",
"in_repo",
"layer",
"name",
"platform",
"platform_id",
"reason",
"required",
"status",
"system"
],
"properties": {
"name": {
"type": "string"
},
"platform": {
"type": "string"
},
"platform_id": {
"type": "string"
},
"system": {
"type": "string"
},
"emulator": {
"type": "string"
},
"destination": {
"type": "string"
},
"status": {
"type": "string"
},
"layer": {
"type": "string"
},
"reason": {
"type": "string"
},
"expected": {
"type": "string"
},
"discrepancy": {
"type": "string"
},
"required": {
"type": "boolean"
},
"in_repo": {
"type": [
"boolean",
"string"
]
}
}
}
}
}
}
},
{
"if": {
"properties": {
"kind": {
"const": "file-locations"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"sha1",
"url"
],
"properties": {
"sha1": {
"type": "string",
"pattern": "^[0-9a-f]{40}$"
},
"url": {
"type": "string",
"description": "Site-absolute path of the file's card, starting at /retrobios/."
}
}
}
}
}
}
},
{
"if": {
"properties": {
"kind": {
"const": "systems"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"consoles",
"id",
"name"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"consoles": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"path",
"sha1"
],
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"size": {
"type": "integer",
"minimum": 0
},
"sha1": {
"type": "string",
"pattern": "^[0-9a-f]{40}$"
},
"md5": {
"type": "string"
},
"sha256": {
"type": "string"
},
"crc32": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
},
{
"if": {
"properties": {
"kind": {
"const": "file-lookup"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"value",
"algorithm",
"layer",
"name",
"url"
],
"properties": {
"value": {
"type": "string",
"pattern": "^[0-9a-f]+$"
},
"algorithm": {
"enum": [
"sha1",
"md5",
"crc32",
"sha256"
]
},
"layer": {
"enum": [
"collection",
"archive-member",
"retired",
"data-directory",
"platform",
"emulator"
]
},
"left": {
"type": "string",
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
"description": "On a retired record: the day the file, whose SHA1 is `sha1`, left the collection (retired.json)."
},
"successor": {
"type": "string",
"pattern": "^[0-9a-f]{40}$",
"description": "On a retired record: SHA1 of the collection file now holding its place, whose card `url` leads to."
},
"archive": {
"type": "string",
"description": "On an archive-member record: the name of the collection archive holding the member, whose SHA1 is `sha1`. Its value is the member's CRC32, read from the archive's central directory."
},
"name": {
"type": "string"
},
"url": {
"type": "string",
"description": "Site-absolute path of the page that shows the value, starting at /retrobios/. Prefix https://abdess.github.io for a full URL."
},
"sha1": {
"type": "string",
"pattern": "^[0-9a-f]{40}$",
"description": "SHA1 of the collection file the value designates. A platform or emulator record that designates no collection file has none."
},
"declared": {
"enum": [
"sha1",
"md5",
"crc32",
"sha256",
"name"
],
"description": "On a platform or emulator record: the algorithm of the value its owner wrote, filed under that value and under the file's other hashes. name: the emulator reads the file by its name and declares no hash that matches it."
},
"owner": {
"type": "string"
},
"system_name": {
"type": "string",
"description": "The name the site gives the system the record belongs to (Sony PlayStation): the console a collection file is filed under, the system a platform lists it in, the system of an emulator's entry. Absent when none is known."
}
}
}
}
}
}
},
{
"if": {
"properties": {
"kind": {
"const": "index"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"title",
"url"
],
"properties": {
"title": {
"type": "string"
},
"url": {
"type": "string",
"description": "Relative to this document's URL."
},
"description": {
"type": "string"
}
}
}
}
}
}
},
{
"if": {
"properties": {
"kind": {
"const": "system-index"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"id",
"name",
"manufacturer",
"url",
"sha1"
],
"properties": {
"id": {
"type": "string",
"description": "The system id a platform list or an emulator profile writes."
},
"name": {
"type": "string",
"description": "The name the site shows for the id."
},
"manufacturer": {
"type": "string"
},
"url": {
"type": [
"string",
"null"
],
"description": "Site-absolute path of the console section holding the id's files, null when no section holds them."
},
"api": {
"type": [
"string",
"null"
],
"description": "Site-absolute path of the JSON document holding the id's files, api/v1/systems/<slug>.json, keyed by the manufacturer page. Null when no page holds them."
},
"sha1": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[0-9a-f]{40}$"
},
"description": "SHA1 of each collection file a platform list or an emulator profile names for the id."
}
}
}
}
}
}
},
{
"if": {
"properties": {
"kind": {
"const": "core-index"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"type": "object",
"required": [
"name",
"profile"
],
"properties": {
"name": {
"type": "string",
"description": "A core name as the buildbot or a platform writes it (mednafen_psx), a profile id, or an alias profile."
},
"profile": {
"type": "string",
"description": "The profile id whose api/v1/emulators/<id>.json and page describe it."
},
"preferred": {
"type": "boolean",
"description": "The profile a platform list naming this core gets: its own key first, else the first claimant."
}
}
}
}
}
}
}
]
}