Faithful port of AtomCMS's "atom" theme look (light, Habbo-retro, golden #eeb425 / amber #f59e0b accents, white cards, 12px radii, Nunito-first stack): - globals.css: full token set + components (.site-header/.nav-item, .btn-*, .card, .hero, currency pills, article cards, inputs, tables, footer). - SiteHeader (brand + nav + currency pills + auth box, staff-aware) + SiteFooter; layout wraps header/content/footer. Removed the bare SiteNav. - Restyled home (hero + article cards), login (centered card). - siteSettings now falls back to DEFAULTS on missing key OR DB error, so pages render without a DB; DATABASE_CONNECT_TIMEOUT_MS env + pool acquireTimeout make the no-DB fallback fast. Verified in a real browser (computed styles): header white/sticky, golden logo gradient, uppercase nav, amber primary button @12px radius, golden outline, hero gradient — all correct. tsc exit 0, vitest 48/48, next build exit 0.
34 lines
1.6 KiB
TypeScript
34 lines
1.6 KiB
TypeScript
import { z } from "zod";
|
|
|
|
// Minimal validated env for the foundation. When the Next.js app is added this
|
|
// will move to @t3-oss/env-nextjs (the habbo-next pattern), but the data layer
|
|
// only needs the DB connection + a couple of values today.
|
|
const schema = z.object({
|
|
NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
|
|
DATABASE_URL: z.string().url(),
|
|
DATABASE_POOL_SIZE: z.coerce.number().int().positive().default(40),
|
|
DATABASE_IDLE_TIMEOUT_MS: z.coerce.number().int().positive().default(300_000),
|
|
DATABASE_CONNECT_TIMEOUT_MS: z.coerce.number().int().positive().default(10_000),
|
|
HOTEL_NAME: z.string().default("Atom"),
|
|
// RCON link to the Arcturus emulator (raw-JSON TCP protocol).
|
|
RCON_HOST: z.string().default("127.0.0.1"),
|
|
RCON_PORT: z.coerce.number().int().positive().default(3001),
|
|
RCON_TIMEOUT_MS: z.coerce.number().int().positive().default(10_000),
|
|
RCON_MAX_RETRIES: z.coerce.number().int().positive().default(3),
|
|
// NextAuth v5 reads AUTH_SECRET itself; declared here for documentation/typing.
|
|
AUTH_SECRET: z.string().min(1).optional(),
|
|
// Mirrors Laravel config('habbo.site.convert_passwords') — enables md5->argon2id.
|
|
CONVERT_PASSWORDS: z
|
|
.string()
|
|
.optional()
|
|
.transform((v) => v === "true" || v === "1"),
|
|
});
|
|
|
|
type Env = z.infer<typeof schema>;
|
|
|
|
// SKIP_ENV_VALIDATION lets tooling (typecheck, tests that don't touch the DB)
|
|
// import modules transitively without a populated .env.
|
|
export const env: Env = process.env.SKIP_ENV_VALIDATION
|
|
? (process.env as unknown as Env)
|
|
: schema.parse(process.env);
|