@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 +27 -0
- package/README.md +14 -9
- package/bin/cli.js +13 -5
- package/bin/project.js +34 -33
- package/bin/version.js +1 -1
- package/changelog.json +55 -0
- package/package.json +1 -1
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
|
-
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
61
|
-
| `.env.local` | Les valeurs de cette machine :
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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.')}
|
|
179
|
-
console.log(` ${dim('
|
|
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
|
-
*
|
|
117
|
-
*
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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` :
|
|
139
|
-
*
|
|
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-
|
|
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
|
-
*
|
|
262
|
-
*
|
|
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
|
|
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
|
|
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.
|
|
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",
|