docs: remove zen-setup CLI and simplify installation guide
- Remove `zen-setup` binary from package.json and package-lock.json - Replace manual setup steps with `npx @zen/start` CLI command - Simplify INSTALL.md by reducing steps from 6 to 4 - Update DEV.md to reflect removal of zen-setup from CLI scripts - Fix relative path to `.env.example` in documentation
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ On suit ces deux guides :
|
|||||||
|
|
||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
├── cli/ # Scripts CLI : zen-db, zen-setup
|
├── cli/ # Scripts CLI : zen-db
|
||||||
├── core/ # Briques techniques : database, api, email, storage, cron, pdf, toast, payments
|
├── core/ # Briques techniques : database, api, email, storage, cron, pdf, toast, payments
|
||||||
├── features/ # Features utilisateur : auth, admin, provider
|
├── features/ # Features utilisateur : auth, admin, provider
|
||||||
├── modules/ # Modules métier : posts, invoice, nuage…
|
├── modules/ # Modules métier : posts, invoice, nuage…
|
||||||
|
|||||||
+8
-54
@@ -1,69 +1,23 @@
|
|||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
## 1. Configurer le registre npm
|
## 1. Configurer le registre pour le scope `@zen` :
|
||||||
|
|
||||||
Créer un fichier `.npmrc` à la racine du projet avec le contenu suivant :
|
|
||||||
|
|
||||||
```
|
|
||||||
@zen:registry=https://git.hyko.cx/api/packages/zen/npm/
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Installer le package
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install @zen/core
|
npm config set @zen:registry https://git.hyko.cx/api/packages/zen/npm/
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. Installer les styles
|
## 2. Lancer le CLI :
|
||||||
|
|
||||||
Ajouter la ligne suivante dans le fichier `globals.css` :
|
```bash
|
||||||
|
npx @zen/start
|
||||||
```css
|
|
||||||
@import '@zen/core/styles/zen.css';
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4. Ajouter ZenProvider au layout racine
|
## 3. Configurer les variables d'environnement
|
||||||
|
|
||||||
Entourer l'application avec `ZenProvider` dans le layout racine pour activer les notifications toast globalement :
|
Consulter le fichier [`.env.example`](../.env.example) pour les variables d'environnement à ajouter dans le fichier `.env`.
|
||||||
|
|
||||||
```javascript
|
## 4. Initialiser la base de données
|
||||||
// app/layout.js
|
|
||||||
import './globals.css';
|
|
||||||
import { ZenProvider } from '@zen/core/provider';
|
|
||||||
|
|
||||||
export const metadata = {
|
|
||||||
title: 'My App',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function RootLayout({ children }) {
|
|
||||||
return (
|
|
||||||
<html lang="en">
|
|
||||||
<body>
|
|
||||||
<ZenProvider>
|
|
||||||
{children}
|
|
||||||
</ZenProvider>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. Configurer les variables d'environnement
|
|
||||||
|
|
||||||
Consulter le fichier [`.env.example`](.env.example) pour les variables d'environnement à ajouter dans le fichier `.env`.
|
|
||||||
|
|
||||||
## 6. Initialiser la base de données
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx zen-db init
|
npx zen-db init
|
||||||
```
|
```
|
||||||
|
|
||||||
# Configuration
|
|
||||||
|
|
||||||
## Configuration rapide
|
|
||||||
|
|
||||||
On peut créer tous les fichiers requis avec une seule commande :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx zen-setup init
|
|
||||||
```
|
|
||||||
Generated
+1
-2
@@ -21,8 +21,7 @@
|
|||||||
"stripe": "^14.0.0"
|
"stripe": "^14.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"zen-db": "dist/cli/database.js",
|
"zen-db": "dist/cli/database.js"
|
||||||
"zen-setup": "dist/cli/setup.js"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/cli": "^4.2.1",
|
"@tailwindcss/cli": "^4.2.1",
|
||||||
|
|||||||
+1
-2
@@ -23,8 +23,7 @@
|
|||||||
"prepublishOnly": "npm run build"
|
"prepublishOnly": "npm run build"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"zen-db": "./dist/cli/database.js",
|
"zen-db": "./dist/cli/database.js"
|
||||||
"zen-setup": "./dist/cli/setup.js"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "^2.0.0",
|
"@headlessui/react": "^2.0.0",
|
||||||
|
|||||||
@@ -1,251 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Zen Setup CLI
|
|
||||||
* Command-line tool for setting up Zen in a Next.js project
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { mkdir, writeFile } from 'node:fs/promises';
|
|
||||||
import { existsSync } from 'node:fs';
|
|
||||||
import { resolve, dirname } from 'node:path';
|
|
||||||
import readline from 'readline';
|
|
||||||
|
|
||||||
// File templates
|
|
||||||
const templates = {
|
|
||||||
instrumentation: `// instrumentation.js
|
|
||||||
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';
|
|
||||||
`,
|
|
||||||
nextConfig: `// next.config.js
|
|
||||||
module.exports = {
|
|
||||||
experimental: {
|
|
||||||
instrumentationHook: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
`,
|
|
||||||
};
|
|
||||||
|
|
||||||
// File definitions
|
|
||||||
const files = [
|
|
||||||
{
|
|
||||||
path: 'instrumentation.js',
|
|
||||||
template: 'instrumentation',
|
|
||||||
description: 'Instrumentation file (initialize Zen)',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'app/(auth)/auth/page.js',
|
|
||||||
template: 'authRedirect',
|
|
||||||
description: 'Auth redirect page',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'app/(auth)/auth/[...auth]/page.js',
|
|
||||||
template: 'authCatchAll',
|
|
||||||
description: 'Auth catch-all route',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'app/(admin)/admin/page.js',
|
|
||||||
template: 'adminRedirect',
|
|
||||||
description: 'Admin redirect page',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'app/(admin)/admin/[...admin]/page.js',
|
|
||||||
template: 'adminCatchAll',
|
|
||||||
description: 'Admin catch-all route',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'app/zen/api/[...path]/route.js',
|
|
||||||
template: 'zenApiRoute',
|
|
||||||
description: 'Zen API catch-all route',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'app/zen/[...zen]/page.js',
|
|
||||||
template: 'zenPageRoute',
|
|
||||||
description: 'Zen public pages catch-all route',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
async function createFile(filePath, content, force = false) {
|
|
||||||
const fullPath = resolve(process.cwd(), filePath);
|
|
||||||
|
|
||||||
// Check if file already exists
|
|
||||||
if (existsSync(fullPath) && !force) {
|
|
||||||
console.log(`⏭️ Skipped (already exists): ${filePath}`);
|
|
||||||
return { created: false, skipped: true };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create directory if it doesn't exist
|
|
||||||
const dir = dirname(fullPath);
|
|
||||||
await mkdir(dir, { recursive: true });
|
|
||||||
|
|
||||||
// Write the file
|
|
||||||
await writeFile(fullPath, content, 'utf-8');
|
|
||||||
console.log(`✅ Created: ${filePath}`);
|
|
||||||
|
|
||||||
return { created: true, skipped: false };
|
|
||||||
}
|
|
||||||
|
|
||||||
async function setupZen(options = {}) {
|
|
||||||
const { force = false } = options;
|
|
||||||
|
|
||||||
console.log('🚀 Setting up Zen for your Next.js project...\n');
|
|
||||||
|
|
||||||
let created = 0;
|
|
||||||
let skipped = 0;
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
const result = await createFile(
|
|
||||||
file.path,
|
|
||||||
templates[file.template],
|
|
||||||
force
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.created) created++;
|
|
||||||
if (result.skipped) skipped++;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('\n📝 Summary:');
|
|
||||||
console.log(` ✅ Created: ${created} file${created !== 1 ? 's' : ''}`);
|
|
||||||
console.log(` ⏭️ Skipped: ${skipped} file${skipped !== 1 ? 's' : ''}`);
|
|
||||||
|
|
||||||
// Check if next.config.js needs updating
|
|
||||||
const nextConfigPath = resolve(process.cwd(), 'next.config.js');
|
|
||||||
const nextConfigExists = existsSync(nextConfigPath);
|
|
||||||
|
|
||||||
if (!nextConfigExists) {
|
|
||||||
console.log('\n⚠️ Note: next.config.js not found.');
|
|
||||||
console.log(' Make sure to enable instrumentation in your Next.js config:');
|
|
||||||
console.log(' experimental: { instrumentationHook: true }');
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('\n🎉 Setup complete!');
|
|
||||||
console.log('\nNext steps:');
|
|
||||||
console.log(' 1. Add Zen styles to your globals.css:');
|
|
||||||
console.log(' @import \'@zen/core/styles/zen.css\';');
|
|
||||||
console.log(' 2. Configure environment variables (see .env.example)');
|
|
||||||
console.log(' 3. Initialize the database:');
|
|
||||||
console.log(' npx zen-db init');
|
|
||||||
console.log('\nFor more information, check the INSTALL.md file.');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function listFiles() {
|
|
||||||
console.log('📋 Files that will be created:\n');
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
const exists = existsSync(resolve(process.cwd(), file.path));
|
|
||||||
const status = exists ? '✓ exists' : '✗ missing';
|
|
||||||
console.log(` ${status} ${file.path}`);
|
|
||||||
console.log(` ${file.description}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('\nRun "npx zen-setup init" to create missing files.');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runCLI() {
|
|
||||||
const command = process.argv[2];
|
|
||||||
const flags = process.argv.slice(3);
|
|
||||||
const force = flags.includes('--force') || flags.includes('-f');
|
|
||||||
|
|
||||||
if (!command || command === 'help') {
|
|
||||||
console.log(`
|
|
||||||
Zen Setup CLI
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
npx zen-setup <command> [options]
|
|
||||||
|
|
||||||
Commands:
|
|
||||||
init Create all required files for Zen setup
|
|
||||||
list List all files that will be created
|
|
||||||
help Show this help message
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--force, -f Force overwrite existing files
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
npx zen-setup init # Create missing files
|
|
||||||
npx zen-setup init --force # Overwrite all files
|
|
||||||
npx zen-setup list # List all files
|
|
||||||
`);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
switch (command) {
|
|
||||||
case 'init':
|
|
||||||
if (force) {
|
|
||||||
console.log('⚠️ WARNING: --force flag will overwrite existing files!\n');
|
|
||||||
console.log('Type "yes" to confirm or Ctrl+C to cancel...');
|
|
||||||
|
|
||||||
const rl = readline.createInterface({
|
|
||||||
input: process.stdin,
|
|
||||||
output: process.stdout,
|
|
||||||
});
|
|
||||||
|
|
||||||
rl.question('Confirm (yes/no): ', async (answer) => {
|
|
||||||
if (answer.toLowerCase() === 'yes') {
|
|
||||||
await setupZen({ force: true });
|
|
||||||
} else {
|
|
||||||
console.log('❌ Operation cancelled.');
|
|
||||||
}
|
|
||||||
rl.close();
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
return; // Don't exit yet
|
|
||||||
} else {
|
|
||||||
await setupZen({ force: false });
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'list':
|
|
||||||
await listFiles();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
console.log(`❌ Unknown command: ${command}`);
|
|
||||||
console.log('Run "npx zen-setup help" for usage information.');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
process.exit(0);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Error:', error.message);
|
|
||||||
console.error(error.stack);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run CLI if called directly
|
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
import { realpathSync } from 'node:fs';
|
|
||||||
const __filename = realpathSync(fileURLToPath(import.meta.url));
|
|
||||||
const isMainModule = process.argv[1] && realpathSync(process.argv[1]) === __filename;
|
|
||||||
|
|
||||||
if (isMainModule) {
|
|
||||||
runCLI();
|
|
||||||
}
|
|
||||||
|
|
||||||
export { runCLI, setupZen };
|
|
||||||
Reference in New Issue
Block a user