├── .checkstyle
├── checkstyle.xml
└── suppressions.xml
├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .github
└── workflows
│ ├── build.yml
│ ├── deploy.yml
│ └── validate-gradle-wrapper.yml
├── .gitignore
├── .spotless
└── bibliothek.importorder
├── build.gradle.kts
├── cli
├── insertBuild.js
├── package.json
├── promoteBuild.js
└── yarn.lock
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── license.txt
├── license_header.txt
├── readme.md
├── renovate.json
├── settings.gradle.kts
└── src
└── main
├── java
└── io
│ └── papermc
│ └── bibliothek
│ ├── BibliothekApplication.java
│ ├── configuration
│ ├── AppConfiguration.java
│ ├── MongoConfiguration.java
│ ├── OpenAPIConfiguration.java
│ └── WebConfiguration.java
│ ├── controller
│ ├── RootController.java
│ └── v2
│ │ ├── DownloadController.java
│ │ ├── ProjectController.java
│ │ ├── ProjectsController.java
│ │ ├── VersionBuildController.java
│ │ ├── VersionBuildsController.java
│ │ ├── VersionController.java
│ │ ├── VersionFamilyBuildsController.java
│ │ └── VersionFamilyController.java
│ ├── database
│ ├── model
│ │ ├── Build.java
│ │ ├── Project.java
│ │ ├── Version.java
│ │ └── VersionFamily.java
│ └── repository
│ │ ├── BuildCollection.java
│ │ ├── ProjectCollection.java
│ │ ├── VersionCollection.java
│ │ └── VersionFamilyCollection.java
│ ├── exception
│ ├── Advice.java
│ ├── BuildNotFound.java
│ ├── DownloadFailed.java
│ ├── DownloadNotFound.java
│ ├── ProjectNotFound.java
│ └── VersionNotFound.java
│ ├── filter
│ └── CorsFilter.java
│ └── util
│ ├── BringOrderToChaos.java
│ ├── HTTP.java
│ ├── MediaTypes.java
│ ├── NameSource.java
│ └── TimeSource.java
└── resources
└── application.yaml
/.checkstyle/checkstyle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
--------------------------------------------------------------------------------
/.checkstyle/suppressions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | # vim: ft=gitignore
2 | # Everything ignored by default
3 | *
4 | # Only whitelist what's needed
5 | !*.gradle.kts
6 | !docker/
7 | !gradle/
8 | !gradlew
9 | !license*.txt
10 | !src/
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_size = 2
6 | indent_style = space
7 | insert_final_newline = true
8 | max_line_length = off
9 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
3 | *.bat text eol=crlf
4 | *.sh text eol=lf
5 |
6 | gradlew text eol=lf
7 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: "build"
2 |
3 | on: ["pull_request", "push"]
4 |
5 | jobs:
6 | build:
7 | runs-on: "ubuntu-latest"
8 | steps:
9 | - name: "checkout repository"
10 | uses: "actions/checkout@v4"
11 | - name: "setup java"
12 | uses: "actions/setup-java@v4"
13 | with:
14 | distribution: "zulu"
15 | java-version: "17"
16 | - name: "build"
17 | run: "./gradlew build"
18 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: "deploy"
2 |
3 | on:
4 | push:
5 | branches: ["main"]
6 |
7 | concurrency:
8 | cancel-in-progress: true
9 | group: "${{ github.workflow }}-${{ github.event.number || github.ref }}"
10 |
11 | jobs:
12 | deploy:
13 | runs-on: "ubuntu-latest"
14 | outputs:
15 | image-json: "${{ steps.publish.outputs.imageJson }}" # output produced from printJibMeta Gradle task
16 | steps:
17 | - name: "checkout"
18 | uses: "actions/checkout@v4"
19 | - name: "setup java"
20 | uses: "actions/setup-java@v4"
21 | with:
22 | distribution: "zulu"
23 | java-version: "17"
24 | - name: "check"
25 | run: ./gradlew check
26 | - name: "login"
27 | uses: "docker/login-action@v3"
28 | with:
29 | registry: "ghcr.io"
30 | username: "${{ github.actor }}"
31 | password: "${{ secrets.GITHUB_TOKEN }}"
32 | - name: "publish"
33 | id: publish
34 | run: "./gradlew jib -Djib.console=plain"
35 | promote:
36 | needs: "deploy"
37 | runs-on: "ubuntu-latest"
38 | environment: "promoted"
39 | steps:
40 | - name: "login"
41 | uses: "docker/login-action@v3"
42 | with:
43 | registry: "ghcr.io"
44 | username: "${{ github.actor }}"
45 | password: "${{ secrets.GITHUB_TOKEN }}"
46 | - name: "tag"
47 | env:
48 | IMAGE_ID: "${{ fromJSON(needs.deploy.outputs.image-json).imageId }}"
49 | IMAGE_NAME: "${{ fromJSON(needs.deploy.outputs.image-json).image }}"
50 | PROMOTED_TAG_NAME: "stable"
51 | run: |
52 | skopeo copy -a "docker://$IMAGE_NAME@$IMAGE_ID" "docker://$IMAGE_NAME:$PROMOTED_TAG_NAME"
53 |
--------------------------------------------------------------------------------
/.github/workflows/validate-gradle-wrapper.yml:
--------------------------------------------------------------------------------
1 | name: "validate gradle wrapper"
2 |
3 | on: ["pull_request", "push"]
4 |
5 | jobs:
6 | build:
7 | runs-on: "ubuntu-latest"
8 | steps:
9 | - name: "checkout repository"
10 | uses: "actions/checkout@v4"
11 | - name: "validate gradle wrapper"
12 | uses: "gradle/wrapper-validation-action@v1"
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.gradle/
2 | /.idea/
3 | /build/
4 | /cli/node_modules/
5 | /run/
6 | /*.iml
7 |
--------------------------------------------------------------------------------
/.spotless/bibliothek.importorder:
--------------------------------------------------------------------------------
1 | #Organize Import Order
2 | #Mon Dec 05 23:26:49 PST 2022
3 | 0=
4 | 1=\#
5 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import java.nio.file.StandardOpenOption
2 | import java.time.Instant
3 | import kotlin.io.path.Path
4 | import kotlin.io.path.bufferedWriter
5 |
6 | buildscript {
7 | dependencies {
8 | classpath("com.google.cloud.tools:jib-spring-boot-extension-gradle:0.1.0")
9 | }
10 | }
11 |
12 | plugins {
13 | id("java")
14 |
15 | alias(libs.plugins.indra)
16 | alias(libs.plugins.indra.checkstyle)
17 | alias(libs.plugins.indra.git)
18 | alias(libs.plugins.jib)
19 | alias(libs.plugins.spotless)
20 | alias(libs.plugins.spring.dependency.management)
21 | alias(libs.plugins.spring.boot)
22 | }
23 |
24 | repositories {
25 | mavenCentral()
26 | }
27 |
28 | indra {
29 | javaVersions {
30 | target(17)
31 | }
32 |
33 | github("PaperMC", "bibliothek")
34 | mitLicense()
35 | }
36 |
37 | spotless {
38 | java {
39 | endWithNewline()
40 | importOrderFile(rootProject.file(".spotless/bibliothek.importorder"))
41 | indentWithSpaces(2)
42 | licenseHeaderFile(rootProject.file("license_header.txt"))
43 | trimTrailingWhitespace()
44 | }
45 | }
46 |
47 | jib {
48 | to {
49 | image = "ghcr.io/papermc/bibliothek"
50 | tags = setOf(
51 | "latest",
52 | "${indraGit.branchName()}-${indraGit.commit()?.name()?.take(8)}-${Instant.now().epochSecond}"
53 | )
54 | }
55 |
56 | from {
57 | image = "azul/zulu-openjdk-alpine:${indra.javaVersions().target().get()}-jre"
58 | platforms {
59 | // We can only build multi-arch images when pushing to a registry, not when building locally
60 | val requestedTasks = gradle.startParameter.taskNames
61 | if ("jibBuildTar" in requestedTasks || "jibDockerBuild" in requestedTasks) {
62 | platform {
63 | // todo: better logic
64 | architecture = when (System.getProperty("os.arch")) {
65 | "aarch64" -> "arm64"
66 | else -> "amd64"
67 | }
68 | os = "linux"
69 | }
70 | } else {
71 | platform {
72 | architecture = "amd64"
73 | os = "linux"
74 | }
75 | platform {
76 | architecture = "arm64"
77 | os = "linux"
78 | }
79 | }
80 | }
81 | }
82 |
83 | pluginExtensions {
84 | pluginExtension {
85 | implementation = "com.google.cloud.tools.jib.gradle.extension.springboot.JibSpringBootExtension"
86 | }
87 | }
88 |
89 | container {
90 | args = listOf("--spring.config.additional-location=optional:file:/config/")
91 | ports = listOf("8080")
92 | labels.put("org.opencontainers.image.source", indra.scm().map { it.url() })
93 | }
94 | }
95 |
96 | dependencies {
97 | annotationProcessor("org.springframework.boot", "spring-boot-configuration-processor")
98 | checkstyle(libs.stylecheck)
99 | implementation(libs.jetbrains.annotations)
100 | implementation(libs.springdoc.openapi.starter.webmvc.ui)
101 | implementation("org.springframework.boot", "spring-boot-starter-data-mongodb")
102 | implementation("org.springframework.boot", "spring-boot-starter-validation")
103 | implementation("org.springframework.boot", "spring-boot-starter-web")
104 | implementation("org.springframework.boot", "spring-boot-starter-actuator")
105 | testImplementation("org.springframework.boot", "spring-boot-starter-test") {
106 | exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
107 | }
108 | }
109 |
110 | tasks {
111 | val outputImageId = register("printJibMeta") {
112 | description = "Expose image information as an output for GitHub Actions"
113 |
114 | val jibImageJson = project.jib.outputPaths.imageJson
115 | val githubOutput = providers.environmentVariable("GITHUB_OUTPUT")
116 | inputs.property("jibImageJson", jibImageJson)
117 | inputs.property("githubOutput", githubOutput).optional(true)
118 |
119 | doLast {
120 | if (!githubOutput.isPresent) {
121 | didWork = false
122 | return@doLast
123 | }
124 |
125 | Path(githubOutput.get()).bufferedWriter(Charsets.UTF_8, options = arrayOf(StandardOpenOption.CREATE, StandardOpenOption.APPEND)).use {
126 | it.write("imageJson=")
127 | file(jibImageJson).bufferedReader(Charsets.UTF_8).use { meta -> meta.transferTo(it) }
128 | }
129 | }
130 | }
131 |
132 | sequenceOf(jib, jibDockerBuild, jibBuildTar).forEach {
133 | it.configure {
134 | finalizedBy(outputImageId.name)
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/cli/insertBuild.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const gitlog = require("gitlog").default;
3 | const {MongoClient} = require("mongodb");
4 | const path = require("path");
5 | const yargs = require("yargs");
6 |
7 | const argv = yargs
8 | .option("projectName", optionOf("string"))
9 | .option("projectFriendlyName", optionOf("string"))
10 | .option("versionGroupName", optionOf("string"))
11 | .option("versionName", optionOf("string"))
12 | .option("buildNumber", optionOf("number"))
13 | .option("repositoryPath", optionOf("string"))
14 | .option("storagePath", optionOf("string"))
15 | .option("download", optionOf("string"))
16 | .option("buildChannel", optionOf("string", false))
17 | .default("buildChannel", "default")
18 | .help()
19 | .version(false)
20 | .argv;
21 |
22 | const projectName = argv.projectName;
23 | const projectFriendlyName = argv.projectFriendlyName;
24 | const versionGroupName = argv.versionGroupName;
25 | const versionName = argv.versionName;
26 | const buildNumber = argv.buildNumber;
27 | const repositoryPath = argv.repositoryPath;
28 | const storagePath = argv.storagePath;
29 | // type:path:hash:name
30 | let downloads = argv.download;
31 | const buildChannel = argv.buildChannel.toUpperCase();
32 |
33 | // Validate buildChannel
34 | if (buildChannel !== "DEFAULT" && buildChannel !== "EXPERIMENTAL") {
35 | console.log(`Invalid buildChannel: ${buildChannel}`);
36 | return;
37 | }
38 |
39 | if(typeof downloads === "string") {
40 | const tempDownloads = downloads;
41 | downloads = [tempDownloads];
42 | }
43 |
44 | // Validate downloads
45 | let foundPrimary = false;
46 | for(let download of downloads) {
47 | const info = download.split(":");
48 | if(info.length === 3) {
49 | if(foundPrimary === true) {
50 | console.log("Too many primary files.");
51 | return;
52 | } else {
53 | foundPrimary = true;
54 | }
55 | }
56 | }
57 |
58 | // ----------------------------------------------------------------------------------------------------
59 |
60 | const downloadsPath = path.join(
61 | storagePath,
62 | projectName,
63 | versionName,
64 | buildNumber.toString()
65 | );
66 |
67 | if(!fs.existsSync(downloadsPath)) {
68 | fs.mkdirSync(downloadsPath, {
69 | recursive: true
70 | });
71 | }
72 |
73 | for(let download of downloads) {
74 | const info = download.split(":");
75 | if(info.length === 3) {
76 | const downloadPath = path.join(
77 | downloadsPath,
78 | projectName + "-" + versionName + "-" + buildNumber + ".jar"
79 | );
80 | fs.copyFileSync(info[1], downloadPath);
81 | } else if(info.length === 4) {
82 | const downloadPath = path.join(
83 | downloadsPath,
84 | info[3]
85 | );
86 | fs.copyFileSync(info[1], downloadPath);
87 | }
88 | }
89 |
90 | const client = new MongoClient(process.env.MONGODB_URL || "mongodb://localhost:27017", {
91 | useUnifiedTopology: true
92 | });
93 |
94 | async function run() {
95 | try {
96 | await client.connect();
97 | const database = client.db("library"); // "library" instead of "bibliothek" is intentional here
98 | const project = await database.collection("projects").findOneAndUpdate(
99 | {"name": projectName},
100 | {
101 | $setOnInsert: {
102 | "name": projectName,
103 | "friendlyName": projectFriendlyName
104 | }
105 | },
106 | {
107 | new: true,
108 | returnDocument: "after",
109 | upsert: true
110 | }
111 | );
112 | const versionGroup = await database.collection("version_groups").findOneAndUpdate(
113 | {
114 | "project": project.value._id,
115 | "name": versionGroupName
116 | },
117 | {
118 | $setOnInsert: {
119 | "project": project.value._id,
120 | "name": versionGroupName
121 | }
122 | },
123 | {
124 | new: true,
125 | returnDocument: "after",
126 | upsert: true
127 | }
128 | );
129 | const version = await database.collection("versions").findOneAndUpdate(
130 | {
131 | "project": project.value._id,
132 | "name": versionName
133 | },
134 | {
135 | $setOnInsert: {
136 | "project": project.value._id,
137 | "group": versionGroup.value._id,
138 | "name": versionName
139 | }
140 | },
141 | {
142 | new: true,
143 | returnDocument: "after",
144 | upsert: true
145 | }
146 | );
147 | const oldBuild = await database.collection("builds").findOne({
148 | "project": project.value._id,
149 | "version": version.value._id
150 | }, {sort: {_id: -1}});
151 | let changes = [];
152 | const lastBuild = oldBuild && oldBuild.changes.length ? oldBuild.changes.slice(0, 1)[0].commit : "HEAD^1";
153 | const commits = gitlog({
154 | repo: repositoryPath,
155 | fields: ["hash", "subject", "rawBody"],
156 | branch: lastBuild + "...HEAD"
157 | });
158 | commits.forEach(function (commit) {
159 | changes.push({
160 | "commit": commit.hash,
161 | "summary": commit.subject,
162 | "message": commit.rawBody
163 | });
164 | });
165 | const buildDownloads = {};
166 | for(let download of downloads) {
167 | const info = download.split(":");
168 | if(info.length === 3) {
169 | buildDownloads[info[0].replace(".", ":")] = {
170 | "name": projectName + "-" + versionName + "-" + buildNumber + ".jar",
171 | "sha256": info[2]
172 | };
173 | } else if(info.length === 4) {
174 | buildDownloads[info[0].replace(".", ":")] = {
175 | "name": info[3],
176 | "sha256": info[2]
177 | };
178 | }
179 | }
180 | const build = await database.collection("builds").insertOne({
181 | "project": project.value._id,
182 | "version": version.value._id,
183 | "number": buildNumber,
184 | "time": new Date(),
185 | "changes": changes,
186 | "downloads": buildDownloads,
187 | "promoted": false,
188 | "channel": buildChannel
189 | });
190 | console.log("Inserted build " + buildNumber + " (channel: " + buildChannel + ") for project " + project.value.name + " (" + project.value._id + ") version " + version.value.name + " (" + version.value._id + "): " + build.insertedId);
191 | } finally {
192 | await client.close();
193 | }
194 | }
195 |
196 | run().catch(console.dir);
197 |
198 | function optionOf(type, required = true) {
199 | return {
200 | type: type,
201 | required: required
202 | };
203 | }
204 |
--------------------------------------------------------------------------------
/cli/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ruler-cli",
3 | "version": "1.0.0-SNAPSHOT",
4 | "main": "insertBuild.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "gitlog": "^4.0.4",
8 | "mongodb": "^4.2.1",
9 | "yargs": "^17.7.1"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/cli/promoteBuild.js:
--------------------------------------------------------------------------------
1 | const yargs = require("yargs");
2 | const {MongoClient} = require("mongodb");
3 | const ObjectId = require("mongodb").ObjectId;
4 |
5 | const argv = yargs
6 | .option("build", optionOf("string"))
7 | .option("promoted", optionOf("boolean"))
8 | .help()
9 | .alias("help", "h")
10 | .version(false)
11 | .argv;
12 |
13 | const client = new MongoClient("mongodb://localhost:27017", {
14 | useUnifiedTopology: true
15 | });
16 |
17 | async function run() {
18 | try {
19 | await client.connect();
20 | const database = client.db("library");
21 |
22 | const build = await database.collection("builds").findOne({
23 | _id: ObjectId(argv.build)
24 | });
25 |
26 | if (!build) {
27 | console.log(`Build not found with ID ${argv.build}`);
28 | return;
29 | }
30 |
31 | await database.collection("builds").updateOne(
32 | {
33 | _id: ObjectId(argv.build)
34 | },
35 | {
36 | $set: {
37 | promoted: argv.promoted === true
38 | }
39 | }
40 | );
41 |
42 | console.log(`Build ${argv.build} promotion state changed to: ${argv.promoted}`);
43 | } finally {
44 | await client.close();
45 | }
46 | }
47 |
48 | run().catch(console.dir);
49 |
50 | function optionOf(type) {
51 | return {
52 | type,
53 | required: true
54 | };
55 | }
56 |
--------------------------------------------------------------------------------
/cli/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@types/node@*":
6 | version "16.11.10"
7 | resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.10.tgz#2e3ad0a680d96367103d3e670d41c2fed3da61ae"
8 | integrity sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA==
9 |
10 | "@types/webidl-conversions@*":
11 | version "6.1.1"
12 | resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz#e33bc8ea812a01f63f90481c666334844b12a09e"
13 | integrity sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q==
14 |
15 | "@types/whatwg-url@^8.2.1":
16 | version "8.2.1"
17 | resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-8.2.1.tgz#f1aac222dab7c59e011663a0cb0a3117b2ef05d4"
18 | integrity sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==
19 | dependencies:
20 | "@types/node" "*"
21 | "@types/webidl-conversions" "*"
22 |
23 | ansi-regex@^5.0.1:
24 | version "5.0.1"
25 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
26 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
27 |
28 | ansi-styles@^4.0.0:
29 | version "4.3.0"
30 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
31 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
32 | dependencies:
33 | color-convert "^2.0.1"
34 |
35 | base64-js@^1.3.1:
36 | version "1.5.1"
37 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
38 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
39 |
40 | bson@^4.6.0:
41 | version "4.6.0"
42 | resolved "https://registry.yarnpkg.com/bson/-/bson-4.6.0.tgz#15c3b39ba3940c3d915a0c44d51459f4b4fbf1b2"
43 | integrity sha512-8jw1NU1hglS+Da1jDOUYuNcBJ4cNHCFIqzlwoFNnsTOg2R/ox0aTYcTiBN4dzRa9q7Cvy6XErh3L8ReTEb9AQQ==
44 | dependencies:
45 | buffer "^5.6.0"
46 |
47 | buffer@^5.6.0:
48 | version "5.7.1"
49 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
50 | integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
51 | dependencies:
52 | base64-js "^1.3.1"
53 | ieee754 "^1.1.13"
54 |
55 | cliui@^8.0.1:
56 | version "8.0.1"
57 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
58 | integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
59 | dependencies:
60 | string-width "^4.2.0"
61 | strip-ansi "^6.0.1"
62 | wrap-ansi "^7.0.0"
63 |
64 | color-convert@^2.0.1:
65 | version "2.0.1"
66 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
67 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
68 | dependencies:
69 | color-name "~1.1.4"
70 |
71 | color-name@~1.1.4:
72 | version "1.1.4"
73 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
74 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
75 |
76 | debug@^4.1.1:
77 | version "4.3.3"
78 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
79 | integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
80 | dependencies:
81 | ms "2.1.2"
82 |
83 | denque@^2.0.1:
84 | version "2.0.1"
85 | resolved "https://registry.yarnpkg.com/denque/-/denque-2.0.1.tgz#bcef4c1b80dc32efe97515744f21a4229ab8934a"
86 | integrity sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==
87 |
88 | emoji-regex@^8.0.0:
89 | version "8.0.0"
90 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
91 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
92 |
93 | escalade@^3.1.1:
94 | version "3.1.1"
95 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
96 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
97 |
98 | get-caller-file@^2.0.5:
99 | version "2.0.5"
100 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
101 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
102 |
103 | gitlog@^4.0.4:
104 | version "4.0.4"
105 | resolved "https://registry.yarnpkg.com/gitlog/-/gitlog-4.0.4.tgz#8da6c08748dc290eb6c2fc11e3c505fb73715564"
106 | integrity sha512-jeY2kO7CVyTa6cUM7ZD2ZxIyBkna1xvW2esV/3o8tbhiUneX1UBQCH4D9aMrHgGiohBjyXbuZogyjKXslnY5Yg==
107 | dependencies:
108 | debug "^4.1.1"
109 | tslib "^1.14.1"
110 |
111 | ieee754@^1.1.13:
112 | version "1.2.1"
113 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
114 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
115 |
116 | is-fullwidth-code-point@^3.0.0:
117 | version "3.0.0"
118 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
119 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
120 |
121 | memory-pager@^1.0.2:
122 | version "1.5.0"
123 | resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5"
124 | integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==
125 |
126 | mongodb-connection-string-url@^2.2.0:
127 | version "2.2.0"
128 | resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-2.2.0.tgz#e2422bae91a953dc4ae5882e401301f5be39a227"
129 | integrity sha512-U0cDxLUrQrl7DZA828CA+o69EuWPWEJTwdMPozyd7cy/dbtncUZczMw7wRHcwMD7oKOn0NM2tF9jdf5FFVW9CA==
130 | dependencies:
131 | "@types/whatwg-url" "^8.2.1"
132 | whatwg-url "^11.0.0"
133 |
134 | mongodb@^4.2.1:
135 | version "4.2.1"
136 | resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-4.2.1.tgz#c167db158ab0bf6552b3f9c91b396cb4100c2f04"
137 | integrity sha512-nDC+ulM/Ea3Q2VG5eemuGfB7T4ORwrtKegH2XW9OLlUBgQF6OTNrzFCS1Z3SJGVA+T0Sr1xBYV6DMnp0A7us0g==
138 | dependencies:
139 | bson "^4.6.0"
140 | denque "^2.0.1"
141 | mongodb-connection-string-url "^2.2.0"
142 | optionalDependencies:
143 | saslprep "^1.0.3"
144 |
145 | ms@2.1.2:
146 | version "2.1.2"
147 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
148 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
149 |
150 | punycode@^2.1.1:
151 | version "2.1.1"
152 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
153 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
154 |
155 | require-directory@^2.1.1:
156 | version "2.1.1"
157 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
158 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
159 |
160 | saslprep@^1.0.3:
161 | version "1.0.3"
162 | resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226"
163 | integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==
164 | dependencies:
165 | sparse-bitfield "^3.0.3"
166 |
167 | sparse-bitfield@^3.0.3:
168 | version "3.0.3"
169 | resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11"
170 | integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE=
171 | dependencies:
172 | memory-pager "^1.0.2"
173 |
174 | string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
175 | version "4.2.3"
176 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
177 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
178 | dependencies:
179 | emoji-regex "^8.0.0"
180 | is-fullwidth-code-point "^3.0.0"
181 | strip-ansi "^6.0.1"
182 |
183 | strip-ansi@^6.0.0, strip-ansi@^6.0.1:
184 | version "6.0.1"
185 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
186 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
187 | dependencies:
188 | ansi-regex "^5.0.1"
189 |
190 | tr46@^3.0.0:
191 | version "3.0.0"
192 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9"
193 | integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==
194 | dependencies:
195 | punycode "^2.1.1"
196 |
197 | tslib@^1.14.1:
198 | version "1.14.1"
199 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
200 | integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
201 |
202 | webidl-conversions@^7.0.0:
203 | version "7.0.0"
204 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
205 | integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
206 |
207 | whatwg-url@^11.0.0:
208 | version "11.0.0"
209 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018"
210 | integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==
211 | dependencies:
212 | tr46 "^3.0.0"
213 | webidl-conversions "^7.0.0"
214 |
215 | wrap-ansi@^7.0.0:
216 | version "7.0.0"
217 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
218 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
219 | dependencies:
220 | ansi-styles "^4.0.0"
221 | string-width "^4.1.0"
222 | strip-ansi "^6.0.0"
223 |
224 | y18n@^5.0.5:
225 | version "5.0.8"
226 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
227 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
228 |
229 | yargs-parser@^21.1.1:
230 | version "21.1.1"
231 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
232 | integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
233 |
234 | yargs@^17.7.1:
235 | version "17.7.1"
236 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967"
237 | integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==
238 | dependencies:
239 | cliui "^8.0.1"
240 | escalade "^3.1.1"
241 | get-caller-file "^2.0.5"
242 | require-directory "^2.1.1"
243 | string-width "^4.2.3"
244 | y18n "^5.0.5"
245 | yargs-parser "^21.1.1"
246 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | group = io.papermc
2 | version = 1.0.0-SNAPSHOT
3 |
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | indra = "3.1.3"
3 |
4 | [plugins]
5 | indra = { id = "net.kyori.indra", version.ref = "indra" }
6 | indra-checkstyle = { id = "net.kyori.indra.checkstyle", version.ref = "indra" }
7 | indra-git = { id = "net.kyori.indra.git", version.ref = "indra" }
8 | jib = { id = "com.google.cloud.tools.jib", version = "3.4.3" }
9 | spotless = { id = "com.diffplug.spotless", version = "6.25.0" }
10 | spring-boot = { id = "org.springframework.boot", version = "3.2.5" }
11 | spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.5" }
12 |
13 | [libraries]
14 | jetbrains-annotations = { group = "org.jetbrains", name = "annotations", version = "24.1.0" }
15 | springdoc-openapi-starter-webmvc-ui = { group = "org.springdoc", name = "springdoc-openapi-starter-webmvc-ui", version = "2.5.0" }
16 | stylecheck = { group = "ca.stellardrift", name = "stylecheck", version = "0.2.1" }
17 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaperMC/bibliothek/1608a700b8462b0016d38f2459c92bf898c21522/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC2039,SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC2039,SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command:
206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
207 | # and any embedded shellness will be escaped.
208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
209 | # treated as '${Hostname}' itself on the command line.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019-2024 PaperMC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/license_header.txt:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # bibliothek
2 |
3 | A downloads API.
4 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:recommended"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
3 | }
4 |
5 | rootProject.name = "bibliothek"
6 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/BibliothekApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek;
25 |
26 | import io.papermc.bibliothek.configuration.AppConfiguration;
27 | import org.springframework.boot.SpringApplication;
28 | import org.springframework.boot.autoconfigure.SpringBootApplication;
29 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
30 | import org.springframework.boot.web.servlet.ServletComponentScan;
31 |
32 | @EnableConfigurationProperties({
33 | AppConfiguration.class
34 | })
35 | @SpringBootApplication
36 | @ServletComponentScan
37 | public class BibliothekApplication {
38 | public static void main(final String[] args) {
39 | SpringApplication.run(BibliothekApplication.class, args);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/configuration/AppConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.configuration;
25 |
26 | import jakarta.validation.constraints.NotNull;
27 | import java.net.URL;
28 | import java.nio.file.Path;
29 | import org.springframework.boot.context.properties.ConfigurationProperties;
30 | import org.springframework.validation.annotation.Validated;
31 |
32 | @ConfigurationProperties(prefix = "app")
33 | @Validated
34 | public class AppConfiguration {
35 | private URL apiBaseUrl;
36 | private String apiTitle;
37 | private String apiVersion;
38 | private @NotNull Path storagePath;
39 |
40 | public URL getApiBaseUrl() {
41 | return this.apiBaseUrl;
42 | }
43 |
44 | public void setApiBaseUrl(final URL apiBaseUrl) {
45 | this.apiBaseUrl = apiBaseUrl;
46 | }
47 |
48 | public String getApiTitle() {
49 | return this.apiTitle;
50 | }
51 |
52 | public void setApiTitle(final String apiTitle) {
53 | this.apiTitle = apiTitle;
54 | }
55 |
56 | public String getApiVersion() {
57 | return this.apiVersion;
58 | }
59 |
60 | public void setApiVersion(final String apiVersion) {
61 | this.apiVersion = apiVersion;
62 | }
63 |
64 | public Path getStoragePath() {
65 | return this.storagePath;
66 | }
67 |
68 | public void setStoragePath(final Path storagePath) {
69 | this.storagePath = storagePath;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/configuration/MongoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.configuration;
25 |
26 | import org.springframework.context.annotation.Bean;
27 | import org.springframework.context.annotation.Configuration;
28 | import org.springframework.data.mongodb.MongoDatabaseFactory;
29 | import org.springframework.data.mongodb.core.convert.DbRefResolver;
30 | import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
31 | import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
32 | import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
33 | import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
34 | import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
35 |
36 | @Configuration
37 | class MongoConfiguration {
38 | @Bean
39 | MappingMongoConverter mappingMongoConverter(
40 | final MongoDatabaseFactory mongoDatabaseFactory,
41 | final MongoMappingContext context,
42 | final MongoCustomConversions mongoCustomConversions
43 | ) {
44 | final DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDatabaseFactory);
45 | final MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
46 | mappingConverter.setCustomConversions(mongoCustomConversions);
47 | mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null)); // to remove _class
48 | return mappingConverter;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/configuration/OpenAPIConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.configuration;
25 |
26 | import io.swagger.v3.oas.models.OpenAPI;
27 | import io.swagger.v3.oas.models.info.Info;
28 | import io.swagger.v3.oas.models.media.Schema;
29 | import io.swagger.v3.oas.models.servers.Server;
30 | import java.net.URL;
31 | import java.util.List;
32 | import java.util.Map;
33 | import java.util.TreeMap;
34 | import org.springdoc.core.customizers.OpenApiCustomizer;
35 | import org.springframework.context.annotation.Bean;
36 | import org.springframework.context.annotation.Configuration;
37 |
38 | @Configuration
39 | class OpenAPIConfiguration {
40 | @Bean
41 | OpenAPI openAPI(final AppConfiguration configuration) {
42 | final OpenAPI api = new OpenAPI();
43 | api.info(
44 | new Info()
45 | .title(configuration.getApiTitle())
46 | .version(configuration.getApiVersion())
47 | );
48 | final URL apiBaseUrl = configuration.getApiBaseUrl();
49 | if (apiBaseUrl != null) {
50 | api.servers(List.of(new Server().url(apiBaseUrl.toExternalForm())));
51 | }
52 | return api;
53 | }
54 |
55 | @Bean
56 | @SuppressWarnings("rawtypes") // nothing we can do, the API exposes it raw
57 | OpenApiCustomizer sortSchemasAlphabetically() {
58 | return openApi -> {
59 | final Map schemas = openApi.getComponents().getSchemas();
60 | openApi.getComponents().setSchemas(new TreeMap<>(schemas));
61 | };
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/configuration/WebConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.configuration;
25 |
26 | import jakarta.servlet.Filter;
27 | import org.springframework.context.annotation.Bean;
28 | import org.springframework.context.annotation.Configuration;
29 | import org.springframework.web.filter.ShallowEtagHeaderFilter;
30 |
31 | @Configuration
32 | class WebConfiguration {
33 | @Bean
34 | Filter shallowETagHeaderFilter() {
35 | return new ShallowEtagHeaderFilter();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/controller/RootController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.controller;
25 |
26 | import java.net.URI;
27 | import org.springframework.http.HttpStatus;
28 | import org.springframework.http.ResponseEntity;
29 | import org.springframework.stereotype.Controller;
30 | import org.springframework.web.bind.annotation.GetMapping;
31 |
32 | @Controller
33 | public class RootController {
34 | @GetMapping({
35 | "/",
36 | "/docs" // without trailing /
37 | })
38 | public ResponseEntity> redirectToDocs() {
39 | return ResponseEntity.status(HttpStatus.FOUND)
40 | .location(URI.create("docs/"))
41 | .build();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/controller/v2/DownloadController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.controller.v2;
25 |
26 | import io.papermc.bibliothek.configuration.AppConfiguration;
27 | import io.papermc.bibliothek.database.model.Build;
28 | import io.papermc.bibliothek.database.model.Project;
29 | import io.papermc.bibliothek.database.model.Version;
30 | import io.papermc.bibliothek.database.repository.BuildCollection;
31 | import io.papermc.bibliothek.database.repository.ProjectCollection;
32 | import io.papermc.bibliothek.database.repository.VersionCollection;
33 | import io.papermc.bibliothek.exception.BuildNotFound;
34 | import io.papermc.bibliothek.exception.DownloadFailed;
35 | import io.papermc.bibliothek.exception.DownloadNotFound;
36 | import io.papermc.bibliothek.exception.ProjectNotFound;
37 | import io.papermc.bibliothek.exception.VersionNotFound;
38 | import io.papermc.bibliothek.util.HTTP;
39 | import io.papermc.bibliothek.util.MediaTypes;
40 | import io.swagger.v3.oas.annotations.Operation;
41 | import io.swagger.v3.oas.annotations.Parameter;
42 | import io.swagger.v3.oas.annotations.headers.Header;
43 | import io.swagger.v3.oas.annotations.media.Schema;
44 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
45 | import jakarta.validation.constraints.Pattern;
46 | import jakarta.validation.constraints.Positive;
47 | import java.io.IOException;
48 | import java.nio.file.Files;
49 | import java.nio.file.Path;
50 | import java.time.Duration;
51 | import java.util.Map;
52 | import org.springframework.beans.factory.annotation.Autowired;
53 | import org.springframework.core.io.FileSystemResource;
54 | import org.springframework.http.CacheControl;
55 | import org.springframework.http.HttpHeaders;
56 | import org.springframework.http.HttpStatus;
57 | import org.springframework.http.MediaType;
58 | import org.springframework.http.ResponseEntity;
59 | import org.springframework.web.bind.annotation.GetMapping;
60 | import org.springframework.web.bind.annotation.PathVariable;
61 | import org.springframework.web.bind.annotation.RequestMapping;
62 | import org.springframework.web.bind.annotation.RestController;
63 |
64 | @RestController
65 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
66 | public class DownloadController {
67 | private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofDays(7));
68 | private final AppConfiguration configuration;
69 | private final ProjectCollection projects;
70 | private final VersionCollection versions;
71 | private final BuildCollection builds;
72 |
73 | @Autowired
74 | private DownloadController(
75 | final AppConfiguration configuration,
76 | final ProjectCollection projects,
77 | final VersionCollection versions,
78 | final BuildCollection builds
79 | ) {
80 | this.configuration = configuration;
81 | this.projects = projects;
82 | this.versions = versions;
83 | this.builds = builds;
84 | }
85 |
86 | @ApiResponse(
87 | responseCode = "200",
88 | headers = {
89 | @Header(
90 | name = "Content-Disposition",
91 | description = "A header indicating that the content is expected to be displayed as an attachment, that is downloaded and saved locally.",
92 | schema = @Schema(type = "string")
93 | ),
94 | @Header(
95 | name = "ETag",
96 | description = "An identifier for a specific version of a resource. It lets caches be more efficient and save bandwidth, as a web server does not need to resend a full response if the content has not changed.",
97 | schema = @Schema(type = "string")
98 | ),
99 | @Header(
100 | name = "Last-Modified",
101 | description = "The date and time at which the origin server believes the resource was last modified.",
102 | schema = @Schema(type = "string")
103 | )
104 | }
105 | )
106 | @GetMapping(
107 | value = "/v2/projects/{project:[a-z]+}/versions/{version:" + Version.PATTERN + "}/builds/{build:\\d+}/downloads/{download:" + Build.Download.PATTERN + "}",
108 | produces = {
109 | MediaType.APPLICATION_JSON_VALUE,
110 | MediaType.ALL_VALUE
111 | }
112 | )
113 | @Operation(summary = "Downloads the given file from a build's data.")
114 | public ResponseEntity> download(
115 | @Parameter(name = "project", description = "The project identifier.", example = "paper")
116 | @PathVariable("project")
117 | @Pattern(regexp = "[a-z]+") //
118 | final String projectName,
119 | @Parameter(description = "A version of the project.")
120 | @PathVariable("version")
121 | @Pattern(regexp = Version.PATTERN) //
122 | final String versionName,
123 | @Parameter(description = "A build of the version.")
124 | @PathVariable("build")
125 | @Positive //
126 | final int buildNumber,
127 | @Parameter(description = "A download of the build.")
128 | @PathVariable("download")
129 | @Pattern(regexp = Build.Download.PATTERN) //
130 | final String downloadName
131 | ) {
132 | final Project project = this.projects.findByName(projectName).orElseThrow(ProjectNotFound::new);
133 | final Version version = this.versions.findByProjectAndName(project._id(), versionName).orElseThrow(VersionNotFound::new);
134 | final Build build = this.builds.findByProjectAndVersionAndNumber(project._id(), version._id(), buildNumber).orElseThrow(BuildNotFound::new);
135 |
136 | for (final Map.Entry download : build.downloads().entrySet()) {
137 | if (download.getValue().name().equals(downloadName)) {
138 | try {
139 | return new JavaArchive(
140 | this.configuration.getStoragePath()
141 | .resolve(project.name())
142 | .resolve(version.name())
143 | .resolve(String.valueOf(build.number()))
144 | .resolve(download.getValue().name()),
145 | CACHE
146 | );
147 | } catch (final IOException e) {
148 | throw new DownloadFailed(e);
149 | }
150 | }
151 | }
152 | throw new DownloadNotFound();
153 | }
154 |
155 | private static class JavaArchive extends ResponseEntity {
156 | JavaArchive(final Path path, final CacheControl cache) throws IOException {
157 | super(new FileSystemResource(path), headersFor(path, cache), HttpStatus.OK);
158 | }
159 |
160 | private static HttpHeaders headersFor(final Path path, final CacheControl cache) throws IOException {
161 | final HttpHeaders headers = new HttpHeaders();
162 | headers.setCacheControl(cache);
163 | headers.setContentDisposition(HTTP.attachmentDisposition(path.getFileName()));
164 | headers.setContentType(MediaTypes.fromFileName(path.getFileName().toString()));
165 | headers.setLastModified(Files.getLastModifiedTime(path).toInstant());
166 | return headers;
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/controller/v2/ProjectController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.controller.v2;
25 |
26 | import io.papermc.bibliothek.database.model.Project;
27 | import io.papermc.bibliothek.database.model.Version;
28 | import io.papermc.bibliothek.database.model.VersionFamily;
29 | import io.papermc.bibliothek.database.repository.ProjectCollection;
30 | import io.papermc.bibliothek.database.repository.VersionCollection;
31 | import io.papermc.bibliothek.database.repository.VersionFamilyCollection;
32 | import io.papermc.bibliothek.exception.ProjectNotFound;
33 | import io.papermc.bibliothek.util.HTTP;
34 | import io.swagger.v3.oas.annotations.Operation;
35 | import io.swagger.v3.oas.annotations.Parameter;
36 | import io.swagger.v3.oas.annotations.media.Content;
37 | import io.swagger.v3.oas.annotations.media.Schema;
38 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
39 | import jakarta.validation.constraints.Pattern;
40 | import java.time.Duration;
41 | import java.util.List;
42 | import org.springframework.beans.factory.annotation.Autowired;
43 | import org.springframework.http.CacheControl;
44 | import org.springframework.http.MediaType;
45 | import org.springframework.http.ResponseEntity;
46 | import org.springframework.web.bind.annotation.GetMapping;
47 | import org.springframework.web.bind.annotation.PathVariable;
48 | import org.springframework.web.bind.annotation.RequestMapping;
49 | import org.springframework.web.bind.annotation.RestController;
50 |
51 | @RestController
52 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
53 | public class ProjectController {
54 | private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(30));
55 | private final ProjectCollection projects;
56 | private final VersionFamilyCollection families;
57 | private final VersionCollection versions;
58 |
59 | @Autowired
60 | private ProjectController(
61 | final ProjectCollection projects,
62 | final VersionFamilyCollection families,
63 | final VersionCollection versions
64 | ) {
65 | this.projects = projects;
66 | this.families = families;
67 | this.versions = versions;
68 | }
69 |
70 | @ApiResponse(
71 | content = @Content(
72 | schema = @Schema(implementation = ProjectResponse.class)
73 | ),
74 | responseCode = "200"
75 | )
76 | @GetMapping("/v2/projects/{project:[a-z]+}")
77 | @Operation(summary = "Gets information about a project.")
78 | public ResponseEntity> project(
79 | @Parameter(name = "project", description = "The project identifier.", example = "paper")
80 | @PathVariable("project")
81 | @Pattern(regexp = "[a-z]+") //
82 | final String projectName
83 | ) {
84 | final Project project = this.projects.findByName(projectName).orElseThrow(ProjectNotFound::new);
85 | final List families = this.families.findAllByProject(project._id());
86 | final List versions = this.versions.findAllByProject(project._id());
87 | return HTTP.cachedOk(ProjectResponse.from(project, families, versions), CACHE);
88 | }
89 |
90 | @Schema
91 | private record ProjectResponse(
92 | @Schema(name = "project_id", pattern = "[a-z]+", example = "paper")
93 | String project_id,
94 | @Schema(name = "project_name", example = "Paper")
95 | String project_name,
96 | @Schema(name = "version_groups")
97 | List version_groups,
98 | @Schema(name = "versions")
99 | List versions
100 | ) {
101 | static ProjectResponse from(final Project project, final List families, final List versions) {
102 | return new ProjectResponse(
103 | project.name(),
104 | project.friendlyName(),
105 | families.stream().sorted(VersionFamily.COMPARATOR).map(VersionFamily::name).toList(),
106 | versions.stream().sorted(Version.COMPARATOR).map(Version::name).toList()
107 | );
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/controller/v2/ProjectsController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.controller.v2;
25 |
26 | import io.papermc.bibliothek.database.model.Project;
27 | import io.papermc.bibliothek.database.repository.ProjectCollection;
28 | import io.papermc.bibliothek.util.HTTP;
29 | import io.swagger.v3.oas.annotations.Operation;
30 | import io.swagger.v3.oas.annotations.media.Content;
31 | import io.swagger.v3.oas.annotations.media.Schema;
32 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
33 | import java.time.Duration;
34 | import java.util.List;
35 | import org.springframework.beans.factory.annotation.Autowired;
36 | import org.springframework.http.CacheControl;
37 | import org.springframework.http.MediaType;
38 | import org.springframework.http.ResponseEntity;
39 | import org.springframework.web.bind.annotation.GetMapping;
40 | import org.springframework.web.bind.annotation.RequestMapping;
41 | import org.springframework.web.bind.annotation.RestController;
42 |
43 | @RestController
44 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
45 | public class ProjectsController {
46 | private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofDays(7));
47 | private final ProjectCollection projects;
48 |
49 | @Autowired
50 | private ProjectsController(final ProjectCollection projects) {
51 | this.projects = projects;
52 | }
53 |
54 | @ApiResponse(
55 | content = @Content(
56 | schema = @Schema(implementation = ProjectsResponse.class)
57 | ),
58 | responseCode = "200"
59 | )
60 | @GetMapping("/v2/projects")
61 | @Operation(summary = "Gets a list of all available projects.")
62 | public ResponseEntity> projects() {
63 | final List projects = this.projects.findAll();
64 | return HTTP.cachedOk(ProjectsResponse.from(projects), CACHE);
65 | }
66 |
67 | @Schema
68 | private record ProjectsResponse(
69 | @Schema(name = "projects")
70 | List projects
71 | ) {
72 | static ProjectsResponse from(final List projects) {
73 | return new ProjectsResponse(projects.stream().map(Project::name).toList());
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.controller.v2;
25 |
26 | import io.papermc.bibliothek.database.model.Build;
27 | import io.papermc.bibliothek.database.model.Project;
28 | import io.papermc.bibliothek.database.model.Version;
29 | import io.papermc.bibliothek.database.repository.BuildCollection;
30 | import io.papermc.bibliothek.database.repository.ProjectCollection;
31 | import io.papermc.bibliothek.database.repository.VersionCollection;
32 | import io.papermc.bibliothek.exception.BuildNotFound;
33 | import io.papermc.bibliothek.exception.ProjectNotFound;
34 | import io.papermc.bibliothek.exception.VersionNotFound;
35 | import io.papermc.bibliothek.util.HTTP;
36 | import io.swagger.v3.oas.annotations.Operation;
37 | import io.swagger.v3.oas.annotations.Parameter;
38 | import io.swagger.v3.oas.annotations.media.Content;
39 | import io.swagger.v3.oas.annotations.media.Schema;
40 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
41 | import jakarta.validation.constraints.Pattern;
42 | import jakarta.validation.constraints.Positive;
43 | import java.time.Duration;
44 | import java.time.Instant;
45 | import java.util.List;
46 | import java.util.Map;
47 | import org.springframework.beans.factory.annotation.Autowired;
48 | import org.springframework.http.CacheControl;
49 | import org.springframework.http.MediaType;
50 | import org.springframework.http.ResponseEntity;
51 | import org.springframework.web.bind.annotation.GetMapping;
52 | import org.springframework.web.bind.annotation.PathVariable;
53 | import org.springframework.web.bind.annotation.RequestMapping;
54 | import org.springframework.web.bind.annotation.RestController;
55 |
56 | @RestController
57 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
58 | public class VersionBuildController {
59 | private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofDays(7));
60 | private final ProjectCollection projects;
61 | private final VersionCollection versions;
62 | private final BuildCollection builds;
63 |
64 | @Autowired
65 | private VersionBuildController(
66 | final ProjectCollection projects,
67 | final VersionCollection versions,
68 | final BuildCollection builds
69 | ) {
70 | this.projects = projects;
71 | this.versions = versions;
72 | this.builds = builds;
73 | }
74 |
75 | @ApiResponse(
76 | content = @Content(
77 | schema = @Schema(implementation = BuildResponse.class)
78 | ),
79 | responseCode = "200"
80 | )
81 | @GetMapping("/v2/projects/{project:[a-z]+}/versions/{version:" + Version.PATTERN + "}/builds/{build:\\d+}")
82 | @Operation(summary = "Gets information related to a specific build.")
83 | public ResponseEntity> build(
84 | @Parameter(name = "project", description = "The project identifier.", example = "paper")
85 | @PathVariable("project")
86 | @Pattern(regexp = "[a-z]+") //
87 | final String projectName,
88 | @Parameter(description = "A version of the project.")
89 | @PathVariable("version")
90 | @Pattern(regexp = Version.PATTERN) //
91 | final String versionName,
92 | @Parameter(description = "A build of the version.")
93 | @PathVariable("build")
94 | @Positive //
95 | final int buildNumber
96 | ) {
97 | final Project project = this.projects.findByName(projectName).orElseThrow(ProjectNotFound::new);
98 | final Version version = this.versions.findByProjectAndName(project._id(), versionName).orElseThrow(VersionNotFound::new);
99 | final Build build = this.builds.findByProjectAndVersionAndNumber(project._id(), version._id(), buildNumber).orElseThrow(BuildNotFound::new);
100 | return HTTP.cachedOk(BuildResponse.from(project, version, build), CACHE);
101 | }
102 |
103 | @Schema
104 | private record BuildResponse(
105 | @Schema(name = "project_id", pattern = "[a-z]+", example = "paper")
106 | String project_id,
107 | @Schema(name = "project_name", example = "Paper")
108 | String project_name,
109 | @Schema(name = "version", pattern = Version.PATTERN, example = "1.18")
110 | String version,
111 | @Schema(name = "build", pattern = "\\d+", example = "10")
112 | int build,
113 | @Schema(name = "time")
114 | Instant time,
115 | @Schema(name = "channel")
116 | Build.Channel channel,
117 | @Schema(name = "promoted")
118 | boolean promoted,
119 | @Schema(name = "changes")
120 | List changes,
121 | @Schema(name = "downloads")
122 | Map downloads
123 | ) {
124 | static BuildResponse from(final Project project, final Version version, final Build build) {
125 | return new BuildResponse(
126 | project.name(),
127 | project.friendlyName(),
128 | version.name(),
129 | build.number(),
130 | build.time(),
131 | build.channelOrDefault(),
132 | build.promotedOrDefault(),
133 | build.changes(),
134 | build.downloads()
135 | );
136 | }
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildsController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.controller.v2;
25 |
26 | import io.papermc.bibliothek.database.model.Build;
27 | import io.papermc.bibliothek.database.model.Project;
28 | import io.papermc.bibliothek.database.model.Version;
29 | import io.papermc.bibliothek.database.repository.BuildCollection;
30 | import io.papermc.bibliothek.database.repository.ProjectCollection;
31 | import io.papermc.bibliothek.database.repository.VersionCollection;
32 | import io.papermc.bibliothek.exception.ProjectNotFound;
33 | import io.papermc.bibliothek.exception.VersionNotFound;
34 | import io.papermc.bibliothek.util.HTTP;
35 | import io.swagger.v3.oas.annotations.Operation;
36 | import io.swagger.v3.oas.annotations.Parameter;
37 | import io.swagger.v3.oas.annotations.media.Content;
38 | import io.swagger.v3.oas.annotations.media.Schema;
39 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
40 | import jakarta.validation.constraints.Pattern;
41 | import java.time.Duration;
42 | import java.time.Instant;
43 | import java.util.List;
44 | import java.util.Map;
45 | import org.springframework.beans.factory.annotation.Autowired;
46 | import org.springframework.http.CacheControl;
47 | import org.springframework.http.MediaType;
48 | import org.springframework.http.ResponseEntity;
49 | import org.springframework.web.bind.annotation.GetMapping;
50 | import org.springframework.web.bind.annotation.PathVariable;
51 | import org.springframework.web.bind.annotation.RequestMapping;
52 | import org.springframework.web.bind.annotation.RestController;
53 |
54 | @RestController
55 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
56 | public class VersionBuildsController {
57 | private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(5));
58 | private final ProjectCollection projects;
59 | private final VersionCollection versions;
60 | private final BuildCollection builds;
61 |
62 | @Autowired
63 | private VersionBuildsController(
64 | final ProjectCollection projects,
65 | final VersionCollection versions,
66 | final BuildCollection builds
67 | ) {
68 | this.projects = projects;
69 | this.versions = versions;
70 | this.builds = builds;
71 | }
72 |
73 | @ApiResponse(
74 | content = @Content(
75 | schema = @Schema(implementation = BuildsResponse.class)
76 | ),
77 | responseCode = "200"
78 | )
79 | @GetMapping("/v2/projects/{project:[a-z]+}/versions/{version:" + Version.PATTERN + "}/builds")
80 | @Operation(summary = "Gets all available builds for a project's version.")
81 | public ResponseEntity> builds(
82 | @Parameter(name = "project", description = "The project identifier.", example = "paper")
83 | @PathVariable("project")
84 | @Pattern(regexp = "[a-z]+") //
85 | final String projectName,
86 | @Parameter(description = "A version of the project.")
87 | @PathVariable("version")
88 | @Pattern(regexp = Version.PATTERN) //
89 | final String versionName
90 | ) {
91 | final Project project = this.projects.findByName(projectName).orElseThrow(ProjectNotFound::new);
92 | final Version version = this.versions.findByProjectAndName(project._id(), versionName).orElseThrow(VersionNotFound::new);
93 | final List builds = this.builds.findAllByProjectAndVersion(project._id(), version._id());
94 | return HTTP.cachedOk(BuildsResponse.from(project, version, builds), CACHE);
95 | }
96 |
97 | @Schema
98 | private record BuildsResponse(
99 | @Schema(name = "project_id", pattern = "[a-z]+", example = "paper")
100 | String project_id,
101 | @Schema(name = "project_name", example = "Paper")
102 | String project_name,
103 | @Schema(name = "version", pattern = Version.PATTERN, example = "1.18")
104 | String version,
105 | @Schema(name = "builds")
106 | List builds
107 | ) {
108 | static BuildsResponse from(final Project project, final Version version, final List builds) {
109 | return new BuildsResponse(
110 | project.name(),
111 | project.friendlyName(),
112 | version.name(),
113 | builds.stream().map(build -> new VersionBuild(
114 | build.number(),
115 | build.time(),
116 | build.channelOrDefault(),
117 | build.promotedOrDefault(),
118 | build.changes(),
119 | build.downloads()
120 | )).toList()
121 | );
122 | }
123 |
124 | @Schema
125 | public record VersionBuild(
126 | @Schema(name = "build", pattern = "\\d+", example = "10")
127 | int build,
128 | @Schema(name = "time")
129 | Instant time,
130 | @Schema(name = "channel")
131 | Build.Channel channel,
132 | @Schema(name = "promoted")
133 | boolean promoted,
134 | @Schema(name = "changes")
135 | List changes,
136 | @Schema(name = "downloads")
137 | Map downloads
138 | ) {
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/controller/v2/VersionController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.controller.v2;
25 |
26 | import io.papermc.bibliothek.database.model.Build;
27 | import io.papermc.bibliothek.database.model.Project;
28 | import io.papermc.bibliothek.database.model.Version;
29 | import io.papermc.bibliothek.database.repository.BuildCollection;
30 | import io.papermc.bibliothek.database.repository.ProjectCollection;
31 | import io.papermc.bibliothek.database.repository.VersionCollection;
32 | import io.papermc.bibliothek.exception.ProjectNotFound;
33 | import io.papermc.bibliothek.exception.VersionNotFound;
34 | import io.papermc.bibliothek.util.HTTP;
35 | import io.swagger.v3.oas.annotations.Operation;
36 | import io.swagger.v3.oas.annotations.Parameter;
37 | import io.swagger.v3.oas.annotations.media.Content;
38 | import io.swagger.v3.oas.annotations.media.Schema;
39 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
40 | import jakarta.validation.constraints.Pattern;
41 | import java.time.Duration;
42 | import java.util.List;
43 | import org.springframework.beans.factory.annotation.Autowired;
44 | import org.springframework.http.CacheControl;
45 | import org.springframework.http.MediaType;
46 | import org.springframework.http.ResponseEntity;
47 | import org.springframework.web.bind.annotation.GetMapping;
48 | import org.springframework.web.bind.annotation.PathVariable;
49 | import org.springframework.web.bind.annotation.RequestMapping;
50 | import org.springframework.web.bind.annotation.RestController;
51 |
52 | @RestController
53 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
54 | public class VersionController {
55 | private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(5));
56 | private final ProjectCollection projects;
57 | private final VersionCollection versions;
58 | private final BuildCollection builds;
59 |
60 | @Autowired
61 | private VersionController(
62 | final ProjectCollection projects,
63 | final VersionCollection versions,
64 | final BuildCollection builds
65 | ) {
66 | this.projects = projects;
67 | this.versions = versions;
68 | this.builds = builds;
69 | }
70 |
71 | @ApiResponse(
72 | content = @Content(
73 | schema = @Schema(implementation = VersionResponse.class)
74 | ),
75 | responseCode = "200"
76 | )
77 | @GetMapping("/v2/projects/{project:[a-z]+}/versions/{version:" + Version.PATTERN + "}")
78 | @Operation(summary = "Gets information about a version.")
79 | public ResponseEntity> version(
80 | @Parameter(name = "project", description = "The project identifier.", example = "paper")
81 | @PathVariable("project")
82 | @Pattern(regexp = "[a-z]+") //
83 | final String projectName,
84 | @Parameter(description = "A version of the project.")
85 | @PathVariable("version")
86 | @Pattern(regexp = Version.PATTERN) //
87 | final String versionName
88 | ) {
89 | final Project project = this.projects.findByName(projectName).orElseThrow(ProjectNotFound::new);
90 | final Version version = this.versions.findByProjectAndName(project._id(), versionName).orElseThrow(VersionNotFound::new);
91 | final List builds = this.builds.findAllByProjectAndVersion(project._id(), version._id());
92 | return HTTP.cachedOk(VersionResponse.from(project, version, builds), CACHE);
93 | }
94 |
95 | @Schema
96 | private record VersionResponse(
97 | @Schema(name = "project_id", pattern = "[a-z]+", example = "paper")
98 | String project_id,
99 | @Schema(name = "project_name", example = "Paper")
100 | String project_name,
101 | @Schema(name = "version", pattern = Version.PATTERN, example = "1.18")
102 | String version,
103 | @Schema(name = "builds")
104 | List builds
105 | ) {
106 | static VersionResponse from(final Project project, final Version version, final List builds) {
107 | return new VersionResponse(
108 | project.name(),
109 | project.friendlyName(),
110 | version.name(),
111 | builds.stream().map(Build::number).toList()
112 | );
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyBuildsController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.controller.v2;
25 |
26 | import io.papermc.bibliothek.database.model.Build;
27 | import io.papermc.bibliothek.database.model.Project;
28 | import io.papermc.bibliothek.database.model.Version;
29 | import io.papermc.bibliothek.database.model.VersionFamily;
30 | import io.papermc.bibliothek.database.repository.BuildCollection;
31 | import io.papermc.bibliothek.database.repository.ProjectCollection;
32 | import io.papermc.bibliothek.database.repository.VersionCollection;
33 | import io.papermc.bibliothek.database.repository.VersionFamilyCollection;
34 | import io.papermc.bibliothek.exception.ProjectNotFound;
35 | import io.papermc.bibliothek.exception.VersionNotFound;
36 | import io.papermc.bibliothek.util.HTTP;
37 | import io.swagger.v3.oas.annotations.Operation;
38 | import io.swagger.v3.oas.annotations.Parameter;
39 | import io.swagger.v3.oas.annotations.media.Content;
40 | import io.swagger.v3.oas.annotations.media.Schema;
41 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
42 | import jakarta.validation.constraints.Pattern;
43 | import java.time.Duration;
44 | import java.time.Instant;
45 | import java.util.List;
46 | import java.util.Map;
47 | import java.util.function.Function;
48 | import java.util.stream.Collectors;
49 | import org.bson.types.ObjectId;
50 | import org.springframework.beans.factory.annotation.Autowired;
51 | import org.springframework.http.CacheControl;
52 | import org.springframework.http.MediaType;
53 | import org.springframework.http.ResponseEntity;
54 | import org.springframework.web.bind.annotation.GetMapping;
55 | import org.springframework.web.bind.annotation.PathVariable;
56 | import org.springframework.web.bind.annotation.RequestMapping;
57 | import org.springframework.web.bind.annotation.RestController;
58 |
59 | @RestController
60 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
61 | public class VersionFamilyBuildsController {
62 | private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(5));
63 | private final ProjectCollection projects;
64 | private final VersionFamilyCollection families;
65 | private final VersionCollection versions;
66 | private final BuildCollection builds;
67 |
68 | @Autowired
69 | private VersionFamilyBuildsController(
70 | final ProjectCollection projects,
71 | final VersionFamilyCollection families,
72 | final VersionCollection versions,
73 | final BuildCollection builds
74 | ) {
75 | this.projects = projects;
76 | this.families = families;
77 | this.versions = versions;
78 | this.builds = builds;
79 | }
80 |
81 | @ApiResponse(
82 | content = @Content(
83 | schema = @Schema(implementation = VersionFamilyBuildsResponse.class)
84 | ),
85 | responseCode = "200"
86 | )
87 | @GetMapping("/v2/projects/{project:[a-z]+}/version_group/{family:" + Version.PATTERN + "}/builds")
88 | @Operation(summary = "Gets all available builds for a project's version group.")
89 | public ResponseEntity> familyBuilds(
90 | @Parameter(name = "project", description = "The project identifier.", example = "paper")
91 | @PathVariable("project")
92 | @Pattern(regexp = "[a-z]+") //
93 | final String projectName,
94 | @Parameter(description = "The version group name.")
95 | @PathVariable("family")
96 | @Pattern(regexp = Version.PATTERN) //
97 | final String familyName
98 | ) {
99 | final Project project = this.projects.findByName(projectName).orElseThrow(ProjectNotFound::new);
100 | final VersionFamily family = this.families.findByProjectAndName(project._id(), familyName).orElseThrow(VersionNotFound::new);
101 | final Map versions = this.versions.findAllByProjectAndGroup(project._id(), family._id()).stream()
102 | .collect(Collectors.toMap(Version::_id, Function.identity()));
103 | final List builds = this.builds.findAllByProjectAndVersionIn(project._id(), versions.keySet());
104 | return HTTP.cachedOk(VersionFamilyBuildsResponse.from(project, family, versions, builds), CACHE);
105 | }
106 |
107 | @Schema
108 | private record VersionFamilyBuildsResponse(
109 | @Schema(name = "project_id", pattern = "[a-z]+", example = "paper")
110 | String project_id,
111 | @Schema(name = "project_name", example = "Paper")
112 | String project_name,
113 | @Schema(name = "version_group", pattern = Version.PATTERN, example = "1.18")
114 | String version_group,
115 | @Schema(name = "versions")
116 | List versions,
117 | @Schema(name = "builds")
118 | List builds
119 | ) {
120 | static VersionFamilyBuildsResponse from(final Project project, final VersionFamily family, final Map versions, final List builds) {
121 | return new VersionFamilyBuildsResponse(
122 | project.name(),
123 | project.friendlyName(),
124 | family.name(),
125 | versions.values().stream().sorted(Version.COMPARATOR).map(Version::name).toList(),
126 | builds.stream().map(build -> new VersionFamilyBuild(
127 | versions.get(build.version()).name(),
128 | build.number(),
129 | build.time(),
130 | build.channelOrDefault(),
131 | build.promotedOrDefault(),
132 | build.changes(),
133 | build.downloads()
134 | )).toList()
135 | );
136 | }
137 |
138 | @Schema
139 | public static record VersionFamilyBuild(
140 | @Schema(name = "version", pattern = Version.PATTERN, example = "1.18")
141 | String version,
142 | @Schema(name = "build", pattern = "\\d+", example = "10")
143 | int build,
144 | @Schema(name = "time")
145 | Instant time,
146 | @Schema(name = "channel")
147 | Build.Channel channel,
148 | @Schema(name = "promoted")
149 | boolean promoted,
150 | @Schema(name = "changes")
151 | List changes,
152 | @Schema(name = "downloads")
153 | Map downloads
154 | ) {
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.controller.v2;
25 |
26 | import io.papermc.bibliothek.database.model.Project;
27 | import io.papermc.bibliothek.database.model.Version;
28 | import io.papermc.bibliothek.database.model.VersionFamily;
29 | import io.papermc.bibliothek.database.repository.ProjectCollection;
30 | import io.papermc.bibliothek.database.repository.VersionCollection;
31 | import io.papermc.bibliothek.database.repository.VersionFamilyCollection;
32 | import io.papermc.bibliothek.exception.ProjectNotFound;
33 | import io.papermc.bibliothek.exception.VersionNotFound;
34 | import io.papermc.bibliothek.util.HTTP;
35 | import io.swagger.v3.oas.annotations.Operation;
36 | import io.swagger.v3.oas.annotations.Parameter;
37 | import io.swagger.v3.oas.annotations.media.Content;
38 | import io.swagger.v3.oas.annotations.media.Schema;
39 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
40 | import jakarta.validation.constraints.Pattern;
41 | import java.time.Duration;
42 | import java.util.List;
43 | import org.springframework.beans.factory.annotation.Autowired;
44 | import org.springframework.http.CacheControl;
45 | import org.springframework.http.MediaType;
46 | import org.springframework.http.ResponseEntity;
47 | import org.springframework.web.bind.annotation.GetMapping;
48 | import org.springframework.web.bind.annotation.PathVariable;
49 | import org.springframework.web.bind.annotation.RequestMapping;
50 | import org.springframework.web.bind.annotation.RestController;
51 |
52 | @RestController
53 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
54 | public class VersionFamilyController {
55 | private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(5));
56 | private final ProjectCollection projects;
57 | private final VersionFamilyCollection families;
58 | private final VersionCollection versions;
59 |
60 | @Autowired
61 | private VersionFamilyController(
62 | final ProjectCollection projects,
63 | final VersionFamilyCollection families,
64 | final VersionCollection versions
65 | ) {
66 | this.projects = projects;
67 | this.families = families;
68 | this.versions = versions;
69 | }
70 |
71 | @ApiResponse(
72 | content = @Content(
73 | schema = @Schema(implementation = VersionFamilyResponse.class)
74 | ),
75 | responseCode = "200"
76 | )
77 | @GetMapping("/v2/projects/{project:[a-z]+}/version_group/{family:" + Version.PATTERN + "}")
78 | @Operation(summary = "Gets information about a project's version group.")
79 | public ResponseEntity> family(
80 | @Parameter(name = "project", description = "The project identifier.", example = "paper")
81 | @PathVariable("project")
82 | @Pattern(regexp = "[a-z]+") //
83 | final String projectName,
84 | @Parameter(description = "The version group name.")
85 | @PathVariable("family")
86 | @Pattern(regexp = Version.PATTERN) //
87 | final String familyName
88 | ) {
89 | final Project project = this.projects.findByName(projectName).orElseThrow(ProjectNotFound::new);
90 | final VersionFamily family = this.families.findByProjectAndName(project._id(), familyName).orElseThrow(VersionNotFound::new);
91 | final List versions = this.versions.findAllByProjectAndGroup(project._id(), family._id());
92 | return HTTP.cachedOk(VersionFamilyResponse.from(project, family, versions), CACHE);
93 | }
94 |
95 | @Schema
96 | private record VersionFamilyResponse(
97 | @Schema(name = "project_id", pattern = "[a-z]+", example = "paper")
98 | String project_id,
99 | @Schema(name = "project_name", example = "Paper")
100 | String project_name,
101 | @Schema(name = "version_group", pattern = Version.PATTERN, example = "1.18")
102 | String version_group,
103 | @Schema(name = "versions")
104 | List versions
105 | ) {
106 | static VersionFamilyResponse from(final Project project, final VersionFamily family, final List versions) {
107 | return new VersionFamilyResponse(
108 | project.name(),
109 | project.friendlyName(),
110 | family.name(),
111 | versions.stream().sorted(Version.COMPARATOR).map(Version::name).toList()
112 | );
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/database/model/Build.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.database.model;
25 |
26 | import com.fasterxml.jackson.annotation.JsonInclude;
27 | import com.fasterxml.jackson.annotation.JsonProperty;
28 | import io.swagger.v3.oas.annotations.media.Schema;
29 | import java.time.Instant;
30 | import java.util.List;
31 | import java.util.Map;
32 | import java.util.Objects;
33 | import org.bson.types.ObjectId;
34 | import org.intellij.lang.annotations.Language;
35 | import org.jetbrains.annotations.Nullable;
36 | import org.springframework.data.annotation.Id;
37 | import org.springframework.data.mongodb.core.index.CompoundIndex;
38 | import org.springframework.data.mongodb.core.mapping.Document;
39 |
40 | @CompoundIndex(def = "{'project': 1, 'version': 1}")
41 | @CompoundIndex(def = "{'project': 1, 'version': 1, 'number': 1}")
42 | @Document(collection = "builds")
43 | public record Build(
44 | @Id ObjectId _id,
45 | ObjectId project,
46 | ObjectId version,
47 | int number,
48 | Instant time,
49 | List changes,
50 | Map downloads,
51 | @JsonProperty
52 | @Nullable Channel channel,
53 | @JsonInclude(JsonInclude.Include.NON_NULL)
54 | @Nullable Boolean promoted
55 | ) {
56 | public Channel channelOrDefault() {
57 | return Objects.requireNonNullElse(this.channel(), Build.Channel.DEFAULT);
58 | }
59 |
60 | public boolean promotedOrDefault() {
61 | return Objects.requireNonNullElse(this.promoted(), false);
62 | }
63 |
64 | public enum Channel {
65 | @JsonProperty("default")
66 | DEFAULT,
67 | @JsonProperty("experimental")
68 | EXPERIMENTAL;
69 | }
70 |
71 | @Schema
72 | public record Change(
73 | @Schema(name = "commit")
74 | String commit,
75 | @Schema(name = "summary")
76 | String summary,
77 | @Schema(name = "message")
78 | String message
79 | ) {
80 | }
81 |
82 | @Schema
83 | public record Download(
84 | @Schema(name = "name", pattern = "[a-z0-9._-]+", example = "paper-1.18-10.jar")
85 | String name,
86 | @Schema(name = "sha256", pattern = "[a-f0-9]{64}", example = "f065e2d345d9d772d5cf2a1ce5c495c4cc56eb2fcd6820e82856485fa19414c8")
87 | String sha256
88 | ) {
89 | // NOTE: this pattern cannot contain any capturing groups
90 | @Language("RegExp")
91 | public static final String PATTERN = "[a-zA-Z0-9._-]+";
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/database/model/Project.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.database.model;
25 |
26 | import org.bson.types.ObjectId;
27 | import org.springframework.data.annotation.Id;
28 | import org.springframework.data.mongodb.core.index.Indexed;
29 | import org.springframework.data.mongodb.core.mapping.Document;
30 |
31 | @Document(collection = "projects")
32 | public record Project(
33 | @Id ObjectId _id,
34 | @Indexed String name,
35 | String friendlyName
36 | ) {
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/database/model/Version.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.database.model;
25 |
26 | import io.papermc.bibliothek.util.BringOrderToChaos;
27 | import io.papermc.bibliothek.util.NameSource;
28 | import io.papermc.bibliothek.util.TimeSource;
29 | import java.time.Instant;
30 | import java.util.Comparator;
31 | import org.bson.types.ObjectId;
32 | import org.intellij.lang.annotations.Language;
33 | import org.jetbrains.annotations.Nullable;
34 | import org.springframework.data.annotation.Id;
35 | import org.springframework.data.mongodb.core.index.CompoundIndex;
36 | import org.springframework.data.mongodb.core.mapping.Document;
37 |
38 | @CompoundIndex(def = "{'project': 1, 'group': 1}")
39 | @CompoundIndex(def = "{'project': 1, 'name': 1}")
40 | @Document(collection = "versions")
41 | public record Version(
42 | @Id ObjectId _id,
43 | ObjectId project,
44 | ObjectId group,
45 | String name,
46 | @Nullable Instant time
47 | ) implements NameSource, TimeSource {
48 | // NOTE: this pattern cannot contain any capturing groups
49 | @Language("RegExp")
50 | public static final String PATTERN = "[0-9.]+-?(?:pre|SNAPSHOT)?(?:[0-9.]+)?";
51 | public static final Comparator COMPARATOR = BringOrderToChaos.timeOrNameComparator();
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/database/model/VersionFamily.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.database.model;
25 |
26 | import io.papermc.bibliothek.util.BringOrderToChaos;
27 | import io.papermc.bibliothek.util.NameSource;
28 | import io.papermc.bibliothek.util.TimeSource;
29 | import java.time.Instant;
30 | import java.util.Comparator;
31 | import org.bson.types.ObjectId;
32 | import org.jetbrains.annotations.Nullable;
33 | import org.springframework.data.annotation.Id;
34 | import org.springframework.data.mongodb.core.index.CompoundIndex;
35 | import org.springframework.data.mongodb.core.mapping.Document;
36 |
37 | @CompoundIndex(def = "{'project': 1, 'name': 1}")
38 | @Document(collection = "version_groups")
39 | public record VersionFamily(
40 | @Id ObjectId _id,
41 | ObjectId project,
42 | String name,
43 | @Nullable Instant time
44 | ) implements NameSource, TimeSource {
45 | public static final Comparator COMPARATOR = BringOrderToChaos.timeOrNameComparator();
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/database/repository/BuildCollection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.database.repository;
25 |
26 | import io.papermc.bibliothek.database.model.Build;
27 | import java.util.Collection;
28 | import java.util.List;
29 | import java.util.Optional;
30 | import org.bson.types.ObjectId;
31 | import org.springframework.data.mongodb.repository.MongoRepository;
32 | import org.springframework.stereotype.Repository;
33 |
34 | @Repository
35 | public interface BuildCollection extends MongoRepository {
36 | List findAllByProjectAndVersion(final ObjectId project, final ObjectId version);
37 |
38 | List findAllByProjectAndVersionIn(final ObjectId project, final Collection version);
39 |
40 | Optional findByProjectAndVersionAndNumber(final ObjectId project, final ObjectId version, final int number);
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/database/repository/ProjectCollection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.database.repository;
25 |
26 | import io.papermc.bibliothek.database.model.Project;
27 | import java.util.Optional;
28 | import org.bson.types.ObjectId;
29 | import org.springframework.data.mongodb.repository.MongoRepository;
30 | import org.springframework.stereotype.Repository;
31 |
32 | @Repository
33 | public interface ProjectCollection extends MongoRepository {
34 | Optional findByName(final String name);
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/database/repository/VersionCollection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.database.repository;
25 |
26 | import io.papermc.bibliothek.database.model.Version;
27 | import java.util.List;
28 | import java.util.Optional;
29 | import org.bson.types.ObjectId;
30 | import org.springframework.data.mongodb.repository.MongoRepository;
31 | import org.springframework.stereotype.Repository;
32 |
33 | @Repository
34 | public interface VersionCollection extends MongoRepository {
35 | List findAllByProject(final ObjectId project);
36 |
37 | List findAllByProjectAndGroup(final ObjectId project, final ObjectId group);
38 |
39 | Optional findByProjectAndName(final ObjectId project, final String name);
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/database/repository/VersionFamilyCollection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.database.repository;
25 |
26 | import io.papermc.bibliothek.database.model.VersionFamily;
27 | import java.util.List;
28 | import java.util.Optional;
29 | import org.bson.types.ObjectId;
30 | import org.springframework.data.mongodb.repository.MongoRepository;
31 | import org.springframework.stereotype.Repository;
32 |
33 | @Repository
34 | public interface VersionFamilyCollection extends MongoRepository {
35 | List findAllByProject(final ObjectId project);
36 |
37 | Optional findByProjectAndName(final ObjectId project, final String name);
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/exception/Advice.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.exception;
25 |
26 | import com.fasterxml.jackson.databind.ObjectMapper;
27 | import org.springframework.beans.factory.annotation.Autowired;
28 | import org.springframework.http.HttpStatus;
29 | import org.springframework.http.ResponseEntity;
30 | import org.springframework.web.bind.annotation.ControllerAdvice;
31 | import org.springframework.web.bind.annotation.ExceptionHandler;
32 | import org.springframework.web.bind.annotation.ResponseBody;
33 | import org.springframework.web.servlet.NoHandlerFoundException;
34 |
35 | @ControllerAdvice
36 | class Advice {
37 | private final ObjectMapper json;
38 |
39 | @Autowired
40 | private Advice(final ObjectMapper json) {
41 | this.json = json;
42 | }
43 |
44 | @ExceptionHandler(BuildNotFound.class)
45 | @ResponseBody
46 | public ResponseEntity> buildNotFound(final BuildNotFound exception) {
47 | return this.error(HttpStatus.NOT_FOUND, "Build not found.");
48 | }
49 |
50 | @ExceptionHandler(DownloadFailed.class)
51 | @ResponseBody
52 | public ResponseEntity> downloadFailed(final DownloadFailed exception) {
53 | return this.error(HttpStatus.INTERNAL_SERVER_ERROR, "An internal error occurred while serving your download.");
54 | }
55 |
56 | @ExceptionHandler(DownloadNotFound.class)
57 | @ResponseBody
58 | public ResponseEntity> downloadNotFound(final DownloadNotFound exception) {
59 | return this.error(HttpStatus.NOT_FOUND, "Download not found.");
60 | }
61 |
62 | @ExceptionHandler(ProjectNotFound.class)
63 | @ResponseBody
64 | public ResponseEntity> projectNotFound(final ProjectNotFound exception) {
65 | return this.error(HttpStatus.NOT_FOUND, "Project not found.");
66 | }
67 |
68 | @ExceptionHandler(VersionNotFound.class)
69 | @ResponseBody
70 | public ResponseEntity> versionNotFound(final VersionNotFound exception) {
71 | return this.error(HttpStatus.NOT_FOUND, "Version not found.");
72 | }
73 |
74 | @ExceptionHandler(NoHandlerFoundException.class)
75 | @ResponseBody
76 | public ResponseEntity> endpointNotFound(final NoHandlerFoundException exception) {
77 | return this.error(HttpStatus.NOT_FOUND, "Endpoint not found.");
78 | }
79 |
80 | private ResponseEntity> error(final HttpStatus status, final String error) {
81 | return new ResponseEntity<>(
82 | this.json.createObjectNode()
83 | .put("error", error),
84 | status
85 | );
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/exception/BuildNotFound.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.exception;
25 |
26 | import java.io.Serial;
27 |
28 | public class BuildNotFound extends RuntimeException {
29 | @Serial
30 | private static final long serialVersionUID = 4345323173317573160L;
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/exception/DownloadFailed.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.exception;
25 |
26 | import java.io.Serial;
27 |
28 | public class DownloadFailed extends RuntimeException {
29 | @Serial
30 | private static final long serialVersionUID = -1573093686056663600L;
31 |
32 | public DownloadFailed(final Throwable cause) {
33 | super(cause);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/exception/DownloadNotFound.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.exception;
25 |
26 | import java.io.Serial;
27 |
28 | public class DownloadNotFound extends RuntimeException {
29 | @Serial
30 | private static final long serialVersionUID = -1709491048606353671L;
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/exception/ProjectNotFound.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.exception;
25 |
26 | import java.io.Serial;
27 |
28 | public class ProjectNotFound extends RuntimeException {
29 | @Serial
30 | private static final long serialVersionUID = 210738408624095602L;
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/exception/VersionNotFound.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.exception;
25 |
26 | import java.io.Serial;
27 |
28 | public class VersionNotFound extends RuntimeException {
29 | @Serial
30 | private static final long serialVersionUID = 1716350953824887164L;
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/filter/CorsFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.filter;
25 |
26 | import jakarta.servlet.Filter;
27 | import jakarta.servlet.FilterChain;
28 | import jakarta.servlet.ServletException;
29 | import jakarta.servlet.ServletRequest;
30 | import jakarta.servlet.ServletResponse;
31 | import jakarta.servlet.annotation.WebFilter;
32 | import jakarta.servlet.http.HttpServletResponse;
33 | import java.io.IOException;
34 |
35 | @WebFilter("/*")
36 | public class CorsFilter implements Filter {
37 |
38 | @Override
39 | public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
40 | final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
41 | httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
42 | httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET");
43 | chain.doFilter(request, response);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/util/BringOrderToChaos.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.util;
25 |
26 | import java.time.Instant;
27 | import java.util.Comparator;
28 | import java.util.Objects;
29 |
30 | public final class BringOrderToChaos {
31 | private BringOrderToChaos() {
32 | }
33 |
34 | public static Comparator timeOrNameComparator() {
35 | return (o1, o2) -> {
36 | final Instant t1 = o1.time();
37 | final Instant t2 = o2.time();
38 | // Both objects are not guaranteed to have a time present, but are guaranteed
39 | // to have a name present - we prefer to compare them by time, but in cases where
40 | // the time is not available on both objects we will compare them using their name
41 | if (t1 != null && t2 != null) {
42 | return t1.compareTo(t2);
43 | }
44 | final String n1 = Objects.requireNonNull(o1.name(), () -> "name of " + o1);
45 | final String n2 = Objects.requireNonNull(o2.name(), () -> "name of " + o2);
46 | return n1.compareTo(n2);
47 | };
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/util/HTTP.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.util;
25 |
26 | import java.nio.charset.StandardCharsets;
27 | import java.nio.file.Path;
28 | import java.time.Duration;
29 | import org.springframework.http.CacheControl;
30 | import org.springframework.http.ContentDisposition;
31 | import org.springframework.http.ResponseEntity;
32 |
33 | public final class HTTP {
34 | private HTTP() {
35 | }
36 |
37 | public static ResponseEntity cachedOk(final T response, final CacheControl cache) {
38 | return ResponseEntity.ok().cacheControl(cache).body(response);
39 | }
40 |
41 | public static CacheControl sMaxAgePublicCache(final Duration sMaxAge) {
42 | return CacheControl.empty()
43 | .cachePublic()
44 | .sMaxAge(sMaxAge);
45 | }
46 |
47 | public static ContentDisposition attachmentDisposition(final Path filename) {
48 | return ContentDisposition.attachment().filename(filename.getFileName().toString(), StandardCharsets.UTF_8).build();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/util/MediaTypes.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.util;
25 |
26 | import org.jetbrains.annotations.Nullable;
27 | import org.springframework.http.MediaType;
28 | import org.springframework.http.MediaTypeFactory;
29 |
30 | public final class MediaTypes {
31 |
32 | public static final String APPLICATION_ZIP_VALUE = "application/zip";
33 | public static final MediaType APPLICATION_ZIP = MediaType.parseMediaType(APPLICATION_ZIP_VALUE);
34 |
35 | private MediaTypes() {
36 | }
37 |
38 | public static @Nullable MediaType fromFileName(final String name) {
39 | final int index = name.lastIndexOf('.');
40 | if (index != -1) {
41 | return fromFileExtension(name.substring(index + 1));
42 | }
43 | return null;
44 | }
45 |
46 | public static @Nullable MediaType fromFileExtension(final String extension) {
47 | return switch (extension) {
48 | case "mcpack" -> APPLICATION_ZIP;
49 | default -> MediaTypeFactory.getMediaType("." + extension).orElse(MediaType.APPLICATION_OCTET_STREAM);
50 | };
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/util/NameSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.util;
25 |
26 | public interface NameSource {
27 | String name();
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/io/papermc/bibliothek/util/TimeSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of bibliothek, licensed under the MIT License.
3 | *
4 | * Copyright (c) 2019-2024 PaperMC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package io.papermc.bibliothek.util;
25 |
26 | import java.time.Instant;
27 | import org.jetbrains.annotations.UnknownNullability;
28 |
29 | public interface TimeSource {
30 | @UnknownNullability Instant time();
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/resources/application.yaml:
--------------------------------------------------------------------------------
1 | spring:
2 | data:
3 | mongodb:
4 | # "library" instead of "bibliothek" is intentional here
5 | database: "library"
6 | mvc:
7 | throw-exception-if-no-handler-found: true
8 | web:
9 | resources:
10 | add-mappings: false
11 | springdoc:
12 | api-docs:
13 | path: "/openapi"
14 | show-actuator: false
15 | swagger-ui:
16 | disable-swagger-default-url: true
17 | operations-sorter: "alpha"
18 | path: "/docs/"
19 | show-common-extensions: true
20 | server:
21 | error:
22 | whitelabel:
23 | enabled: false
24 |
--------------------------------------------------------------------------------