@fraza/start 0.0.0-stage → 0.3.4

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +180 -0
  2. package/LICENSE +21 -0
  3. package/README.md +169 -2
  4. package/THIRD-PARTY-NOTICES.md +11 -0
  5. package/bin/agents-block.md +61 -0
  6. package/bin/cli.js +197 -0
  7. package/bin/project.js +281 -0
  8. package/bin/version.js +2 -0
  9. package/changelog.json +577 -0
  10. package/package.json +42 -4
  11. package/templates/app/(admin)/admin/[...admin]/layout.js +3 -0
  12. package/templates/app/(admin)/admin/[...admin]/loading.js +3 -0
  13. package/templates/app/(admin)/admin/[...admin]/page.js +1 -0
  14. package/templates/app/(admin)/admin/error.js +4 -0
  15. package/templates/app/(admin)/admin/layout.js +17 -0
  16. package/templates/app/(admin)/admin/not-found.js +2 -0
  17. package/templates/app/(admin)/admin/page.js +5 -0
  18. package/templates/app/(auth)/auth/[...auth]/page.js +1 -0
  19. package/templates/app/(auth)/auth/page.js +5 -0
  20. package/templates/app/(public)/[...slug]/page.js +29 -0
  21. package/templates/app/(public)/error.js +6 -0
  22. package/templates/app/(public)/layout.js +17 -0
  23. package/templates/app/(public)/not-found.js +20 -0
  24. package/templates/app/(public)/page.js +248 -0
  25. package/templates/app/.fraza/blocks.client.js +8 -0
  26. package/templates/app/.fraza/blocks.server.js +4 -0
  27. package/templates/app/.fraza/modules.client.js +6 -0
  28. package/templates/app/.fraza/modules.generated.js +3 -0
  29. package/templates/app/.fraza/public-pages.server.js +4 -0
  30. package/templates/app/.fraza/sources.css +2 -0
  31. package/templates/app/.fraza/templates.server.js +5 -0
  32. package/templates/app/global-error.js +5 -0
  33. package/templates/app/icon.svg +1 -0
  34. package/templates/app/layout.js +31 -0
  35. package/templates/app/za/[...path]/not-found.js +6 -0
  36. package/templates/app/za/[...path]/page.js +8 -0
  37. package/templates/app/za/api/[...path]/route.js +1 -0
  38. package/templates/app/za/media/[filename]/route.js +1 -0
  39. package/templates/components/fraza/blocks/README.md +207 -0
  40. package/templates/components/fraza/blocks/accordion/fields.js +19 -0
  41. package/templates/components/fraza/blocks/accordion/render.js +47 -0
  42. package/templates/components/fraza/blocks/accordion/template.js +28 -0
  43. package/templates/components/fraza/blocks/callout/fields.js +15 -0
  44. package/templates/components/fraza/blocks/callout/render.js +28 -0
  45. package/templates/components/fraza/blocks/callout/template.js +37 -0
  46. package/templates/components/fraza/blocks/icon-list/fields.js +20 -0
  47. package/templates/components/fraza/blocks/icon-list/render.js +44 -0
  48. package/templates/components/fraza/blocks/icon-list/template.js +89 -0
  49. package/templates/components/fraza/blocks/three-cards/fields.js +19 -0
  50. package/templates/components/fraza/blocks/three-cards/render.js +33 -0
  51. package/templates/components/fraza/blocks/three-cards/template.js +57 -0
  52. package/templates/components/fraza/templates/README.md +293 -0
  53. package/templates/components/fraza/templates/content.js +271 -0
  54. package/templates/components/fraza/templates/default.js +18 -0
  55. package/templates/components/fraza/templates/post-blogue.js +97 -0
  56. package/templates/instrumentation.js +21 -0
  57. package/templates/jsconfig.json +9 -0
  58. package/templates/styles/globals.css +25 -0
  59. package/templates/theme.js +25 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,180 @@
