@fraza/start 0.3.13 → 0.3.15

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/CHANGELOG.md CHANGED
@@ -4,6 +4,33 @@ Historique des versions publiées de `@fraza/start`.
4
4
 
5
5
  Ce fichier est généré par `fraza-module changelog` à partir des messages de commit. Ne pas le modifier à la main.
6
6
 
7
+ ## 0.3.15 (2026-10-29)
8
+
9
+ Maintenance interne, aucun changement de comportement.
10
+
11
+ ## 0.3.14 (2026-10-28)
12
+
13
+ ### Ruptures
14
+
15
+ - leave the local development setup to fraza-dev init
16
+ - generate compose.yaml, fraza-dev scripts and a first test
17
+
18
+ ### Ajouts
19
+
20
+ - **start** : generate compose.yaml, fraza-dev scripts and a first test (359a957)
21
+
22
+ ### Corrections
23
+
24
+ - **start** : start npm through a shell on Windows in generate-notices (ab746c9)
25
+
26
+ ### Refontes
27
+
28
+ - **start** : leave the local development setup to fraza-dev init (e5a5f0e)
29
+
30
+ ### Autres
31
+
32
+ - drop the Gitea workflow, tests run locally (01b5765)
33
+
7
34
  ## 0.3.13 (2026-10-26)
8
35
 
9
36
  Maintenance interne, aucun changement de comportement.
package/README.md CHANGED
@@ -21,7 +21,7 @@ npx @fraza/start
21
21
  ## Prérequis
22
22
 
23
23
  - Node.js 20.12 ou plus.
24
- - Une base PostgreSQL 14 ou plus.
24
+ - Docker, pour les services locaux du `compose.yaml` : PostgreSQL, S3 et boîte de réception. Sans Docker, une base PostgreSQL 14 ou plus.
25
25
  - Un dossier vide. Seules les métadonnées d'éditeur ou de git y sont tolérées : `.git`, `.vscode`, `.idea`, `.DS_Store`, `LICENSE`.
26
26
 
27
27
  ## Utilisation
@@ -32,38 +32,43 @@ Dans le dossier du nouveau projet :
32
32
  npx @fraza/start
33
33
  ```
34
34
 
35
- Renseignez au moins `FRAZA_DATABASE_URL` dans `.env.local`. `npx fraza-doctor` liste les variables qui manquent vraiment. Créez ensuite les tables et démarrez :
35
+ Puis démarrez les services locaux, créez les tables et lancez le site :
36
36
 
37
37
  ```bash
38
+ npm run services
38
39
  npx fraza-db init
39
40
  npm run dev
