feat(app) : socle SvelteKit phase 0 — SSO, thème OKI, adapter-node
- Scaffold SvelteKit 2 + Svelte 5 (runes), TypeScript strict, adapter-node - Auth SSO via header Ynh-User (hooks.server) ; accueil public minimal sans header, 401 sur toute autre route ; DEV_USER en dev local uniquement - Design system OKI : tokens, thème sombre par défaut, clair opt-in anti-FOUC, flag-bar, fonts Archivo/Inter self-hébergées, sprite icons.svg (zéro emoji) - CSP via kit.csp (mode nonce) + en-têtes de sécurité ; paths.base configurable au build (BASE_PATH) pour le sous-chemin YunoHost, paths.relative = false - i18n fr (structure prête gcf/en), pages : accueil public/privé, erreurs designées - Tests vitest : résolution SSO + routes publiques (10 cas) - Vérifié : check/lint/test/build verts, test fumée HTTP sur build (SSO, CSP, sous-chemin /veille), zéro emoji et zéro domaine tiers dans le build
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import adapter from '@sveltejs/adapter-node';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
|
||||
// Sous-chemin de montage (YunoHost sert l'app sous https://domaine.tld/<path>).
|
||||
// Injecté au build par le script d'install YNH (BASE_PATH=/veille-ia npm run build).
|
||||
// Vide en dev local. Doit commencer par '/' et ne pas finir par '/'.
|
||||
const envBasePath = process.env.BASE_PATH ?? '';
|
||||
if (envBasePath !== '' && (!envBasePath.startsWith('/') || envBasePath.endsWith('/'))) {
|
||||
throw new Error(`BASE_PATH invalide : "${envBasePath}" (doit commencer par '/' sans '/' final)`);
|
||||
}
|
||||
const basePath = envBasePath as '' | `/${string}`;
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
sveltekit({
|
||||
compilerOptions: {
|
||||
// Force runes mode for the project, except for libraries. Can be removed in svelte 6.
|
||||
runes: ({ filename }) =>
|
||||
filename.split(/[/\\]/).includes('node_modules') ? undefined : true
|
||||
},
|
||||
adapter: adapter(),
|
||||
paths: {
|
||||
base: basePath,
|
||||
// Obligatoire dès que paths.base est utilisé (évite les URLs relatives cassées).
|
||||
relative: false
|
||||
},
|
||||
csp: {
|
||||
mode: 'nonce',
|
||||
directives: {
|
||||
'default-src': ['self'],
|
||||
'script-src': ['self'],
|
||||
// Les transitions Svelte créent des <style> inline : unsafe-inline requis.
|
||||
'style-src': ['self', 'unsafe-inline'],
|
||||
'img-src': ['self', 'data:'],
|
||||
'font-src': ['self'],
|
||||
'connect-src': ['self'],
|
||||
'frame-ancestors': ['none'],
|
||||
'base-uri': ['self'],
|
||||
'form-action': ['self'],
|
||||
'object-src': ['none']
|
||||
}
|
||||
}
|
||||
})
|
||||
],
|
||||
test: {
|
||||
expect: { requireAssertions: true },
|
||||
projects: [
|
||||
{
|
||||
extends: './vite.config.ts',
|
||||
test: {
|
||||
name: 'server',
|
||||
environment: 'node',
|
||||
include: ['src/**/*.{test,spec}.{js,ts}'],
|
||||
exclude: ['src/**/*.svelte.{test,spec}.{js,ts}']
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user