Add swagger docs + icon marketplace get icons endpoint
This commit is contained in:
57
bun.lock
57
bun.lock
@@ -5,33 +5,44 @@
|
||||
"": {
|
||||
"name": "lncvrt-games-api",
|
||||
"dependencies": {
|
||||
"@elysiajs/cors": "1.4.0",
|
||||
"@elysiajs/cors": "1.4.1",
|
||||
"@elysiajs/swagger": "1.3.1",
|
||||
"dotenv": "17.2.3",
|
||||
"drizzle-orm": "0.45.1",
|
||||
"elysia": "1.4.19",
|
||||
"mysql2": "3.16.0",
|
||||
"elysia": "1.4.22",
|
||||
"mysql2": "3.16.1",
|
||||
},
|
||||
"devDependencies": {
|
||||
"bun-types": "1.3.5",
|
||||
"bun-types": "1.3.6",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@borewit/text-codec": ["@borewit/text-codec@0.1.1", "", {}, "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA=="],
|
||||
"@borewit/text-codec": ["@borewit/text-codec@0.2.1", "", {}, "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw=="],
|
||||
|
||||
"@elysiajs/cors": ["@elysiajs/cors@1.4.0", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-pb0SCzBfFbFSYA/U40HHO7R+YrcXBJXOWgL20eSViK33ol1e20ru2/KUaZYo5IMUn63yaTJI/bQERuQ+77ND8g=="],
|
||||
"@elysiajs/cors": ["@elysiajs/cors@1.4.1", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-lQfad+F3r4mNwsxRKbXyJB8Jg43oAOXjRwn7sKUL6bcOW3KjUqUimTS+woNpO97efpzjtDE0tEjGk9DTw8lqTQ=="],
|
||||
|
||||
"@sinclair/typebox": ["@sinclair/typebox@0.34.41", "", {}, "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g=="],
|
||||
"@elysiajs/swagger": ["@elysiajs/swagger@1.3.1", "", { "dependencies": { "@scalar/themes": "^0.9.52", "@scalar/types": "^0.0.12", "openapi-types": "^12.1.3", "pathe": "^1.1.2" }, "peerDependencies": { "elysia": ">= 1.3.0" } }, "sha512-LcbLHa0zE6FJKWPWKsIC/f+62wbDv3aXydqcNPVPyqNcaUgwvCajIi+5kHEU6GO3oXUCpzKaMsb3gsjt8sLzFQ=="],
|
||||
|
||||
"@scalar/openapi-types": ["@scalar/openapi-types@0.1.1", "", {}, "sha512-NMy3QNk6ytcCoPUGJH0t4NNr36OWXgZhA3ormr3TvhX1NDgoF95wFyodGVH8xiHeUyn2/FxtETm8UBLbB5xEmg=="],
|
||||
|
||||
"@scalar/themes": ["@scalar/themes@0.9.86", "", { "dependencies": { "@scalar/types": "0.1.7" } }, "sha512-QUHo9g5oSWi+0Lm1vJY9TaMZRau8LHg+vte7q5BVTBnu6NuQfigCaN+ouQ73FqIVd96TwMO6Db+dilK1B+9row=="],
|
||||
|
||||
"@scalar/types": ["@scalar/types@0.0.12", "", { "dependencies": { "@scalar/openapi-types": "0.1.1", "@unhead/schema": "^1.9.5" } }, "sha512-XYZ36lSEx87i4gDqopQlGCOkdIITHHEvgkuJFrXFATQs9zHARop0PN0g4RZYWj+ZpCUclOcaOjbCt8JGe22mnQ=="],
|
||||
|
||||
"@sinclair/typebox": ["@sinclair/typebox@0.34.47", "", {}, "sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw=="],
|
||||
|
||||
"@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
|
||||
|
||||
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
||||
|
||||
"@types/node": ["@types/node@25.0.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA=="],
|
||||
"@types/node": ["@types/node@25.0.9", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw=="],
|
||||
|
||||
"@unhead/schema": ["@unhead/schema@1.11.20", "", { "dependencies": { "hookable": "^5.5.3", "zhead": "^2.2.4" } }, "sha512-0zWykKAaJdm+/Y7yi/Yds20PrUK7XabLe9c3IRcjnwYmSWY6z0Cr19VIs3ozCj8P+GhR+/TI2mwtGlueCEYouA=="],
|
||||
|
||||
"aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="],
|
||||
|
||||
"bun-types": ["bun-types@1.3.5", "", { "dependencies": { "@types/node": "*" } }, "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw=="],
|
||||
"bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
|
||||
|
||||
"cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
|
||||
|
||||
@@ -43,17 +54,19 @@
|
||||
|
||||
"drizzle-orm": ["drizzle-orm@0.45.1", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-Te0FOdKIistGNPMq2jscdqngBRfBpC8uMFVwqjf6gtTVJHIQ/dosgV/CLBU2N4ZJBsXL5savCba9b0YJskKdcA=="],
|
||||
|
||||
"elysia": ["elysia@1.4.19", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "0.2.5", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-DZb9y8FnWyX5IuqY44SvqAV0DjJ15NeCWHrLdgXrKgTPDPsl3VNwWHqrEr9bmnOCpg1vh6QUvAX/tcxNj88jLA=="],
|
||||
"elysia": ["elysia@1.4.22", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "^0.2.6", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-Q90VCb1RVFxnFaRV0FDoSylESQQLWgLHFmWciQJdX9h3b2cSasji9KWEUvaJuy/L9ciAGg4RAhUVfsXHg5K2RQ=="],
|
||||
|
||||
"exact-mirror": ["exact-mirror@0.2.5", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-u8Wu2lO8nio5lKSJubOydsdNtQmH8ENba5m0nbQYmTvsjksXKYIS1nSShdDlO8Uem+kbo+N6eD5I03cpZ+QsRQ=="],
|
||||
"exact-mirror": ["exact-mirror@0.2.6", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-7s059UIx9/tnOKSySzUk5cPGkoILhTE4p6ncf6uIPaQ+9aRBQzQjc9+q85l51+oZ+P6aBxh084pD0CzBQPcFUA=="],
|
||||
|
||||
"fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
|
||||
|
||||
"file-type": ["file-type@21.1.1", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-ifJXo8zUqbQ/bLbl9sFoqHNTNWbnPY1COImFfM6CCy7z+E+jC1eY9YfOKkx0fckIg+VljAy2/87T61fp0+eEkg=="],
|
||||
"file-type": ["file-type@21.3.0", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA=="],
|
||||
|
||||
"generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "^1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.7.1", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw=="],
|
||||
"hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
|
||||
|
||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||
|
||||
@@ -67,12 +80,16 @@
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"mysql2": ["mysql2@3.16.0", "", { "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.7.0", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" } }, "sha512-AEGW7QLLSuSnjCS4pk3EIqOmogegmze9h8EyrndavUQnIUcfkVal/sK7QznE+a3bc6rzPbAiui9Jcb+96tPwYA=="],
|
||||
"mysql2": ["mysql2@3.16.1", "", { "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.7.0", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.6", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" } }, "sha512-b75qsDB3ieYEzMsT1uRGsztM/sy6vWPY40uPZlVVl8eefAotFCoS7jaDB5DxDNtlW5kdVGd9jptSpkvujNxI2A=="],
|
||||
|
||||
"named-placeholders": ["named-placeholders@1.1.6", "", { "dependencies": { "lru.min": "^1.1.0" } }, "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w=="],
|
||||
|
||||
"nanoid": ["nanoid@5.1.6", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg=="],
|
||||
|
||||
"openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
|
||||
|
||||
"pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
|
||||
|
||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||
|
||||
"seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="],
|
||||
@@ -81,10 +98,20 @@
|
||||
|
||||
"strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
|
||||
|
||||
"token-types": ["token-types@6.1.1", "", { "dependencies": { "@borewit/text-codec": "^0.1.0", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ=="],
|
||||
"token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
|
||||
|
||||
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
|
||||
|
||||
"uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
|
||||
|
||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||
|
||||
"zhead": ["zhead@2.2.4", "", {}, "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag=="],
|
||||
|
||||
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
"@scalar/themes/@scalar/types": ["@scalar/types@0.1.7", "", { "dependencies": { "@scalar/openapi-types": "0.2.0", "@unhead/schema": "^1.11.11", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "zod": "^3.23.8" } }, "sha512-irIDYzTQG2KLvFbuTI8k2Pz/R4JR+zUUSykVTbEMatkzMmVFnn1VzNSMlODbadycwZunbnL2tA27AXed9URVjw=="],
|
||||
|
||||
"@scalar/themes/@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.2.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-waiKk12cRCqyUCWTOX0K1WEVX46+hVUK+zRPzAahDJ7G0TApvbNkuy5wx7aoUyEk++HHde0XuQnshXnt8jsddA=="],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
"dev": "bun run --watch src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@elysiajs/cors": "1.4.0",
|
||||
"@elysiajs/cors": "1.4.1",
|
||||
"@elysiajs/swagger": "1.3.1",
|
||||
"dotenv": "17.2.3",
|
||||
"drizzle-orm": "0.45.1",
|
||||
"elysia": "1.4.19",
|
||||
"mysql2": "3.16.0"
|
||||
"elysia": "1.4.22",
|
||||
"mysql2": "3.16.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bun-types": "1.3.5"
|
||||
"bun-types": "1.3.6"
|
||||
},
|
||||
"module": "src/index.js"
|
||||
}
|
||||
|
||||
249
src/index.ts
249
src/index.ts
@@ -1,63 +1,250 @@
|
||||
import { Elysia } from 'elysia'
|
||||
import { Elysia, t } from 'elysia'
|
||||
import { cors } from '@elysiajs/cors'
|
||||
import { jsonResponse } from './lib/util'
|
||||
import dotenv from 'dotenv'
|
||||
import swagger from '@elysiajs/swagger'
|
||||
|
||||
import { handler as canLoadClientHandler } from './routes/can-load-client'
|
||||
|
||||
import { handler as launcherVersionsHandler } from './routes/launcher/versions'
|
||||
import { handler as launcherLatestHandler } from './routes/launcher/latest'
|
||||
import { handler as launcherLoaderLatestHandler } from './routes/launcher/loader/latest'
|
||||
import { handler as launcherLoaderUpdateDataHandler } from './routes/launcher/loader/update-data'
|
||||
|
||||
import { handler as berrydashLeaderboardsGetHandler } from './routes/berrydash/leaderboards/get'
|
||||
|
||||
import { handler as berrydashProfileGetHandler } from './routes/berrydash/profile/get'
|
||||
import { handler as berrydashProfilePostsDeleteHandler } from './routes/berrydash/profile/posts/delete'
|
||||
import { handler as berrydashProfilePostsGetHandler } from './routes/berrydash/profile/posts/get'
|
||||
import { handler as berrydashProfilePostsPostHandler } from './routes/berrydash/profile/posts/post'
|
||||
import { handler as berrydashProfilePostsPutHandler } from './routes/berrydash/profile/posts/put'
|
||||
|
||||
import { handler as berryDashIconMarketplacePostHandler } from './routes/berrydash/icon-marketplace/post'
|
||||
|
||||
dotenv.config()
|
||||
|
||||
const app = new Elysia().use(
|
||||
cors({
|
||||
origin: '*',
|
||||
methods: ['POST', 'GET']
|
||||
})
|
||||
)
|
||||
const intNotStr = (name: string) => {
|
||||
return (
|
||||
'\n\n**The type for parameter `' +
|
||||
name +
|
||||
'` is actually a `number`, but it shows as a `string` here.**'
|
||||
)
|
||||
}
|
||||
|
||||
const boolNotStr = (name: string) => {
|
||||
return (
|
||||
'\n\n**The type for parameter `' +
|
||||
name +
|
||||
'` is actually a `boolean`, but it shows as a `string` here.**'
|
||||
)
|
||||
}
|
||||
|
||||
const app = new Elysia()
|
||||
.use(
|
||||
cors({
|
||||
origin: '*',
|
||||
methods: ['POST', 'GET']
|
||||
})
|
||||
)
|
||||
.use(
|
||||
swagger({
|
||||
path: '/docs',
|
||||
documentation: {
|
||||
info: {
|
||||
title: 'Lncvrt Games API',
|
||||
description:
|
||||
'This is the official documentation for the Lncvrt Games API!',
|
||||
version: '1.0.0'
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
app.get('/can-load-client', context => canLoadClientHandler(context))
|
||||
app.get('/launcher/versions', context => launcherVersionsHandler(context))
|
||||
app.get('/launcher/latest', launcherLatestHandler)
|
||||
app.get('/launcher/loader/latest', launcherLoaderLatestHandler)
|
||||
app.get('/launcher/loader/update-data', context =>
|
||||
launcherLoaderUpdateDataHandler(context)
|
||||
app.get('/launcher/versions', context => launcherVersionsHandler(context), {
|
||||
detail: {
|
||||
description:
|
||||
'The endpoint for getting the launcher manifest.\n\nNote: if going to use the params, both must be provided at the same time.',
|
||||
tags: ['Launcher']
|
||||
},
|
||||
params: t.Object({
|
||||
platform: t.Optional(t.String()),
|
||||
arch: t.Optional(t.String())
|
||||
})
|
||||
})
|
||||
app.get('/launcher/latest', launcherLatestHandler, {
|
||||
detail: {
|
||||
description: 'The endpoint for getting the latest launcher version.',
|
||||
tags: ['Launcher']
|
||||
}
|
||||
})
|
||||
app.get('/launcher/loader/latest', launcherLoaderLatestHandler, {
|
||||
detail: {
|
||||
description:
|
||||
'The endpoint for getting the latest loader/auto updater version.',
|
||||
tags: ['Launcher']
|
||||
}
|
||||
})
|
||||
app.get(
|
||||
'/launcher/loader/update-data',
|
||||
context => launcherLoaderUpdateDataHandler(context),
|
||||
{
|
||||
detail: {
|
||||
description:
|
||||
'The endpoint for getting Launcher Update data for when a new Update is released. It will be send & read by the updater.\n\nNote: if going to use the params, both must be provided at the same time.',
|
||||
tags: ['Launcher']
|
||||
},
|
||||
params: t.Object({
|
||||
platform: t.Optional(t.String()),
|
||||
arch: t.Optional(t.String())
|
||||
})
|
||||
}
|
||||
)
|
||||
app.get('/berrydash/leaderboards/score', context =>
|
||||
berrydashLeaderboardsGetHandler(context, 0)
|
||||
app.get(
|
||||
'/berrydash/leaderboards/score',
|
||||
context => berrydashLeaderboardsGetHandler(context, 0),
|
||||
{
|
||||
detail: {
|
||||
description: 'The endpoint for getting the score leaderboards.',
|
||||
tags: ['Berry Dash', 'Leaderboards']
|
||||
}
|
||||
}
|
||||
)
|
||||
app.get('/berrydash/leaderboards/berry', context =>
|
||||
berrydashLeaderboardsGetHandler(context, 1)
|
||||
app.get(
|
||||
'/berrydash/leaderboards/berry',
|
||||
context => berrydashLeaderboardsGetHandler(context, 1),
|
||||
{
|
||||
detail: {
|
||||
description:
|
||||
'The endpoint for getting the berry leaderboards.' + intNotStr('berry'),
|
||||
tags: ['Berry Dash', 'Leaderboards']
|
||||
},
|
||||
params: t.Object({
|
||||
berry: t.String()
|
||||
})
|
||||
}
|
||||
)
|
||||
app.get('/berrydash/leaderboards/coin', context =>
|
||||
berrydashLeaderboardsGetHandler(context, 2)
|
||||
app.get(
|
||||
'/berrydash/leaderboards/coin',
|
||||
context => berrydashLeaderboardsGetHandler(context, 2),
|
||||
{
|
||||
detail: {
|
||||
description: 'The endpoint for getting the coin leaderboards.',
|
||||
tags: ['Berry Dash', 'Leaderboards']
|
||||
}
|
||||
}
|
||||
)
|
||||
app.get('/berrydash/leaderboards/legacy', context =>
|
||||
berrydashLeaderboardsGetHandler(context, 3)
|
||||
app.get(
|
||||
'/berrydash/leaderboards/legacy',
|
||||
context => berrydashLeaderboardsGetHandler(context, 3),
|
||||
{
|
||||
detail: {
|
||||
description: 'The endpoint for getting the legacy leaderboards.',
|
||||
tags: ['Berry Dash', 'Leaderboards']
|
||||
}
|
||||
}
|
||||
)
|
||||
app.get('/berrydash/leaderboards/total', context =>
|
||||
berrydashLeaderboardsGetHandler(context, 4)
|
||||
app.get(
|
||||
'/berrydash/leaderboards/total',
|
||||
context => berrydashLeaderboardsGetHandler(context, 4),
|
||||
{
|
||||
detail: {
|
||||
description: 'The endpoint for getting the total leaderboards.',
|
||||
tags: ['Berry Dash', 'Leaderboards']
|
||||
}
|
||||
}
|
||||
)
|
||||
app.get('/berrydash/profile', context => berrydashProfileGetHandler(context))
|
||||
app.delete('/berrydash/profile/posts', context =>
|
||||
berrydashProfilePostsDeleteHandler(context)
|
||||
app.get('/berrydash/profile', context => berrydashProfileGetHandler(context), {
|
||||
detail: {
|
||||
description:
|
||||
"The endpoint for getting a user's profile." + intNotStr('userId'),
|
||||
tags: ['Berry Dash', 'Profiles']
|
||||
},
|
||||
params: t.Object({
|
||||
userId: t.String()
|
||||
})
|
||||
})
|
||||
app.delete(
|
||||
'/berrydash/profile/posts',
|
||||
context => berrydashProfilePostsDeleteHandler(context),
|
||||
{
|
||||
detail: {
|
||||
description: 'This endpoint is for deleting a post.' + intNotStr('id'),
|
||||
tags: ['Berry Dash', 'Profiles']
|
||||
},
|
||||
headers: t.Object({
|
||||
authorization: t.String()
|
||||
}),
|
||||
params: t.Object({
|
||||
id: t.String()
|
||||
})
|
||||
}
|
||||
)
|
||||
app.get('/berrydash/profile/posts', context =>
|
||||
berrydashProfilePostsGetHandler(context)
|
||||
app.get(
|
||||
'/berrydash/profile/posts',
|
||||
context => berrydashProfilePostsGetHandler(context),
|
||||
{
|
||||
detail: {
|
||||
description:
|
||||
'This endpoint is for getting posts from a user.' + intNotStr('userId'),
|
||||
tags: ['Berry Dash', 'Profiles']
|
||||
},
|
||||
params: t.Object({
|
||||
userId: t.String()
|
||||
})
|
||||
}
|
||||
)
|
||||
app.post('/berrydash/profile/posts', context =>
|
||||
berrydashProfilePostsPostHandler(context)
|
||||
app.post(
|
||||
'/berrydash/profile/posts',
|
||||
context => berrydashProfilePostsPostHandler(context),
|
||||
{
|
||||
detail: {
|
||||
description: 'This endpoint is for uploading a new post.',
|
||||
tags: ['Berry Dash', 'Profiles']
|
||||
},
|
||||
body: t.Object({
|
||||
content: t.String()
|
||||
})
|
||||
}
|
||||
)
|
||||
app.put('/berrydash/profile/posts', context =>
|
||||
berrydashProfilePostsPutHandler(context)
|
||||
app.put(
|
||||
'/berrydash/profile/posts',
|
||||
context => berrydashProfilePostsPutHandler(context),
|
||||
{
|
||||
detail: {
|
||||
description:
|
||||
'This endpoint is for liking/disliking a post.' +
|
||||
intNotStr('id') +
|
||||
boolNotStr('likedQuery'),
|
||||
tags: ['Berry Dash', 'Profiles']
|
||||
},
|
||||
params: t.Object({
|
||||
id: t.String(),
|
||||
likedQuery: t.String()
|
||||
})
|
||||
}
|
||||
)
|
||||
app.post(
|
||||
'/berrydash/icon-marketplace',
|
||||
context => berryDashIconMarketplacePostHandler(context),
|
||||
{
|
||||
detail: {
|
||||
description:
|
||||
'The endpoint for getting the icon marketplace icons.\n\nPretty much none of the body types are correct.',
|
||||
tags: ['Berry Dash', 'Icon Marketplace']
|
||||
},
|
||||
body: t.Object({
|
||||
sortBy: t.String(),
|
||||
priceRangeEnabled: t.String(),
|
||||
priceRangeMin: t.String(),
|
||||
priceRangeMax: t.String(),
|
||||
searchForEnabled: t.String(),
|
||||
searchForValue: t.String(),
|
||||
onlyShowEnabled: t.String(),
|
||||
onlyShowValue: t.String(),
|
||||
currentIcons: t.String()
|
||||
})
|
||||
}
|
||||
)
|
||||
app.all('*', () =>
|
||||
jsonResponse(
|
||||
|
||||
178
src/routes/berrydash/icon-marketplace/post.ts
Normal file
178
src/routes/berrydash/icon-marketplace/post.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
import { Context } from 'elysia'
|
||||
import { getDatabaseConnection, jsonResponse } from '../../../lib/util'
|
||||
import {
|
||||
berryDashMarketplaceIcons,
|
||||
berryDashUserData,
|
||||
users
|
||||
} from '../../../lib/tables'
|
||||
import { and, eq, inArray, or, sql, not, like } from 'drizzle-orm'
|
||||
|
||||
type Body = {
|
||||
sortBy: number
|
||||
priceRangeEnabled: boolean
|
||||
priceRangeMin: number
|
||||
priceRangeMax: number
|
||||
searchForEnabled: boolean
|
||||
searchForValue: string
|
||||
onlyShowEnabled: boolean
|
||||
onlyShowValue: number
|
||||
currentIcons: string[]
|
||||
}
|
||||
|
||||
const requiredKeys = [
|
||||
'sortBy',
|
||||
'priceRangeEnabled',
|
||||
'priceRangeMin',
|
||||
'priceRangeMax',
|
||||
'searchForEnabled',
|
||||
'searchForValue',
|
||||
'onlyShowEnabled',
|
||||
'onlyShowValue',
|
||||
'currentIcons'
|
||||
]
|
||||
|
||||
export async function handler (context: Context) {
|
||||
const dbInfo0 = getDatabaseConnection(0)
|
||||
const dbInfo1 = getDatabaseConnection(1)
|
||||
|
||||
if (!dbInfo0 || !dbInfo1)
|
||||
return jsonResponse(
|
||||
{ success: false, message: 'Failed to connect to database', data: null },
|
||||
500
|
||||
)
|
||||
|
||||
const { connection: connection0, db: db0 } = dbInfo0
|
||||
const { connection: connection1, db: db1 } = dbInfo1
|
||||
|
||||
const body: { [key: string]: any } = context.body as any
|
||||
|
||||
for (const key of requiredKeys) {
|
||||
if (!(key in body)) {
|
||||
return jsonResponse(
|
||||
{ success: false, message: 'Invalid POST data', data: null },
|
||||
400
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
let body2: { [key: string]: any } = {}
|
||||
body2.sortBy = Number(body.sortBy)
|
||||
body2.priceRangeEnabled = body.priceRangeEnabled.toLowerCase() === 'true'
|
||||
body2.priceRangeMin = Number(body.priceRangeMin)
|
||||
body2.priceRangeMax = Number(body.priceRangeMax)
|
||||
body2.searchForEnabled = body.searchForEnabled.toLowerCase() === 'true'
|
||||
body2.searchForValue = body.searchForValue as string
|
||||
body2.onlyShowEnabled = body.onlyShowEnabled.toLowerCase() === 'true'
|
||||
body2.onlyShowValue = Number(body.onlyShowValue)
|
||||
body2.currentIcons = JSON.parse(atob(body.currentIcons))
|
||||
const body3: Body = body2 as Body
|
||||
|
||||
const authorizationToken = context.headers.authorization
|
||||
if (!authorizationToken) {
|
||||
connection0.end()
|
||||
connection1.end()
|
||||
return jsonResponse(
|
||||
{ success: false, message: 'Unauthorized', data: null },
|
||||
401
|
||||
)
|
||||
}
|
||||
|
||||
const userData = await db1
|
||||
.select({ id: berryDashUserData.id })
|
||||
.from(berryDashUserData)
|
||||
.where(eq(berryDashUserData.token, authorizationToken))
|
||||
.execute()
|
||||
|
||||
if (!userData[0]) {
|
||||
connection0.end()
|
||||
connection1.end()
|
||||
return jsonResponse(
|
||||
{ success: false, message: 'Unauthorized', data: null },
|
||||
401
|
||||
)
|
||||
}
|
||||
|
||||
const userId = userData[0].id
|
||||
|
||||
const filters: any[] = [
|
||||
or(
|
||||
eq(berryDashMarketplaceIcons.state, 1),
|
||||
eq(berryDashMarketplaceIcons.state, 2)
|
||||
)
|
||||
]
|
||||
|
||||
if (body3.priceRangeEnabled) {
|
||||
filters.push(
|
||||
sql`${berryDashMarketplaceIcons.price} >= ${body3.priceRangeMin}`,
|
||||
sql`${berryDashMarketplaceIcons.price} <= ${body3.priceRangeMax}`
|
||||
)
|
||||
}
|
||||
|
||||
if (body3.searchForEnabled) {
|
||||
filters.push(
|
||||
sql`FROM_BASE64(${
|
||||
berryDashMarketplaceIcons.name
|
||||
}) LIKE ${`%${body3.searchForValue}%`}`
|
||||
)
|
||||
}
|
||||
|
||||
if (body3.onlyShowEnabled) {
|
||||
if (body3.onlyShowValue === 0) {
|
||||
filters.push(eq(berryDashMarketplaceIcons.userId, userId))
|
||||
} else if (body3.onlyShowValue === 1) {
|
||||
filters.push(sql`${berryDashMarketplaceIcons.userId} != ${userId}`)
|
||||
} else if (body3.onlyShowValue === 2) {
|
||||
filters.push(inArray(berryDashMarketplaceIcons.uuid, body3.currentIcons))
|
||||
} else if (body3.onlyShowValue === 3) {
|
||||
filters.push(
|
||||
not(inArray(berryDashMarketplaceIcons.uuid, body3.currentIcons))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
let orderBy: any
|
||||
switch (body3.sortBy) {
|
||||
case 1:
|
||||
orderBy = sql`price ASC`
|
||||
break
|
||||
case 2:
|
||||
orderBy = sql`id ASC`
|
||||
break
|
||||
case 3:
|
||||
orderBy = sql`id DESC`
|
||||
break
|
||||
default:
|
||||
orderBy = sql`price DESC`
|
||||
break
|
||||
}
|
||||
|
||||
const icons = await db1
|
||||
.select()
|
||||
.from(berryDashMarketplaceIcons)
|
||||
.where(and(...filters))
|
||||
.orderBy(orderBy)
|
||||
.execute()
|
||||
|
||||
const userIds = Array.from(new Set(icons.map(i => i.userId)))
|
||||
const usersData = await db0
|
||||
.select({ id: users.id, username: users.username })
|
||||
.from(users)
|
||||
.where(inArray(users.id, userIds))
|
||||
.execute()
|
||||
|
||||
const usersMap = Object.fromEntries(usersData.map(u => [u.id, u.username]))
|
||||
|
||||
const result = icons.map(i => ({
|
||||
username: usersMap[i.userId] ?? 'Unknown',
|
||||
userid: i.userId,
|
||||
data: i.data,
|
||||
uuid: i.uuid,
|
||||
price: i.state === 2 ? 100000000 : i.price,
|
||||
name: atob(i.name)
|
||||
}))
|
||||
|
||||
connection0.end()
|
||||
connection1.end()
|
||||
|
||||
return jsonResponse({ success: true, message: null, data: result })
|
||||
}
|
||||
Reference in New Issue
Block a user