diff --git a/.github/workflows/jsonCheck.yaml b/.github/workflows/jsonCheck.yaml index bdb3b877..78881708 100644 --- a/.github/workflows/jsonCheck.yaml +++ b/.github/workflows/jsonCheck.yaml @@ -1,14 +1,17 @@ -name: Json Check +name: Check json in index on: push: - branches: [ v5, maintainer-test ] + branches: + - v5 + - maintainer-test pull_request: - branches: [ v5 ] + branches: + - v5 jobs: - build: + validate: runs-on: ubuntu-latest steps: - - name: Do the checking of index and manifest files - uses: reviversmc/the-mod-index-validation@latest \ No newline at end of file + - name: Check index and manifest files + uses: ReviversMC/the-mod-index-validation@latest diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 9c99b96a..760458bd 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -14,7 +14,7 @@ permissions: contents: write jobs: build-and-deploy: - concurrency: ci-${{ github.ref }} + concurrency: ci-${{ github.ref }} runs-on: ubuntu-latest steps: - name: Checkout @@ -29,4 +29,4 @@ jobs: uses: JamesIves/github-pages-deploy-action@v4 with: folder: build - target-folder: ${{ github.ref }} # Publish docs to a specific path. This allows spec updates to not override existing prod sites + target-folder: ${{ github.ref_name }} # Publish docs to a specific path. This allows spec updates to not override existing prod site diff --git a/mods/index.json b/mods/index.json deleted file mode 100644 index 693d0b9e..00000000 --- a/mods/index.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "indexVersion": "5.2.0", - "identifiers": [], - "eolEpochTime": null -} diff --git a/mods/indices/index.json b/mods/indices/index.json new file mode 100644 index 00000000..5244fd60 --- /dev/null +++ b/mods/indices/index.json @@ -0,0 +1 @@ +{"indexVersion":"5.2.0","modLoaders":[],"identifiers":[],"eolEpochTime":null} diff --git a/schema/indexSchema.json b/schema/indexSchema.json deleted file mode 100644 index 6075a334..00000000 --- a/schema/indexSchema.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/ReviversMC/the-mod-index/blob/v3/schema/indexSchema.json", - "title": "Index Schema", - "description": "The file to search when searching for mods.", - "type": "object", - "properties": { - "indexVersion": { - "type": "string", - "description": "The semver version of the targeted index.", - "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" - }, - "identifiers": { - "type": "array", - "description": "The identifiers of the manifests available", - "items": { - "type": "string", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+:[a-z0-9]{15}$" - } - }, - "eolEpochTime": { - "type": [ - "integer", - null - ], - "description": "The epoch time when index version will no longer receive mod updates. May be larger than a 32 bit integer." - } - }, - "required": [ - "identifier", - "sha512Hash", - "eolEpochTime" - ] -} diff --git a/schema/manifestSchema.json b/schema/manifestSchema.json deleted file mode 100644 index eb5541bc..00000000 --- a/schema/manifestSchema.json +++ /dev/null @@ -1,677 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/ReviversMC/the-mod-index/blob/v3/schema/manifestSchema.json", - "title": "Manifest Schema", - "description": "The file for each of a mod per its loader", - "type": "object", - "properties": { - "indexVersion": { - "type": "string", - "description": "The semver version of the targeted index.", - "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" - }, - "genericIdentifier": { - "type": "string", - "description": "The fancy name of the mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - }, - "fancyName": { - "type": "string", - "description": "The fancy name of the mod.", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "author": { - "type": "string", - "description": "The author of the mod.", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "license": { - "type": [ - "string", - null - ], - "description": "The license of the mod, or url if not a standard license.", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "curseForgeId": { - "type": [ - "integer", - null - ], - "description": "The curseforge id of the mod." - }, - "modrinthId": { - "type": [ - "string", - null - ], - "description": "The modrinth id of the mod.", - "pattern": "^[a-zA-Z0-9]+$" - }, - "links": { - "type": "object", - "description": "The external links a mod has.", - "properties": { - "issue": { - "type": [ - "string", - null - ], - "description": "The issue tracker link.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - }, - "sourceControl": { - "type": [ - "string", - null - ], - "description": "The source control link.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - }, - "others": { - "type": "array", - "description": "Other links.", - "items": { - "type": "object", - "properties": { - "linkName": { - "type": "string", - "description": "The type of link, like \"discord\", \"irc\", or \"GitHub wiki\"", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "url": { - "type": "string", - "description": "The url of the link.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - } - }, - "required": [ - "linkName", - "url" - ] - } - } - }, - "required": [ - "issue", - "sourceControl", - "others" - ] - }, - "files": { - "type": "array", - "description": "The files the mod has.", - "items": { - "type": "object", - "properties": { - "fileName": { - "type": "string", - "description": "The name of the file.", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "mcVersions": { - "type": "array", - "description": "The minecraft versions the file is compatible with. Do not include mod loaders.", - "items": { - "type": "string", - "description": "The minecraft version. Does not include mod loaders.", - "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+[a-zA-Z0-9\\-+._\\s]*$" - } - }, - "shortSha512Hash": { - "type": "string", - "description": "The short sha512 hash of the file, consisting of only 15 characters", - "pattern": "^[a-z0-9]{15}$" - }, - "downloadUrls": { - "type": "array", - "description": "The download urls of the file.", - "items": { - "type": "string", - "description": "The download url of the file.", - "pattern": "^[a-zA-Z0-9\\-_:\/?&]+$" - } - }, - "curseDownloadAvailable": { - "type": "boolean", - "description": "Whether the file is available on curseforge." - }, - "relationsToOtherMods": { - "type": "object", - "description": "The relations (i.e. dependencies/conflicts) of the file.", - "properties": { - "required": { - "type": "array", - "description": "The other mods that this mod requires to run (i.e. dependencies).", - "items": { - "type": "string", - "description": "The generic identifier of the required mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - }, - "incompatible": { - "type": "array", - "description": "The other mods that this mod is incompatible with (i.e. conflicts).", - "items": { - "type": "string", - "description": "The generic identifier of the incompatible mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - } - }, - "required": [ - "required", - "incompatible" - ] - } - }, - "required": [ - "fileName", - "mcVersions", - "shortSha512Hash", - "downloadUrls", - "curseDownloadAvailable", - "relationsToOtherMods" - ] - } - }, - "overrides": { - "type": "object", - "description": "The manual overrides the mod has. Mostly for the maintainer's internal use", - "properties": { - "genericIdentifier": { - "type": "string", - "description": "The fancy name of the mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - }, - "fancyName": { - "type": "string", - "description": "The fancy name of the mod.", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "author": { - "type": "string", - "description": "The author of the mod.", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "license": { - "type": [ - "string", - null - ], - "description": "The license of the mod, or url if not a standard license.", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "curseForgeId": { - "type": [ - "integer", - null - ], - "description": "The curseforge id of the mod." - }, - "modrinthId": { - "type": [ - "string", - null - ], - "description": "The modrinth id of the mod.", - "pattern": "^[a-zA-Z0-9]+$" - }, - "links": { - "type": "object", - "description": "The external links a mod has.", - "properties": { - "issue": { - "type": [ - "string", - null - ], - "description": "The issue tracker link.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - }, - "sourceControl": { - "type": [ - "string", - null - ], - "description": "The source control link.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - }, - "others": { - "type": "object", - "description": "Other links to override", - "properties": { - "add": { - "type": "object", - "description": "The links to add.", - "properties": { - "linkName": { - "type": "string", - "description": "The type of link, like \"discord\", \"irc\", or \"GitHub wiki\"", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "url": { - "type": "string", - "description": "The url of the link.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - } - }, - "required": [ - "linkName", - "url" - ] - }, - "remove": { - "type": "array", - "description": "The links to remove.", - "items": { - "type": "string", - "description": "The type of link to remove, like \"discord\", \"irc\", or \"GitHub wiki\"", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - } - }, - "replace": { - "type": "object", - "description": "The links to replace.", - "properties": { - "linkName": { - "type": "string", - "description": "The type of link, like \"discord\", \"irc\", or \"GitHub wiki\"", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "url": { - "type": "string", - "description": "The url of the link.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - } - }, - "required": [ - "linkName", - "url" - ] - } - } - } - } - }, - "files": { - "type": "object", - "description": "The overrides for the files of the mod.", - "properties": { - "add": { - "type": "array", - "description": "The files to add for the mod.", - "items": { - "type": "object", - "properties": { - "fileName": { - "type": "string", - "description": "The name of the file.", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "mcVersions": { - "type": "object", - "description": "The minecraft versions the file is compatible with.", - "properties": { - "add": { - "type": "array", - "description": "The mc versions to add.", - "items": { - "type": "string", - "description": "The minecraft version. Does not include mod loaders.", - "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+[a-zA-Z0-9\\-+._\\s]*$" - } - }, - "remove": { - "type": "array", - "description": "The mc versions to remove.", - "items": { - "type": "string", - "description": "The minecraft version. Does not include mod loaders.", - "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+[a-zA-Z0-9\\-+._\\s]*$" - } - }, - "replace": { - "type": "array", - "description": "The mc versions to replace.", - "items": { - "type": "string", - "description": "The minecraft version. Does not include mod loaders.", - "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+[a-zA-Z0-9\\-+._\\s]*$" - } - } - } - }, - "shortSha512Hash": { - "type": "string", - "description": "The short sha512 hash of the file, consisting of only 15 characters", - "pattern": "^[a-z0-9]{15}$" - }, - "downloadUrls": { - "type": "object", - "description": "The download urls of the file.", - "properties": { - "add": { - "type": "array", - "description": "The download urls to add.", - "items": { - "type": "string", - "description": "The download url of the file.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - } - }, - "remove": { - "type": "array", - "description": "The download urls to remove.", - "items": { - "type": "string", - "description": "The download url of the file.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - } - }, - "replace": { - "type": "array", - "description": "The download urls to replace.", - "items": { - "type": "string", - "description": "The download url of the file.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - } - } - } - }, - "curseDownloadAvailable": { - "type": "boolean", - "description": "Whether the file is available on curseforge." - }, - "relationsToOtherMods": { - "type": "object", - "description": "The relations (i.e. dependencies/conflicts) of the file.", - "properties": { - "add": { - "type": "object", - "description": "The relations to add.", - "properties": { - "required": { - "type": "array", - "description": "The other mods that this mod requires to run (i.e. dependencies).", - "items": { - "type": "string", - "description": "The generic identifier of the required mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - }, - "incompatible": { - "type": "array", - "description": "The other mods that this mod is incompatible with (i.e. conflicts).", - "items": { - "type": "string", - "description": "The generic identifier of the incompatible mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - } - } - }, - "remove": { - "type": "object", - "description": "The relations to remove.", - "properties": { - "required": { - "type": "array", - "description": "The other mods that this mod requires to run (i.e. dependencies).", - "items": { - "type": "string", - "description": "The generic identifier of the required mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - }, - "incompatible": { - "type": "array", - "description": "The other mods that this mod is incompatible with (i.e. conflicts).", - "items": { - "type": "string", - "description": "The generic identifier of the incompatible mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - } - } - }, - "replace": { - "type": "object", - "description": "The relations to replace.", - "properties": { - "required": { - "type": "array", - "description": "The other mods that this mod requires to run (i.e. dependencies).", - "items": { - "type": "string", - "description": "The generic identifier of the required mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - }, - "incompatible": { - "type": "array", - "description": "The other mods that this mod is incompatible with (i.e. conflicts).", - "items": { - "type": "string", - "description": "The generic identifier of the incompatible mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - } - } - } - } - } - }, - "required": [ - "fileName", - "mcVersions", - "shortSha512Hash", - "downloadUrls", - "curseDownloadAvailable", - "relationsToOtherMods" - ] - } - }, - "remove": { - "type": "array", - "description": "The files to remove.", - "items": { - "shortSha512Hash": { - "type": "string", - "description": "The short sha512 hash of the file, consisting of only 15 characters", - "pattern": "^[a-z0-9]{15}$" - } - } - }, - "replace": { - "type": "array", - "description": "The files to use instead of the original files generated", - "items": { - "type": "object", - "properties": { - "fileName": { - "type": "string", - "description": "The name of the file.", - "pattern": "^[a-zA-Z0-9\\-_\\s]+$" - }, - "mcVersions": { - "type": "object", - "description": "The minecraft versions the file is compatible with.", - "properties": { - "add": { - "type": "array", - "description": "The mc versions to add.", - "items": { - "type": "string", - "description": "The minecraft version. Does not include mod loaders.", - "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+[a-zA-Z0-9\\-+._\\s]*$" - } - }, - "remove": { - "type": "array", - "description": "The mc versions to remove.", - "items": { - "type": "string", - "description": "The minecraft version. Does not include mod loaders.", - "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+[a-zA-Z0-9\\-+._\\s]*$" - } - }, - "replace": { - "type": "array", - "description": "The mc versions to replace.", - "items": { - "type": "string", - "description": "The minecraft version. Does not include mod loaders.", - "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+[a-zA-Z0-9\\-+._\\s]*$" - } - } - } - }, - "shortSha512Hash": { - "type": "string", - "description": "The short sha512 hash of the file, consisting of only 15 characters", - "pattern": "^[a-z0-9]{15}$" - }, - "downloadUrls": { - "type": "object", - "description": "The download urls of the file.", - "properties": { - "add": { - "type": "array", - "description": "The download urls to add.", - "items": { - "type": "string", - "description": "The download url of the file.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - } - }, - "remove": { - "type": "array", - "description": "The download urls to remove.", - "items": { - "type": "string", - "description": "The download url of the file.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - } - }, - "replace": { - "type": "array", - "description": "The download urls to replace.", - "items": { - "type": "string", - "description": "The download url of the file.", - "pattern": "^[a-zA-Z0-9\\-_:/?&]+$" - } - } - } - }, - "curseDownloadAvailable": { - "type": "boolean", - "description": "Whether the file is available on curseforge." - }, - "relationsToOtherMods": { - "type": "object", - "description": "The relations (i.e. dependencies/conflicts) of the file.", - "properties": { - "add": { - "type": "object", - "description": "The relations to add.", - "properties": { - "required": { - "type": "array", - "description": "The other mods that this mod requires to run (i.e. dependencies).", - "items": { - "type": "string", - "description": "The generic identifier of the required mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - }, - "incompatible": { - "type": "array", - "description": "The other mods that this mod is incompatible with (i.e. conflicts).", - "items": { - "type": "string", - "description": "The generic identifier of the incompatible mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - } - } - }, - "remove": { - "type": "object", - "description": "The relations to remove.", - "properties": { - "required": { - "type": "array", - "description": "The other mods that this mod requires to run (i.e. dependencies).", - "items": { - "type": "string", - "description": "The generic identifier of the required mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - }, - "incompatible": { - "type": "array", - "description": "The other mods that this mod is incompatible with (i.e. conflicts).", - "items": { - "type": "string", - "description": "The generic identifier of the incompatible mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - } - } - }, - "replace": { - "type": "object", - "description": "The relations to replace.", - "properties": { - "required": { - "type": "array", - "description": "The other mods that this mod requires to run (i.e. dependencies).", - "items": { - "type": "string", - "description": "The generic identifier of the required mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - }, - "incompatible": { - "type": "array", - "description": "The other mods that this mod is incompatible with (i.e. conflicts).", - "items": { - "type": "string", - "description": "The generic identifier of the incompatible mod.", - "pattern": "^[a-z0-9\\-_]+:[a-z0-9\\-_]+$" - } - } - } - } - } - } - }, - "required": [ - "fileName", - "mcVersions", - "shortSha512Hash", - "downloadUrls", - "curseDownloadAvailable", - "relationsToOtherMods" - ] - } - } - } - } - } - } - }, - "required": [ - "name", - "description", - "version", - "authors", - "curseForgeId", - "modrinthId", - "links", - "files" - ] -} diff --git a/schema/openapi.yaml b/schema/openapi.yaml new file mode 100644 index 00000000..44128b18 --- /dev/null +++ b/schema/openapi.yaml @@ -0,0 +1,471 @@ +openapi: "3.1.0" +info: + title: "the-mod-index" + version: "6.0.0" + description: | + The Mod Index plans to be a source where anyone can refer to for Minecraft mods, + bridging the gap between multiple major mod hosting sites. Get mod metadata, download links, and more. + + The index does **NOT** host or redistribute mod files (e.g. jars), but instead provides links/information to the mod files. + license: + name: "GNU Affero General Public License v3.0" + identifier: "AGPL-3.0" + +servers: + - url: "https://raw.githubusercontent.com/ReviversMC/the-mod-index/v6/mods" + description: "The Mod Index v6" + +components: + schemas: + indexVersion: &indexVersion + type: "string" + description: "The semver version of the targeted index." + pattern: "^[0-9]+\\.[0-9]+\\.[0-9]+$" + example: "6.0.0" + + identifier: &identifier + type: "string" + description: "The internal identifier of the manifest available" + pattern: "^[a-z0-9\\-_]+:[a-z0-9\\-_]+:[a-z0-9]{15}$" + example: "fabric:modget:9da29a647bab8cf" + + indexForModLoader: &indexForModLoader + type: "object" + description: "The index for a specific mod loader." + properties: + indexVersion: *indexVersion + identifiers: + type: "array" + description: "The identifiers of the manifests available" + pattern: "^(?!\bindex\b|\bindices\b)[a-z0-9\\-_]+:[a-z0-9\\-_]+:[a-z0-9]{15}$" + items: *identifier + eolEpochTime: + oneOf: + - type: "integer" + description: "The epoch time when index version will no longer receive mod updates. May be larger than a 32 bit integer." + - type: "null" + description: "If the index version is still in use" + description: "The epoch time when index version will no longer receive mod updates. May be larger than a 32 bit integer." + example: "null" + required: + - "indexVersion" + - "identifiers" + - "eolEpochTime" + + modLoader: &modLoaderSchema + type: "string" + description: "The mod loader for the manifest available" + pattern: "^(?!\bindex\b|\bindices\b)[a-z0-9\\-_]+$" + example: "fabric" + + loaderModName: &loaderModNameSchema + type: "string" + description: "The given mod name for a mod in the index. Usually used in combination with the a `modLoader` to form a `genericIdentifier`" + pattern: "^[a-z0-9\\-_]+$" + example: "modget" + + shortSha512Hash: &shortSha512Hash + type: "string" + description: "A truncated sha512 hash, consisting of the first 15 characters of the lowercase hexadecimal hash" + pattern: "^[a-z0-9]{15}$" + example: "9da29a647bab8cf" + + genericIdentifier: &genericIdentifier + type: "string" + description: "The generic identifier for a mod in the index, consisting of a `modLoader` and a `loaderModName` in the format of `modLoader:loaderModName`" + pattern: "^(?!\bindex\b|\bindices\b)[a-z0-9\\-_]+:[a-z0-9\\-_]+$" + example: "fabric:modget" + + fancyName: &fancyName + type: "string" + description: "The fancy name of the mod" + pattern: "^[a-zA-Z0-9\\-_\\s]+$" + example: "modget" + + authors: &authors + type: "array" + description: "The author(s) of the mod" + pattern: "^[a-zA-Z0-9\\-_\\s]+$" + items: + type: "string" + description: "The author(s) of the mod" + example: "ReviversMC" + minItems: 1 + + license: &license + oneOf: + - type: "object" + description: "The license of the mod" + properties: + spdxId: + type: "string" + description: "The spdx license code of the mod" + pattern: "^[a-zA-Z0-9\\-_\\s]+$" + example: "AGPL-3.0" + required: + - "spdxId" + - type: "object" + description: "The license of the mod" + properties: + url: + type: "string" + description: "The url of the license" + pattern: "^(http(s)?://.)?(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$" + example: "https://spdx.org/licenses/AGPL-3.0.html" + required: + - "url" + - type: "null" + description: "If the license is not available" + example: "null" + + + curseForgeId: &curseForgeId + oneOf: + - type: "integer" + description: "The curseforge id of the mod" + example: "533960" + - type: "null" + description: "If the curseforge id is not available" + example: "null" + + + modrinthId: &modrinthId + oneOf: + - type: "string" + description: "The modrinth id of the mod" + pattern: "^[a-zA-Z0-9]+$" + example: "2NpFE0R3" + - type: "null" + description: "If the modrinth id is not available" + example: "null" + + issueLink: &issueLink + oneOf: + - type: "string" + description: "The issue link for the mod" + pattern: "^(http(s)?://.)?(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$" + example: "https://github.com/ReviversMC/modget/issues/" + - type: "null" + description: "If the issue link is not available" + example: "null" + + sourceControlLink: &sourceControlLink + oneOf: + - type: "string" + description: "The source control link for the mod" + pattern: "^(http(s)?://.)?(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$" + example: "https://github.com/ReviversMC/modget/" + - type: "null" + description: "If the source control link is not available" + example: "null" + + otherLinks: &otherLinks + type: "array" + description: "Other links for the mod" + items: + type: "object" + description: "Other links for the mod" + properties: + linkName: + type: "string" + description: "The name of the link" + pattern: "^[a-zA-Z0-9\\-_\\s]+$" + example: "Discord" + url: + type: "string" + description: "The url of the link" + pattern: "^(http(s)?://.)?(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$" + example: "https://discord.gg/6bTGYFppfz" + required: + - "linkName" + - "url" + minItems: 0 + + links: &links + type: "object" + description: "The links for the mod" + properties: + issue: *issueLink + sourceControl: *sourceControlLink + others: *otherLinks + required: + - "issue" + - "sourceControl" + - "others" + + mcVersions: &mcVersions + type: "array" + description: "The minecraft versions the mod is compatible with" + items: + type: "string" + description: "The minecraft version the mod is compatible with" + pattern: "^[a-zA-Z0-9\\-_\\s]+$" # Don't limit to just a pattern of x.y.z, cause there are things like snapshots, pre releases, etc + example: "1.12.2, 22w24a" + minItems: 0 + + files: &files + type: "array" + description: "The files of the mod" + items: + type: "object" + description: "The file of a mod, specific to the mod loader" + properties: + fileName: + type: "string" + description: "The name of the file" + pattern: "^[a-zA-Z0-9\\-_\\s]+$" + example: "Modget 0.0.1 for MC 1.16" + mcVersions: *mcVersions + shortSha512Hash: *shortSha512Hash + downloadUrls: + type: "array" + description: "The download urls of the file, excluding CurseForge. CF links are unable to be stored due to their TOS" + pattern: "^(http(s)?://.)?(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$" + items: + type: "string" + description: "The url of the file" + pattern: "^(http(s)?://.)?(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$" + example: "https://github.com/ReviversMC/modget-minecraft/releases/download/0.4.3/modget-minecraft-0.4.3+1.17.jar" + minItems: 0 + curseDownloadAvailable: + type: "boolean" + description: "If the file is available on CurseForge, and can be retrieved with an api call to CF" + example: "true" + relationsToOtherMods: + type: "object" + description: "The relations to other mods" + properties: + required: + type: "array" + description: | + The mods required for the mod to work (i.e. dependencies). + It is possible that there are further dependencies that are not declared here + pattern: "^(?!\bindex\b|\bindices\b)[a-z0-9\\-_]+:[a-z0-9\\-_]+$" + items: *genericIdentifier + minItems: 0 + incompatible: + type: "array" + description: | + The mods that are incompatible with the mod. + It is possible that there are further incompatibilities that are not declared here + pattern: "^(?!\bindex\b|\bindices\b)[a-z0-9\\-_]+:[a-z0-9\\-_]+$" + items: *genericIdentifier + minItems: 0 + required: + - "required" + - "incompatible" + required: + - "fileName" + - "mcVersions" + - "shortSha512Hash" + - "downloadUrls" + - "curseDownloadAvailable" + - "relationsToOtherMods" + minItems: 0 + + manifest: &manifest + type: "object" + properties: + indexVersion: *indexVersion + genericIdentifier: *genericIdentifier + fancyName: *fancyName + authors: *authors + license: *license + curseForgeId: *curseForgeId + modrinthId: *modrinthId + links: *links + files: *files + overrides: + type: "object" + description: "The overrides for the mod. Information in this field should already be reflected in the rest of the fields" + # No property should be required in overrides, as it is possible that the mod has no overrides, and there is thus no reason to send it + properties: + # Leave out index version. We do not want index version to be overrideable + + genericIdentifier: + oneOf: + - *genericIdentifier + - type: "null" + description: "If the override is not available" + example: "null" + fancyName: + oneOf: + - *fancyName + - type: "null" + description: "If the override is not available" + example: "null" + authors: + oneOf: + - *authors + - type: "null" + description: "If the override is not available" + example: "null" + license: *license # License is already nullable + curseForgeId: *curseForgeId # CurseForgeId is already nullable + modrinthId: *modrinthId # ModrinthId is already nullable + links: + oneOf: + - type: "object" + description: "If there are overrides available for links" + properties: + issues: *issueLink + sourceControl: *sourceControlLink + others: + type: "object" + description: "Other miscellaneous links to add, remove, or replace" + properties: + add: + oneOf: + - *otherLinks + - type: "null" + description: "If the override is not available" + example: "null" + remove: + oneOf: + - *otherLinks + - type: "null" + description: "If the override is not available" + example: "null" + replace: + oneOf: + - *otherLinks + - type: "null" + description: "If the override is not available" + example: "null" + - type: "null" + description: "If there are no overrides available for links" + example: "null" + + files: + oneOf: + - type: "object" + description: "Files to add, remove, or replace. Edit a file by removing it and adding it again" + properties: + add: + oneOf: + - *files + - type: "null" + description: "If the override is not available" + example: "null" + remove: + oneOf: + - *files + - type: "null" + description: "If the override is not available" + example: "null" + replace: + oneOf: + - *files + - type: "null" + description: "If the override is not available" + example: "null" + - type: "null" + description: "If there are no overrides available for files" + example: "null" + + required: + - "indexVersion" + - "genericIdentifier" + - "fancyName" + - "authors" + - "license" + - "curseForgeId" + - "modrinthId" + - "links" + - "files" + # Do not make overrides required. If not present, the entire field should be omitted + + parameters: + modLoaderParam: &modLoaderParam + name: "modLoader" + in: "path" + description: "The mod loader for which to get the index" + required: "true" + schema: *modLoaderSchema + + loaderModNameParam: &loaderModNameParam + name: "loaderModName" + in: "path" + description: "The given mod name for a mod in the index. Usually used in combination with the a `modLoader` to form a `genericIdentifier`" + required: "true" + schema: *loaderModNameSchema + +tags: + - name: "indexFiles" + x-displayName: "Index Files" + description: "The index files to navigate \"the-mod-index\"" + - name: "manifestFiles" + x-displayName: "Manifest Files" + description: "The manifest files found in \"the-mod-index\"" + +paths: + /indices/index.json: + get: + operationId: "getIndex" + summary: "Get the index for all mod loaders." + description: "Get the index for all mod loaders. Does not include similar mods from other mod loaders." + tags: + - "indexFiles" + responses: + 200: + description: "Expected response to a valid request" + content: + application/json: + schema: + allOf: + - *indexForModLoader + - type: "object" + properties: + modLoaders: + type: "array" + description: "The mod loaders that are available" + items: *modLoaderSchema + required: + - "modLoaders" + + 404: + description: "The page was not found" + + # {modLoader} in the path to explicitly exclude `index` as a result, as `index.json` redirects to `/indices/index.json`. + /indices/{modLoader}.json: + get: + operationId: "getLoaderIndex" + summary: "Get the index for a specific mod loader." + description: "Get the index for a specific mod loader. Does not include similar mods from other mod loaders." + tags: + - "indexFiles" + parameters: + - *modLoaderParam + responses: + 200: + description: "Expected response to a valid request" + content: + application/json: + schema: *indexForModLoader + 404: + description: "The page was not found" + + /{modLoader}/{loaderModName}.json: + get: + operationId: "getModManifest" + summary: "Get the manifest for a specific mod." + description: | + Get the manifest for a specific mod. + Only returns valid information for the mod loader specified in the path, not all information for the mod + + For example, in a mod which has separate Fabric and Forge files, should {modLoader} be `forge`, + only the Forge files will be reflected in the Forge manifest + tags: + - "manifestFiles" + parameters: + - *modLoaderParam + - *loaderModNameParam + responses: + 200: + description: "Expected response to a valid request" + content: + application/json: + schema: *manifest + 404: + description: "The page was not found" +