40
41
  ```
41
42
 
42
- Ouvrez `http://localhost:3000/auth` pour créer le premier compte, qui reçoit le rôle `admin`.
43
+ `.env.local` est déjà rempli pour les services du `compose.yaml` : il n'y a rien à saisir. `npm run services` choisit des ports libres pour cette machine et les y écrit. Ouvrez l'adresse affichée par `npm run dev`, d'habitude `http://localhost:3000/auth`, pour créer le premier compte, qui reçoit le rôle `admin`. Les courriels du site arrivent dans la boîte de réception affichée par `npm run services`.
44
+
45
+ Sans Docker, faites viser `FRAZA_DATABASE_URL` vers votre PostgreSQL dans `.env.local`, et posez `FRAZA_EMAIL_PROVIDER=log` pour lire les courriels dans le terminal. Voir [Développer en local](https://docs.fraza.ca/docs/guides/developper-en-local).
46
+
47
+ Un collègue qui clone le projet lance les mêmes trois commandes : `npm run dev` crée son `.env.local` depuis `.env.example`.
43
48
 
44
49
  ## Ce que fait le CLI
45
50
 
46
51
  1. Crée le projet avec `create-next-app` 16.4.3, la version de Next contre laquelle le core est validé.
47
52
  2. Remplace le dossier `app/` de Next par les gabarits Fraza : administration, authentification, API, page d'accueil, pages d'erreur, gabarits de page, exemples de blocs, `theme.js`, `instrumentation.js` et `jsconfig.json`.
48
- 3. Ajoute les scripts `dev`, `build` et `postinstall`, qui lancent `fraza-modules sync`.
53
+ 3. Ajoute les scripts `dev` (`fraza-dev`, qui lance `fraza-modules sync` puis `next dev`), `build` et `postinstall` (`fraza-modules sync`).
49
54
  4. Masque l'indicateur de développement de Next dans `next.config.mjs`.
50
55
  5. Ajoute `!.env.example` et `app/.fraza/` au `.gitignore`, en gardant la règle `.env*` de Next.
51
56
  6. Ajoute un bloc Fraza à l'`AGENTS.md`, qui renvoie un agent à la documentation livrée dans `node_modules/@fraza/core/dist/docs/`.
52
57
  7. Écrit le `.npmrc` du projet, sans jeton.
53
58
  8. Installe `@fraza/core`.
54
- 9. Crée `.env.example`, suivi par git, et `.env.local`, ignoré par git, avec `FRAZA_ENCRYPTION_KEY` générée et `NEXT_PUBLIC_URL` locale. Crée aussi `.env.development.local`, ignoré par git, avec `NEXT_PUBLIC_URL=http://localhost:3000` et `FRAZA_DEVKIT=true`.
59
+ 9. Crée `.env.example`, suivi par git, avec les valeurs locales du `compose.yaml`, et `.env.local`, ignoré par git, la même copie avec `FRAZA_ENCRYPTION_KEY` générée.
60
+ 10. Lance `npx fraza-dev init` du core, qui ajoute le développement local : le `compose.yaml` des services, les scripts `services`, `services:stop`, `services:reset` et `test`, un premier test dans `test/`, et le `distDir` du serveur de test dans `next.config.mjs`. La même commande sert à un projet créé par une version antérieure.
55
61
 
56
62
  ## Variables d'environnement
57
63
 
58
64
  | Fichier | Contenu | Suivi par git |
59
65
  |---|---|---|
60
- | `.env.example` | La liste des variables, sans aucune valeur secrète. Une variable ajoutée par le projet y entre aussi. | Oui |
61
- | `.env.local` | Les valeurs de cette machine : base de données, stockage, courriel, clés. | Non |
62
- | `.env.development.local` | Les valeurs du développement local, lues seulement par `npm run dev` : URL locale et devkit de l'admin. | Non |
66
+ | `.env.example` | La liste des variables, avec les valeurs locales du `compose.yaml` et aucune valeur secrète. Une variable ajoutée par le projet y entre aussi. | Oui |
67
+ | `.env.local` | Les valeurs de cette machine : ports locaux, clé de chiffrement, clés de test. | Non |
63
68
 
64
69
  En production, les variables se saisissent dans la plateforme d'hébergement, jamais dans un fichier suivi par git. Partez de `.env.example` pour la liste.
65
70
 
66
- **Copiez `FRAZA_ENCRYPTION_KEY` telle quelle depuis `.env.local`, et ne la changez jamais.** Tout ce que le site chiffre en base l'est avec cette clé : une nouvelle clé rend ces données illisibles. Gardez-en une copie hors du serveur.
71
+ **Copiez `FRAZA_ENCRYPTION_KEY` telle quelle depuis `.env.local`, et ne la changez jamais.** Tout ce que le site chiffre en base l'est avec cette clé : une nouvelle clé rend ces données illisibles. Gardez-en une copie dans le coffre de l'équipe, hors du serveur.
67
72
 
68
73
  La liste complète est dans [Variables d'environnement](https://docs.fraza.ca/docs/reference/configuration/variables-d-environnement).
69
74
 
package/bin/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  MIN_NODE,
11
11
  REGISTRY_HOST,
12
12
  findConflictingEntries,
13
- hideDevIndicators,
13
+ completeNextConfig,
14
14
  isSupportedNode,
15
15
  withFrazaGitignore,
16
16
  withFrazaScripts,
@@ -133,7 +133,7 @@ async function initProject() {
133
133
  fs.cpSync(templatesPath, cwd, { recursive: true, force: true });
134
134
  done('Gabarits copiés');
135
135
 
136
- if (hideDevIndicators(path.join(cwd, 'next.config.mjs'))) {
136
+ if (completeNextConfig(path.join(cwd, 'next.config.mjs'))) {
137
137
  done('Indicateur de développement de Next masqué dans next.config.mjs');
138
138
  } else {
139
139
  fail('next.config.mjs non reconnu : ajouter `devIndicators: false` à la main');
@@ -169,18 +169,26 @@ async function initProject() {
169
169
  const env = writeEnvFiles(envTemplate, cwd);
170
170
  if (env.example) done('.env.example créé à partir du modèle de @fraza/core');
171
171
  if (env.local) done('.env.local créé, FRAZA_ENCRYPTION_KEY générée');
172
- if (env.development) done('.env.development.local créé (URL locale, devkit activé)');
172
+
173
+ // Le développement local appartient au core : compose.yaml, scripts
174
+ // services et test, premier test, distDir du serveur de test. La même
175
+ // commande l'ajoute à un projet existant.
176
+ step('Mise en place du développement local (fraza-dev init)');
177
+ execSync('npx fraza-dev init', { stdio: 'inherit' });
173
178
 
174
179
  const file = (name) => `${c.cyan}${name}${c.reset}`;
175
180
  const dim = (text) => `${c.dim}${text}${c.reset}`;
176
181
 
177
182
  console.log(`\n ${c.green}${c.bold}Projet prêt.${c.reset} Étapes suivantes :\n`);
178
- console.log(` ${dim('1.')} Remplir les variables de ${file('.env.local')}, à commencer par ${file('FRAZA_DATABASE_URL')}`);
179
- console.log(` ${dim('Ce fichier reste sur cette machine. Le modèle sans secret,')} ${file('.env.example')}${dim(', est suivi par git.')}`);
183
+ console.log(` ${dim('1.')} Démarrer les services locaux : PostgreSQL, S3 et boîte de réception (Docker)`);
184
+ console.log(` ${dim('npm run services')}`);
185
+ console.log(` ${dim('Sans Docker : viser son propre PostgreSQL dans')} ${file('.env.local')}${dim(', et')} ${file('FRAZA_EMAIL_PROVIDER=log')}${dim('.')}`);
180
186
  console.log(` ${dim('2.')} Initialiser la base de données`);
181
187
  console.log(` ${dim('npx fraza-db init')}`);
182
188
  console.log(` ${dim('3.')} Démarrer le site`);
183
189
  console.log(` ${dim('npm run dev')}\n`);
190
+ console.log(` ${file('.env.local')} ${dim('porte les valeurs de cette machine. Le modèle sans secret,')} ${file('.env.example')}${dim(', est suivi par git :')}`);
191
+ console.log(` ${dim('un collègue qui clone le projet lance les mêmes trois commandes.')}\n`);
184
192
 
185
193
  console.log(` ${c.bold}En production :${c.reset} les variables se saisissent dans la plateforme d'hébergement (Coolify, par exemple),`);
186
194
  console.log(` ${dim('jamais dans un fichier suivi par git.')} ${file('FRAZA_ENCRYPTION_KEY')} ${dim('se copie telle quelle depuis')} ${file('.env.local')}${dim(' :')}`);
package/bin/project.js CHANGED
@@ -113,30 +113,48 @@ export function writeAgentsBlock(agentsPath, block) {
113
113
  }
114
114
 
115
115
  /**
116
- * Masque l'indicateur de développement de Next dans le `next.config.mjs` écrit
117
- * par `create-next-app`. Le fichier est complété, jamais remplacé : avec
116
+ * Lignes que start ajoute à la configuration de Next, chacune repérée par sa
117
+ * clé. `devIndicators: false` masque l'indicateur de développement de Next.
118
+ * Le `distDir` du serveur de test vient ensuite de `fraza-dev init`, qui le
119
+ * pose aussi sur un projet existant.
120
+ */
121
+ const NEXT_CONFIG_LINES = [
122
+ { key: 'devIndicators', line: ' devIndicators: false,' },
123
+ ];
124
+
125
+ /**
126
+ * Complète le `next.config.mjs` écrit par `create-next-app` avec les lignes de
127
+ * `NEXT_CONFIG_LINES`. Le fichier est complété, jamais remplacé : avec
118
128
  * Turbopack, `create-next-app` peut y brancher Tailwind (règle `turbopack.rules`
119
129
  * vers `@tailwindcss/turbopack`, sans `postcss.config.mjs`). Un gabarit qui
120
- * l'écraserait laisserait alors le projet sans aucun style.
130
+ * l'écraserait laisserait alors le projet sans aucun style. Une clé déjà
131
+ * présente n'est pas touchée.
121
132
  * @param {string} configPath
122
133
  * @returns {boolean} `false` si le fichier manque ou n'a pas la forme attendue.
123
134
  */
124
- export function hideDevIndicators(configPath) {
135
+ export function completeNextConfig(configPath) {
125
136
  if (!fs.existsSync(configPath)) return false;
126
137
 
127
138
  const existing = fs.readFileSync(configPath, 'utf-8');
128
- if (existing.includes('devIndicators')) return true;
139
+ const missing = NEXT_CONFIG_LINES.filter(({ key }) => !existing.includes(key));
140
+ if (missing.length === 0) return true;
129
141
 
130
142
  const pattern = /(const nextConfig = \{\n)/;
131
143
  if (!pattern.test(existing)) return false;
132
144
 
133
- fs.writeFileSync(configPath, existing.replace(pattern, '$1 devIndicators: false,\n'));
145
+ const lines = missing.map(({ line }) => `${line}\n`).join('');
146
+ fs.writeFileSync(configPath, existing.replace(pattern, () => `const nextConfig = {\n${lines}`));
134
147
  return true;
135
148
  }
136
149
 
137
150
  /**
138
- * Complète le `package.json` écrit par `create-next-app` : `fraza-modules sync`
139
- * avant `next dev` et `next build`, et à chaque installation.
151
+ * Complète le `package.json` écrit par `create-next-app` :
152
+ *
153
+ * - `dev` passe par `fraza-dev`, qui crée `.env.local` s'il manque, choisit le
154
+ * port du site pour cette machine, lance `fraza-modules sync` puis `next dev` ;
155
+ * - `build` et `postinstall` lancent `fraza-modules sync`.
156
+ *
157
+ * Les scripts `services*` et `test` viennent ensuite de `fraza-dev init`.
140
158
  * @param {object} pkg
141
159
  * @param {Record<string, string>} siteOverrides
142
160
  * @returns {object} Un nouvel objet, `pkg` n'est pas modifié.
@@ -144,7 +162,7 @@ export function hideDevIndicators(configPath) {
144
162
  export function withFrazaScripts(pkg, siteOverrides = {}) {
145
163
  const next = { ...pkg, scripts: { ...pkg.scripts } };
146
164
  next.scripts.postinstall = 'fraza-modules sync';
147
- next.scripts.dev = 'fraza-modules sync && next dev';
165
+ next.scripts.dev = 'fraza-dev';
148
166
  next.scripts.build = 'fraza-modules sync && next build';
149
167
  next.scripts.audit = 'npm audit --omit=dev';
150
168
 
@@ -258,34 +276,21 @@ export function fillLocalEnv(template, { key = randomBytes(32).toString('hex'),
258
276
  }
259
277
 
260
278
  /**
261
- * Contenu de `.env.development.local` : les valeurs du développement local, que
262
- * Next.js ne lit qu'avec `next dev` et qui passent avant `.env.local`. On y met
263
- * l'origine locale et le devkit de l'admin, qui ne doivent jamais aller en
264
- * production.
265
- */
266
- export const DEVELOPMENT_ENV = [
267
- '# Valeurs du développement local, lues par Next.js avec `next dev` seulement,',
268
- '# avant celles de .env.local. Ignoré par git.',
269
- 'NEXT_PUBLIC_URL=http://localhost:3000',
270
- 'FRAZA_DEVKIT=true',
271
- '',
272
- ].join('\n');
273
-
274
- /**
275
- * Crée `.env.example` (copie du modèle du core, suivie par git), `.env.local`
276
- * (la même copie remplie pour cette machine, ignorée par git) et
277
- * `.env.development.local` (`DEVELOPMENT_ENV`, ignoré par git). Un fichier qui
279
+ * Crée `.env.example` (copie du modèle du core, suivie par git) et `.env.local`
280
+ * (la même copie remplie pour cette machine, ignorée par git). Un fichier qui
278
281
  * existe déjà n'est jamais remplacé.
282
+ *
283
+ * Il n'y a pas de `.env.development.local` : il passerait avant `.env.local` et
284
+ * figerait `NEXT_PUBLIC_URL`, que `fraza-dev` fait suivre au port du site.
279
285
  * @param {string} templatePath `node_modules/@fraza/core/.env.example`.
280
286
  * @param {string} projectDir
281
- * @returns {{ example: boolean, local: boolean, development: boolean }} Les fichiers créés.
287
+ * @returns {{ example: boolean, local: boolean }} Les fichiers créés.
282
288
  */
283
289
  export function writeEnvFiles(templatePath, projectDir) {
284
290
  const template = fs.readFileSync(templatePath, 'utf-8');
285
291
  const examplePath = path.join(projectDir, '.env.example');
286
292
  const localPath = path.join(projectDir, '.env.local');
287
- const developmentPath = path.join(projectDir, '.env.development.local');
288
- const created = { example: false, local: false, development: false };
293
+ const created = { example: false, local: false };
289
294
 
290
295
  if (!fs.existsSync(examplePath)) {
291
296
  fs.writeFileSync(examplePath, template);
@@ -296,9 +301,5 @@ export function writeEnvFiles(templatePath, projectDir) {
296
301
  fs.writeFileSync(localPath, fillLocalEnv(template), { mode: 0o600 });
297
302
  created.local = true;
298
303
  }
299
- if (!fs.existsSync(developmentPath)) {
300
- fs.writeFileSync(developmentPath, DEVELOPMENT_ENV);
301
- created.development = true;
302
- }
303
304
  return created;
304
305
  }
package/bin/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // AUTO-GÉNÉRÉ par `fraza-module sync-version`, ne pas modifier à la main.
2
- export const STARTER_VERSION = '0.3.13';
2
+ export const STARTER_VERSION = '0.3.15';
package/changelog.json CHANGED
@@ -1,6 +1,61 @@
1
1
  {
2
2
  "name": "@fraza/start",
3
3
  "versions": [
4
+ {
5
+ "version": "0.3.15",
6
+ "date": "2026-10-29",
7
+ "breaking": [],
8
+ "envAdded": [],
9
+ "envRemoved": [],
10
+ "templateChanged": [],
11
+ "action": [],
12
+ "entries": []
13
+ },
14
+ {
15
+ "version": "0.3.14",
16
+ "date": "2026-10-28",
17
+ "breaking": [
18
+ "leave the local development setup to fraza-dev init",
19
+ "generate compose.yaml, fraza-dev scripts and a first test"
20
+ ],
21
+ "envAdded": [],
22
+ "envRemoved": [],
23
+ "templateChanged": [
24
+ "compose.yaml",
25
+ "test/site.test.js"
26
+ ],
27
+ "action": [],
28
+ "entries": [
29
+ {
30
+ "type": "refactor",
31
+ "scope": "start",
32
+ "subject": "leave the local development setup to fraza-dev init",
33
+ "hash": "e5a5f0e",
34
+ "breaking": true
35
+ },
36
+ {
37
+ "type": "ci",
38
+ "scope": null,
39
+ "subject": "drop the Gitea workflow, tests run locally",
40
+ "hash": "01b5765",
41
+ "breaking": false
42
+ },
43
+ {
44
+ "type": "fix",
45
+ "scope": "start",
46
+ "subject": "start npm through a shell on Windows in generate-notices",
47
+ "hash": "ab746c9",
48
+ "breaking": false
49
+ },
50
+ {
51
+ "type": "feat",
52
+ "scope": "start",
53
+ "subject": "generate compose.yaml, fraza-dev scripts and a first test",
54
+ "hash": "359a957",
55
+ "breaking": true
56
+ }
57
+ ]
58
+ },
4
59
  {
5
60
  "version": "0.3.13",
6
61
  "date": "2026-10-26",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fraza/start",
3
- "version": "0.3.13",
3
+ "version": "0.3.15",
4
4
  "description": "CLI pour créer un projet Fraza avec Next.js",
5
5
  "publishConfig": {
6
6
  "access": "public"