diff --git a/Cargo.lock b/Cargo.lock index 7a82d348..77398bf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,7 +69,7 @@ dependencies = [ "actix-service", "actix-utils", "ahash", - "base64", + "base64 0.13.1", "bitflags", "brotli", "bytes", @@ -443,6 +443,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + [[package]] name = "base64ct" version = "1.5.3" @@ -574,9 +580,9 @@ dependencies = [ [[package]] name = "censor" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5563d2728feef9a6186acdd148bccbe850dad63c5ba55a3b3355abc9137cb3eb" +checksum = "d41e3b9fdbb9b3edc10dc66a06dc255822f699c432e19403fb966e6d60e0dec4" dependencies = [ "once_cell", ] @@ -976,9 +982,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", @@ -1538,7 +1544,7 @@ dependencies = [ "actix-rt", "actix-web", "async-trait", - "base64", + "base64 0.20.0", "bitflags", "bytes", "censor", @@ -2278,7 +2284,7 @@ version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" dependencies = [ - "base64", + "base64 0.13.1", "bytes", "encoding_rs", "futures-core", @@ -2345,7 +2351,7 @@ dependencies = [ "async-trait", "aws-creds", "aws-region", - "base64", + "base64 0.13.1", "cfg-if", "hex", "hmac 0.12.1", @@ -2411,7 +2417,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" dependencies = [ - "base64", + "base64 0.13.1", ] [[package]] @@ -2502,9 +2508,9 @@ checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" [[package]] name = "sentry" -version = "0.28.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a120fb5e8b7975736bf1fc57de380531e617a6a8f5a55d037bcea25a7f5e8371" +checksum = "17ad137b9df78294b98cab1a650bef237cc6c950e82e5ce164655e674d07c5cc" dependencies = [ "httpdate", "native-tls", @@ -2519,9 +2525,9 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.28.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b889eb376e04a7f3b61aee3ed158c90dac12671042e07b6f54452be099ba5db7" +checksum = "8c832f99bbda819c89ce700fba806ff4def97d6bdff59d15b5c898bfaf54a956" dependencies = [ "actix-web", "futures-util", @@ -2530,9 +2536,9 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.28.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ac56ff9aae25b024a5aad4f0242808dfde29161c82d183adce778338c6822ef" +checksum = "afe4800806552aab314129761d5d3b3d422284eca3de2ab59e9fd133636cbd3d" dependencies = [ "backtrace", "once_cell", @@ -2542,9 +2548,9 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.28.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "188506b08b5e64004c71b7a5edb34959083e6e1288fada3b8d18d0bc7449ce1e" +checksum = "a42938426670f6e7974989cd1417837a96dd8bbb01567094f567d6acb360bf88" dependencies = [ "hostname", "libc", @@ -2556,9 +2562,9 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.28.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff58433a7ad557b586a09c42c4298d5f3ddb0c777e1a79d950e510d7b93fce0e" +checksum = "4df9b9d8de2658a1ecd4e45f7b06c80c5dd97b891bfbc7c501186189b7e9bbdf" dependencies = [ "once_cell", "rand", @@ -2569,9 +2575,9 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.28.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4145005d9b5c117132765c34e2cb33e9d24d16e73d7f3a357122b77fe3a3b815" +checksum = "0af37b8500f273e511ebd6eb0d342ff7937d64ce3f134764b2b4653112d48cb4" dependencies = [ "sentry-backtrace", "sentry-core", @@ -2579,11 +2585,10 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.28.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb30d75498a041005a774ec1b6b7d9589c5906d17ebaca338cb685dc92170f9b" +checksum = "ccc95faa4078768a6bf8df45e2b894bbf372b3dbbfb364e9429c1c58ab7545c6" dependencies = [ - "chrono", "debugid", "getrandom", "hex", @@ -2656,7 +2661,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "368f2d60d049ea019a84dcd6687b0d1e0030fe663ae105039bdf967ed5e6a9a7" dependencies = [ - "base64", + "base64 0.13.1", "chrono", "hex", "indexmap", @@ -2826,7 +2831,7 @@ checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105" dependencies = [ "ahash", "atoi", - "base64", + "base64 0.13.1", "bitflags", "byteorder", "bytes", @@ -3255,7 +3260,7 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97acb4c28a254fd7a4aeec976c46a7fa404eac4d7c134b30c75144846d7cb8f" dependencies = [ - "base64", + "base64 0.13.1", "chunked_transfer", "log", "native-tls", @@ -3667,8 +3672,9 @@ dependencies = [ [[package]] name = "zip" -version = "0.6.2" -source = "git+https://github.com/zip-rs/zip?rev=bb230ef56adc13436d1fcdfaa489249d119c498f#bb230ef56adc13436d1fcdfaa489249d119c498f" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080" dependencies = [ "aes", "byteorder", diff --git a/Cargo.toml b/Cargo.toml index 12cbb2e1..b4765bac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,12 +5,11 @@ authors = ["geometrically "] edition = "2018" license = "AGPL-3.0" +# This seems redundant, but it's necessary for Docker to work [[bin]] name = "labrinth" path = "src/main.rs" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] actix = "0.13.0" actix-web = "4.2.1" @@ -41,7 +40,7 @@ xml-rs = "0.8.4" rand = "0.8.5" bytes = "1.2.1" -base64 = "0.13.0" +base64 = "0.20.0" sha1 = { version = "0.6.1", features = ["std"] } sha2 = "0.9.9" hmac = "0.11.0" @@ -51,14 +50,13 @@ hex = "0.4.3" url = "2.3.1" urlencoding = "2.1.2" -# Temporary - to fix zstd conflict -zip = { git = "https://github.com/zip-rs/zip", rev = "bb230ef56adc13436d1fcdfaa489249d119c498f" } +zip = "0.6.3" itertools = "0.10.5" validator = { version = "0.16.0", features = ["derive", "phone"] } regex = "1.6.0" -censor = "0.2.0" +censor = "0.3.0" spdx = { version = "0.9.0", features = ["text"] } dotenvy = "0.15.6" @@ -69,5 +67,5 @@ thiserror = "1.0.37" sqlx = { version = "0.6.2", features = ["runtime-actix-rustls", "postgres", "chrono", "offline", "macros", "migrate", "decimal", "json"] } rust_decimal = { version = "1.26", features = ["serde-with-float", "serde-with-str"] } -sentry = "0.28.0" -sentry-actix = "0.28.0" +sentry = "0.29.1" +sentry-actix = "0.29.1" diff --git a/docker-compose.yml b/docker-compose.yml index 4b9e4a70..8d2e5d3d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,17 +20,6 @@ services: - meilisearch-data:/data.ms environment: MEILI_MASTER_KEY: modrinth - pgadmin: - image: dpage/pgadmin4:latest - environment: - PGADMIN_DEFAULT_EMAIL: admin@modrinth.com - PGADMIN_DEFAULT_PASSWORD: secret - PGADMIN_CONFIG_SERVER_MODE: "False" - PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False" - ports: - - "8070:80" - volumes: - - ./pgadmin_default_servers.json:/pgadmin4/servers.json volumes: meilisearch-data: db-data: diff --git a/migrations/20221217215337_drop-body_url-changelog_url.sql b/migrations/20221217215337_drop-body_url-changelog_url.sql new file mode 100644 index 00000000..fd036517 --- /dev/null +++ b/migrations/20221217215337_drop-body_url-changelog_url.sql @@ -0,0 +1,2 @@ +ALTER TABLE mods DROP COLUMN body_url; +ALTER TABLE versions DROP COLUMN changelog_url; \ No newline at end of file diff --git a/pgadmin_default_servers.json b/pgadmin_default_servers.json deleted file mode 100644 index 18e3cf62..00000000 --- a/pgadmin_default_servers.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "Servers": { - "1": { - "Name": "Labrinth", - "Group": "Servers", - "Host": "postgres_db", - "Port": 5432, - "MaintenanceDB": "postgres", - "Username": "labrinth", - "SSLMode": "prefer", - "SSLCompression": 0, - "Timeout": 10, - "UseSSHTunnel": 0, - "TunnelPort": "22", - "TunnelAuthentication": 0 - } - } -} diff --git a/sqlx-data.json b/sqlx-data.json index f1762ae9..82db515b 100644 --- a/sqlx-data.json +++ b/sqlx-data.json @@ -65,29 +65,6 @@ }, "query": "\n SELECT EXISTS(SELECT 1 FROM users WHERE id = $1 AND email IS NULL)\n " }, - "034350830d7b406f8cc5520a80d3fa83056920d8e2decc8a4d88d5016a91673e": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Timestamptz", - "Int4", - "Varchar", - "Bool", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO versions (\n id, mod_id, author_id, name, version_number,\n changelog, changelog_url, date_published,\n downloads, version_type, featured, status\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7,\n $8, $9,\n $10, $11, $12\n )\n " - }, "041f499f542ddab1b81bd445d6cabe225b1b2ad3ec7bbc1f755346c016ae06e6": { "describe": { "columns": [], @@ -232,6 +209,92 @@ }, "query": "\n UPDATE versions\n SET name = $1\n WHERE (id = $2)\n " }, + "0b77fb8853f15ba9814c80feab68515aa81b82da1414210635239ae6adcd0dd1": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "mod_id", + "ordinal": 1, + "type_info": "Int8" + }, + { + "name": "author_id", + "ordinal": 2, + "type_info": "Int8" + }, + { + "name": "name", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "version_number", + "ordinal": 4, + "type_info": "Varchar" + }, + { + "name": "changelog", + "ordinal": 5, + "type_info": "Varchar" + }, + { + "name": "date_published", + "ordinal": 6, + "type_info": "Timestamptz" + }, + { + "name": "downloads", + "ordinal": 7, + "type_info": "Int4" + }, + { + "name": "version_type", + "ordinal": 8, + "type_info": "Varchar" + }, + { + "name": "featured", + "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "status", + "ordinal": 10, + "type_info": "Varchar" + }, + { + "name": "requested_status", + "ordinal": 11, + "type_info": "Varchar" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true + ], + "parameters": { + "Left": [ + "Int8Array" + ] + } + }, + "query": "\n SELECT v.id, v.mod_id, v.author_id, v.name, v.version_number,\n v.changelog, v.date_published, v.downloads,\n v.version_type, v.featured, v.status, v.requested_status\n FROM versions v\n WHERE v.id = ANY($1)\n ORDER BY v.date_published ASC\n " + }, "0ba5a9f4d1381ed37a67b7dc90edf7e3ec86cae6c2860e5db1e53144d4654e58": { "describe": { "columns": [ @@ -1348,6 +1411,182 @@ }, "query": "\n SELECT f.version_id version_id\n FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v on f.version_id = v.id AND v.status != ANY($1)\n INNER JOIN mods m on v.mod_id = m.id\n WHERE h.algorithm = $3 AND h.hash = $2 AND m.status != ANY($4)\n " }, + "3b898f215cf98cbe9204f93b04be659790d2278610da186304bbf056533d5c55": { + "describe": { + "columns": [ + { + "name": "project_type", + "ordinal": 0, + "type_info": "Int4" + }, + { + "name": "title", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "description", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "downloads", + "ordinal": 3, + "type_info": "Int4" + }, + { + "name": "follows", + "ordinal": 4, + "type_info": "Int4" + }, + { + "name": "icon_url", + "ordinal": 5, + "type_info": "Varchar" + }, + { + "name": "body", + "ordinal": 6, + "type_info": "Varchar" + }, + { + "name": "published", + "ordinal": 7, + "type_info": "Timestamptz" + }, + { + "name": "updated", + "ordinal": 8, + "type_info": "Timestamptz" + }, + { + "name": "approved", + "ordinal": 9, + "type_info": "Timestamptz" + }, + { + "name": "status", + "ordinal": 10, + "type_info": "Varchar" + }, + { + "name": "requested_status", + "ordinal": 11, + "type_info": "Varchar" + }, + { + "name": "issues_url", + "ordinal": 12, + "type_info": "Varchar" + }, + { + "name": "source_url", + "ordinal": 13, + "type_info": "Varchar" + }, + { + "name": "wiki_url", + "ordinal": 14, + "type_info": "Varchar" + }, + { + "name": "discord_url", + "ordinal": 15, + "type_info": "Varchar" + }, + { + "name": "license_url", + "ordinal": 16, + "type_info": "Varchar" + }, + { + "name": "team_id", + "ordinal": 17, + "type_info": "Int8" + }, + { + "name": "client_side", + "ordinal": 18, + "type_info": "Int4" + }, + { + "name": "server_side", + "ordinal": 19, + "type_info": "Int4" + }, + { + "name": "license", + "ordinal": 20, + "type_info": "Varchar" + }, + { + "name": "slug", + "ordinal": 21, + "type_info": "Varchar" + }, + { + "name": "moderation_message", + "ordinal": 22, + "type_info": "Varchar" + }, + { + "name": "moderation_message_body", + "ordinal": 23, + "type_info": "Varchar" + }, + { + "name": "flame_anvil_project", + "ordinal": 24, + "type_info": "Int4" + }, + { + "name": "flame_anvil_user", + "ordinal": 25, + "type_info": "Int8" + }, + { + "name": "webhook_sent", + "ordinal": 26, + "type_info": "Bool" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + true, + false, + false, + false, + true, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false + ], + "parameters": { + "Left": [ + "Int8" + ] + } + }, + "query": "\n SELECT project_type, title, description, downloads, follows,\n icon_url, body, published,\n updated, approved, status, requested_status,\n issues_url, source_url, wiki_url, discord_url, license_url,\n team_id, client_side, server_side, license, slug,\n moderation_message, moderation_message_body, flame_anvil_project,\n flame_anvil_user, webhook_sent\n FROM mods\n WHERE id = $1\n " + }, "3bdcbfa5abe43cc9b4f996f147277a7f6921cca00f82cad0ef5d85032c761a36": { "describe": { "columns": [], @@ -1830,243 +2069,6 @@ }, "query": "\n UPDATE mods\n SET slug = LOWER($1)\n WHERE (id = $2)\n " }, - "4ff8a5f4f8f902ad82cd1563dbd436cd2fabe484d6484527da7b9c557367963d": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "project_type", - "ordinal": 1, - "type_info": "Int4" - }, - { - "name": "title", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "description", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "downloads", - "ordinal": 4, - "type_info": "Int4" - }, - { - "name": "follows", - "ordinal": 5, - "type_info": "Int4" - }, - { - "name": "icon_url", - "ordinal": 6, - "type_info": "Varchar" - }, - { - "name": "body", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "body_url", - "ordinal": 8, - "type_info": "Varchar" - }, - { - "name": "published", - "ordinal": 9, - "type_info": "Timestamptz" - }, - { - "name": "updated", - "ordinal": 10, - "type_info": "Timestamptz" - }, - { - "name": "approved", - "ordinal": 11, - "type_info": "Timestamptz" - }, - { - "name": "status", - "ordinal": 12, - "type_info": "Varchar" - }, - { - "name": "requested_status", - "ordinal": 13, - "type_info": "Varchar" - }, - { - "name": "issues_url", - "ordinal": 14, - "type_info": "Varchar" - }, - { - "name": "source_url", - "ordinal": 15, - "type_info": "Varchar" - }, - { - "name": "wiki_url", - "ordinal": 16, - "type_info": "Varchar" - }, - { - "name": "discord_url", - "ordinal": 17, - "type_info": "Varchar" - }, - { - "name": "license_url", - "ordinal": 18, - "type_info": "Varchar" - }, - { - "name": "team_id", - "ordinal": 19, - "type_info": "Int8" - }, - { - "name": "client_side", - "ordinal": 20, - "type_info": "Int4" - }, - { - "name": "server_side", - "ordinal": 21, - "type_info": "Int4" - }, - { - "name": "license", - "ordinal": 22, - "type_info": "Varchar" - }, - { - "name": "slug", - "ordinal": 23, - "type_info": "Varchar" - }, - { - "name": "moderation_message", - "ordinal": 24, - "type_info": "Varchar" - }, - { - "name": "moderation_message_body", - "ordinal": 25, - "type_info": "Varchar" - }, - { - "name": "client_side_type", - "ordinal": 26, - "type_info": "Varchar" - }, - { - "name": "server_side_type", - "ordinal": 27, - "type_info": "Varchar" - }, - { - "name": "project_type_name", - "ordinal": 28, - "type_info": "Varchar" - }, - { - "name": "flame_anvil_project", - "ordinal": 29, - "type_info": "Int4" - }, - { - "name": "flame_anvil_user", - "ordinal": 30, - "type_info": "Int8" - }, - { - "name": "webhook_sent", - "ordinal": 31, - "type_info": "Bool" - }, - { - "name": "categories", - "ordinal": 32, - "type_info": "VarcharArray" - }, - { - "name": "additional_categories", - "ordinal": 33, - "type_info": "VarcharArray" - }, - { - "name": "versions", - "ordinal": 34, - "type_info": "Jsonb" - }, - { - "name": "gallery", - "ordinal": 35, - "type_info": "Jsonb" - }, - { - "name": "donations", - "ordinal": 36, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - true, - false, - false, - true, - false, - true, - true, - true, - true, - true, - true, - false, - false, - false, - false, - true, - true, - true, - false, - false, - false, - true, - true, - false, - null, - null, - null, - null, - null - ], - "parameters": { - "Left": [ - "Int8", - "TextArray" - ] - } - }, - "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.body body, m.body_url body_url, m.published published,\n m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,\n m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,\n m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent webhook_sent,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,\n JSONB_AGG(DISTINCT jsonb_build_object('image_url', mg.image_url, 'featured', mg.featured, 'title', mg.title, 'description', mg.description, 'created', mg.created, 'ordering', mg.ordering)) filter (where mg.image_url is not null) gallery,\n JSONB_AGG(DISTINCT jsonb_build_object('platform_id', md.joining_platform_id, 'platform_short', dp.short, 'platform_name', dp.name,'url', md.url)) filter (where md.joining_platform_id is not null) donations\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n LEFT JOIN mods_donations md ON md.joining_mod_id = m.id\n LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)\n LEFT JOIN mods_gallery mg ON mg.mod_id = m.id\n WHERE m.id = $1\n GROUP BY pt.id, cs.id, ss.id, m.id;\n " - }, "501c4aec0d0b2b17b86b1923b949b27e8091ff8f9a75fa4a2ce7ecf294241f46": { "describe": { "columns": [ @@ -2163,6 +2165,122 @@ }, "query": "\n UPDATE versions\n SET version_number = $1\n WHERE (id = $2)\n " }, + "5482c526f66da3d7e4618a546f900f312e6382684ad3cd8fc84cc7b961cfb91e": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "mod_id", + "ordinal": 1, + "type_info": "Int8" + }, + { + "name": "author_id", + "ordinal": 2, + "type_info": "Int8" + }, + { + "name": "version_name", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "version_number", + "ordinal": 4, + "type_info": "Varchar" + }, + { + "name": "changelog", + "ordinal": 5, + "type_info": "Varchar" + }, + { + "name": "date_published", + "ordinal": 6, + "type_info": "Timestamptz" + }, + { + "name": "downloads", + "ordinal": 7, + "type_info": "Int4" + }, + { + "name": "version_type", + "ordinal": 8, + "type_info": "Varchar" + }, + { + "name": "featured", + "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "status", + "ordinal": 10, + "type_info": "Varchar" + }, + { + "name": "requested_status", + "ordinal": 11, + "type_info": "Varchar" + }, + { + "name": "game_versions", + "ordinal": 12, + "type_info": "Jsonb" + }, + { + "name": "loaders", + "ordinal": 13, + "type_info": "VarcharArray" + }, + { + "name": "files", + "ordinal": 14, + "type_info": "Jsonb" + }, + { + "name": "hashes", + "ordinal": 15, + "type_info": "Jsonb" + }, + { + "name": "dependencies", + "ordinal": 16, + "type_info": "Jsonb" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + null, + null, + null, + null, + null + ], + "parameters": { + "Left": [ + "Int8Array" + ] + } + }, + "query": "\n SELECT v.id id, v.mod_id mod_id, v.author_id author_id, v.name version_name, v.version_number version_number,\n v.changelog changelog, v.date_published date_published, v.downloads downloads,\n v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status,\n JSONB_AGG(DISTINCT jsonb_build_object('version', gv.version, 'created', gv.created)) filter (where gv.version is not null) game_versions,\n ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders,\n JSONB_AGG(DISTINCT jsonb_build_object('id', f.id, 'url', f.url, 'filename', f.filename, 'primary', f.is_primary, 'size', f.size)) filter (where f.id is not null) files,\n JSONB_AGG(DISTINCT jsonb_build_object('algorithm', h.algorithm, 'hash', encode(h.hash, 'escape'), 'file_id', h.file_id)) filter (where h.hash is not null) hashes,\n JSONB_AGG(DISTINCT jsonb_build_object('project_id', d.mod_dependency_id, 'version_id', d.dependency_id, 'dependency_type', d.dependency_type,'file_name', dependency_file_name)) filter (where d.dependency_type is not null) dependencies\n FROM versions v\n LEFT OUTER JOIN game_versions_versions gvv on v.id = gvv.joining_version_id\n LEFT OUTER JOIN game_versions gv on gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv on v.id = lv.version_id\n LEFT OUTER JOIN loaders l on lv.loader_id = l.id\n LEFT OUTER JOIN files f on v.id = f.version_id\n LEFT OUTER JOIN hashes h on f.id = h.file_id\n LEFT OUTER JOIN dependencies d on v.id = d.dependent_id\n WHERE v.id = ANY($1)\n GROUP BY v.id\n ORDER BY v.date_published ASC;\n " + }, "57a38641fe5bdb273190e8d586f46284340b9ff11b6ae3177923631a37bb11eb": { "describe": { "columns": [], @@ -2987,6 +3105,86 @@ }, "query": "SELECT EXISTS(SELECT 1 FROM team_members WHERE team_id = $1 AND user_id = $2)" }, + "79848ca51533ae6e70ff46986f1fd3a69d1ce4aa88a20541af7f347b19bf95d9": { + "describe": { + "columns": [ + { + "name": "mod_id", + "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "author_id", + "ordinal": 1, + "type_info": "Int8" + }, + { + "name": "name", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "version_number", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "changelog", + "ordinal": 4, + "type_info": "Varchar" + }, + { + "name": "date_published", + "ordinal": 5, + "type_info": "Timestamptz" + }, + { + "name": "downloads", + "ordinal": 6, + "type_info": "Int4" + }, + { + "name": "version_type", + "ordinal": 7, + "type_info": "Varchar" + }, + { + "name": "featured", + "ordinal": 8, + "type_info": "Bool" + }, + { + "name": "status", + "ordinal": 9, + "type_info": "Varchar" + }, + { + "name": "requested_status", + "ordinal": 10, + "type_info": "Varchar" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true + ], + "parameters": { + "Left": [ + "Int8" + ] + } + }, + "query": "\n SELECT v.mod_id, v.author_id, v.name, v.version_number,\n v.changelog, v.date_published, v.downloads,\n v.version_type, v.featured, v.status, v.requested_status\n FROM versions v\n WHERE v.id = $1\n " + }, "79b896b1a8ddab285294638302976b75d0d915f36036383cc21bd2fc48d4502c": { "describe": { "columns": [], @@ -3829,6 +4027,237 @@ }, "query": "\n SELECT u.stripe_customer_id\n FROM users u\n WHERE u.id = $1\n " }, + "9f6fda46555ce4466b69cabecfa5e167918e54b61257e9b0f5c4fdb7cdbdf4d9": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "project_type", + "ordinal": 1, + "type_info": "Int4" + }, + { + "name": "title", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "description", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "downloads", + "ordinal": 4, + "type_info": "Int4" + }, + { + "name": "follows", + "ordinal": 5, + "type_info": "Int4" + }, + { + "name": "icon_url", + "ordinal": 6, + "type_info": "Varchar" + }, + { + "name": "body", + "ordinal": 7, + "type_info": "Varchar" + }, + { + "name": "published", + "ordinal": 8, + "type_info": "Timestamptz" + }, + { + "name": "updated", + "ordinal": 9, + "type_info": "Timestamptz" + }, + { + "name": "approved", + "ordinal": 10, + "type_info": "Timestamptz" + }, + { + "name": "status", + "ordinal": 11, + "type_info": "Varchar" + }, + { + "name": "requested_status", + "ordinal": 12, + "type_info": "Varchar" + }, + { + "name": "issues_url", + "ordinal": 13, + "type_info": "Varchar" + }, + { + "name": "source_url", + "ordinal": 14, + "type_info": "Varchar" + }, + { + "name": "wiki_url", + "ordinal": 15, + "type_info": "Varchar" + }, + { + "name": "discord_url", + "ordinal": 16, + "type_info": "Varchar" + }, + { + "name": "license_url", + "ordinal": 17, + "type_info": "Varchar" + }, + { + "name": "team_id", + "ordinal": 18, + "type_info": "Int8" + }, + { + "name": "client_side", + "ordinal": 19, + "type_info": "Int4" + }, + { + "name": "server_side", + "ordinal": 20, + "type_info": "Int4" + }, + { + "name": "license", + "ordinal": 21, + "type_info": "Varchar" + }, + { + "name": "slug", + "ordinal": 22, + "type_info": "Varchar" + }, + { + "name": "moderation_message", + "ordinal": 23, + "type_info": "Varchar" + }, + { + "name": "moderation_message_body", + "ordinal": 24, + "type_info": "Varchar" + }, + { + "name": "client_side_type", + "ordinal": 25, + "type_info": "Varchar" + }, + { + "name": "server_side_type", + "ordinal": 26, + "type_info": "Varchar" + }, + { + "name": "project_type_name", + "ordinal": 27, + "type_info": "Varchar" + }, + { + "name": "flame_anvil_project", + "ordinal": 28, + "type_info": "Int4" + }, + { + "name": "flame_anvil_user", + "ordinal": 29, + "type_info": "Int8" + }, + { + "name": "webhook_sent", + "ordinal": 30, + "type_info": "Bool" + }, + { + "name": "categories", + "ordinal": 31, + "type_info": "VarcharArray" + }, + { + "name": "additional_categories", + "ordinal": 32, + "type_info": "VarcharArray" + }, + { + "name": "versions", + "ordinal": 33, + "type_info": "Jsonb" + }, + { + "name": "gallery", + "ordinal": 34, + "type_info": "Jsonb" + }, + { + "name": "donations", + "ordinal": 35, + "type_info": "Jsonb" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + false, + true, + false, + false, + false, + true, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + true, + true, + false, + null, + null, + null, + null, + null + ], + "parameters": { + "Left": [ + "Int8", + "TextArray" + ] + } + }, + "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.body body, m.published published,\n m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,\n m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,\n m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent webhook_sent,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,\n JSONB_AGG(DISTINCT jsonb_build_object('image_url', mg.image_url, 'featured', mg.featured, 'title', mg.title, 'description', mg.description, 'created', mg.created, 'ordering', mg.ordering)) filter (where mg.image_url is not null) gallery,\n JSONB_AGG(DISTINCT jsonb_build_object('platform_id', md.joining_platform_id, 'platform_short', dp.short, 'platform_name', dp.name,'url', md.url)) filter (where md.joining_platform_id is not null) donations\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n LEFT JOIN mods_donations md ON md.joining_mod_id = m.id\n LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)\n LEFT JOIN mods_gallery mg ON mg.mod_id = m.id\n WHERE m.id = $1\n GROUP BY pt.id, cs.id, ss.id, m.id;\n " + }, "a0148ff25855202e7bb220b6a2bc9220a95e309fb0dae41d9a05afa86e6b33af": { "describe": { "columns": [], @@ -4036,45 +4465,6 @@ }, "query": "\n INSERT INTO files (id, version_id, url, filename, is_primary, size)\n VALUES ($1, $2, $3, $4, $5, $6)\n " }, - "a8f22bd234488500b06855c8258e1e290696adba0766b46640bf87d91b150518": { - "describe": { - "columns": [ - { - "name": "url", - "ordinal": 0, - "type_info": "Varchar" - }, - { - "name": "id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "version_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 3, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false, - false - ], - "parameters": { - "Left": [ - "Bytea", - "Text" - ] - } - }, - "query": "\n SELECT f.url url, f.id id, f.version_id version_id, v.mod_id mod_id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v ON v.id = f.version_id\n WHERE h.algorithm = $2 AND h.hash = $1\n " - }, "a90bb6904e1b790c0e29e060dac5ba4c2a6087e07c1197dc1f59f0aff31944c9": { "describe": { "columns": [], @@ -4246,194 +4636,6 @@ }, "query": "\n DELETE FROM teams\n WHERE id = $1\n " }, - "b13eba8e7fa3863b3788efb5a9286831125c2d2ff18a0996ec8d291a3bb30520": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "project_type", - "ordinal": 1, - "type_info": "Int4" - }, - { - "name": "title", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "description", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "downloads", - "ordinal": 4, - "type_info": "Int4" - }, - { - "name": "follows", - "ordinal": 5, - "type_info": "Int4" - }, - { - "name": "icon_url", - "ordinal": 6, - "type_info": "Varchar" - }, - { - "name": "body", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "body_url", - "ordinal": 8, - "type_info": "Varchar" - }, - { - "name": "published", - "ordinal": 9, - "type_info": "Timestamptz" - }, - { - "name": "updated", - "ordinal": 10, - "type_info": "Timestamptz" - }, - { - "name": "approved", - "ordinal": 11, - "type_info": "Timestamptz" - }, - { - "name": "status", - "ordinal": 12, - "type_info": "Varchar" - }, - { - "name": "requested_status", - "ordinal": 13, - "type_info": "Varchar" - }, - { - "name": "issues_url", - "ordinal": 14, - "type_info": "Varchar" - }, - { - "name": "source_url", - "ordinal": 15, - "type_info": "Varchar" - }, - { - "name": "wiki_url", - "ordinal": 16, - "type_info": "Varchar" - }, - { - "name": "discord_url", - "ordinal": 17, - "type_info": "Varchar" - }, - { - "name": "license_url", - "ordinal": 18, - "type_info": "Varchar" - }, - { - "name": "team_id", - "ordinal": 19, - "type_info": "Int8" - }, - { - "name": "client_side", - "ordinal": 20, - "type_info": "Int4" - }, - { - "name": "server_side", - "ordinal": 21, - "type_info": "Int4" - }, - { - "name": "license", - "ordinal": 22, - "type_info": "Varchar" - }, - { - "name": "slug", - "ordinal": 23, - "type_info": "Varchar" - }, - { - "name": "moderation_message", - "ordinal": 24, - "type_info": "Varchar" - }, - { - "name": "moderation_message_body", - "ordinal": 25, - "type_info": "Varchar" - }, - { - "name": "flame_anvil_project", - "ordinal": 26, - "type_info": "Int4" - }, - { - "name": "flame_anvil_user", - "ordinal": 27, - "type_info": "Int8" - }, - { - "name": "webhook_sent", - "ordinal": 28, - "type_info": "Bool" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - true, - false, - false, - true, - false, - true, - true, - true, - true, - true, - true, - false, - false, - false, - false, - true, - true, - true, - true, - true, - false - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT id, project_type, title, description, downloads, follows,\n icon_url, body, body_url, published,\n updated, approved, status, requested_status,\n issues_url, source_url, wiki_url, discord_url, license_url,\n team_id, client_side, server_side, license, slug,\n moderation_message, moderation_message_body, flame_anvil_project,\n flame_anvil_user, webhook_sent\n FROM mods\n WHERE id = ANY($1)\n " - }, "b1e77dbaf4b190ab361f4fa203c442e5905cef6c1a135011a59ebd6e2dc0a92a": { "describe": { "columns": [], @@ -4587,6 +4789,188 @@ }, "query": "\n SELECT tm.id id, tm.role member_role, tm.permissions permissions, tm.accepted accepted, tm.payouts_split payouts_split, tm.ordering ordering,\n u.id user_id, u.github_id github_id, u.name user_name, u.email email,\n u.avatar_url avatar_url, u.username username, u.bio bio,\n u.created created, u.role user_role, u.badges badges, u.balance balance,\n u.payout_wallet payout_wallet, u.payout_wallet_type payout_wallet_type,\n u.payout_address payout_address, u.flame_anvil_key flame_anvil_key\n FROM team_members tm\n INNER JOIN users u ON u.id = tm.user_id\n WHERE tm.team_id = $1\n ORDER BY tm.ordering\n " }, + "b660307d4e4027223c6b7297237ee57e5d82c40423707c1fb0f3b8b45737a353": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "project_type", + "ordinal": 1, + "type_info": "Int4" + }, + { + "name": "title", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "description", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "downloads", + "ordinal": 4, + "type_info": "Int4" + }, + { + "name": "follows", + "ordinal": 5, + "type_info": "Int4" + }, + { + "name": "icon_url", + "ordinal": 6, + "type_info": "Varchar" + }, + { + "name": "body", + "ordinal": 7, + "type_info": "Varchar" + }, + { + "name": "published", + "ordinal": 8, + "type_info": "Timestamptz" + }, + { + "name": "updated", + "ordinal": 9, + "type_info": "Timestamptz" + }, + { + "name": "approved", + "ordinal": 10, + "type_info": "Timestamptz" + }, + { + "name": "status", + "ordinal": 11, + "type_info": "Varchar" + }, + { + "name": "requested_status", + "ordinal": 12, + "type_info": "Varchar" + }, + { + "name": "issues_url", + "ordinal": 13, + "type_info": "Varchar" + }, + { + "name": "source_url", + "ordinal": 14, + "type_info": "Varchar" + }, + { + "name": "wiki_url", + "ordinal": 15, + "type_info": "Varchar" + }, + { + "name": "discord_url", + "ordinal": 16, + "type_info": "Varchar" + }, + { + "name": "license_url", + "ordinal": 17, + "type_info": "Varchar" + }, + { + "name": "team_id", + "ordinal": 18, + "type_info": "Int8" + }, + { + "name": "client_side", + "ordinal": 19, + "type_info": "Int4" + }, + { + "name": "server_side", + "ordinal": 20, + "type_info": "Int4" + }, + { + "name": "license", + "ordinal": 21, + "type_info": "Varchar" + }, + { + "name": "slug", + "ordinal": 22, + "type_info": "Varchar" + }, + { + "name": "moderation_message", + "ordinal": 23, + "type_info": "Varchar" + }, + { + "name": "moderation_message_body", + "ordinal": 24, + "type_info": "Varchar" + }, + { + "name": "flame_anvil_project", + "ordinal": 25, + "type_info": "Int4" + }, + { + "name": "flame_anvil_user", + "ordinal": 26, + "type_info": "Int8" + }, + { + "name": "webhook_sent", + "ordinal": 27, + "type_info": "Bool" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + false, + true, + false, + false, + false, + true, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false + ], + "parameters": { + "Left": [ + "Int8Array" + ] + } + }, + "query": "\n SELECT id, project_type, title, description, downloads, follows,\n icon_url, body, published,\n updated, approved, status, requested_status,\n issues_url, source_url, wiki_url, discord_url, license_url,\n team_id, client_side, server_side, license, slug,\n moderation_message, moderation_message_body, flame_anvil_project,\n flame_anvil_user, webhook_sent\n FROM mods\n WHERE id = ANY($1)\n " + }, "b69a6f42965b3e7103fcbf46e39528466926789ff31e9ed2591bb175527ec169": { "describe": { "columns": [], @@ -4710,98 +5094,6 @@ }, "query": "\n DELETE FROM notifications_actions\n WHERE notification_id = ANY($1)\n " }, - "bb30f376f5ea8ddb66371b937812511c1685871c1efccfca0d190bbb5103eaa7": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "author_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "name", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "version_number", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "changelog", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "changelog_url", - "ordinal": 6, - "type_info": "Varchar" - }, - { - "name": "date_published", - "ordinal": 7, - "type_info": "Timestamptz" - }, - { - "name": "downloads", - "ordinal": 8, - "type_info": "Int4" - }, - { - "name": "version_type", - "ordinal": 9, - "type_info": "Varchar" - }, - { - "name": "featured", - "ordinal": 10, - "type_info": "Bool" - }, - { - "name": "status", - "ordinal": 11, - "type_info": "Varchar" - }, - { - "name": "requested_status", - "ordinal": 12, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - false, - false, - false, - false, - true - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT v.id, v.mod_id, v.author_id, v.name, v.version_number,\n v.changelog, v.changelog_url, v.date_published, v.downloads,\n v.version_type, v.featured, v.status, v.requested_status\n FROM versions v\n WHERE v.id = ANY($1)\n ORDER BY v.date_published ASC\n " - }, "bbfb47ae2c972734785df6b7c3e62077dc544ef4ccf8bb89e9c22c2f50a933c1": { "describe": { "columns": [], @@ -4980,128 +5272,6 @@ }, "query": "SELECT EXISTS(SELECT 1 FROM users WHERE id=$1)" }, - "c08f3872248983fe17c5ecd4cb09b14f2c4797b1073af5ec1e71d6887a44928c": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "author_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "version_name", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "version_number", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "changelog", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "changelog_url", - "ordinal": 6, - "type_info": "Varchar" - }, - { - "name": "date_published", - "ordinal": 7, - "type_info": "Timestamptz" - }, - { - "name": "downloads", - "ordinal": 8, - "type_info": "Int4" - }, - { - "name": "version_type", - "ordinal": 9, - "type_info": "Varchar" - }, - { - "name": "featured", - "ordinal": 10, - "type_info": "Bool" - }, - { - "name": "status", - "ordinal": 11, - "type_info": "Varchar" - }, - { - "name": "requested_status", - "ordinal": 12, - "type_info": "Varchar" - }, - { - "name": "game_versions", - "ordinal": 13, - "type_info": "Jsonb" - }, - { - "name": "loaders", - "ordinal": 14, - "type_info": "VarcharArray" - }, - { - "name": "files", - "ordinal": 15, - "type_info": "Jsonb" - }, - { - "name": "hashes", - "ordinal": 16, - "type_info": "Jsonb" - }, - { - "name": "dependencies", - "ordinal": 17, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - false, - false, - false, - false, - true, - null, - null, - null, - null, - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT v.id id, v.mod_id mod_id, v.author_id author_id, v.name version_name, v.version_number version_number,\n v.changelog changelog, v.changelog_url changelog_url, v.date_published date_published, v.downloads downloads,\n v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status,\n JSONB_AGG(DISTINCT jsonb_build_object('version', gv.version, 'created', gv.created)) filter (where gv.version is not null) game_versions,\n ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders,\n JSONB_AGG(DISTINCT jsonb_build_object('id', f.id, 'url', f.url, 'filename', f.filename, 'primary', f.is_primary, 'size', f.size)) filter (where f.id is not null) files,\n JSONB_AGG(DISTINCT jsonb_build_object('algorithm', h.algorithm, 'hash', encode(h.hash, 'escape'), 'file_id', h.file_id)) filter (where h.hash is not null) hashes,\n JSONB_AGG(DISTINCT jsonb_build_object('project_id', d.mod_dependency_id, 'version_id', d.dependency_id, 'dependency_type', d.dependency_type,'file_name', dependency_file_name)) filter (where d.dependency_type is not null) dependencies\n FROM versions v\n LEFT OUTER JOIN game_versions_versions gvv on v.id = gvv.joining_version_id\n LEFT OUTER JOIN game_versions gv on gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv on v.id = lv.version_id\n LEFT OUTER JOIN loaders l on lv.loader_id = l.id\n LEFT OUTER JOIN files f on v.id = f.version_id\n LEFT OUTER JOIN hashes h on f.id = h.file_id\n LEFT OUTER JOIN dependencies d on v.id = d.dependent_id\n WHERE v.id = $1\n GROUP BY v.id;\n " - }, "c100a3be0e1b7bf449576c4052d87494979cb89d194805a5ce9e928eef796ae9": { "describe": { "columns": [], @@ -5376,46 +5546,58 @@ }, "query": "SELECT id, mod_id FROM versions\n WHERE ((version_number = $1 OR id = $3) AND mod_id = $2)" }, - "c771a0d517feda271f5a759394834ab4ae4d9611b361bc242cd96a6e4dfae1c7": { + "c8a27a122160a0896914c786deef9e8193eb240501d30d5ffb4129e2103efd3d": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Left": [ + "Text" + ] + } + }, + "query": "\n UPDATE versions\n SET status = requested_status\n WHERE status = $1 AND date_published < CURRENT_DATE AND requested_status IS NOT NULL\n " + }, + "c9686c5c7dc5a9496fdf3c9b7b5a05c64abf77bb5d525a54c697c2c87a95fc57": { "describe": { "columns": [ { - "name": "project_type", + "name": "id", "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "project_type", + "ordinal": 1, "type_info": "Int4" }, { "name": "title", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "description", "ordinal": 2, "type_info": "Varchar" }, { - "name": "downloads", + "name": "description", "ordinal": 3, - "type_info": "Int4" + "type_info": "Varchar" }, { - "name": "follows", + "name": "downloads", "ordinal": 4, "type_info": "Int4" }, { - "name": "icon_url", + "name": "follows", "ordinal": 5, - "type_info": "Varchar" + "type_info": "Int4" }, { - "name": "body", + "name": "icon_url", "ordinal": 6, "type_info": "Varchar" }, { - "name": "body_url", + "name": "body", "ordinal": 7, "type_info": "Varchar" }, @@ -5505,19 +5687,59 @@ "type_info": "Varchar" }, { - "name": "flame_anvil_project", + "name": "client_side_type", "ordinal": 25, + "type_info": "Varchar" + }, + { + "name": "server_side_type", + "ordinal": 26, + "type_info": "Varchar" + }, + { + "name": "project_type_name", + "ordinal": 27, + "type_info": "Varchar" + }, + { + "name": "flame_anvil_project", + "ordinal": 28, "type_info": "Int4" }, { "name": "flame_anvil_user", - "ordinal": 26, + "ordinal": 29, "type_info": "Int8" }, { "name": "webhook_sent", - "ordinal": 27, + "ordinal": 30, "type_info": "Bool" + }, + { + "name": "categories", + "ordinal": 31, + "type_info": "VarcharArray" + }, + { + "name": "additional_categories", + "ordinal": 32, + "type_info": "VarcharArray" + }, + { + "name": "versions", + "ordinal": 33, + "type_info": "Jsonb" + }, + { + "name": "gallery", + "ordinal": 34, + "type_info": "Jsonb" + }, + { + "name": "donations", + "ordinal": 35, + "type_info": "Jsonb" } ], "nullable": [ @@ -5526,11 +5748,11 @@ false, false, false, - true, false, true, false, false, + false, true, false, true, @@ -5546,29 +5768,26 @@ true, true, true, + false, + false, + false, true, true, - false + false, + null, + null, + null, + null, + null ], "parameters": { "Left": [ - "Int8" + "Int8Array", + "TextArray" ] } }, - "query": "\n SELECT project_type, title, description, downloads, follows,\n icon_url, body, body_url, published,\n updated, approved, status, requested_status,\n issues_url, source_url, wiki_url, discord_url, license_url,\n team_id, client_side, server_side, license, slug,\n moderation_message, moderation_message_body, flame_anvil_project,\n flame_anvil_user, webhook_sent\n FROM mods\n WHERE id = $1\n " - }, - "c8a27a122160a0896914c786deef9e8193eb240501d30d5ffb4129e2103efd3d": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n UPDATE versions\n SET status = requested_status\n WHERE status = $1 AND date_published < CURRENT_DATE AND requested_status IS NOT NULL\n " + "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.body body, m.published published,\n m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,\n m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,\n m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,\n JSONB_AGG(DISTINCT jsonb_build_object('image_url', mg.image_url, 'featured', mg.featured, 'title', mg.title, 'description', mg.description, 'created', mg.created, 'ordering', mg.ordering)) filter (where mg.image_url is not null) gallery,\n JSONB_AGG(DISTINCT jsonb_build_object('platform_id', md.joining_platform_id, 'platform_short', dp.short, 'platform_name', dp.name,'url', md.url)) filter (where md.joining_platform_id is not null) donations\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n LEFT JOIN mods_donations md ON md.joining_mod_id = m.id\n LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)\n LEFT JOIN mods_gallery mg ON mg.mod_id = m.id\n WHERE m.id = ANY($1)\n GROUP BY pt.id, cs.id, ss.id, m.id;\n " }, "c9d63ed46799db7c30a7e917d97a5d4b2b78b0234cce49e136fa57526b38c1ca": { "describe": { @@ -5846,6 +6065,122 @@ }, "query": "\n DELETE FROM team_members\n WHERE team_id = $1\n " }, + "d13d26a088c67d3b38a84d63241106ce78734bc34a51d8f01dcd4f9ea1d13717": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "mod_id", + "ordinal": 1, + "type_info": "Int8" + }, + { + "name": "author_id", + "ordinal": 2, + "type_info": "Int8" + }, + { + "name": "version_name", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "version_number", + "ordinal": 4, + "type_info": "Varchar" + }, + { + "name": "changelog", + "ordinal": 5, + "type_info": "Varchar" + }, + { + "name": "date_published", + "ordinal": 6, + "type_info": "Timestamptz" + }, + { + "name": "downloads", + "ordinal": 7, + "type_info": "Int4" + }, + { + "name": "version_type", + "ordinal": 8, + "type_info": "Varchar" + }, + { + "name": "featured", + "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "status", + "ordinal": 10, + "type_info": "Varchar" + }, + { + "name": "requested_status", + "ordinal": 11, + "type_info": "Varchar" + }, + { + "name": "game_versions", + "ordinal": 12, + "type_info": "Jsonb" + }, + { + "name": "loaders", + "ordinal": 13, + "type_info": "VarcharArray" + }, + { + "name": "files", + "ordinal": 14, + "type_info": "Jsonb" + }, + { + "name": "hashes", + "ordinal": 15, + "type_info": "Jsonb" + }, + { + "name": "dependencies", + "ordinal": 16, + "type_info": "Jsonb" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + null, + null, + null, + null, + null + ], + "parameters": { + "Left": [ + "Int8" + ] + } + }, + "query": "\n SELECT v.id id, v.mod_id mod_id, v.author_id author_id, v.name version_name, v.version_number version_number,\n v.changelog changelog, v.date_published date_published, v.downloads downloads,\n v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status,\n JSONB_AGG(DISTINCT jsonb_build_object('version', gv.version, 'created', gv.created)) filter (where gv.version is not null) game_versions,\n ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders,\n JSONB_AGG(DISTINCT jsonb_build_object('id', f.id, 'url', f.url, 'filename', f.filename, 'primary', f.is_primary, 'size', f.size)) filter (where f.id is not null) files,\n JSONB_AGG(DISTINCT jsonb_build_object('algorithm', h.algorithm, 'hash', encode(h.hash, 'escape'), 'file_id', h.file_id)) filter (where h.hash is not null) hashes,\n JSONB_AGG(DISTINCT jsonb_build_object('project_id', d.mod_dependency_id, 'version_id', d.dependency_id, 'dependency_type', d.dependency_type,'file_name', dependency_file_name)) filter (where d.dependency_type is not null) dependencies\n FROM versions v\n LEFT OUTER JOIN game_versions_versions gvv on v.id = gvv.joining_version_id\n LEFT OUTER JOIN game_versions gv on gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv on v.id = lv.version_id\n LEFT OUTER JOIN loaders l on lv.loader_id = l.id\n LEFT OUTER JOIN files f on v.id = f.version_id\n LEFT OUTER JOIN hashes h on f.id = h.file_id\n LEFT OUTER JOIN dependencies d on v.id = d.dependent_id\n WHERE v.id = $1\n GROUP BY v.id;\n " + }, "d1866ecc161c3fe3fbe094289510e99b17de563957e1f824c347c1e6ac40c40c": { "describe": { "columns": [ @@ -6124,242 +6459,27 @@ }, "query": "\n SELECT id, user_id, role, permissions, accepted, payouts_split, ordering\n FROM team_members\n WHERE (team_id = $1 AND user_id = $2)\n " }, - "de71dc18c26fbf70055a5f308a7421eca6191d15e870e1119e316d9b44b597ff": { + "df871bd959ba97f105ac575f34d8d2a39cbc44a07e0339750a0e477e6fd582ed": { "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "project_type", - "ordinal": 1, - "type_info": "Int4" - }, - { - "name": "title", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "description", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "downloads", - "ordinal": 4, - "type_info": "Int4" - }, - { - "name": "follows", - "ordinal": 5, - "type_info": "Int4" - }, - { - "name": "icon_url", - "ordinal": 6, - "type_info": "Varchar" - }, - { - "name": "body", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "body_url", - "ordinal": 8, - "type_info": "Varchar" - }, - { - "name": "published", - "ordinal": 9, - "type_info": "Timestamptz" - }, - { - "name": "updated", - "ordinal": 10, - "type_info": "Timestamptz" - }, - { - "name": "approved", - "ordinal": 11, - "type_info": "Timestamptz" - }, - { - "name": "status", - "ordinal": 12, - "type_info": "Varchar" - }, - { - "name": "requested_status", - "ordinal": 13, - "type_info": "Varchar" - }, - { - "name": "issues_url", - "ordinal": 14, - "type_info": "Varchar" - }, - { - "name": "source_url", - "ordinal": 15, - "type_info": "Varchar" - }, - { - "name": "wiki_url", - "ordinal": 16, - "type_info": "Varchar" - }, - { - "name": "discord_url", - "ordinal": 17, - "type_info": "Varchar" - }, - { - "name": "license_url", - "ordinal": 18, - "type_info": "Varchar" - }, - { - "name": "team_id", - "ordinal": 19, - "type_info": "Int8" - }, - { - "name": "client_side", - "ordinal": 20, - "type_info": "Int4" - }, - { - "name": "server_side", - "ordinal": 21, - "type_info": "Int4" - }, - { - "name": "license", - "ordinal": 22, - "type_info": "Varchar" - }, - { - "name": "slug", - "ordinal": 23, - "type_info": "Varchar" - }, - { - "name": "moderation_message", - "ordinal": 24, - "type_info": "Varchar" - }, - { - "name": "moderation_message_body", - "ordinal": 25, - "type_info": "Varchar" - }, - { - "name": "client_side_type", - "ordinal": 26, - "type_info": "Varchar" - }, - { - "name": "server_side_type", - "ordinal": 27, - "type_info": "Varchar" - }, - { - "name": "project_type_name", - "ordinal": 28, - "type_info": "Varchar" - }, - { - "name": "flame_anvil_project", - "ordinal": 29, - "type_info": "Int4" - }, - { - "name": "flame_anvil_user", - "ordinal": 30, - "type_info": "Int8" - }, - { - "name": "webhook_sent", - "ordinal": 31, - "type_info": "Bool" - }, - { - "name": "categories", - "ordinal": 32, - "type_info": "VarcharArray" - }, - { - "name": "additional_categories", - "ordinal": 33, - "type_info": "VarcharArray" - }, - { - "name": "versions", - "ordinal": 34, - "type_info": "Jsonb" - }, - { - "name": "gallery", - "ordinal": 35, - "type_info": "Jsonb" - }, - { - "name": "donations", - "ordinal": 36, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - true, - false, - false, - true, - false, - true, - true, - true, - true, - true, - true, - false, - false, - false, - false, - true, - true, - true, - false, - false, - false, - true, - true, - false, - null, - null, - null, - null, - null - ], + "columns": [], + "nullable": [], "parameters": { "Left": [ - "Int8Array", - "TextArray" + "Int8", + "Int8", + "Int8", + "Varchar", + "Varchar", + "Varchar", + "Timestamptz", + "Int4", + "Varchar", + "Bool", + "Varchar" ] } }, - "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.body body, m.body_url body_url, m.published published,\n m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,\n m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,\n m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,\n JSONB_AGG(DISTINCT jsonb_build_object('image_url', mg.image_url, 'featured', mg.featured, 'title', mg.title, 'description', mg.description, 'created', mg.created, 'ordering', mg.ordering)) filter (where mg.image_url is not null) gallery,\n JSONB_AGG(DISTINCT jsonb_build_object('platform_id', md.joining_platform_id, 'platform_short', dp.short, 'platform_name', dp.name,'url', md.url)) filter (where md.joining_platform_id is not null) donations\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n LEFT JOIN mods_donations md ON md.joining_mod_id = m.id\n LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)\n LEFT JOIN mods_gallery mg ON mg.mod_id = m.id\n WHERE m.id = ANY($1)\n GROUP BY pt.id, cs.id, ss.id, m.id;\n " + "query": "\n INSERT INTO versions (\n id, mod_id, author_id, name, version_number,\n changelog, date_published, downloads,\n version_type, featured, status\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7, $8,\n $9, $10, $11\n )\n " }, "e04e0d7add07dc7ae16496badcadd3789be22c80a04a01fbeda3f8dfca01f4b2": { "describe": { @@ -6539,128 +6659,6 @@ }, "query": "\n UPDATE versions\n SET featured = $1\n WHERE (id = $2)\n " }, - "e4c3ad615aac0477f763de03bb2355cba257e62ce986fed2ccb8d720b9f5608c": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "author_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "version_name", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "version_number", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "changelog", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "changelog_url", - "ordinal": 6, - "type_info": "Varchar" - }, - { - "name": "date_published", - "ordinal": 7, - "type_info": "Timestamptz" - }, - { - "name": "downloads", - "ordinal": 8, - "type_info": "Int4" - }, - { - "name": "version_type", - "ordinal": 9, - "type_info": "Varchar" - }, - { - "name": "featured", - "ordinal": 10, - "type_info": "Bool" - }, - { - "name": "status", - "ordinal": 11, - "type_info": "Varchar" - }, - { - "name": "requested_status", - "ordinal": 12, - "type_info": "Varchar" - }, - { - "name": "game_versions", - "ordinal": 13, - "type_info": "Jsonb" - }, - { - "name": "loaders", - "ordinal": 14, - "type_info": "VarcharArray" - }, - { - "name": "files", - "ordinal": 15, - "type_info": "Jsonb" - }, - { - "name": "hashes", - "ordinal": 16, - "type_info": "Jsonb" - }, - { - "name": "dependencies", - "ordinal": 17, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - false, - false, - false, - false, - true, - null, - null, - null, - null, - null - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT v.id id, v.mod_id mod_id, v.author_id author_id, v.name version_name, v.version_number version_number,\n v.changelog changelog, v.changelog_url changelog_url, v.date_published date_published, v.downloads downloads,\n v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status,\n JSONB_AGG(DISTINCT jsonb_build_object('version', gv.version, 'created', gv.created)) filter (where gv.version is not null) game_versions,\n ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders,\n JSONB_AGG(DISTINCT jsonb_build_object('id', f.id, 'url', f.url, 'filename', f.filename, 'primary', f.is_primary, 'size', f.size)) filter (where f.id is not null) files,\n JSONB_AGG(DISTINCT jsonb_build_object('algorithm', h.algorithm, 'hash', encode(h.hash, 'escape'), 'file_id', h.file_id)) filter (where h.hash is not null) hashes,\n JSONB_AGG(DISTINCT jsonb_build_object('project_id', d.mod_dependency_id, 'version_id', d.dependency_id, 'dependency_type', d.dependency_type,'file_name', dependency_file_name)) filter (where d.dependency_type is not null) dependencies\n FROM versions v\n LEFT OUTER JOIN game_versions_versions gvv on v.id = gvv.joining_version_id\n LEFT OUTER JOIN game_versions gv on gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv on v.id = lv.version_id\n LEFT OUTER JOIN loaders l on lv.loader_id = l.id\n LEFT OUTER JOIN files f on v.id = f.version_id\n LEFT OUTER JOIN hashes h on f.id = h.file_id\n LEFT OUTER JOIN dependencies d on v.id = d.dependent_id\n WHERE v.id = ANY($1)\n GROUP BY v.id\n ORDER BY v.date_published ASC;\n " - }, "e5a485770edb23ed77c56cb0bbd7ed28f8789c740c194ff23c44eafab78d440c": { "describe": { "columns": [ @@ -7045,92 +7043,6 @@ }, "query": "\n SELECT n.id FROM notifications n\n WHERE n.user_id = $1\n " }, - "ec22b034f9f08d85e2bad06e49db2aa4ba66d0d03679543125608914f0373a89": { - "describe": { - "columns": [ - { - "name": "mod_id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "author_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "name", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "version_number", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "changelog", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "changelog_url", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "date_published", - "ordinal": 6, - "type_info": "Timestamptz" - }, - { - "name": "downloads", - "ordinal": 7, - "type_info": "Int4" - }, - { - "name": "version_type", - "ordinal": 8, - "type_info": "Varchar" - }, - { - "name": "featured", - "ordinal": 9, - "type_info": "Bool" - }, - { - "name": "status", - "ordinal": 10, - "type_info": "Varchar" - }, - { - "name": "requested_status", - "ordinal": 11, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - true, - false, - false, - false, - false, - false, - true - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT v.mod_id, v.author_id, v.name, v.version_number,\n v.changelog, v.changelog_url, v.date_published, v.downloads,\n v.version_type, v.featured, v.status, v.requested_status\n FROM versions v\n WHERE v.id = $1\n " - }, "ed1d5d9433bc7f4a360431ecfdd9430c5e58cd6d1c623c187d8661200400b1a4": { "describe": { "columns": [], diff --git a/src/database/models/project_item.rs b/src/database/models/project_item.rs index 81acf3ab..be147e55 100644 --- a/src/database/models/project_item.rs +++ b/src/database/models/project_item.rs @@ -274,7 +274,7 @@ impl Project { let result = sqlx::query!( " SELECT project_type, title, description, downloads, follows, - icon_url, body, body_url, published, + icon_url, body, published, updated, approved, status, requested_status, issues_url, source_url, wiki_url, discord_url, license_url, team_id, client_side, server_side, license, slug, @@ -296,7 +296,7 @@ impl Project { title: row.title, description: row.description, downloads: row.downloads, - body_url: row.body_url, + body_url: None, icon_url: row.icon_url, published: row.published, updated: row.updated, @@ -341,7 +341,7 @@ impl Project { let projects = sqlx::query!( " SELECT id, project_type, title, description, downloads, follows, - icon_url, body, body_url, published, + icon_url, body, published, updated, approved, status, requested_status, issues_url, source_url, wiki_url, discord_url, license_url, team_id, client_side, server_side, license, slug, @@ -361,7 +361,7 @@ impl Project { title: m.title, description: m.description, downloads: m.downloads, - body_url: m.body_url, + body_url: None, icon_url: m.icon_url, published: m.published, updated: m.updated, @@ -662,7 +662,7 @@ impl Project { let result = sqlx::query!( " SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows, - m.icon_url icon_url, m.body body, m.body_url body_url, m.published published, + m.icon_url icon_url, m.body body, m.published published, m.updated updated, m.approved approved, m.status status, m.requested_status requested_status, m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url, m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body, @@ -700,7 +700,7 @@ impl Project { title: m.title.clone(), description: m.description.clone(), downloads: m.downloads, - body_url: m.body_url.clone(), + body_url: None, icon_url: m.icon_url.clone(), published: m.published, updated: m.updated, @@ -790,7 +790,7 @@ impl Project { sqlx::query!( " SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows, - m.icon_url icon_url, m.body body, m.body_url body_url, m.published published, + m.icon_url icon_url, m.body body, m.published published, m.updated updated, m.approved approved, m.status status, m.requested_status requested_status, m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url, m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body, @@ -829,7 +829,7 @@ impl Project { title: m.title.clone(), description: m.description.clone(), downloads: m.downloads, - body_url: m.body_url.clone(), + body_url: None, icon_url: m.icon_url.clone(), published: m.published, updated: m.updated, diff --git a/src/database/models/version_item.rs b/src/database/models/version_item.rs index be4343bd..01787490 100644 --- a/src/database/models/version_item.rs +++ b/src/database/models/version_item.rs @@ -268,14 +268,13 @@ impl Version { " INSERT INTO versions ( id, mod_id, author_id, name, version_number, - changelog, changelog_url, date_published, - downloads, version_type, featured, status + changelog, date_published, downloads, + version_type, featured, status ) VALUES ( $1, $2, $3, $4, $5, - $6, $7, - $8, $9, - $10, $11, $12 + $6, $7, $8, + $9, $10, $11 ) ", self.id as VersionId, @@ -284,7 +283,6 @@ impl Version { &self.name, &self.version_number, self.changelog, - self.changelog_url.as_ref(), self.date_published, self.downloads, &self.version_type, @@ -508,7 +506,7 @@ impl Version { let result = sqlx::query!( " SELECT v.mod_id, v.author_id, v.name, v.version_number, - v.changelog, v.changelog_url, v.date_published, v.downloads, + v.changelog, v.date_published, v.downloads, v.version_type, v.featured, v.status, v.requested_status FROM versions v WHERE v.id = $1 @@ -526,7 +524,7 @@ impl Version { name: row.name, version_number: row.version_number, changelog: row.changelog, - changelog_url: row.changelog_url, + changelog_url: None, date_published: row.date_published, downloads: row.downloads, version_type: row.version_type, @@ -555,7 +553,7 @@ impl Version { let versions = sqlx::query!( " SELECT v.id, v.mod_id, v.author_id, v.name, v.version_number, - v.changelog, v.changelog_url, v.date_published, v.downloads, + v.changelog, v.date_published, v.downloads, v.version_type, v.featured, v.status, v.requested_status FROM versions v WHERE v.id = ANY($1) @@ -572,7 +570,7 @@ impl Version { name: v.name, version_number: v.version_number, changelog: v.changelog, - changelog_url: v.changelog_url, + changelog_url: None, date_published: v.date_published, downloads: v.downloads, featured: v.featured, @@ -599,7 +597,7 @@ impl Version { let result = sqlx::query!( " SELECT v.id id, v.mod_id mod_id, v.author_id author_id, v.name version_name, v.version_number version_number, - v.changelog changelog, v.changelog_url changelog_url, v.date_published date_published, v.downloads downloads, + v.changelog changelog, v.date_published date_published, v.downloads downloads, v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status, JSONB_AGG(DISTINCT jsonb_build_object('version', gv.version, 'created', gv.created)) filter (where gv.version is not null) game_versions, ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders, @@ -631,7 +629,7 @@ impl Version { name: v.version_name, version_number: v.version_number, changelog: v.changelog, - changelog_url: v.changelog_url, + changelog_url: None, date_published: v.date_published, downloads: v.downloads, version_type: v.version_type, @@ -749,7 +747,7 @@ impl Version { sqlx::query!( " SELECT v.id id, v.mod_id mod_id, v.author_id author_id, v.name version_name, v.version_number version_number, - v.changelog changelog, v.changelog_url changelog_url, v.date_published date_published, v.downloads downloads, + v.changelog changelog, v.date_published date_published, v.downloads downloads, v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status, JSONB_AGG(DISTINCT jsonb_build_object('version', gv.version, 'created', gv.created)) filter (where gv.version is not null) game_versions, ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders, @@ -781,7 +779,7 @@ impl Version { name: v.version_name, version_number: v.version_number, changelog: v.changelog, - changelog_url: v.changelog_url, + changelog_url: None, date_published: v.date_published, downloads: v.downloads, version_type: v.version_type, diff --git a/src/models/projects.rs b/src/models/projects.rs index 1a90bedc..f1d0cd12 100644 --- a/src/models/projects.rs +++ b/src/models/projects.rs @@ -36,7 +36,7 @@ pub struct Project { pub description: String, /// A long form description of the project. pub body: String, - /// The link to the long description of the project. (Deprecated), being replaced by `body` + /// The link to the long description of the project. Deprecated, always None pub body_url: Option, /// The date at which the project was first published. @@ -110,7 +110,7 @@ impl From for Project { title: m.title, description: m.description, body: m.body, - body_url: m.body_url, + body_url: None, published: m.published, updated: m.updated, approved: m.approved, @@ -402,7 +402,7 @@ pub struct Version { pub version_number: String, /// The changelog for this version of the project. pub changelog: String, - /// A link to the changelog for this version of the project. (Deprecated), being replaced by `changelog` + /// A link to the changelog for this version of the project. Deprecated, always None pub changelog_url: Option, /// The date that this version was published. @@ -439,7 +439,7 @@ impl From for Version { name: v.name, version_number: v.version_number, changelog: v.changelog, - changelog_url: v.changelog_url, + changelog_url: None, date_published: v.date_published, downloads: v.downloads as u32, version_type: match v.version_type.as_str() { diff --git a/src/models/reports.rs b/src/models/reports.rs index e970f343..fe458e88 100644 --- a/src/models/reports.rs +++ b/src/models/reports.rs @@ -23,6 +23,8 @@ pub struct Report { #[serde(rename_all = "kebab-case")] pub enum ItemType { Project, + // TODO remove when API v1 POST routes are removed + Mod, Version, User, Unknown, @@ -32,6 +34,7 @@ impl ItemType { pub fn as_str(&self) -> &'static str { match self { ItemType::Project => "project", + ItemType::Mod => "mod", ItemType::Version => "version", ItemType::User => "user", ItemType::Unknown => "unknown", diff --git a/src/routes/reports.rs b/src/routes/reports.rs index b1f50531..ff3dbe4a 100644 --- a/src/routes/reports.rs +++ b/src/routes/reports.rs @@ -64,7 +64,7 @@ pub async fn report_create( }; match new_report.item_type { - ItemType::Project => { + ItemType::Project | ItemType::Mod => { report.project_id = Some( serde_json::from_str::(&format!( "\"{}\"", diff --git a/src/routes/v1/mod.rs b/src/routes/v1/mod.rs index a4abdc55..4e54b2ce 100644 --- a/src/routes/v1/mod.rs +++ b/src/routes/v1/mod.rs @@ -1,8 +1,6 @@ use actix_web::web; -mod moderation; mod mods; -mod reports; mod tags; mod teams; mod users; @@ -11,13 +9,11 @@ mod versions; pub fn v1_config(cfg: &mut web::ServiceConfig) { cfg.service( web::scope("api/v1") - .configure(super::auth_config) .configure(tags_config) .configure(mods_config) .configure(versions_config) .configure(teams_config) .configure(users_config) - .configure(moderation_config) .configure(reports_config) .configure(notifications_config), ); @@ -27,20 +23,9 @@ pub fn tags_config(cfg: &mut web::ServiceConfig) { cfg.service( web::scope("tag") .service(tags::category_list) - .service(tags::category_create) - .service(super::tags::category_delete) .service(tags::loader_list) - .service(tags::loader_create) - .service(super::tags::loader_delete) .service(tags::game_version_list) - .service(super::tags::game_version_create) - .service(super::tags::game_version_delete) .service(super::tags::license_list) - .service(super::tags::donation_platform_create) - .service(super::tags::donation_platform_list) - .service(super::tags::donation_platform_delete) - .service(super::tags::report_type_create) - .service(super::tags::report_type_delete) .service(super::tags::report_type_list), ); } @@ -74,9 +59,9 @@ pub fn versions_config(cfg: &mut web::ServiceConfig) { ); cfg.service( web::scope("version_file") - .service(versions::delete_file) - .service(versions::get_version_from_hash) - .service(versions::download_version), + .service(super::version_file::delete_file) + .service(super::version_file::get_version_from_hash) + .service(super::version_file::download_version), ); } @@ -117,12 +102,6 @@ pub fn notifications_config(cfg: &mut web::ServiceConfig) { ); } -pub fn moderation_config(cfg: &mut web::ServiceConfig) { - cfg.service(web::scope("moderation").service(moderation::get_mods)); -} - pub fn reports_config(cfg: &mut web::ServiceConfig) { - cfg.service(reports::reports); - cfg.service(reports::report_create); - cfg.service(super::reports::delete_report); + cfg.service(super::reports::report_create); } diff --git a/src/routes/v1/moderation.rs b/src/routes/v1/moderation.rs deleted file mode 100644 index 95ed2f67..00000000 --- a/src/routes/v1/moderation.rs +++ /dev/null @@ -1,45 +0,0 @@ -use crate::database; -use crate::models::projects::{Project, ProjectStatus}; -use crate::routes::moderation::ResultCount; -use crate::routes::ApiError; -use crate::util::auth::check_is_moderator_from_headers; -use actix_web::web; -use actix_web::{get, HttpRequest, HttpResponse}; -use sqlx::PgPool; - -#[get("mods")] -pub async fn get_mods( - req: HttpRequest, - pool: web::Data, - count: web::Query, -) -> Result { - check_is_moderator_from_headers(req.headers(), &**pool).await?; - - use futures::stream::TryStreamExt; - - let project_ids = sqlx::query!( - " - SELECT id FROM mods - WHERE status = $1 - ORDER BY updated ASC - LIMIT $2; - ", - ProjectStatus::Processing.as_str(), - count.count as i64 - ) - .fetch_many(&**pool) - .try_filter_map(|e| async { - Ok(e.right().map(|m| database::models::ProjectId(m.id))) - }) - .try_collect::>() - .await?; - - let projects: Vec<_> = - database::Project::get_many_full(project_ids, &**pool) - .await? - .into_iter() - .map(Project::from) - .collect(); - - Ok(HttpResponse::Ok().json(projects)) -} diff --git a/src/routes/v1/reports.rs b/src/routes/v1/reports.rs deleted file mode 100644 index 4b778b80..00000000 --- a/src/routes/v1/reports.rs +++ /dev/null @@ -1,218 +0,0 @@ -use crate::models::ids::ReportId; -use crate::models::projects::{ProjectId, VersionId}; -use crate::models::users::UserId; -use crate::routes::ApiError; -use crate::util::auth::{ - check_is_moderator_from_headers, get_user_from_headers, -}; -use actix_web::web; -use actix_web::{get, post, HttpRequest, HttpResponse}; -use chrono::{DateTime, Utc}; -use futures::StreamExt; -use serde::{Deserialize, Serialize}; -use sqlx::PgPool; - -#[derive(Serialize, Deserialize)] -pub struct Report { - pub id: ReportId, - pub report_type: String, - pub item_id: String, - pub item_type: ItemType, - pub reporter: UserId, - pub body: String, - pub created: DateTime, -} - -#[derive(Serialize, Deserialize, Clone)] -#[serde(rename_all = "kebab-case")] -pub enum ItemType { - Mod, - Version, - User, - Unknown, -} - -impl ItemType { - pub fn as_str(&self) -> &'static str { - match self { - ItemType::Mod => "mod", - ItemType::Version => "version", - ItemType::User => "user", - ItemType::Unknown => "unknown", - } - } -} -#[derive(Deserialize)] -pub struct CreateReport { - pub report_type: String, - pub item_id: String, - pub item_type: ItemType, - pub body: String, -} - -#[post("report")] -pub async fn report_create( - req: HttpRequest, - pool: web::Data, - mut body: web::Payload, -) -> Result { - let mut transaction = pool.begin().await?; - - let current_user = - get_user_from_headers(req.headers(), &mut *transaction).await?; - - let mut bytes = web::BytesMut::new(); - while let Some(item) = body.next().await { - bytes.extend_from_slice(&item.map_err(|_| { - ApiError::InvalidInput( - "Error while parsing request payload!".to_string(), - ) - })?); - } - let new_report: CreateReport = serde_json::from_slice(bytes.as_ref())?; - - let id = - crate::database::models::generate_report_id(&mut transaction).await?; - let report_type = crate::database::models::categories::ReportType::get_id( - &new_report.report_type, - &mut *transaction, - ) - .await? - .ok_or_else(|| { - ApiError::InvalidInput(format!( - "Invalid report type: {}", - new_report.report_type - )) - })?; - let mut report = crate::database::models::report_item::Report { - id, - report_type_id: report_type, - project_id: None, - version_id: None, - user_id: None, - body: new_report.body.clone(), - reporter: current_user.id.into(), - created: Utc::now(), - }; - - match new_report.item_type { - ItemType::Mod => { - report.project_id = Some( - serde_json::from_str::(&format!( - "\"{}\"", - new_report.item_id - ))? - .into(), - ) - } - ItemType::Version => { - report.version_id = Some( - serde_json::from_str::(&format!( - "\"{}\"", - new_report.item_id - ))? - .into(), - ) - } - ItemType::User => { - report.user_id = Some( - serde_json::from_str::(&format!( - "\"{}\"", - new_report.item_id - ))? - .into(), - ) - } - ItemType::Unknown => { - return Err(ApiError::InvalidInput(format!( - "Invalid report item type: {}", - new_report.item_type.as_str() - ))) - } - } - - report.insert(&mut transaction).await?; - transaction.commit().await?; - - Ok(HttpResponse::Ok().json(Report { - id: id.into(), - report_type: new_report.report_type.clone(), - item_id: new_report.item_id.clone(), - item_type: new_report.item_type.clone(), - reporter: current_user.id, - body: new_report.body.clone(), - created: Utc::now(), - })) -} - -#[derive(Deserialize)] -pub struct ResultCount { - #[serde(default = "default_count")] - count: i16, -} - -fn default_count() -> i16 { - 100 -} - -#[get("report")] -pub async fn reports( - req: HttpRequest, - pool: web::Data, - count: web::Query, -) -> Result { - check_is_moderator_from_headers(req.headers(), &**pool).await?; - - use futures::stream::TryStreamExt; - - let report_ids = sqlx::query!( - " - SELECT id FROM reports - ORDER BY created ASC - LIMIT $1; - ", - count.count as i64 - ) - .fetch_many(&**pool) - .try_filter_map(|e| async { - Ok(e.right() - .map(|m| crate::database::models::ids::ReportId(m.id))) - }) - .try_collect::>() - .await?; - - let query_reports = crate::database::models::report_item::Report::get_many( - report_ids, &**pool, - ) - .await?; - - let mut reports = Vec::new(); - - for x in query_reports { - let mut item_id = "".to_string(); - let mut item_type = ItemType::Unknown; - - if let Some(project_id) = x.project_id { - item_id = serde_json::to_string::(&project_id.into())?; - item_type = ItemType::Mod; - } else if let Some(version_id) = x.version_id { - item_id = serde_json::to_string::(&version_id.into())?; - item_type = ItemType::Version; - } else if let Some(user_id) = x.user_id { - item_id = serde_json::to_string::(&user_id.into())?; - item_type = ItemType::User; - } - - reports.push(Report { - id: x.id.into(), - report_type: x.report_type, - item_id, - item_type, - reporter: x.reporter.into(), - body: x.body, - created: x.created, - }) - } - - Ok(HttpResponse::Ok().json(reports)) -} diff --git a/src/routes/v1/tags.rs b/src/routes/v1/tags.rs index 0c48747a..18abb65d 100644 --- a/src/routes/v1/tags.rs +++ b/src/routes/v1/tags.rs @@ -1,14 +1,8 @@ -use crate::database::models::categories::{ - Category, GameVersion, Loader, ProjectType, -}; +use crate::database::models::categories::{Category, GameVersion, Loader}; use crate::routes::ApiError; -use crate::util::auth::check_is_admin_from_headers; -use actix_web::{get, put, web}; -use actix_web::{HttpRequest, HttpResponse}; +use actix_web::{get, web, HttpResponse}; use sqlx::PgPool; -const DEFAULT_ICON: &str = r#""#; - #[get("category")] pub async fn category_list( pool: web::Data, @@ -22,37 +16,6 @@ pub async fn category_list( Ok(HttpResponse::Ok().json(results)) } -#[put("category/{name}")] -pub async fn category_create( - req: HttpRequest, - pool: web::Data, - category: web::Path<(String,)>, -) -> Result { - check_is_admin_from_headers(req.headers(), &**pool).await?; - - let name = category.into_inner().0; - - let project_type = crate::database::models::ProjectTypeId::get_id( - "mod".to_string(), - &**pool, - ) - .await? - .ok_or_else(|| { - ApiError::InvalidInput( - "Specified project type does not exist!".to_string(), - ) - })?; - - let _id = Category::builder() - .name(&name)? - .icon(DEFAULT_ICON)? - .project_type(&project_type)? - .insert(&**pool) - .await?; - - Ok(HttpResponse::NoContent().body("")) -} - #[get("loader")] pub async fn loader_list( pool: web::Data, @@ -67,33 +30,6 @@ pub async fn loader_list( Ok(HttpResponse::Ok().json(results)) } -#[put("loader/{name}")] -pub async fn loader_create( - req: HttpRequest, - pool: web::Data, - loader: web::Path<(String,)>, -) -> Result { - check_is_admin_from_headers(req.headers(), &**pool).await?; - - let name = loader.into_inner().0; - let mut transaction = pool.begin().await?; - - let project_types = - ProjectType::get_many_id(&["mod".to_string()], &mut *transaction) - .await?; - - let _id = Loader::builder() - .name(&name)? - .icon(DEFAULT_ICON)? - .supported_project_types( - &project_types.into_iter().map(|x| x.id).collect::>(), - )? - .insert(&mut transaction) - .await?; - - Ok(HttpResponse::NoContent().body("")) -} - #[derive(serde::Deserialize)] pub struct GameVersionQueryData { #[serde(rename = "type")] diff --git a/src/routes/v1/versions.rs b/src/routes/v1/versions.rs index 461fc68d..87c31e2f 100644 --- a/src/routes/v1/versions.rs +++ b/src/routes/v1/versions.rs @@ -4,6 +4,7 @@ use crate::models::projects::{ Dependency, GameVersion, Loader, Version, VersionFile, VersionType, }; use crate::models::teams::Permissions; +use crate::routes::version_file::Algorithm; use crate::routes::versions::{VersionIds, VersionListFilters}; use crate::routes::ApiError; use crate::util::auth::get_user_from_headers; @@ -41,7 +42,7 @@ fn convert_to_legacy(version: Version) -> LegacyVersion { name: version.name, version_number: version.version_number, changelog: version.changelog, - changelog_url: version.changelog_url, + changelog_url: None, date_published: version.date_published, downloads: version.downloads, version_type: version.version_type, @@ -192,174 +193,3 @@ pub async fn version_get( Ok(HttpResponse::NotFound().body("")) } } - -#[derive(Deserialize)] -pub struct Algorithm { - #[serde(default = "default_algorithm")] - algorithm: String, -} - -fn default_algorithm() -> String { - "sha1".into() -} - -// under /api/v1/version_file/{hash} -#[get("{version_id}")] -pub async fn get_version_from_hash( - info: web::Path<(String,)>, - pool: web::Data, - algorithm: web::Query, -) -> Result { - let hash = info.into_inner().0.to_lowercase(); - - let result = sqlx::query!( - " - SELECT f.version_id version_id FROM hashes h - INNER JOIN files f ON h.file_id = f.id - WHERE h.algorithm = $2 AND h.hash = $1 - ", - hash.as_bytes(), - algorithm.algorithm - ) - .fetch_optional(&**pool) - .await?; - - if let Some(id) = result { - let version_data = database::models::Version::get_full( - database::models::VersionId(id.version_id), - &**pool, - ) - .await?; - - if let Some(data) = version_data { - Ok(HttpResponse::Ok() - .json(crate::models::projects::Version::from(data))) - } else { - Ok(HttpResponse::NotFound().body("")) - } - } else { - Ok(HttpResponse::NotFound().body("")) - } -} - -#[derive(Serialize, Deserialize)] -pub struct DownloadRedirect { - pub url: String, -} - -// under /api/v1/version_file/{hash}/download -#[allow(clippy::await_holding_refcell_ref)] -#[get("{version_id}/download")] -pub async fn download_version( - info: web::Path<(String,)>, - pool: web::Data, - algorithm: web::Query, -) -> Result { - let hash = info.into_inner().0; - - let result = sqlx::query!( - " - SELECT f.url url, f.id id, f.version_id version_id, v.mod_id mod_id FROM hashes h - INNER JOIN files f ON h.file_id = f.id - INNER JOIN versions v ON v.id = f.version_id - WHERE h.algorithm = $2 AND h.hash = $1 - ", - hash.as_bytes(), - algorithm.algorithm - ) - .fetch_optional(&**pool) - .await - .map_err(|e| ApiError::Database(e.into()))?; - - if let Some(id) = result { - Ok(HttpResponse::TemporaryRedirect() - .append_header(("Location", &*id.url)) - .json(DownloadRedirect { url: id.url })) - } else { - Ok(HttpResponse::NotFound().body("")) - } -} - -// under /api/v1/version_file/{hash} -#[delete("{version_id}")] -pub async fn delete_file( - req: HttpRequest, - info: web::Path<(String,)>, - pool: web::Data, - algorithm: web::Query, -) -> Result { - let user = get_user_from_headers(req.headers(), &**pool).await?; - - let hash = info.into_inner().0.to_lowercase(); - - let result = sqlx::query!( - " - SELECT f.id id, f.version_id version_id, f.filename filename, v.version_number version_number, v.mod_id project_id FROM hashes h - INNER JOIN files f ON h.file_id = f.id - INNER JOIN versions v ON v.id = f.version_id - WHERE h.algorithm = $2 AND h.hash = $1 - ", - hash.as_bytes(), - algorithm.algorithm - ) - .fetch_optional(&**pool) - .await - ?; - - if let Some(row) = result { - if !user.role.is_admin() { - let team_member = - database::models::TeamMember::get_from_user_id_version( - database::models::ids::VersionId(row.version_id), - user.id.into(), - &**pool, - ) - .await - .map_err(ApiError::Database)? - .ok_or_else(|| { - ApiError::CustomAuthentication( - "You don't have permission to delete this file!" - .to_string(), - ) - })?; - - if !team_member - .permissions - .contains(Permissions::DELETE_VERSION) - { - return Err(ApiError::CustomAuthentication( - "You don't have permission to delete this file!" - .to_string(), - )); - } - } - - let mut transaction = pool.begin().await?; - - sqlx::query!( - " - DELETE FROM hashes - WHERE file_id = $1 - ", - row.id - ) - .execute(&mut *transaction) - .await?; - - sqlx::query!( - " - DELETE FROM files - WHERE files.id = $1 - ", - row.id, - ) - .execute(&mut *transaction) - .await?; - - transaction.commit().await?; - - Ok(HttpResponse::NoContent().body("")) - } else { - Ok(HttpResponse::NotFound().body("")) - } -} diff --git a/src/routes/version_file.rs b/src/routes/version_file.rs index ce0cee01..d86bd746 100644 --- a/src/routes/version_file.rs +++ b/src/routes/version_file.rs @@ -14,7 +14,7 @@ use tokio::sync::RwLock; #[derive(Deserialize)] pub struct Algorithm { #[serde(default = "default_algorithm")] - algorithm: String, + pub algorithm: String, } fn default_algorithm() -> String {