Initial commit

This commit is contained in:
2026-04-12 16:53:58 -04:00
parent 48c2356383
commit fe84ec6a43
17 changed files with 628 additions and 1 deletions
+168
View File
@@ -0,0 +1,168 @@
#!/usr/bin/env node
import { execSync } from 'child_process';
import fs from 'fs-extra';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const logStep = (stepNumber, message) => {
console.log(`\n📋 Étape ${stepNumber}: ${message}`);
};
// Templates zen (inline pour éviter des dépendances externes)
const zenTemplates = {
instrumentation: `export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
const { initializeZen } = await import('@zen/core');
await initializeZen();
}
}
`,
authRedirect: `import { redirect } from 'next/navigation';
export default function Redirect() {
redirect('/auth/login/');
}
`,
authCatchAll: `export { default } from '@zen/core/auth/page';
`,
adminRedirect: `import { redirect } from 'next/navigation';
export default function Redirect() {
redirect('/admin/dashboard');
}
`,
adminCatchAll: `export { default } from '@zen/core/admin/page';
`,
zenApiRoute: `export { GET, POST, PUT, DELETE, PATCH } from '@zen/core/zen/api';
`,
zenPageRoute: `export { default, generateMetadata } from '@zen/core/modules/page';
`,
};
// Fichiers zen à créer dans le projet cible
const zenFiles = [
{ path: 'instrumentation.js', template: 'instrumentation' },
{ path: 'app/(auth)/auth/page.js', template: 'authRedirect' },
{ path: 'app/(auth)/auth/[...auth]/page.js', template: 'authCatchAll' },
{ path: 'app/(admin)/admin/page.js', template: 'adminRedirect' },
{ path: 'app/(admin)/admin/[...admin]/page.js', template: 'adminCatchAll' },
{ path: 'app/zen/api/[...path]/route.js', template: 'zenApiRoute' },
{ path: 'app/zen/[...zen]/page.js', template: 'zenPageRoute' },
];
async function createZenFile(filePath, content) {
const fullPath = path.resolve(process.cwd(), filePath);
const dir = path.dirname(fullPath);
await fs.ensureDir(dir);
await fs.writeFile(fullPath, content, 'utf-8');
console.log(`${filePath}`);
}
async function initProject() {
try {
console.log('\n🚀 Initialisation du projet Next.js avec @zen/core...\n');
// Étape 1 : Créer le projet Next.js (le dossier doit être vide)
logStep(1, 'Création du projet Next.js');
execSync('npx create-next-app@latest ./ --javascript --tailwind --app --empty', { stdio: 'inherit' });
// Étape 2 : Supprimer /app (sera remplacé par le template)
logStep(2, 'Suppression du dossier /app par défaut');
if (fs.existsSync('./app')) {
fs.removeSync('./app');
console.log(' 📁 Dossier /app supprimé');
}
// Étape 3 : Mettre à jour jsconfig.json (path aliases)
logStep(3, 'Configuration des path aliases (jsconfig.json)');
fs.writeJsonSync('./jsconfig.json', {
compilerOptions: {
paths: { '@*': ['./*'] },
},
}, { spaces: 2 });
console.log(' ⚙️ jsconfig.json mis à jour');
// Étape 4 : Mettre à jour next.config.mjs
logStep(4, 'Configuration de next.config.mjs');
fs.writeFileSync('./next.config.mjs', `/** @type {import('next').NextConfig} */
const nextConfig = {
\tdevIndicators: false,
\texperimental: {
\t\tinstrumentationHook: true,
\t},
};
export default nextConfig;
`);
console.log(' ⚙️ next.config.mjs mis à jour');
// Étape 5 : Mettre à jour README.md
logStep(5, 'Mise à jour du README.md');
const packageJsonPath = './package.json';
if (fs.existsSync(packageJsonPath)) {
const packageJson = fs.readJsonSync(packageJsonPath);
const projectName = packageJson.name || 'Mon projet';
fs.writeFileSync('README.md', `# ${projectName}
Un site web construit avec Next.js, Tailwind CSS et @zen/core.
![screenshot](/.github/assets/screenshot.png)`);
console.log(' 📘 README.md mis à jour');
}
// Étape 6 : Ajouter le script make-favicon dans package.json
logStep(6, 'Ajout du script make-favicon');
if (fs.existsSync(packageJsonPath)) {
const packageJson = fs.readJsonSync(packageJsonPath);
if (!packageJson.scripts) packageJson.scripts = {};
packageJson.scripts['make-favicon'] = 'node dev/icons/make-favicon.js';
fs.writeJsonSync(packageJsonPath, packageJson, { spaces: 2 });
console.log(' ⚙️ Script make-favicon ajouté');
}
// Étape 7 : Copier les fichiers template (app/, styles/, dev/, components/)
logStep(7, 'Copie des fichiers template');
const templatesPath = path.join(__dirname, '..', 'templates');
if (fs.existsSync(templatesPath)) {
fs.copySync(templatesPath, './', { overwrite: true });
console.log(' 📁 Fichiers template copiés');
} else {
console.error(' ❌ Dossier templates introuvable dans le package zen-start');
process.exit(1);
}
// Étape 8 : Créer les fichiers zen (auth, admin, api, instrumentation)
logStep(8, 'Création des fichiers @zen/core');
for (const file of zenFiles) {
await createZenFile(file.path, zenTemplates[file.template]);
}
// Étape 9 : Créer .npmrc avec le registre Gitea (APRÈS create-next-app !)
logStep(9, 'Configuration du registre npm (@zen/core)');
fs.writeFileSync('./.npmrc', '@zen:registry=https://git.hyko.cx/api/packages/zen/npm/\n');
console.log(' ⚙️ .npmrc créé');
// Étape 10 : Installer @zen/core
logStep(10, 'Installation de @zen/core');
execSync('npm install @zen/core', { stdio: 'inherit' });
// Fin
console.log('\n✅ Projet zen prêt !\n');
console.log('Prochaines étapes :');
console.log(' 1. Configurer les variables d\'environnement');
console.log(' (voir la doc : https://git.hyko.cx/zen/core)');
console.log(' 2. Initialiser la base de données :');
console.log(' npx zen-db init');
console.log('');
} catch (error) {
console.error('\n❌ Une erreur est survenue :', error.message);
process.exit(1);
}
}
initProject();