2025-02-14 20:01:18 +11:00
|
|
|
import tailwindcss from "@tailwindcss/vite";
|
2025-05-29 13:27:38 -04:00
|
|
|
import { execSync } from "node:child_process";
|
2026-01-13 22:49:58 -05:00
|
|
|
import { readFileSync, existsSync } from "node:fs";
|
2025-06-07 23:49:43 -04:00
|
|
|
import path from "node:path";
|
2026-01-19 17:50:04 -05:00
|
|
|
import module from "node:module";
|
|
|
|
|
import { fileURLToPath } from "node:url";
|
2025-07-08 22:01:23 -04:00
|
|
|
import { type } from "arktype";
|
2024-10-25 13:15:46 +11:00
|
|
|
|
2025-07-08 22:01:23 -04:00
|
|
|
const packageJsonSchema = type({
|
|
|
|
|
name: "string",
|
|
|
|
|
version: "string",
|
|
|
|
|
});
|
2025-05-10 15:16:26 -04:00
|
|
|
|
2026-02-09 11:27:31 -05:00
|
|
|
const twemojiPackage = module.findPackageJSON(
|
2026-01-13 22:49:58 -05:00
|
|
|
"@discordapp/twemoji",
|
|
|
|
|
import.meta.url,
|
|
|
|
|
);
|
2026-02-09 11:27:31 -05:00
|
|
|
if (!twemojiPackage) {
|
2026-01-13 22:49:58 -05:00
|
|
|
throw new Error("Could not find @discordapp/twemoji package.");
|
|
|
|
|
}
|
2026-02-09 11:27:31 -05:00
|
|
|
const twemojiAssetsPath = path.join(
|
|
|
|
|
path.dirname(twemojiPackage),
|
|
|
|
|
"dist",
|
|
|
|
|
"svg",
|
|
|
|
|
);
|
2026-01-13 22:49:58 -05:00
|
|
|
|
2025-07-08 22:01:23 -04:00
|
|
|
// get drop version
|
|
|
|
|
const dropVersion = getDropVersion();
|
|
|
|
|
|
|
|
|
|
// get git ref or supply during build
|
|
|
|
|
const commitHash =
|
|
|
|
|
process.env.BUILD_GIT_REF ??
|
|
|
|
|
execSync("git rev-parse --short HEAD").toString().trim();
|
|
|
|
|
|
|
|
|
|
console.log(`Drop ${dropVersion} #${commitHash}`);
|
|
|
|
|
|
2024-09-28 19:12:11 +10:00
|
|
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
|
|
|
|
export default defineNuxtConfig({
|
2026-03-30 19:38:14 +11:00
|
|
|
extends: ["../libraries/base"],
|
2025-05-10 16:18:28 -04:00
|
|
|
// Module config from here down
|
2025-06-07 17:21:07 +10:00
|
|
|
|
2025-05-10 16:18:28 -04:00
|
|
|
modules: [
|
|
|
|
|
"vue3-carousel-nuxt",
|
2025-07-30 13:40:49 +10:00
|
|
|
"nuxt-security", // "@nuxt/image",
|
2025-05-10 16:18:28 -04:00
|
|
|
"@nuxt/fonts",
|
|
|
|
|
"@nuxt/eslint",
|
2025-06-04 19:53:30 -04:00
|
|
|
"@nuxtjs/i18n",
|
2025-07-30 13:40:49 +10:00
|
|
|
"@vueuse/nuxt",
|
2025-05-10 16:18:28 -04:00
|
|
|
],
|
|
|
|
|
|
2024-10-25 13:15:46 +11:00
|
|
|
// Nuxt-only config
|
2024-11-04 22:15:11 +11:00
|
|
|
telemetry: false,
|
2024-10-08 13:17:30 +11:00
|
|
|
compatibilityDate: "2024-04-03",
|
2025-04-07 19:57:00 -04:00
|
|
|
devtools: {
|
|
|
|
|
enabled: true,
|
|
|
|
|
telemetry: false,
|
|
|
|
|
timeline: {
|
2025-05-07 21:45:13 -04:00
|
|
|
// this seems to be the tracking issue, composables not registered
|
|
|
|
|
// https://github.com/nuxt/devtools/issues/662
|
2025-04-07 19:57:00 -04:00
|
|
|
enabled: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
2025-02-14 20:01:18 +11:00
|
|
|
css: ["~/assets/tailwindcss.css", "~/assets/core.scss"],
|
2024-10-25 13:15:46 +11:00
|
|
|
|
2025-06-07 23:49:43 -04:00
|
|
|
sourcemap: {
|
|
|
|
|
server: true,
|
|
|
|
|
client: true,
|
|
|
|
|
},
|
|
|
|
|
|
2025-03-14 20:18:26 -04:00
|
|
|
experimental: {
|
|
|
|
|
buildCache: true,
|
2026-01-15 15:34:17 +11:00
|
|
|
viewTransition: false,
|
2026-01-23 05:04:38 +00:00
|
|
|
appManifest: false,
|
2025-06-04 19:53:30 -04:00
|
|
|
componentIslands: true,
|
2025-03-14 20:18:26 -04:00
|
|
|
},
|
|
|
|
|
|
2025-05-10 16:18:28 -04:00
|
|
|
// future: {
|
|
|
|
|
// compatibilityVersion: 4,
|
|
|
|
|
// },
|
|
|
|
|
|
2025-02-14 20:01:18 +11:00
|
|
|
vite: {
|
2025-06-07 23:49:43 -04:00
|
|
|
plugins: [
|
2025-08-31 14:50:56 +10:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
|
tailwindcss() as any,
|
2025-06-07 23:49:43 -04:00
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
|
2025-05-29 13:27:38 -04:00
|
|
|
runtimeConfig: {
|
|
|
|
|
gitRef: commitHash,
|
|
|
|
|
dropVersion: dropVersion,
|
|
|
|
|
},
|
|
|
|
|
|
2024-10-04 15:35:03 +10:00
|
|
|
app: {
|
|
|
|
|
head: {
|
2024-10-08 13:17:30 +11:00
|
|
|
link: [{ rel: "icon", href: "/favicon.ico" }],
|
|
|
|
|
},
|
|
|
|
|
},
|
2024-10-10 16:13:10 +11:00
|
|
|
|
2025-03-14 20:18:26 -04:00
|
|
|
routeRules: {
|
|
|
|
|
"/api/**": { cors: true },
|
2026-01-19 17:50:04 -05:00
|
|
|
|
|
|
|
|
// redirect old OIDC callback route
|
|
|
|
|
"/auth/callback/oidc": {
|
2026-02-09 11:27:31 -05:00
|
|
|
redirect: "/api/v1/auth/oidc/callback",
|
2026-01-19 17:50:04 -05:00
|
|
|
},
|
2025-03-14 20:18:26 -04:00
|
|
|
},
|
|
|
|
|
|
2026-02-09 11:27:31 -05:00
|
|
|
devServer: {
|
|
|
|
|
port: 4000,
|
|
|
|
|
},
|
|
|
|
|
|
2024-10-10 16:13:10 +11:00
|
|
|
nitro: {
|
2025-03-14 20:18:26 -04:00
|
|
|
minify: true,
|
2025-05-10 15:16:26 -04:00
|
|
|
compressPublicAssets: true,
|
2025-03-14 20:18:26 -04:00
|
|
|
|
2024-10-10 16:13:10 +11:00
|
|
|
experimental: {
|
|
|
|
|
websocket: true,
|
2024-11-07 23:23:49 +11:00
|
|
|
tasks: true,
|
2025-05-10 15:16:26 -04:00
|
|
|
openAPI: true,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
openAPI: {
|
|
|
|
|
// tracking for dynamic openapi schema https://github.com/nitrojs/nitro/issues/2974
|
2025-05-30 13:17:21 +10:00
|
|
|
// create body from types: https://github.com/nitrojs/nitro/issues/3275
|
2025-05-10 15:16:26 -04:00
|
|
|
meta: {
|
|
|
|
|
title: "Drop",
|
|
|
|
|
description:
|
|
|
|
|
"Drop is an open-source, self-hosted game distribution platform, creating a Steam-like experience for DRM-free games.",
|
|
|
|
|
version: dropVersion,
|
|
|
|
|
},
|
2024-11-07 23:23:49 +11:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
scheduledTasks: {
|
2025-06-04 19:53:30 -04:00
|
|
|
"0 * * * *": ["dailyTasks"],
|
2024-10-10 16:13:10 +11:00
|
|
|
},
|
2025-03-14 20:18:26 -04:00
|
|
|
|
2025-05-07 22:13:22 -04:00
|
|
|
storage: {
|
|
|
|
|
appCache: {
|
|
|
|
|
driver: "lru-cache",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
devStorage: {
|
|
|
|
|
appCache: {
|
|
|
|
|
// store cache on fs to handle dev server restarts
|
|
|
|
|
driver: "fs",
|
|
|
|
|
base: "./.data/appCache",
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-01-13 22:49:58 -05:00
|
|
|
|
|
|
|
|
serverAssets: [
|
|
|
|
|
{
|
|
|
|
|
baseName: "twemoji",
|
|
|
|
|
// get path to twemoji svg assets
|
2026-02-09 11:27:31 -05:00
|
|
|
dir: twemojiAssetsPath,
|
2026-01-13 22:49:58 -05:00
|
|
|
},
|
|
|
|
|
],
|
2024-10-10 16:13:10 +11:00
|
|
|
},
|
2024-10-25 13:15:46 +11:00
|
|
|
|
2025-04-05 09:40:05 +11:00
|
|
|
typescript: {
|
2025-04-04 18:52:34 -04:00
|
|
|
typeCheck: true,
|
|
|
|
|
|
2025-04-05 09:40:05 +11:00
|
|
|
tsConfig: {
|
|
|
|
|
compilerOptions: {
|
|
|
|
|
verbatimModuleSyntax: false,
|
2025-04-07 19:55:33 -04:00
|
|
|
strictNullChecks: true,
|
|
|
|
|
exactOptionalPropertyTypes: true,
|
2025-04-05 09:40:05 +11:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
2024-10-27 15:21:31 +11:00
|
|
|
carousel: {
|
|
|
|
|
prefix: "Vue",
|
|
|
|
|
},
|
2024-10-25 13:15:46 +11:00
|
|
|
|
2025-06-04 19:53:30 -04:00
|
|
|
i18n: {
|
2025-11-20 03:02:56 +00:00
|
|
|
bundle: {
|
|
|
|
|
optimizeTranslationDirective: false,
|
|
|
|
|
},
|
2025-06-04 19:53:30 -04:00
|
|
|
defaultLocale: "en-us",
|
2026-02-09 11:27:31 -05:00
|
|
|
lazy: true,
|
2025-06-04 19:53:30 -04:00
|
|
|
strategy: "no_prefix",
|
|
|
|
|
experimental: {
|
|
|
|
|
localeDetector: "localeDetector.ts",
|
2025-06-07 23:49:43 -04:00
|
|
|
autoImportTranslationFunctions: true,
|
2025-06-04 19:53:30 -04:00
|
|
|
},
|
|
|
|
|
detectBrowserLanguage: {
|
|
|
|
|
useCookie: true,
|
|
|
|
|
cookieKey: "drop_i18n_redirected",
|
|
|
|
|
fallbackLocale: "en-us",
|
|
|
|
|
},
|
|
|
|
|
locales: [
|
2025-06-07 23:49:43 -04:00
|
|
|
{ code: "en-us", language: "en-us", name: "English", file: "en_us.json" },
|
|
|
|
|
{
|
|
|
|
|
code: "en-gb",
|
|
|
|
|
language: "en-gb",
|
|
|
|
|
name: "English (UK)",
|
|
|
|
|
file: "en_gb.json",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
code: "en-au",
|
|
|
|
|
language: "en-au",
|
|
|
|
|
name: "English (Australia)",
|
|
|
|
|
file: "en_au.json",
|
|
|
|
|
},
|
2025-06-04 19:53:30 -04:00
|
|
|
{
|
|
|
|
|
code: "en-pirate",
|
2025-06-07 23:49:43 -04:00
|
|
|
language: "en-pirate",
|
2025-06-04 19:53:30 -04:00
|
|
|
name: "English (Pirate)",
|
|
|
|
|
file: "en_pirate.json",
|
|
|
|
|
},
|
2025-06-07 23:49:43 -04:00
|
|
|
{
|
|
|
|
|
code: "fr",
|
|
|
|
|
language: "fr",
|
|
|
|
|
name: "French",
|
|
|
|
|
file: "fr.json",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
code: "de",
|
|
|
|
|
language: "de",
|
|
|
|
|
name: "German",
|
|
|
|
|
file: "de.json",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
code: "it",
|
|
|
|
|
language: "it",
|
|
|
|
|
name: "Italian",
|
|
|
|
|
file: "it.json",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
code: "es",
|
|
|
|
|
language: "es",
|
|
|
|
|
name: "Spanish",
|
|
|
|
|
file: "es.json",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
code: "zh",
|
|
|
|
|
language: "zh",
|
|
|
|
|
name: "Chinese",
|
|
|
|
|
file: "zh.json",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
code: "zh-tw",
|
|
|
|
|
language: "zh-tw",
|
|
|
|
|
name: "Chinese (Taiwan)",
|
|
|
|
|
file: "zh_tw.json",
|
|
|
|
|
},
|
2025-06-04 19:53:30 -04:00
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
|
2025-03-11 20:03:28 -04:00
|
|
|
security: {
|
|
|
|
|
headers: {
|
|
|
|
|
contentSecurityPolicy: {
|
2025-03-15 15:04:52 +11:00
|
|
|
"upgrade-insecure-requests": false,
|
|
|
|
|
|
2025-03-11 20:03:28 -04:00
|
|
|
"img-src": [
|
|
|
|
|
"'self'",
|
|
|
|
|
"data:",
|
|
|
|
|
"https://www.giantbomb.com",
|
|
|
|
|
"https://images.pcgamingwiki.com",
|
2025-03-12 14:19:33 -04:00
|
|
|
"https://images.igdb.com",
|
2025-09-21 02:43:35 +02:00
|
|
|
"https://*.steamstatic.com",
|
2025-03-11 20:03:28 -04:00
|
|
|
],
|
|
|
|
|
},
|
2025-03-14 20:31:00 +11:00
|
|
|
strictTransportSecurity: false,
|
2025-03-11 20:03:28 -04:00
|
|
|
},
|
2025-04-01 21:20:54 +11:00
|
|
|
rateLimiter: false,
|
|
|
|
|
xssValidator: false,
|
2025-06-10 10:08:01 +10:00
|
|
|
requestSizeLimiter: false,
|
2025-03-11 20:03:28 -04:00
|
|
|
},
|
2025-03-14 20:18:26 -04:00
|
|
|
});
|
2025-07-08 22:01:23 -04:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the drop version from the environment variable or package.json
|
|
|
|
|
* @returns {string} The drop version
|
|
|
|
|
*/
|
|
|
|
|
function getDropVersion(): string {
|
|
|
|
|
// get drop version from environment variable
|
|
|
|
|
if (process.env.BUILD_DROP_VERSION) {
|
|
|
|
|
return process.env.BUILD_DROP_VERSION;
|
|
|
|
|
}
|
|
|
|
|
// example nightly: "v0.3.0-nightly.2025.05.28"
|
|
|
|
|
const defaultVersion = "v0.0.0-alpha.0";
|
|
|
|
|
|
2026-01-19 17:50:04 -05:00
|
|
|
const packageJsonPath = fileURLToPath(import.meta.resolve("./package.json"));
|
2025-07-25 07:28:00 -04:00
|
|
|
|
2025-07-08 22:01:23 -04:00
|
|
|
if (!existsSync(packageJsonPath)) {
|
|
|
|
|
console.error("Could not find package.json, using default version.");
|
|
|
|
|
return defaultVersion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// parse package.json
|
|
|
|
|
const raw = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
|
|
|
const packageJson = packageJsonSchema(raw);
|
|
|
|
|
if (packageJson instanceof type.errors) {
|
|
|
|
|
console.error("Failed to parse package.json", packageJson.summary);
|
|
|
|
|
return defaultVersion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ensure version starts with 'v'
|
|
|
|
|
if (packageJson.version.startsWith("v")) {
|
|
|
|
|
return packageJson.version;
|
|
|
|
|
}
|
|
|
|
|
return `v${packageJson.version}`;
|
|
|
|
|
}
|