1
+ # Journal des versions
2
+
3
+ Historique des versions publiées de `@fraza/start`.
4
+
5
+ Ce fichier est généré par `fraza-module changelog` à partir des messages de commit. Ne pas le modifier à la main.
6
+
7
+ ## 0.3.4 (2026-10-25)
8
+
9
+ ### Documentation
10
+
11
+ - update README and CLI configuration (7fecf81)
12
+
13
+ ## 0.3.3 (2026-10-24)
14
+
15
+ ### Action requise
16
+
17
+ - `npx fraza-doctor --fix`
18
+
19
+ ### Refontes
20
+
21
+ - **templates/components/fraza/blocks/icon-list** : update icon resolution (d5ad8f2)
22
+ - **components** : remove unused icon module (5fb8291)
23
+
24
+ ## 0.3.2 (2026-10-24)
25
+
26
+ ### Action requise
27
+
28
+ - `npx fraza-doctor --fix`
29
+
30
+ ### Refontes
31
+
32
+ - **components/frazaicons** : group imports and update descriptions (9fba523)
33
+
34
+ ## 0.3.1 (2026-10-24)
35
+
36
+ ### Action requise
37
+
38
+ - `npx fraza-doctor --fix`
39
+
40
+ ### Corrections
41
+
42
+ - **package.json, package-lock.json** : bump version to 0.3.0 (1a1aa74)
43
+
44
+ ### Refontes
45
+
46
+ - **cli** : ensure exact package versions for Fraza projects (70fa0a3)
47
+ - **fraza** : update icon names and descriptions (08cdcfe)
48
+
49
+ ### Autres
50
+
51
+ - fix(fraza(blocks)): update icon imports and labels (863eeab)
52
+
53
+ ## 0.2.6 (2026-10-23)
54
+
55
+ ### Action requise
56
+
57
+ - `npx fraza-doctor --fix`
58
+
59
+ ### Refontes
60
+
61
+ - **bin/cli.js, templates/components/fraza/blocks/**/*.render.js, templates/components/fraza/blocks/icon-list/template.js, test/templates.test.js** : update dependencies and imports to use @fraza/icons (8a1bc61)
62
+
63
+ ## 0.2.5 (2026-10-22)
64
+
65
+ ### Action requise
66
+
67
+ - `npx fraza-doctor --fix`
68
+
69
+ ### Refontes
70
+
71
+ - **fraza/icons** : update icon descriptions and paths (12490c5)
72
+
73
+ ## 0.2.4 (2026-10-21)
74
+
75
+ ### Action requise
76
+
77
+ - `npx fraza-doctor --fix`
78
+
79
+ Maintenance interne, aucun changement de comportement.
80
+
81
+ ## 0.2.3 (2026-10-21)
82
+
83
+ ### Action requise
84
+
85
+ - `npx fraza-doctor --fix`
86
+
87
+ ### Corrections
88
+
89
+ - **components/fraza** : update API endpoint URLs (a6839a7)
90
+
91
+ ### Refontes
92
+
93
+ - rename files from fraza to za (da3f362)
94
+
95
+ ## 0.2.2 (2026-10-20)
96
+
97
+ ### Corrections
98
+
99
+ - **package.json** : correct bin path (ef61e32)
100
+
101
+ ## 0.2.1 (2026-10-20)
102
+
103
+ ### Ruptures
104
+
105
+ - decide the admin 404 in the layout of [...admin], render it in the shell
106
+ - boot from @fraza/core/init, import Button by its own entry on the public pages
107
+ - drop app/(public)/loading.js, which made every unknown URL answer 200
108
+ - pin create-next-app to the tested Next, check the prerequisites first
109
+ - track .env.example, keep .env.local and every other .env out of git
110
+ - never copy the registry token into the project .npmrc
111
+ - drop fs-extra, require Node 20.12, test the generation steps
112
+
113
+ ### Action requise
114
+
115
+ - `npx fraza-doctor --fix`
116
+
117
+ ### Ajouts
118
+
119
+ - **release** : bump the version in npm run release, patch by default (6a87a26)
120
+ - **release** : check, publish, then tag and push, with changelog and version module (ce8f04a)
121
+ - **templates** : add error, loading and global-error boundaries (8a38c39)
122
+ - **cli** : write every message in French, like the rest of the product (d9b776f)
123
+ - **cli** : pin create-next-app to the tested Next, check the prerequisites first (63d338c)
124
+ - **cli** : track .env.example, keep .env.local and every other .env out of git (f7252c8)
125
+
126
+ ### Corrections
127
+
128
+ - **templates** : pass the links of an image and an icon list through sanitizeUrl (d268cc2)
129
+ - **templates** : decide the admin 404 in the layout of [...admin], render it in the shell (69c8bca)
130
+ - **templates** : render a linked image from the filename the Medias module resolves (8cfc288)
131
+ - **templates** : boot from @fraza/core/init, import Button by its own entry on the public pages (c62e26c)
132
+ - **templates** : drop app/(public)/loading.js, which made every unknown URL answer 200 (32fd83f)
133
+ - **cli** : give .env.local a header written for it, not the one of .env.example (382a376)
134
+ - **cli** : install the latest patch of the tested Next minor, 16.3.8 (83dea71)
135
+ - **templates** : use the core Button on the home page, drop its hard-coded title (7805ebc)
136
+ - **templates** : clip horizontal overflow without breaking sticky elements (b775491)
137
+ - **templates** : keep the @/* alias of create-next-app in jsconfig.json (2a5edf6)
138
+ - **templates** : title the public pages with FRAZA_NAME instead of an empty string (84fa798)
139
+ - **cli** : never copy the registry token into the project .npmrc (fc9160e)
140
+
141
+ ### Refontes
142
+
143
+ - **templates** : drop the dead branches of the public catch-all (27e9cb1)
144
+ - **cli** : drop fs-extra, require Node 20.12, test the generation steps (bd10684)
145
+
146
+ ### Documentation
147
+
148
+ - **readme** : npm run release warns about breaking changes in a patch, it no longer refuses (e913df9)
149
+ - **readme** : say npm run release refuses patch while breaking changes wait (ed209d8)
150
+ - **cli** : say the core now declares Next 16.3.8 as tested (9ddec07)
151
+ - **blocks** : say that two blocks under one id stop the startup (b3ed4ff)
152
+
153
+ ## 0.1.2 (2026-10-19)
154
+
155
+ ### Action requise
156
+
157
+ - `npx fraza-doctor --fix`
158
+
159
+ ### Ajouts
160
+
161
+ - write the @fraza-pro scope in .npmrc, no token needed for free packages (3279869)
162
+
163
+ ### Refontes
164
+
165
+ - **fraza** : update icon list to use local icon import (a0aa439)
166
+ - **api** : remove unused Icons component (ae72fcd)
167
+
168
+ ## 0.1.1 (2026-10-19)
169
+
170
+ ### Action requise
171
+
172
+ - `npx fraza-doctor --fix`
173
+
174
+ ### Ajouts
175
+
176
+ - initial Fraza 0.1.0 codebase (85f1053)
177
+
178
+ ### Autres
179
+
180
+ - Initial commit (402f173)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 HYKO
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,170 @@
1
- # Temporary Holding Version
1
+ # @fraza/start
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Crée un projet Fraza : un projet Next.js avec `@fraza/core` déjà branché.
4
+
5
+ > [!WARNING]
6
+ > Fraza est en version 0.x. L'API, la structure des projets et les fonctionnalités peuvent encore changer d'une version mineure à l'autre.
7
+
8
+ ## Prérequis
9
+
10
+ - Node.js 20.12 ou plus.
11
+ - Un dossier vide. Seules les métadonnées d'éditeur ou de git y sont tolérées : `.git`, `.vscode`, `.idea`, `.DS_Store`, `LICENSE` par exemple.
12
+ - Le registre npm joignable, sans compte : `@fraza/core` est publié sur npmjs.
13
+
14
+ Le CLI vérifie les trois avant d'écrire quoi que ce soit : un échec laisse le dossier tel qu'il était.
15
+
16
+ ## Ce que fait le CLI
17
+
18
+ Lancé dans un dossier vide, `npx @fraza/start` :
19
+
20
+ 1. crée un projet Next.js avec `create-next-app` 16.3.8, le dernier correctif de la version de Next contre laquelle le core est validé (`packages.next.tested` du `supported.json` du core). Toutes les options sont passées, aucune question n'est posée : JavaScript, Tailwind CSS, ESLint, App Router, pas de dossier `src/`, alias `@/*`, sans React Compiler ni Cache Components ;
21
+ 2. supprime le dossier `app/` de Next et copie les gabarits Fraza : routes de l'administration, de l'authentification et de l'API, page d'accueil publique (qui suit la mise en route du projet : `.env.local`, tables, premier compte), pages d'erreur et de chargement, gabarits de page, exemples de blocs, `theme.js`, `instrumentation.js` et `jsconfig.json` (l'alias `@/*` de Next, plus `@styles/*` et `@components/*`) ;
22
+ 3. ajoute au `package.json` les scripts `dev`, `build` et `postinstall`, qui lancent `fraza-modules sync` ;
23
+ 4. masque l'indicateur de développement de Next dans `next.config.mjs` ;
24
+ 5. ajoute au `.gitignore` les lignes `!.env.example` et `app/.fraza/`, en gardant la règle `.env*` de Next ;
25
+ 6. ajoute un bloc Fraza à l'`AGENTS.md` du projet ;
26
+ 7. écrit le `.npmrc` du projet : le scope `@fraza-pro` vers `https://registry.fraza.ca/`, sans jeton ;
27
+ 8. installe `@fraza/core` ;
28
+ 9. crée `.env.example`, copie du modèle du core suivie par git, et `.env.local`, la même copie remplie pour cette machine (`FRAZA_ENCRYPTION_KEY` générée, `NEXT_PUBLIC_URL` locale), ignorée par git. L'en-tête de `.env.local` est réécrit pour ce fichier : celui du modèle décrit `.env.example`.
29
+
30
+ ## Utilisation
31
+
32
+ ### 1. Lancer le CLI
33
+
34
+ Les paquets `@fraza` sont publiés sur npmjs : aucune configuration ni connexion n'est demandée. Dans le dossier du nouveau projet :
35
+
36
+ ```bash
37
+ npx @fraza/start
38
+ ```
39
+
40
+ ### 2. Configurer les variables d'environnement
41
+
42
+ Le CLI écrit deux fichiers à partir du modèle du core, qui ne porte que le nécessaire au démarrage :
43
+
44
+ | Fichier | Contenu | Suivi par git |
45
+ |---|---|---|
46
+ | `.env.example` | Le modèle tel quel, sans aucune valeur secrète. Une variable que le projet ajoute y entre, vide ou avec une valeur d'exemple. | Oui |
47
+ | `.env.local` | Les valeurs de cette machine : base de données, stockage, courriel, clés. | Non |
48
+
49
+ Remplissez `.env.local`. `FRAZA_ENCRYPTION_KEY` y est déjà : le CLI génère 32 octets aléatoires en hexadécimal. Next.js et les CLI `fraza-*` lisent `.env.local` d'eux-mêmes.
50
+
51
+ Le `.gitignore` garde la règle `.env*` de `create-next-app` et n'en retire que `.env.example` : un secret ne peut pas partir dans git par un `.env` oublié.
52
+
53
+ La liste complète des variables, avec leur valeur par défaut et leur effet, est dans la documentation du core, livrée hors ligne dans `node_modules/@fraza/core/dist/docs/03-reference/06-configuration/variables-d-environnement.md`.
54
+
55
+ `npx fraza-doctor` dit lesquelles manquent vraiment : il connaît toutes les variables du core et de chaque module installé, et ne signale que celles dont l'absence empêche le projet de fonctionner.
56
+
57
+ ### 3. Initialiser la base de données
58
+
59
+ ```bash
60
+ npx fraza-db init
61
+ ```
62
+
63
+ ## Les variables en production
64
+
65
+ Les variables de production se saisissent dans la plateforme d'hébergement (Coolify, par exemple, ou l'environnement d'un conteneur), jamais dans un fichier suivi par git. Partez de `.env.example` pour la liste.
66
+
67
+ **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, dans un gestionnaire de mots de passe par exemple.
68
+
69
+ ## Le `.npmrc` et les modules Pro
70
+
71
+ Le CLI écrit un `.npmrc` dans le projet, avec une ligne et rien d'autre :
72
+
73
+ ```ini
74
+ @fraza-pro:registry=https://registry.fraza.ca/
75
+ ```
76
+
77
+ `@fraza/core` et les modules gratuits viennent de npmjs, sans ligne ni connexion. Aucun jeton n'est recopié, même si `~/.npmrc` en porte un. Sans secret, le fichier reste suivi par git, et la machine de build sait où chercher les modules Pro : sans lui, `npm ci` les cherche sur npmjs et échoue avec un 404.
78
+
79
+ Chaque version gratuite est aussi publiée sur `https://registry.fraza.ca/`, en copie de secours. Si npmjs devient indisponible, la page « Registre de secours » de la documentation du core explique comment y basculer.
80
+
81
+ Les modules Pro (`@fraza-pro/module-*`) demandent un jeton. Connectez-vous au registre, puis lancez `fraza-key`, qui écrit le jeton dans le `.npmrc` du projet :
82
+
83
+ ```bash
84
+ npm login --registry=https://registry.fraza.ca/
85
+ npx fraza-key
86
+ ```
87
+
88
+ Le jeton est alors en clair dans un fichier suivi par git : traitez-le comme une clé de licence propre au projet, en lecture seule, distincte du compte qui publie. La page `fraza-key` de la documentation du core détaille ce cas.
89
+
90
+ ## Pages d'erreur, de chargement et de page introuvable
91
+
92
+ Le projet reçoit six fichiers qui réexportent chacun un composant du core :
93
+
94
+ | Fichier | Composant du core | Rôle |
95
+ |---|---|---|
96
+ | `app/(admin)/admin/error.js` | `@fraza/core/features/admin/error` | Erreur au rendu d'une page de l'administration. |
97
+ | `app/(admin)/admin/not-found.js` | `@fraza/core/features/admin/not-found` | Page introuvable de l'administration, dans la coquille. |
98
+ | `app/(admin)/admin/[...admin]/layout.js` | `@fraza/core/features/admin/page-layout` | Vérifie la fiche et la permission d'une page d'admin avant que la réponse parte. |
99
+ | `app/(admin)/admin/[...admin]/loading.js` | `@fraza/core/features/admin/loading` | Chargement d'une page de l'administration. |
100
+ | `app/(public)/error.js` | `@fraza/core/shared/public/error` | Erreur au rendu d'une page du site public. |
101
+ | `app/global-error.js` | `@fraza/core/shared/global-error` | Erreur du layout racine lui-même. |
102
+
103
+ Ceux de l'administration suivent le core et n'ont pas à changer. Ceux du site public sont des gabarits, comme la page 404 : remplacez le réexport par un composant du projet pour leur donner l'allure du site.
104
+
105
+ Le site public n'a pas de `loading.js`, et ne doit pas en recevoir : il entourerait la page attrape-tout d'un `Suspense`, la réponse partirait avec le statut 200 avant que la page sache si le contenu existe, et toute URL inconnue répondrait 200 au lieu de 404. Une page qui veut un état de chargement pose son propre `Suspense`, après l'appel éventuel à `notFound()`.
106
+
107
+ Pour la même raison, le `loading.js` de l'administration vit sous `app/(admin)/admin/[...admin]/`, et non dans `app/(admin)/admin/` : à ce niveau, son `Suspense` entourerait aussi le layout de `[...admin]`, qui décide du 404 d'une page inconnue ou refusée. Un projet généré avant ce changement lance `npx fraza-doctor --fix`, qui déplace le fichier et ajoute les deux autres.
108
+
109
+ ## `AGENTS.md` du projet généré
110
+
111
+ Le CLI ajoute un bloc `fraza-agent-rules` à l'`AGENTS.md` créé par Next.js. Il indique qu'il s'agit d'un projet Fraza et renvoie à la documentation livrée dans le paquet, sous `node_modules/@fraza/core/dist/docs/`. Un agent qui ouvre le dépôt lit ainsi la documentation de la version exacte installée, sans accès réseau.
112
+
113
+ Le contenu du bloc est dans [`bin/agents-block.md`](./bin/agents-block.md). Il est délimité par ses propres marqueurs : `next dev` ne réécrit que le bloc `nextjs-agent-rules` et laisse celui-ci intact.
114
+
115
+ ## Contribuer
116
+
117
+ ### Installer un core local
118
+
119
+ La variable `FRAZA_START_CORE_SPEC` remplace la cible du `npm install` du core. Elle vaut `@fraza/core` par défaut. Elle sert aux tests de bout en bout, pour installer un core local au lieu de la version publiée :
120
+
121
+ ```bash
122
+ cd ../core
123
+ npm pack
124
+ cd ../projet-test
125
+ FRAZA_START_CORE_SPEC=../core/fraza-core-0.1.0.tgz npx ../start
126
+ ```
127
+
128
+ En PowerShell, définissez la variable avant de lancer le CLI :
129
+
130
+ ```powershell
131
+ $env:FRAZA_START_CORE_SPEC = "../core/fraza-core-0.1.0.tgz"
132
+ npx ../start
133
+ ```
134
+
135
+ Toute cible acceptée par `npm install` convient : une archive `.tgz`, un dossier ou une version précise. Cette variable sert au développement de Fraza. Un projet normal n'en a pas besoin.
136
+
137
+ ### Vérifier les gabarits
138
+
139
+ `npm run check:contract` vérifie que `templates/` suit le contrat d'amorçage déclaré par le core, et que la version de `create-next-app` épinglée dans `bin/project.js` est un correctif de la version mineure `packages.next.tested` du `supported.json` du core, au moins égal à celle-ci. Le script cherche un core buildé dans `../core`, puis dans `node_modules/@fraza/core`.
140
+
141
+ `npm run build` lance cette vérification, puis régénère `THIRD-PARTY-NOTICES.md`.
142
+
143
+ ### Lancer les tests
144
+
145
+ ```bash
146
+ npm test
147
+ ```
148
+
149
+ Les étapes de génération vivent dans `bin/project.js`, sans effet de bord à l'import. Les tests de `test/` les appellent une par une sur un dossier temporaire, avec `node:test` : aucune dépendance à installer.
150
+
151
+ `test/templates.test.js` lit les imports des gabarits, sans core installé. Le projet atteint `@fraza/core` par ses sous-chemins, jamais par la racine, et `instrumentation.js` démarre par `@fraza/core/init`. Les pages du site public, les gabarits de page et les `render.js` des blocs importent chaque composant et chaque icône par son propre sous-chemin (`@fraza/core/shared/components/Button`, `@fraza/icons/CheckIcon`) : les barrels `shared/components` et `@fraza/icons` tireraient tout le jeu dans le code envoyé au visiteur.
152
+
153
+ ### Publier
154
+
155
+ Le paquet suit la procédure de publication du core : voir [Publication](https://docs.fraza.ca/docs/contribution/publication). Ses outils sont ceux de `fraza-module`, lancés par `scripts/fraza-module.js` sur le core buildé de `../core`, puis de `node_modules/@fraza/core`. Le paquet n'installe pas le core : le déclarer en dépendance figerait dans le lockfile un core publié, qui peut ne pas encore porter ces outils.
156
+
157
+ | Script | Rôle |
158
+ |---|---|
159
+ | `npm run sync:version` | Recopie `package.json#version` dans `bin/version.js`, que le CLI affiche au lancement. |
160
+ | `npm run build:changelog` | Régénère `CHANGELOG.md`, `changelog.json` et `package.json#fraza`, avec les gabarits changés (`templateChanged`). |
161
+ | `npm run release` | Vérifie le paquet, monte sa version (`patch` par défaut), committe `chore: bump version to X.Y.Z`, le publie sur npmjs puis sur `registry.fraza.ca`, puis pose l'étiquette `v<version>` et la pousse (`fraza-module release`). |
162
+ | `npm run release:publish` | Publie la version actuelle sur chaque registre où elle manque (`fraza-module publish`). Sert à terminer une publication interrompue. |
163
+
164
+ Comme pour le core, `npm run release -- minor` monte la version mineure, pour un changement cassant en `0.x`. La commande liste les ruptures en attente depuis la dernière version et avertit si `patch` ne les annonce pas, puis publie quand même le niveau demandé. Avant toute écriture, elle fait aussi un `git fetch` et refuse une branche en retard sur le dépôt distant. `npm run release -- --dry-run` fait ces vérifications et affiche la version calculée sans rien écrire ni publier. `scripts/fraza-module.js` transmet ces arguments au core buildé de `../core`, qui doit donc porter la commande `release`.
165
+
166
+ ## Licence
167
+
168
+ Licence MIT. Copyright (c) 2026 HYKO. Voir [LICENSE](./LICENSE).
169
+
170
+ Ce paquet fait partie de Fraza Libre. Les dépendances tierces et leurs licences sont listées dans [THIRD-PARTY-NOTICES.md](./THIRD-PARTY-NOTICES.md).
@@ -0,0 +1,11 @@
1
+ # Avis relatifs aux composants tiers
2
+
3
+ Ce document inventorie les dépendances de production de `@fraza/start` et leurs licences.
4
+
5
+ Il est généré par `npm run build:notices` à partir de l'arbre réellement installé. Ne pas le modifier à la main.
6
+
7
+ `@fraza/start` ne bundle aucun code tiers : les dépendances ci-dessous sont installées séparément par le gestionnaire de paquets, depuis leurs sources respectives. Elles ne sont ni distribuées ni couvertes par la [licence MIT](./LICENSE) de ce paquet. Cet inventaire sert à vérifier qu'aucune licence copyleft ne contamine l'application qui installe le paquet, et à fournir la liste nécessaire aux obligations d'attribution du projet consommateur, dont le build, lui, bundle ces dépendances.
8
+
9
+ ## Résumé
10
+
11
+ Aucune. `@fraza/start` n'a pas de dépendance de production : tout ce dont il a besoin à l'exécution est déclaré en `peerDependencies` et fourni par le projet consommateur. Il n'y a donc aucun composant tiers à inventorier ici.
@@ -0,0 +1,61 @@
1
+ <!-- BEGIN:fraza-agent-rules -->
2
+
3
+ # This is a Fraza project
4
+
5
+ The project was generated by `npx @fraza/start`, and most of the behaviour comes
6
+ from `@fraza/core`: authentication, database, storage, emails, payments, PDF,
7
+ scheduled tasks, administration. Before writing anything, check whether the core
8
+ or an official module already does the job.
9
+
10
+ ## Where the documentation is
11
+
12
+ It ships inside the package, in French, matching the exact version installed
13
+ here, and readable offline:
14
+
15
+ `node_modules/@fraza/core/dist/docs/`
16
+
17
+ The documentation of the official modules lives there too, one folder per
18
+ module, under `node_modules/@fraza/core/dist/docs/06-modules/`. The module
19
+ packages themselves ship no docs folder. Each module's `README.md` covers its
20
+ installation.
21
+
22
+ ## Working rules
23
+
24
+ Read the relevant page before writing code. Fraza conventions take precedence
25
+ over Next.js habits, and the core often exposes a dedicated API where Next.js
26
+ offers a generic one.
27
+
28
+ To follow the project theme, light and dark modes included, style with the
29
+ role utilities (`bg-surface`, `text-fg`, `border-line`, `bg-primary`,
30
+ `text-accent`...) rather than Tailwind palette classes or hex values. The
31
+ appearance is set in `theme.js`. See `04-architecture/06-design-system.md` in
32
+ the docs.
33
+
34
+ Never edit anything in `app/.fraza/`. The directory is regenerated by
35
+ `fraza-modules sync`, which runs on every `npm run dev`, `npm run build` and
36
+ `npm install`.
37
+
38
+ ## The development server
39
+
40
+ The developer often already has `npm run dev` running, so check
41
+ `http://localhost:3000` before starting one. If it answers, use that server
42
+ rather than a second instance. You may kill and restart it when a change
43
+ requires it.
44
+
45
+ Leave a server running only if it is the one the developer opened. Always close
46
+ the ones you opened yourself: start them in background, keep track of their
47
+ process, and always kill them before you hand the work back.
48
+
49
+ `.env.local` holds the values of this machine (database, storage, keys) and is
50
+ never tracked by git. `.env.example` is the tracked template and must stay free
51
+ of any secret: a variable the project adds goes there empty or with a sample
52
+ value. In production, variables are set in the hosting platform, never in a
53
+ tracked file. Never change `FRAZA_ENCRYPTION_KEY`: data already encrypted with
54
+ it would become unreadable.
55
+
56
+ Environment variables are read at boot only, hot reload never picks up
57
+ `.env.local`. After changing one, restart the server before you trust what you
58
+ see.
59
+
60
+
61
+ <!-- END:fraza-agent-rules -->
package/bin/cli.js ADDED
@@ -0,0 +1,197 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync } from 'node:child_process';
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ import {
9
+ CREATE_NEXT_APP_VERSION,
10
+ MIN_NODE,
11
+ REGISTRY_URL,
12
+ findConflictingEntries,
13
+ hideDevIndicators,
14
+ isSupportedNode,
15
+ withFrazaGitignore,
16
+ withFrazaScripts,
17
+ writeAgentsBlock,
18
+ writeEnvFiles,
19
+ writeProjectNpmrc,
20
+ } from './project.js';
21
+ import { STARTER_VERSION } from './version.js';
22
+
23
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
24
+
25
+ const c = {
26
+ reset: '\x1b[0m',
27
+ dim: '\x1b[2m',
28
+ green: '\x1b[32m',
29
+ cyan: '\x1b[36m',
30
+ red: '\x1b[31m',
31
+ bold: '\x1b[1m',
32
+ };
33
+
34
+ // Source de vérité unique des `overrides` de l'écosystème Fraza.
35
+ //
36
+ // npm n'honore `overrides` que depuis le package.json racine du projet installé.
37
+ // Un `overrides` déclaré dans @fraza/core ou dans un module Fraza est ignoré au
38
+ // moment où le site les installe : il n'agit que sur le node_modules du dépôt de
39
+ // la librairie. Le seul endroit qui protège vraiment un site, c'est ici.
40
+ //
41
+ // Le bloc est vide, et c'est l'état normal. Une entrée ne s'ajoute que pour une
42
+ // faille qu'aucune mise à jour amont ne peut corriger, typiquement une version
43
+ // épinglée exactement par une dépendance directe. Elle se retire dès que l'amont
44
+ // est à jour de lui-même : un override laissé en place fige une version pour rien
45
+ // et donne une fausse impression de correctif.
46
+ //
47
+ // Format : { 'nom-du-paquet': '^1.2.3' }
48
+ //
49
+ // Attention, npm refuse un override qui porte sur un paquet déclaré en
50
+ // dependencies du site (erreur EOVERRIDE). Dans ce cas, corriger la dépendance
51
+ // directe plutôt que d'ajouter une entrée ici.
52
+ const SITE_OVERRIDES = {};
53
+
54
+ // Contributor-only override: the npm spec used to install the core. Defaults to
55
+ // the published package; the e2e test points it at a local tarball.
56
+ const CORE_SPEC = process.env.FRAZA_START_CORE_SPEC || '@fraza/core';
57
+
58
+ // Every create-next-app question answered on the command line, so the run never
59
+ // stops on a prompt and never depends on preferences saved on this machine.
60
+ // `--no-cache-components` is ignored by 16.3, which does not enable Cache
61
+ // Components, but keeps a later bump of the pin from turning them on: the
62
+ // admin and auth layouts read cookies outside <Suspense>, which fails
63
+ // `next build` under that mode.
64
+ const CREATE_NEXT_APP_ARGS = [
65
+ './',
66
+ '--js',
67
+ '--tailwind',
68
+ '--eslint',
69
+ '--app',
70
+ '--no-src-dir',
71
+ '--import-alias "@/*"',
72
+ '--empty',
73
+ '--agents-md',
74
+ '--no-react-compiler',
75
+ '--no-cache-components',
76
+ '--use-npm',
77
+ '--yes',
78
+ ];
79
+
80
+ const step = (msg) => process.stdout.write(` ${c.dim}◆${c.reset} ${msg}...\n`);
81
+ const done = (msg) => process.stdout.write(` ${c.green}✓${c.reset} ${msg}\n`);
82
+ const fail = (msg) => process.stdout.write(` ${c.red}✗${c.reset} ${msg}\n`);
83
+
84
+ // Vérifications faites avant d'écrire quoi que ce soit : un échec laisse le
85
+ // dossier tel qu'il était.
86
+ function checkPrerequisites(cwd) {
87
+ if (!isSupportedNode(process.versions.node)) {
88
+ throw new Error(`Node.js ${process.versions.node} détecté : @fraza/start demande Node.js ${MIN_NODE.join('.')} ou plus.`);
89
+ }
90
+
91
+ const conflicts = findConflictingEntries(cwd);
92
+ if (conflicts.length > 0) {
93
+ throw new Error(`Le dossier courant n'est pas vide (${conflicts.join(', ')}). Lancer @fraza/start dans un dossier vide.`);
94
+ }
95
+
96
+ // Un core local (FRAZA_START_CORE_SPEC) ne passe pas par le registre.
97
+ // `@fraza/core` vient du registre que npm choisit pour `@fraza` : npmjs par
98
+ // défaut, registry.fraza.ca si la configuration de l'utilisateur l'y envoie.
99
+ if (CORE_SPEC !== '@fraza/core') return;
100
+ try {
101
+ execSync('npm view @fraza/core version', { stdio: 'pipe', timeout: 30_000 });
102
+ } catch {
103
+ throw new Error('Le registre npm ne répond pas : @fraza/core n\'a pas pu être lu. Vérifier la connexion, puis relancer.');
104
+ }
105
+ }
106
+
107
+ async function initProject() {
108
+ const cwd = process.cwd();
109
+ try {
110
+ console.log(`\n ${c.bold}${c.cyan}fraza-start${c.reset} ${c.dim}${STARTER_VERSION}${c.reset}\n`);
111
+
112
+ checkPrerequisites(cwd);
113
+ done('Prérequis vérifiés');
114
+
115
+ step(`Création du projet Next.js (create-next-app ${CREATE_NEXT_APP_VERSION})`);
116
+ execSync(`npx --yes create-next-app@${CREATE_NEXT_APP_VERSION} ${CREATE_NEXT_APP_ARGS.join(' ')}`, { stdio: 'inherit' });
117
+ done('Projet Next.js créé');
118
+
119
+ fs.rmSync(path.join(cwd, 'app'), { recursive: true, force: true });
120
+ done('Dossier app/ de Next supprimé');
121
+
122
+ const packageJsonPath = path.join(cwd, 'package.json');
123
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
124
+ const projectName = packageJson.name || 'project';
125
+ fs.writeFileSync(path.join(cwd, 'README.md'), `# ${projectName}\n\nConstruit avec Next.js, Tailwind CSS et @fraza/core.\n`);
126
+ fs.writeFileSync(packageJsonPath, `${JSON.stringify(withFrazaScripts(packageJson, SITE_OVERRIDES), null, 2)}\n`);
127
+ done('README.md et package.json mis à jour');
128
+
129
+ const templatesPath = path.join(__dirname, '..', 'templates');
130
+ if (!fs.existsSync(templatesPath)) {
131
+ throw new Error('Dossier des gabarits introuvable dans @fraza/start.');
132
+ }
133
+ fs.cpSync(templatesPath, cwd, { recursive: true, force: true });
134
+ done('Gabarits copiés');
135
+
136
+ if (hideDevIndicators(path.join(cwd, 'next.config.mjs'))) {
137
+ done('Indicateur de développement de Next masqué dans next.config.mjs');
138
+ } else {
139
+ fail('next.config.mjs non reconnu : ajouter `devIndicators: false` à la main');
140
+ }
141
+
142
+ const gitignorePath = path.join(cwd, '.gitignore');
143
+ const gitignore = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
144
+ fs.writeFileSync(gitignorePath, withFrazaGitignore(gitignore));
145
+ done('.gitignore mis à jour');
146
+
147
+ const agentsBlockPath = path.join(__dirname, 'agents-block.md');
148
+ if (fs.existsSync(agentsBlockPath)) {
149
+ const block = fs.readFileSync(agentsBlockPath, 'utf-8').trim();
150
+ writeAgentsBlock(path.join(cwd, 'AGENTS.md'), block);
151
+ done('Bloc Fraza ajouté à AGENTS.md');
152
+ }
153
+
154
+ writeProjectNpmrc(path.join(cwd, '.npmrc'));
155
+ done('.npmrc créé (scope @fraza-pro, sans jeton)');
156
+
157
+ // Les gabarits importent leurs icônes de @fraza/icons : le projet le déclare
158
+ // lui-même, même s'il arrive aussi avec le core. Les dernières versions de
159
+ // tous les paquets Fraza vont ensemble ; elles sont écrites exactes, et
160
+ // `npx fraza-update` les fait avancer toutes à la fois.
161
+ step('Installation de @fraza/core et @fraza/icons');
162
+ execSync(`npm install --save-exact "${CORE_SPEC}" @fraza/icons`, { stdio: 'inherit' });
163
+ done('@fraza/core et @fraza/icons installés');
164
+
165
+ const envTemplate = path.join(cwd, 'node_modules', '@fraza', 'core', '.env.example');
166
+ if (!fs.existsSync(envTemplate)) {
167
+ throw new Error('Modèle .env.example introuvable dans @fraza/core.');
168
+ }
169
+ const env = writeEnvFiles(envTemplate, cwd);
170
+ if (env.example) done('.env.example créé à partir du modèle de @fraza/core');
171
+ if (env.local) done('.env.local créé, FRAZA_ENCRYPTION_KEY générée');
172
+
173
+ const file = (name) => `${c.cyan}${name}${c.reset}`;
174
+ const dim = (text) => `${c.dim}${text}${c.reset}`;
175
+
176
+ console.log(`\n ${c.green}${c.bold}Projet prêt.${c.reset} Étapes suivantes :\n`);
177
+ console.log(` ${dim('1.')} Remplir les variables de ${file('.env.local')}, à commencer par ${file('FRAZA_DATABASE_URL')}`);
178
+ console.log(` ${dim('Ce fichier reste sur cette machine. Le modèle sans secret,')} ${file('.env.example')}${dim(', est suivi par git.')}`);
179
+ console.log(` ${dim('2.')} Initialiser la base de données`);
180
+ console.log(` ${dim('npx fraza-db init')}`);
181
+ console.log(` ${dim('3.')} Démarrer le site`);
182
+ console.log(` ${dim('npm run dev')}\n`);
183
+
184
+ console.log(` ${c.bold}En production :${c.reset} les variables se saisissent dans la plateforme d'hébergement (Coolify, par exemple),`);
185
+ console.log(` ${dim('jamais dans un fichier suivi par git.')} ${file('FRAZA_ENCRYPTION_KEY')} ${dim('se copie telle quelle depuis')} ${file('.env.local')}${dim(' :')}`);
186
+ console.log(` ${dim('elle ne doit jamais changer, sinon les données chiffrées avec elle deviennent illisibles.')}\n`);
187
+
188
+ console.log(` ${c.bold}Modules Pro :${c.reset} se connecter au registre, puis écrire le jeton dans ${file('.npmrc')} avec ${file('npx fraza-key')}`);
189
+ console.log(` ${dim(`npm login --registry=${REGISTRY_URL}`)}`);
190
+ console.log(` ${dim('npx fraza-key')}\n`);
191
+ } catch (error) {
192
+ fail(error.message);
193
+ process.exit(1);
194
+ }
195
+ }
196
+
197
+ initProject();