You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.5 KiB

Nexo desktop-first redesign + demo restructure Move servers/dating → demos/dating/server and the dating route's co-located _components/_lib/_design assets → demos/dating/web. Single `npm run dating:dev` boots both server and web via concurrently. Replace the warm-paper / raspberry-pink Claude Design adaptation with a sober desktop-first system: - Tokens: slate neutrals + violet accent, Inter family, dark mode via prefers-color-scheme + explicit data-theme. - Inline SVG icon set (Icon.svelte, Feather-style) — no Unicode glyph placeholders. - Layout shell: 240px rail nav on desktop, bottom tab bar on mobile; auth + onboarding own their own shell. - Discover: square photo carousel (dots + chevrons), name/age/location overlay, action buttons floating off the photo edge, sticky context panel on desktop. - Matches: clean conversation list with unread dot + chevron-on-hover. - Chat: 3-column on desktop (threads + thread + match context), 2-col on tablet, single thread on mobile. Day separators, retry/dismiss on failed messages, autogrow composer with Enter-to-send. - Profile: sticky hero card + 3-section form, dirty/saved indicator. - Photos: dropzone + grid with hover-only cell toolbar (set primary, reorder, delete). - Onboarding: sidebar stepper (320px) + content panel. - Auth: split layout (form left, brand quote right) on ≥900px. Server boot: env loader's repo-root resolution corrected after the move (../../.. instead of ../..) so .env.local at the repo root is picked up again. Hoist BRAND.md and SECURITY.md into docs/, drop superseded audit notes that were already closed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
import { existsSync, readFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const serverDir = dirname(fileURLToPath(import.meta.url));
// The server now lives at `<repo>/demos/dating/server/`, so the repo
// root is three levels up — not two as it was when the server lived
// at `<repo>/servers/dating/`. Loading `.env`/`.env.local` from both
// the repo root and the server directory keeps either location valid.
const rootDir = resolve(serverDir, '../../..');
loadEnvFile(resolve(rootDir, '.env'));
loadEnvFile(resolve(rootDir, '.env.local'));
loadEnvFile(resolve(serverDir, '.env'));
loadEnvFile(resolve(serverDir, '.env.local'));
export const config = {
host: process.env.DATING_SERVER_HOST || '127.0.0.1',
port: readPort(process.env.DATING_SERVER_PORT, 8787),
allowedOrigins: readList(
process.env.DATING_ALLOWED_ORIGINS,
['http://localhost:5173', 'http://127.0.0.1:5173']
),
cookieName: process.env.DATING_SESSION_COOKIE || 'dating_session',
secureCookies: process.env.DATING_SECURE_COOKIES === 'true',
pocketBaseUrl: stripTrailingSlash(
process.env.POCKETBASE_URL || process.env.PUBLIC_POCKETBASE_URL || 'http://127.0.0.1:8090'
),
pocketBaseSuperuserEmail: requireEnv('POCKETBASE_SUPERUSER_EMAIL'),
pocketBaseSuperuserPassword: requireEnv('POCKETBASE_SUPERUSER_PASSWORD')
};
function loadEnvFile(file) {
if (!existsSync(file)) return;
const text = readFileSync(file, 'utf8');
for (const rawLine of text.split(/\r?\n/)) {
const line = rawLine.trim();
if (!line || line.startsWith('#')) continue;
const eq = line.indexOf('=');
if (eq === -1) continue;
const key = line.slice(0, eq).trim();
const value = unquote(line.slice(eq + 1).trim());
if (key && process.env[key] == null) {
process.env[key] = value;
}
}
}
function unquote(value) {
if (
(value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))
) {
return value.slice(1, -1);
}
return value;
}
function readPort(value, fallback) {
const port = Number(value);
return Number.isInteger(port) && port > 0 && port < 65536 ? port : fallback;
}
function readList(value, fallback) {
if (!value) return fallback;
return value
.split(',')
.map((item) => item.trim())
.filter(Boolean);
}
function stripTrailingSlash(value) {
return value.replace(/\/+$/, '');
}
function requireEnv(name) {
const value = process.env[name];
if (!value) {
throw new Error(`Missing required env var ${name}`);
}
return value;
}

Powered by TurnKey Linux.