nexu-app 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +149 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1192 -0
- package/package.json +43 -0
- package/templates/default/.changeset/config.json +11 -0
- package/templates/default/.eslintignore +16 -0
- package/templates/default/.eslintrc.js +67 -0
- package/templates/default/.github/actions/build/action.yml +35 -0
- package/templates/default/.github/actions/quality/action.yml +53 -0
- package/templates/default/.github/dependabot.yml +51 -0
- package/templates/default/.github/workflows/deploy-dev.yml +83 -0
- package/templates/default/.github/workflows/deploy-prod.yml +83 -0
- package/templates/default/.github/workflows/deploy-rec.yml +83 -0
- package/templates/default/.husky/commit-msg +1 -0
- package/templates/default/.husky/pre-commit +1 -0
- package/templates/default/.nexu-version +1 -0
- package/templates/default/.prettierignore +7 -0
- package/templates/default/.prettierrc +19 -0
- package/templates/default/.vscode/extensions.json +14 -0
- package/templates/default/.vscode/settings.json +36 -0
- package/templates/default/apps/gitkeep +0 -0
- package/templates/default/commitlint.config.js +26 -0
- package/templates/default/docker/docker-compose.dev.yml +49 -0
- package/templates/default/docker/docker-compose.prod.yml +64 -0
- package/templates/default/docker/docker-compose.yml +6 -0
- package/templates/default/docs/architecture.md +452 -0
- package/templates/default/docs/cli.md +330 -0
- package/templates/default/docs/contributing.md +462 -0
- package/templates/default/docs/scripts.md +460 -0
- package/templates/default/gitignore +44 -0
- package/templates/default/lintstagedrc.cjs +4 -0
- package/templates/default/package.json +51 -0
- package/templates/default/packages/auth/package.json +61 -0
- package/templates/default/packages/auth/src/components/ProtectedRoute.tsx +75 -0
- package/templates/default/packages/auth/src/components/SignInForm.tsx +153 -0
- package/templates/default/packages/auth/src/components/SignUpForm.tsx +179 -0
- package/templates/default/packages/auth/src/components/SocialButtons.tsx +147 -0
- package/templates/default/packages/auth/src/components/index.ts +4 -0
- package/templates/default/packages/auth/src/hooks/index.ts +4 -0
- package/templates/default/packages/auth/src/hooks/useAuth.ts +51 -0
- package/templates/default/packages/auth/src/hooks/useRequireAuth.ts +54 -0
- package/templates/default/packages/auth/src/hooks/useSession.ts +48 -0
- package/templates/default/packages/auth/src/hooks/useUser.ts +48 -0
- package/templates/default/packages/auth/src/index.ts +45 -0
- package/templates/default/packages/auth/src/next/index.ts +18 -0
- package/templates/default/packages/auth/src/next/middleware.ts +183 -0
- package/templates/default/packages/auth/src/next/server.ts +219 -0
- package/templates/default/packages/auth/src/providers/AuthContext.tsx +435 -0
- package/templates/default/packages/auth/src/providers/index.ts +1 -0
- package/templates/default/packages/auth/src/types/index.ts +284 -0
- package/templates/default/packages/auth/src/utils/api.ts +228 -0
- package/templates/default/packages/auth/src/utils/index.ts +3 -0
- package/templates/default/packages/auth/src/utils/oauth.ts +230 -0
- package/templates/default/packages/auth/src/utils/token.ts +204 -0
- package/templates/default/packages/auth/tsconfig.json +14 -0
- package/templates/default/packages/auth/tsup.config.ts +18 -0
- package/templates/default/packages/cache/package.json +26 -0
- package/templates/default/packages/cache/src/index.ts +137 -0
- package/templates/default/packages/cache/tsconfig.json +9 -0
- package/templates/default/packages/cache/tsup.config.ts +9 -0
- package/templates/default/packages/config/eslint/index.js +20 -0
- package/templates/default/packages/config/package.json +9 -0
- package/templates/default/packages/config/typescript/base.json +26 -0
- package/templates/default/packages/constants/package.json +26 -0
- package/templates/default/packages/constants/src/index.ts +121 -0
- package/templates/default/packages/constants/tsconfig.json +9 -0
- package/templates/default/packages/constants/tsup.config.ts +9 -0
- package/templates/default/packages/logger/package.json +27 -0
- package/templates/default/packages/logger/src/index.ts +197 -0
- package/templates/default/packages/logger/tsconfig.json +11 -0
- package/templates/default/packages/logger/tsup.config.ts +9 -0
- package/templates/default/packages/result/package.json +26 -0
- package/templates/default/packages/result/src/index.ts +142 -0
- package/templates/default/packages/result/tsconfig.json +9 -0
- package/templates/default/packages/result/tsup.config.ts +9 -0
- package/templates/default/packages/types/package.json +26 -0
- package/templates/default/packages/types/src/index.ts +78 -0
- package/templates/default/packages/types/tsconfig.json +9 -0
- package/templates/default/packages/types/tsup.config.ts +10 -0
- package/templates/default/packages/ui/package.json +38 -0
- package/templates/default/packages/ui/src/components/Button.tsx +58 -0
- package/templates/default/packages/ui/src/components/Card.tsx +85 -0
- package/templates/default/packages/ui/src/components/Input.tsx +45 -0
- package/templates/default/packages/ui/src/index.ts +15 -0
- package/templates/default/packages/ui/tsconfig.json +11 -0
- package/templates/default/packages/ui/tsup.config.ts +11 -0
- package/templates/default/packages/utils/package.json +30 -0
- package/templates/default/packages/utils/src/index.test.ts +130 -0
- package/templates/default/packages/utils/src/index.ts +154 -0
- package/templates/default/packages/utils/tsconfig.json +10 -0
- package/templates/default/packages/utils/tsup.config.ts +10 -0
- package/templates/default/pnpm-workspace.yaml +3 -0
- package/templates/default/scripts/audit.mjs +700 -0
- package/templates/default/scripts/deploy.mjs +40 -0
- package/templates/default/scripts/generate-app.mjs +808 -0
- package/templates/default/scripts/lib/package-manager.mjs +186 -0
- package/templates/default/scripts/setup.mjs +102 -0
- package/templates/default/services/.env.example +16 -0
- package/templates/default/services/docker-compose.yml +207 -0
- package/templates/default/services/grafana/provisioning/dashboards/dashboards.yml +11 -0
- package/templates/default/services/grafana/provisioning/datasources/datasources.yml +9 -0
- package/templates/default/services/postgres/init/gitkeep +2 -0
- package/templates/default/services/prometheus/prometheus.yml +13 -0
- package/templates/default/tsconfig.json +27 -0
- package/templates/default/turbo.json +40 -0
- package/templates/default/vitest.config.ts +15 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
# Documentation des Scripts
|
|
2
|
+
|
|
3
|
+
Ce document décrit les scripts disponibles dans le monorepo Nexu.
|
|
4
|
+
|
|
5
|
+
## Scripts npm (package.json)
|
|
6
|
+
|
|
7
|
+
### Développement
|
|
8
|
+
|
|
9
|
+
| Script | Commande | Description |
|
|
10
|
+
| ------- | ------------------------------------ | ----------------------------------------- |
|
|
11
|
+
| `dev` | `turbo dev` | Lance tous les apps en mode développement |
|
|
12
|
+
| `build` | `turbo build` | Build tous les packages et apps |
|
|
13
|
+
| `clean` | `turbo clean && rm -rf node_modules` | Nettoie tous les caches et node_modules |
|
|
14
|
+
|
|
15
|
+
### Qualité du code
|
|
16
|
+
|
|
17
|
+
| Script | Commande | Description |
|
|
18
|
+
| -------------- | ------------------ | ------------------------------------------ |
|
|
19
|
+
| `lint` | `turbo lint` | Vérifie le code avec ESLint |
|
|
20
|
+
| `lint:fix` | `turbo lint:fix` | Corrige automatiquement les erreurs ESLint |
|
|
21
|
+
| `format` | `prettier --write` | Formate le code avec Prettier |
|
|
22
|
+
| `format:check` | `prettier --check` | Vérifie le formatage |
|
|
23
|
+
| `typecheck` | `turbo typecheck` | Vérifie les types TypeScript |
|
|
24
|
+
|
|
25
|
+
### Tests
|
|
26
|
+
|
|
27
|
+
| Script | Commande | Description |
|
|
28
|
+
| --------------- | --------------------- | --------------------------------- |
|
|
29
|
+
| `test` | `turbo test` | Exécute tous les tests |
|
|
30
|
+
| `test:coverage` | `turbo test:coverage` | Exécute les tests avec couverture |
|
|
31
|
+
|
|
32
|
+
### Docker
|
|
33
|
+
|
|
34
|
+
| Script | Commande | Description |
|
|
35
|
+
| -------------- | -------------------------------------------------------- | ------------------------------------ |
|
|
36
|
+
| `docker:dev` | `docker-compose -f docker/docker-compose.dev.yml up` | Lance l'environnement de dev Docker |
|
|
37
|
+
| `docker:build` | `docker-compose -f docker/docker-compose.prod.yml build` | Build les images de production |
|
|
38
|
+
| `docker:prod` | `docker-compose -f docker/docker-compose.prod.yml up -d` | Lance l'environnement de prod Docker |
|
|
39
|
+
|
|
40
|
+
### Génération et audit
|
|
41
|
+
|
|
42
|
+
| Script | Commande | Description |
|
|
43
|
+
| ------------------- | ---------------------------------------- | ------------------------------- |
|
|
44
|
+
| `generate:app` | `node scripts/generate-app.mjs` | Génère une nouvelle application |
|
|
45
|
+
| `generate:template` | `node scripts/generate-template.mjs` | Génère le template CLI |
|
|
46
|
+
| `audit` | `node scripts/audit.mjs` | Audit complet du code |
|
|
47
|
+
| `audit:security` | `node scripts/audit.mjs --security` | Audit de sécurité |
|
|
48
|
+
| `audit:quality` | `node scripts/audit.mjs --quality` | Audit de qualité |
|
|
49
|
+
| `audit:fix` | `node scripts/audit.mjs --quality --fix` | Audit avec auto-correction |
|
|
50
|
+
|
|
51
|
+
### Versioning
|
|
52
|
+
|
|
53
|
+
| Script | Commande | Description |
|
|
54
|
+
| ------------------ | ------------------- | ------------------------- |
|
|
55
|
+
| `changeset` | `changeset` | Crée un nouveau changeset |
|
|
56
|
+
| `version-packages` | `changeset version` | Met à jour les versions |
|
|
57
|
+
| `release` | `changeset publish` | Publie les packages |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## generate-app.mjs
|
|
62
|
+
|
|
63
|
+
Script pour créer une nouvelle application dans le monorepo avec support de multiples frameworks.
|
|
64
|
+
|
|
65
|
+
### Usage
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Mode interactif
|
|
69
|
+
pnpm generate:app
|
|
70
|
+
|
|
71
|
+
# Avec arguments
|
|
72
|
+
pnpm generate:app <nom> [framework] [port]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Frameworks supportés
|
|
76
|
+
|
|
77
|
+
#### Frontend
|
|
78
|
+
|
|
79
|
+
| Framework | Clé | Port par défaut | Description |
|
|
80
|
+
| ------------- | ------------- | --------------- | -------------------------- |
|
|
81
|
+
| Next.js | `next` | 3000 | Framework React full-stack |
|
|
82
|
+
| Vite + React | `vite-react` | 5173 | SPA React rapide |
|
|
83
|
+
| Vite + Vue | `vite-vue` | 5173 | SPA Vue.js |
|
|
84
|
+
| Vite + Svelte | `vite-svelte` | 5173 | SPA Svelte |
|
|
85
|
+
| Nuxt | `nuxt` | 3000 | Framework Vue full-stack |
|
|
86
|
+
|
|
87
|
+
#### Backend
|
|
88
|
+
|
|
89
|
+
| Framework | Clé | Port par défaut | Description |
|
|
90
|
+
| ---------- | --------- | --------------- | ------------------------------ |
|
|
91
|
+
| Express.js | `express` | 4000 | Framework Node.js classique |
|
|
92
|
+
| Fastify | `fastify` | 4000 | Framework Node.js performant |
|
|
93
|
+
| Hono | `hono` | 4000 | Framework ultraléger |
|
|
94
|
+
| NestJS | `nestjs` | 4000 | Framework TypeScript structuré |
|
|
95
|
+
| Empty | `empty` | 3000 | Projet Node.js vide |
|
|
96
|
+
|
|
97
|
+
### Exemples
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Next.js sur le port 3000
|
|
101
|
+
pnpm generate:app web next 3000
|
|
102
|
+
|
|
103
|
+
# API Express sur le port 4000
|
|
104
|
+
pnpm generate:app api express 4000
|
|
105
|
+
|
|
106
|
+
# Vite + React sur le port 3001
|
|
107
|
+
pnpm generate:app dashboard vite-react 3001
|
|
108
|
+
|
|
109
|
+
# Mode interactif
|
|
110
|
+
pnpm generate:app
|
|
111
|
+
# > App name: web
|
|
112
|
+
# > Select framework: Next.js (frontend)
|
|
113
|
+
# > Port: 3000
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Fichiers créés
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
apps/<nom>/
|
|
120
|
+
├── src/
|
|
121
|
+
│ └── index.ts # Point d'entrée (backend)
|
|
122
|
+
├── docker/
|
|
123
|
+
│ ├── Dockerfile # Multi-stage build
|
|
124
|
+
│ └── nginx.conf # Pour Vite uniquement
|
|
125
|
+
├── docker-compose.yml # Configuration dev
|
|
126
|
+
├── docker-compose.prod.yml # Configuration prod
|
|
127
|
+
├── package.json
|
|
128
|
+
└── tsconfig.json
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Actions automatiques
|
|
132
|
+
|
|
133
|
+
1. **Création du projet** via le CLI du framework (si disponible)
|
|
134
|
+
2. **Configuration package.json** avec le préfixe `@repo/`
|
|
135
|
+
3. **Génération Dockerfile** optimisé pour le framework
|
|
136
|
+
4. **Configuration Docker Compose** pour dev et prod
|
|
137
|
+
5. **Mise à jour** du `docker/docker-compose.yml` principal
|
|
138
|
+
6. **Installation des dépendances** (si setup manuel)
|
|
139
|
+
|
|
140
|
+
### Templates de code
|
|
141
|
+
|
|
142
|
+
#### Express.js
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import express from 'express';
|
|
146
|
+
import cors from 'cors';
|
|
147
|
+
import helmet from 'helmet';
|
|
148
|
+
|
|
149
|
+
const app = express();
|
|
150
|
+
const port = process.env.PORT || 4000;
|
|
151
|
+
|
|
152
|
+
app.use(helmet());
|
|
153
|
+
app.use(cors());
|
|
154
|
+
app.use(express.json());
|
|
155
|
+
|
|
156
|
+
app.get('/', (req, res) => {
|
|
157
|
+
res.json({ message: 'Hello from my-app!' });
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
app.get('/health', (req, res) => {
|
|
161
|
+
res.json({ status: 'ok' });
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
app.listen(port, () => {
|
|
165
|
+
console.log(`🚀 Server running on http://localhost:${port}`);
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Fastify
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import Fastify from 'fastify';
|
|
173
|
+
import cors from '@fastify/cors';
|
|
174
|
+
|
|
175
|
+
const fastify = Fastify({ logger: true });
|
|
176
|
+
const port = parseInt(process.env.PORT || '4000', 10);
|
|
177
|
+
|
|
178
|
+
await fastify.register(cors);
|
|
179
|
+
|
|
180
|
+
fastify.get('/', async () => {
|
|
181
|
+
return { message: 'Hello from my-app!' };
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
fastify.get('/health', async () => {
|
|
185
|
+
return { status: 'ok' };
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
await fastify.listen({ port, host: '0.0.0.0' });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### Hono
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import { serve } from '@hono/node-server';
|
|
195
|
+
import { Hono } from 'hono';
|
|
196
|
+
import { cors } from 'hono/cors';
|
|
197
|
+
|
|
198
|
+
const app = new Hono();
|
|
199
|
+
const port = parseInt(process.env.PORT || '4000', 10);
|
|
200
|
+
|
|
201
|
+
app.use('*', cors());
|
|
202
|
+
|
|
203
|
+
app.get('/', c => c.json({ message: 'Hello from my-app!' }));
|
|
204
|
+
app.get('/health', c => c.json({ status: 'ok' }));
|
|
205
|
+
|
|
206
|
+
serve({ fetch: app.fetch, port });
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## audit.mjs
|
|
212
|
+
|
|
213
|
+
Script d'audit de code pour vérifier la sécurité et la qualité du codebase.
|
|
214
|
+
|
|
215
|
+
### Usage
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Audit complet
|
|
219
|
+
pnpm audit
|
|
220
|
+
|
|
221
|
+
# Options spécifiques
|
|
222
|
+
pnpm audit --security # Sécurité uniquement
|
|
223
|
+
pnpm audit --quality # Qualité uniquement
|
|
224
|
+
pnpm audit --deps # Dépendances uniquement
|
|
225
|
+
pnpm audit --secrets # Détection de secrets
|
|
226
|
+
pnpm audit --fix # Auto-correction ESLint
|
|
227
|
+
pnpm audit --verbose # Sortie détaillée
|
|
228
|
+
pnpm audit --app=<name> # Auditer une app spécifique
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Options
|
|
232
|
+
|
|
233
|
+
| Option | Alias | Description |
|
|
234
|
+
| -------------- | ----- | ------------------------------- |
|
|
235
|
+
| `--all` | `-a` | Exécute tous les checks |
|
|
236
|
+
| `--security` | `-s` | Vulnérabilités + secrets |
|
|
237
|
+
| `--quality` | `-q` | ESLint + TypeScript |
|
|
238
|
+
| `--deps` | `-d` | Outdated + unused + licenses |
|
|
239
|
+
| `--secrets` | | Détection de secrets uniquement |
|
|
240
|
+
| `--fix` | | Auto-correction ESLint |
|
|
241
|
+
| `--verbose` | `-v` | Affichage détaillé |
|
|
242
|
+
| `--app=<name>` | | Auditer une app spécifique |
|
|
243
|
+
| `--help` | `-h` | Afficher l'aide |
|
|
244
|
+
|
|
245
|
+
### Checks effectués
|
|
246
|
+
|
|
247
|
+
#### 1. Vulnérabilités des dépendances
|
|
248
|
+
|
|
249
|
+
Utilise `npm audit`, `pnpm audit` ou `yarn audit` selon le gestionnaire de packages détecté.
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# Sortie exemple
|
|
253
|
+
▶ Dependency Vulnerabilities
|
|
254
|
+
|
|
255
|
+
✓ No vulnerabilities found
|
|
256
|
+
# ou
|
|
257
|
+
✗ Found 2 critical and 5 high vulnerabilities
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### 2. Détection de secrets
|
|
261
|
+
|
|
262
|
+
Recherche de patterns sensibles dans le code:
|
|
263
|
+
|
|
264
|
+
| Type | Pattern |
|
|
265
|
+
| -------------- | -------------------------------------- |
|
|
266
|
+
| AWS Access Key | `AKIA[0-9A-Z]{16}` |
|
|
267
|
+
| AWS Secret Key | Clé de 40 caractères avec contexte AWS |
|
|
268
|
+
| GitHub Token | `gh[pousr]_[A-Za-z0-9_]{36,}` |
|
|
269
|
+
| API Key | `api[_-]?key...` |
|
|
270
|
+
| Private Key | `-----BEGIN ... PRIVATE KEY-----` |
|
|
271
|
+
| JWT Token | `eyJ...` |
|
|
272
|
+
| Database URL | `postgres://user:pass@...` |
|
|
273
|
+
| Password | `password=...` |
|
|
274
|
+
|
|
275
|
+
**Exclusions automatiques:**
|
|
276
|
+
|
|
277
|
+
- `node_modules`, `.git`, `dist`, `build`
|
|
278
|
+
- Fichiers binaires (`.png`, `.jpg`, etc.)
|
|
279
|
+
- Fichiers de lock (`pnpm-lock.yaml`, etc.)
|
|
280
|
+
- Commentaires et documentation
|
|
281
|
+
- Valeurs placeholder (`example`, `your-`)
|
|
282
|
+
|
|
283
|
+
#### 3. ESLint
|
|
284
|
+
|
|
285
|
+
Exécute ESLint sur tout le projet via Turborepo.
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Sans fix
|
|
289
|
+
pnpm audit --quality
|
|
290
|
+
|
|
291
|
+
# Avec fix
|
|
292
|
+
pnpm audit --quality --fix
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
#### 4. TypeScript
|
|
296
|
+
|
|
297
|
+
Vérifie les types avec `tsc --noEmit`.
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
▶ TypeScript Type Checking
|
|
301
|
+
|
|
302
|
+
✓ No TypeScript errors found
|
|
303
|
+
# ou
|
|
304
|
+
✗ Found 12 TypeScript errors
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
#### 5. Dépendances obsolètes
|
|
308
|
+
|
|
309
|
+
Vérifie les packages qui ont des mises à jour disponibles.
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
▶ Outdated Dependencies
|
|
313
|
+
|
|
314
|
+
! 15 outdated packages (3 major updates available)
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
#### 6. Dépendances inutilisées
|
|
318
|
+
|
|
319
|
+
Utilise `depcheck` pour trouver les dépendances non utilisées.
|
|
320
|
+
|
|
321
|
+
**Note:** Nécessite `npm install -g depcheck`
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
▶ Unused Dependencies
|
|
325
|
+
|
|
326
|
+
! Found 5 potentially unused dependencies
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
#### 7. Conformité des licences
|
|
330
|
+
|
|
331
|
+
Vérifie que les licences des dépendances sont compatibles.
|
|
332
|
+
|
|
333
|
+
**Note:** Nécessite `npm install -g license-checker`
|
|
334
|
+
|
|
335
|
+
Licences problématiques signalées:
|
|
336
|
+
|
|
337
|
+
- GPL, AGPL, LGPL
|
|
338
|
+
- SSPL, BUSL
|
|
339
|
+
- Commons Clause
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
▶ License Compliance
|
|
343
|
+
|
|
344
|
+
✓ All licenses are compliant
|
|
345
|
+
# ou
|
|
346
|
+
! Found 2 packages with restrictive licenses
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Résumé
|
|
350
|
+
|
|
351
|
+
À la fin de l'audit, un résumé est affiché:
|
|
352
|
+
|
|
353
|
+
```
|
|
354
|
+
📊 Audit Summary
|
|
355
|
+
|
|
356
|
+
✓ Dependency Vulnerabilities
|
|
357
|
+
✓ Secrets Detection
|
|
358
|
+
✓ ESLint
|
|
359
|
+
✓ TypeScript
|
|
360
|
+
! Outdated Dependencies (15 outdated, 3 major)
|
|
361
|
+
! Unused Dependencies (5 unused)
|
|
362
|
+
✓ License Compliance
|
|
363
|
+
|
|
364
|
+
Results: 4 passed, 2 warnings, 0 errors
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Code de sortie
|
|
368
|
+
|
|
369
|
+
- `0` : Succès (pas d'erreurs)
|
|
370
|
+
- `1` : Échec (au moins une erreur critique)
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## generate-template.mjs
|
|
375
|
+
|
|
376
|
+
Script pour générer le template du CLI à partir du monorepo actuel.
|
|
377
|
+
|
|
378
|
+
### Usage
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
pnpm generate:template
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Fonctionnement
|
|
385
|
+
|
|
386
|
+
1. **Supprime** l'ancien template dans `nexu-app/templates/default/`
|
|
387
|
+
2. **Copie** les fichiers du monorepo
|
|
388
|
+
3. **Exclut** les fichiers non nécessaires
|
|
389
|
+
4. **Modifie** le `package.json` avec un placeholder
|
|
390
|
+
5. **Nettoie** les références au CLI
|
|
391
|
+
|
|
392
|
+
### Fichiers exclus
|
|
393
|
+
|
|
394
|
+
- `node_modules`
|
|
395
|
+
- `.git`
|
|
396
|
+
- `.turbo`
|
|
397
|
+
- `*.log`
|
|
398
|
+
- `.DS_Store`
|
|
399
|
+
- `dist`
|
|
400
|
+
- `coverage`
|
|
401
|
+
- `.next`
|
|
402
|
+
- `pnpm-lock.yaml`
|
|
403
|
+
- `nexu-app` (le CLI lui-même)
|
|
404
|
+
- `.claude`
|
|
405
|
+
- `README.md`
|
|
406
|
+
- `.lintstagedrc.cjs`
|
|
407
|
+
|
|
408
|
+
### Modifications automatiques
|
|
409
|
+
|
|
410
|
+
1. **package.json**: `"name": "nexu"` → `"name": "{{PROJECT_NAME}}"`
|
|
411
|
+
2. **pnpm-workspace.yaml**: Supprime `- 'nexu-app'`
|
|
412
|
+
3. **eslintrc.js**: Supprime `'nexu-app'` des ignorePatterns
|
|
413
|
+
4. **Scripts supprimés**: `generate:template`, `publish:cli`
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## publish-cli.mjs
|
|
418
|
+
|
|
419
|
+
Script pour publier le CLI nexu-app sur npm.
|
|
420
|
+
|
|
421
|
+
### Usage
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
pnpm publish:cli
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Prérequis
|
|
428
|
+
|
|
429
|
+
- Être connecté à npm (`npm login`)
|
|
430
|
+
- Avoir les droits de publication sur le package
|
|
431
|
+
|
|
432
|
+
### Étapes
|
|
433
|
+
|
|
434
|
+
1. Génère le template (`generate:template`)
|
|
435
|
+
2. Build le CLI (`tsup`)
|
|
436
|
+
3. Publie sur npm (`npm publish`)
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## Utilitaires communs
|
|
441
|
+
|
|
442
|
+
### lib/package-manager.mjs
|
|
443
|
+
|
|
444
|
+
Module partagé pour la détection du gestionnaire de packages.
|
|
445
|
+
|
|
446
|
+
```javascript
|
|
447
|
+
import { detectPackageManager, getRunCommand, getExecCommand } from './lib/package-manager.mjs';
|
|
448
|
+
|
|
449
|
+
const pm = detectPackageManager(ROOT_DIR); // 'pnpm' | 'yarn' | 'npm'
|
|
450
|
+
const runCmd = getRunCommand(pm); // 'pnpm' | 'yarn' | 'npm run'
|
|
451
|
+
const execCmd = getExecCommand(pm); // 'pnpm exec' | 'yarn' | 'npx'
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Détection
|
|
455
|
+
|
|
456
|
+
La détection se base sur:
|
|
457
|
+
|
|
458
|
+
1. Présence de `pnpm-lock.yaml` → pnpm
|
|
459
|
+
2. Présence de `yarn.lock` → yarn
|
|
460
|
+
3. Sinon → npm
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules
|
|
3
|
+
.pnpm-store
|
|
4
|
+
|
|
5
|
+
# Build outputs
|
|
6
|
+
dist
|
|
7
|
+
.next
|
|
8
|
+
out
|
|
9
|
+
build
|
|
10
|
+
|
|
11
|
+
# Environment
|
|
12
|
+
.env
|
|
13
|
+
.env.local
|
|
14
|
+
.env.*.local
|
|
15
|
+
*.local
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.idea
|
|
19
|
+
.vscode/*
|
|
20
|
+
!.vscode/settings.json
|
|
21
|
+
!.vscode/extensions.json
|
|
22
|
+
|
|
23
|
+
# Logs
|
|
24
|
+
*.log
|
|
25
|
+
npm-debug.log*
|
|
26
|
+
pnpm-debug.log*
|
|
27
|
+
|
|
28
|
+
# Testing
|
|
29
|
+
coverage
|
|
30
|
+
.nyc_output
|
|
31
|
+
|
|
32
|
+
# Turbo
|
|
33
|
+
.turbo
|
|
34
|
+
|
|
35
|
+
# OS
|
|
36
|
+
.DS_Store
|
|
37
|
+
Thumbs.db
|
|
38
|
+
|
|
39
|
+
# Docker
|
|
40
|
+
.docker
|
|
41
|
+
|
|
42
|
+
# Misc
|
|
43
|
+
*.tgz
|
|
44
|
+
.cache
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}",
|
|
3
|
+
"version": "1.1.4",
|
|
4
|
+
"private": true,
|
|
5
|
+
"packageManager": "pnpm@9.0.0",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "turbo build",
|
|
8
|
+
"dev": "turbo dev --filter='./apps/*'",
|
|
9
|
+
"lint": "turbo lint",
|
|
10
|
+
"lint:fix": "turbo lint:fix",
|
|
11
|
+
"format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
12
|
+
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
13
|
+
"test": "turbo test",
|
|
14
|
+
"test:coverage": "turbo test:coverage",
|
|
15
|
+
"typecheck": "turbo typecheck",
|
|
16
|
+
"clean": "turbo clean && rm -rf node_modules",
|
|
17
|
+
"nexu:version": "cat \"$PNPM_SCRIPT_SRC_DIR/.nexu-version\" 2>/dev/null || cat .nexu-version",
|
|
18
|
+
"prepare": "husky install",
|
|
19
|
+
"docker:dev": "docker-compose -f docker/docker-compose.dev.yml up",
|
|
20
|
+
"docker:build": "docker-compose -f docker/docker-compose.prod.yml build",
|
|
21
|
+
"docker:prod": "docker-compose -f docker/docker-compose.prod.yml up -d",
|
|
22
|
+
"generate:app": "node scripts/generate-app.mjs",
|
|
23
|
+
"audit": "node scripts/audit.mjs",
|
|
24
|
+
"audit:security": "node scripts/audit.mjs --security",
|
|
25
|
+
"audit:quality": "node scripts/audit.mjs --quality",
|
|
26
|
+
"audit:fix": "node scripts/audit.mjs --quality --fix",
|
|
27
|
+
"changeset": "changeset",
|
|
28
|
+
"version-packages": "changeset version",
|
|
29
|
+
"release": "changeset publish"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@changesets/cli": "^2.27.0",
|
|
33
|
+
"@commitlint/cli": "^20.3.1",
|
|
34
|
+
"@commitlint/config-conventional": "^20.3.1",
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
36
|
+
"@typescript-eslint/parser": "^7.0.0",
|
|
37
|
+
"@vitest/coverage-v8": "^2.0.0",
|
|
38
|
+
"@vitest/ui": "^2.0.0",
|
|
39
|
+
"eslint": "^8.57.0",
|
|
40
|
+
"eslint-config-prettier": "^10.1.8",
|
|
41
|
+
"eslint-plugin-import": "^2.29.0",
|
|
42
|
+
"eslint-plugin-unused-imports": "^4.3.0",
|
|
43
|
+
"husky": "^9.0.0",
|
|
44
|
+
"lint-staged": "^16.2.7",
|
|
45
|
+
"prettier": "^3.8.0",
|
|
46
|
+
"prettier-plugin-tailwindcss": "^0.7.2",
|
|
47
|
+
"turbo": "^2.7.5",
|
|
48
|
+
"typescript": "^5.4.0",
|
|
49
|
+
"vitest": "^2.0.0"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@repo/auth",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./hooks": {
|
|
15
|
+
"types": "./dist/hooks/index.d.ts",
|
|
16
|
+
"import": "./dist/hooks/index.mjs",
|
|
17
|
+
"require": "./dist/hooks/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./components": {
|
|
20
|
+
"types": "./dist/components/index.d.ts",
|
|
21
|
+
"import": "./dist/components/index.mjs",
|
|
22
|
+
"require": "./dist/components/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./next": {
|
|
25
|
+
"types": "./dist/next/index.d.ts",
|
|
26
|
+
"import": "./dist/next/index.mjs",
|
|
27
|
+
"require": "./dist/next/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsup",
|
|
32
|
+
"dev": "tsup --watch",
|
|
33
|
+
"lint": "eslint src/",
|
|
34
|
+
"lint:fix": "eslint src/ --fix",
|
|
35
|
+
"typecheck": "tsc --noEmit"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"js-cookie": "^3.0.5",
|
|
39
|
+
"jwt-decode": "^4.0.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@repo/config": "workspace:*",
|
|
43
|
+
"@types/js-cookie": "^3.0.6",
|
|
44
|
+
"@types/node": "^22.0.0",
|
|
45
|
+
"@types/react": "^19.2.8",
|
|
46
|
+
"@types/react-dom": "^19.2.3",
|
|
47
|
+
"react": "^19.2.3",
|
|
48
|
+
"tsup": "^8.0.0",
|
|
49
|
+
"typescript": "^5.4.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
53
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
54
|
+
"next": ">=13.0.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependenciesMeta": {
|
|
57
|
+
"next": {
|
|
58
|
+
"optional": true
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useRequireAuth } from '../hooks/useRequireAuth';
|
|
4
|
+
import type { ProtectedRouteProps } from '../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Protected route component that requires authentication
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* // Basic usage
|
|
12
|
+
* <ProtectedRoute redirectTo="/login">
|
|
13
|
+
* <Dashboard />
|
|
14
|
+
* </ProtectedRoute>
|
|
15
|
+
*
|
|
16
|
+
* // With loading fallback
|
|
17
|
+
* <ProtectedRoute
|
|
18
|
+
* redirectTo="/login"
|
|
19
|
+
* fallback={<LoadingSpinner />}
|
|
20
|
+
* >
|
|
21
|
+
* <Dashboard />
|
|
22
|
+
* </ProtectedRoute>
|
|
23
|
+
*
|
|
24
|
+
* // With role-based access
|
|
25
|
+
* <ProtectedRoute
|
|
26
|
+
* redirectTo="/unauthorized"
|
|
27
|
+
* roles={['admin', 'moderator']}
|
|
28
|
+
* >
|
|
29
|
+
* <AdminPanel />
|
|
30
|
+
* </ProtectedRoute>
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function ProtectedRoute({
|
|
34
|
+
children,
|
|
35
|
+
fallback,
|
|
36
|
+
redirectTo = '/login',
|
|
37
|
+
roles,
|
|
38
|
+
permissions,
|
|
39
|
+
}: ProtectedRouteProps) {
|
|
40
|
+
const { isAuthenticated, isLoading, user } = useRequireAuth({
|
|
41
|
+
redirectTo,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Show loading state
|
|
45
|
+
if (isLoading) {
|
|
46
|
+
return fallback ? <>{fallback}</> : null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Not authenticated - useRequireAuth will handle redirect
|
|
50
|
+
if (!isAuthenticated) {
|
|
51
|
+
return fallback ? <>{fallback}</> : null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Check roles if specified
|
|
55
|
+
if (roles && roles.length > 0) {
|
|
56
|
+
const userRoles = (user?.metadata?.roles as string[]) || [];
|
|
57
|
+
const hasRole = roles.some(role => userRoles.includes(role));
|
|
58
|
+
|
|
59
|
+
if (!hasRole) {
|
|
60
|
+
return fallback ? <>{fallback}</> : null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Check permissions if specified
|
|
65
|
+
if (permissions && permissions.length > 0) {
|
|
66
|
+
const userPermissions = (user?.metadata?.permissions as string[]) || [];
|
|
67
|
+
const hasPermission = permissions.every(perm => userPermissions.includes(perm));
|
|
68
|
+
|
|
69
|
+
if (!hasPermission) {
|
|
70
|
+
return fallback ? <>{fallback}</> : null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return <>{children}</>;
|
|
75
|
+
}
|