@fraza/core 0.3.4 → 0.3.7
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 +21 -1
- package/README.md +71 -35
- package/THIRD-PARTY-NOTICES.md +25 -3
- package/changelog.json +54 -1
- package/dist/docs/02-guides/basculer-sur-le-registre-de-secours.md +3 -1
- package/dist/docs/03-reference/05-cli/fraza-module.md +15 -7
- package/dist/docs/05-contribution/05-publication.md +41 -10
- package/dist/docs/05-contribution/06-registre-verdaccio.md +1 -1
- package/dist/docs/05-contribution/index.md +1 -1
- package/dist/shared/lib/version.js +1 -1
- package/dist/tools/cli.js +14 -5
- package/dist/tools/publish.server.js +14 -8
- package/dist/tools/release.server.js +31 -17
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,27 @@ Historique des versions publiées de `@fraza/core`.
|
|
|
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.
|
|
7
|
+
## 0.3.7 (2026-10-25)
|
|
8
|
+
|
|
9
|
+
### Refontes
|
|
10
|
+
|
|
11
|
+
- **README** : update landing page to remove redundant commands (fe88136)
|
|
12
|
+
|
|
13
|
+
### Autres
|
|
14
|
+
|
|
15
|
+
- **README** : update content and structure (2a08dbf)
|
|
16
|
+
|
|
17
|
+
## 0.3.6 (2026-10-25)
|
|
18
|
+
|
|
19
|
+
Maintenance interne, aucun changement de comportement.
|
|
20
|
+
|
|
21
|
+
## 0.3.5 (2026-10-25)
|
|
22
|
+
|
|
23
|
+
### Refontes
|
|
24
|
+
|
|
25
|
+
- **docs, src/tools, test/tools** : update documentation and CLI for version intermediately published on Fraza registry (0595be8)
|
|
26
|
+
|
|
27
|
+
## 0.3.4 (2026-10-24)
|
|
8
28
|
|
|
9
29
|
### Refontes
|
|
10
30
|
|
package/README.md
CHANGED
|
@@ -1,57 +1,93 @@
|
|
|
1
|
-
|
|
1
|
+
<img src="https://docs.fraza.ca/readme/core.png" alt="Fraza : ce qui reste à écrire, c'est votre projet" width="100%">
|
|
2
2
|
|
|
3
|
-
Fraza
|
|
3
|
+
Fraza branche dans un projet Next.js ordinaire les comptes, les rôles, une administration extensible, les courriels, les fichiers et les paiements. Conçu au Québec.
|
|
4
|
+
|
|
5
|
+
[Documentation](https://docs.fraza.ca/docs) · [Installation](https://docs.fraza.ca/docs/demarrage/installation) · [Modules](https://docs.fraza.ca/docs/modules)
|
|
4
6
|
|
|
5
7
|
> [!WARNING]
|
|
6
|
-
> Fraza est en version `0.x`.
|
|
8
|
+
> Fraza est en version `0.x`. Une nouvelle version mineure peut contenir un changement cassant.
|
|
7
9
|
|
|
8
|
-
##
|
|
10
|
+
## Points forts
|
|
9
11
|
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **Routeur API** : API REST avec authentification, protection CSRF et limitation du débit.
|
|
15
|
-
- **Courriels** : gabarits écrits avec React Email.
|
|
16
|
-
- **Stockage** : fichiers sur un stockage objet compatible S3.
|
|
17
|
-
- **Paiements** : intégration Stripe.
|
|
18
|
-
- **Tâches planifiées** : exécution de tâches programmées.
|
|
19
|
-
- **Outillage** : commandes `fraza-db`, `fraza-modules`, `fraza-key`, `fraza-doctor` et `fraza-update`.
|
|
12
|
+
- **Un back-office complet dès le départ.** Connexion, inscription, invitations, utilisateurs, rôles et permissions, tableau de bord, mode sombre.
|
|
13
|
+
- **Extensible sans toucher au core.** Un module apporte ses tables, ses écrans, ses permissions et ses routes. Il s'installe avec npm et s'active par une variable.
|
|
14
|
+
- **Les services de tous les projets.** Routeur API avec CSRF et limitation du débit, courriels React Email, stockage compatible S3, paiements Stripe, tâches planifiées.
|
|
15
|
+
- **La documentation dans le paquet.** `node_modules/@fraza/core/dist/docs/` porte la documentation de la version installée, lisible hors ligne, par vous comme par un agent.
|
|
20
16
|
|
|
21
|
-
##
|
|
17
|
+
## Démarrage rapide
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
Dans un dossier vide, avec Node.js 20.12 ou plus et une base PostgreSQL 14 ou plus :
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
| [Guides](./docs/02-guides/index.md) | Un cas d'usage par page. |
|
|
29
|
-
| [Référence](./docs/03-reference/index.md) | Chaque module, fonction, commande et variable d'environnement. |
|
|
30
|
-
| [Architecture](./docs/04-architecture/index.md) | Principes, frontières serveur/client, build, sécurité, design system. |
|
|
31
|
-
| [Contribution](./docs/05-contribution/index.md) | Conventions de code, de rédaction, de commit et publication. |
|
|
32
|
-
| [Modules](./docs/06-modules/index.md) | Usage des modules officiels `@fraza/module-*` et `@fraza-pro/module-*`. |
|
|
21
|
+
```bash
|
|
22
|
+
npx @fraza/start
|
|
23
|
+
```
|
|
33
24
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## Démarrage rapide
|
|
25
|
+
Renseignez `FRAZA_DATABASE_URL` dans le `.env.local` créé, puis :
|
|
37
26
|
|
|
38
27
|
```bash
|
|
39
|
-
npm config set "@fraza:registry" https://registry.fraza.ca/
|
|
40
|
-
npx @fraza/start
|
|
41
28
|
npx fraza-db init
|
|
42
29
|
npm run dev
|
|
43
30
|
```
|
|
44
31
|
|
|
45
|
-
|
|
32
|
+
Ouvrez `http://localhost:3000/auth` pour créer le premier compte, qui reçoit le rôle `admin`. Le détail est dans [Installation](https://docs.fraza.ca/docs/demarrage/installation).
|
|
33
|
+
|
|
34
|
+
## Ajouter un module
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm i @fraza/module-pages
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```dotenv
|
|
41
|
+
# .env.local
|
|
42
|
+
FRAZA_MODULE_PAGES=true
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx fraza-modules sync
|
|
47
|
+
npx fraza-db init
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Module | Paquet | Licence |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| [Pages](https://docs.fraza.ca/docs/modules/pages) | `@fraza/module-pages` | MIT |
|
|
53
|
+
| [Posts](https://docs.fraza.ca/docs/modules/posts) | `@fraza/module-posts` | MIT |
|
|
54
|
+
| [Médias](https://docs.fraza.ca/docs/modules/medias) | `@fraza/module-medias` | MIT |
|
|
55
|
+
| [Formulaires](https://docs.fraza.ca/docs/modules/forms) | `@fraza/module-forms` | MIT |
|
|
56
|
+
| [Facturation](https://docs.fraza.ca/docs/modules/facturation) | `@fraza-pro/module-billing` | Fraza Pro |
|
|
57
|
+
| [Rendez-vous](https://docs.fraza.ca/docs/modules/booking) | `@fraza-pro/module-booking` | Fraza Pro |
|
|
58
|
+
| [Fichiers](https://docs.fraza.ca/docs/modules/drive) | `@fraza-pro/module-drive` | Fraza Pro |
|
|
59
|
+
|
|
60
|
+
Le core et les modules gratuits s'installent depuis npmjs, sans compte. Les modules Pro demandent un compte sur `https://registry.fraza.ca/`.
|
|
61
|
+
|
|
62
|
+
## Commandes
|
|
63
|
+
|
|
64
|
+
| Commande | Rôle |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `fraza-db` | Créer, tester et supprimer les tables du core et des modules. |
|
|
67
|
+
| `fraza-modules` | Régénérer les manifestes des modules, blocs et templates. |
|
|
68
|
+
| `fraza-doctor` | Diagnostiquer le projet : variables manquantes, modules, paquets, vulnérabilités. |
|
|
69
|
+
| `fraza-update` | Mettre à jour le core, les icônes et les modules en une commande. |
|
|
70
|
+
| `fraza-key` | Écrire le jeton du registre pour les modules Pro. |
|
|
71
|
+
|
|
72
|
+
Chaque commande est détaillée dans la [référence des CLI](https://docs.fraza.ca/docs/reference/cli).
|
|
73
|
+
|
|
74
|
+
## Documentation
|
|
75
|
+
|
|
76
|
+
| Section | Contenu |
|
|
77
|
+
|---|---|
|
|
78
|
+
| [Découverte](https://docs.fraza.ca/docs/decouverte) | Ce qu'est Fraza, sans rien installer. |
|
|
79
|
+
| [Démarrage](https://docs.fraza.ca/docs/demarrage) | De l'installation au premier module, à lire dans l'ordre. |
|
|
80
|
+
| [Guides](https://docs.fraza.ca/docs/guides) | Un cas d'usage par page. |
|
|
81
|
+
| [Référence](https://docs.fraza.ca/docs/reference) | Chaque fonction, commande et variable d'environnement. |
|
|
82
|
+
| [Architecture](https://docs.fraza.ca/docs/architecture) | Principes, frontières serveur/client, sécurité, design system. |
|
|
83
|
+
| [Contribution](https://docs.fraza.ca/docs/contribution) | Conventions de code, de rédaction, de commit et publication. |
|
|
46
84
|
|
|
47
85
|
## Sécurité
|
|
48
86
|
|
|
49
|
-
|
|
87
|
+
N'ouvrez pas d'issue publique pour une faille. Écrivez à **security@hyko.cx**. La politique complète est dans [SECURITY.md](./SECURITY.md).
|
|
50
88
|
|
|
51
89
|
## Licence
|
|
52
90
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
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).
|
|
91
|
+
MIT. Copyright (c) 2026 HYKO. Voir [LICENSE](./LICENSE). Les dépendances tierces sont listées dans [THIRD-PARTY-NOTICES.md](./THIRD-PARTY-NOTICES.md).
|
|
56
92
|
|
|
57
|
-
Les modules Facturation, Rendez-vous et Fichiers
|
|
93
|
+
Le core et les modules Pages, Posts, Médias et Formulaires forment Fraza Libre. Les modules Facturation, Rendez-vous et Fichiers sont sous la licence Fraza Pro, une licence par projet en production : voir [Licence et propriété](https://docs.fraza.ca/docs/architecture/licence-et-propriete).
|
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -19,7 +19,7 @@ Il est généré par `fraza-module notices` à partir de l'arbre réellement ins
|
|
|
19
19
|
|
|
20
20
|
| Paquet | Version | Licence |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| `@fraza/icons` | 0.3.
|
|
22
|
+
| `@fraza/icons` | 0.3.10 | MIT |
|
|
23
23
|
| `node-cron` | 4.2.1 | ISC |
|
|
24
24
|
| `pg` | 8.20.0 | MIT |
|
|
25
25
|
| `pg-cloudflare` | 1.3.0 | MIT |
|
|
@@ -146,11 +146,33 @@ OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
|
146
146
|
|
|
147
147
|
## Textes de licence
|
|
148
148
|
|
|
149
|
-
### @fraza/icons@0.3.
|
|
149
|
+
### @fraza/icons@0.3.10
|
|
150
150
|
|
|
151
151
|
Licence : MIT
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
```
|
|
154
|
+
MIT License
|
|
155
|
+
|
|
156
|
+
Copyright (c) 2026 HYKO
|
|
157
|
+
|
|
158
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
159
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
160
|
+
in the Software without restriction, including without limitation the rights
|
|
161
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
162
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
163
|
+
furnished to do so, subject to the following conditions:
|
|
164
|
+
|
|
165
|
+
The above copyright notice and this permission notice shall be included in all
|
|
166
|
+
copies or substantial portions of the Software.
|
|
167
|
+
|
|
168
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
169
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
170
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
171
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
172
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
173
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
174
|
+
SOFTWARE.
|
|
175
|
+
```
|
|
154
176
|
|
|
155
177
|
### node-cron@4.2.1
|
|
156
178
|
|
package/changelog.json
CHANGED
|
@@ -2,13 +2,66 @@
|
|
|
2
2
|
"name": "@fraza/core",
|
|
3
3
|
"versions": [
|
|
4
4
|
{
|
|
5
|
-
"version": "0.3.
|
|
5
|
+
"version": "0.3.7",
|
|
6
6
|
"date": "2026-10-25",
|
|
7
7
|
"breaking": [],
|
|
8
8
|
"envAdded": [],
|
|
9
9
|
"envRemoved": [],
|
|
10
10
|
"templateChanged": [],
|
|
11
11
|
"action": [],
|
|
12
|
+
"entries": [
|
|
13
|
+
{
|
|
14
|
+
"type": "refactor",
|
|
15
|
+
"scope": "README",
|
|
16
|
+
"subject": "update landing page to remove redundant commands",
|
|
17
|
+
"hash": "fe88136",
|
|
18
|
+
"breaking": false
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"type": "Refactor",
|
|
22
|
+
"scope": "README",
|
|
23
|
+
"subject": "update content and structure",
|
|
24
|
+
"hash": "2a08dbf",
|
|
25
|
+
"breaking": false
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"version": "0.3.6",
|
|
31
|
+
"date": "2026-10-25",
|
|
32
|
+
"breaking": [],
|
|
33
|
+
"envAdded": [],
|
|
34
|
+
"envRemoved": [],
|
|
35
|
+
"templateChanged": [],
|
|
36
|
+
"action": [],
|
|
37
|
+
"entries": []
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"version": "0.3.5",
|
|
41
|
+
"date": "2026-10-25",
|
|
42
|
+
"breaking": [],
|
|
43
|
+
"envAdded": [],
|
|
44
|
+
"envRemoved": [],
|
|
45
|
+
"templateChanged": [],
|
|
46
|
+
"action": [],
|
|
47
|
+
"entries": [
|
|
48
|
+
{
|
|
49
|
+
"type": "refactor",
|
|
50
|
+
"scope": "docs, src/tools, test/tools",
|
|
51
|
+
"subject": "update documentation and CLI for version intermediately published on Fraza registry",
|
|
52
|
+
"hash": "0595be8",
|
|
53
|
+
"breaking": false
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"version": "0.3.4",
|
|
59
|
+
"date": "2026-10-24",
|
|
60
|
+
"breaking": [],
|
|
61
|
+
"envAdded": [],
|
|
62
|
+
"envRemoved": [],
|
|
63
|
+
"templateChanged": [],
|
|
64
|
+
"action": [],
|
|
12
65
|
"entries": [
|
|
13
66
|
{
|
|
14
67
|
"type": "refactor",
|
|
@@ -12,7 +12,7 @@ Ce guide s'adresse à qui doit installer ou déployer un projet Fraza pendant qu
|
|
|
12
12
|
|
|
13
13
|
## Pourquoi c'est possible
|
|
14
14
|
|
|
15
|
-
Le core, `@fraza/start` et les modules gratuits sont publiés sur npmjs, d'où un projet les installe par défaut. Chaque version est aussi
|
|
15
|
+
Le core, `@fraza/start` et les modules gratuits sont publiés sur npmjs, d'où un projet les installe par défaut. Chaque version publiée sur npmjs l'est aussi sur `https://registry.fraza.ca/`, en copie de secours, en lecture libre. Ce registre porte en plus des versions intermédiaires, publiées pour tester un changement, qui ne vont pas sur npmjs.
|
|
16
16
|
|
|
17
17
|
Les deux registres reçoivent le même fichier, octet pour octet : la commande de publication construit un seul tarball et l'envoie aux deux. Le `package-lock.json` vérifie l'empreinte (`integrity`) de chaque paquet installé. Comme l'empreinte est la même sur les deux registres, le lockfile reste valable après la bascule.
|
|
18
18
|
|
|
@@ -57,6 +57,8 @@ La commande retire la ligne `@fraza:registry` du `.npmrc` et remet les adresses
|
|
|
57
57
|
|
|
58
58
|
Un projet créé avant la publication sur npmjs pointe encore `@fraza` vers `https://registry.fraza.ca/`. La même commande le fait passer sur npmjs, à condition que ses versions de `@fraza/*` y soient publiées : lancer d'abord `npx fraza-update` si elles sont anciennes.
|
|
59
59
|
|
|
60
|
+
Un `npx fraza-update` lancé pendant la bascule peut installer une version intermédiaire, présente sur `registry.fraza.ca` seulement. Le lockfile la désigne alors, et `npm ci` échouerait après le retour sur npmjs. Dans ce cas, attendre que cette version ou une plus récente soit sur npmjs, puis relancer `npx fraza-update` après le retour.
|
|
61
|
+
|
|
60
62
|
## Diagnostiquer
|
|
61
63
|
|
|
62
64
|
| Symptôme | Cause probable |
|
|
@@ -169,6 +169,7 @@ npx fraza-module release
|
|
|
169
169
|
npx fraza-module release minor
|
|
170
170
|
npx fraza-module release 0.2.1
|
|
171
171
|
npx fraza-module release --dry-run
|
|
172
|
+
npx fraza-module release -g
|
|
172
173
|
```
|
|
173
174
|
|
|
174
175
|
Au lieu d'un niveau, un numéro exact `X.Y.Z` fixe la version, par exemple pour aligner le core, start et les modules sur un même numéro. Il doit être une version stable, supérieure à la version actuelle.
|
|
@@ -177,41 +178,47 @@ Publie une nouvelle version du paquet en une commande. Le seul choix qui reste a
|
|
|
177
178
|
|
|
178
179
|
Chaque paquet la lance par son script `release`, en un seul appel, pour que les arguments de `npm run release -- minor` arrivent à la commande.
|
|
179
180
|
|
|
181
|
+
Sans `-g`, la version part sur `registry.fraza.ca` seulement : c'est le mode des versions qui servent à tester un changement dans un projet. Avec `-g`, un paquet `@fraza/*` part aussi sur npmjs, d'où les sites installent. Un module `@fraza-pro/*` ne va jamais sur npmjs : `-g` ne change rien pour lui, et la commande le dit.
|
|
182
|
+
|
|
180
183
|
Les étapes s'enchaînent dans cet ordre, et la première qui échoue arrête la commande :
|
|
181
184
|
|
|
182
|
-
1. **Vérifications, avant toute écriture.** Le paquet est dans un dépôt git, sur une branche qui suit une branche distante, affichée en tête. La commande lance `git fetch` sur le dépôt distant de cette branche et refuse une branche en retard sur lui : sans cela, la publication partirait et seul `git push`, à la fin, serait refusé. Sans réseau, elle s'arrête là. Aucune publication précédente n'est restée arrêtée après son commit de version. L'arbre de travail est propre, l'étiquette `v<nouvelle version>` n'existe ni en local ni sur le dépôt distant, `CHANGELOG.md` et `changelog.json` sont déclarés dans `files`, et `publishConfig` est conforme (voir [`publish`](#publish)). Puis la commande installe la dernière version publiée de chaque dépendance Fraza du paquet (`npm install --no-save @fraza/…@latest`, sans toucher à `package.json` ni au lockfile),
|
|
185
|
+
1. **Vérifications, avant toute écriture.** Le paquet est dans un dépôt git, sur une branche qui suit une branche distante, affichée en tête. La commande lance `git fetch` sur le dépôt distant de cette branche et refuse une branche en retard sur lui : sans cela, la publication partirait et seul `git push`, à la fin, serait refusé. Sans réseau, elle s'arrête là. Aucune publication précédente n'est restée arrêtée après son commit de version. L'arbre de travail est propre, l'étiquette `v<nouvelle version>` n'existe ni en local ni sur le dépôt distant, `CHANGELOG.md` et `changelog.json` sont déclarés dans `files`, et `publishConfig` est conforme (voir [`publish`](#publish)). Puis la commande installe la dernière version publiée de chaque dépendance Fraza du paquet (`npm install --no-save @fraza/…@latest`, sans toucher à `package.json` ni au lockfile). Le registre suit la publication, jamais `~/.npmrc` : `registry.fraza.ca` par défaut, qui porte les dernières versions de test, npmjs avec `-g`, pour vérifier le paquet contre les versions qu'un site recevra avec lui. Elle lance ensuite `npm run build`, `check` pour un module, `npm test` quand le paquet déclare ce script, et l'arbre doit être resté propre après le build. Un échec ici laisse le dépôt exactement dans son état d'avant.
|
|
183
186
|
2. **Montée de version.** La commande affiche `ancienne → nouvelle`, écrit la version dans `package.json` et dans les entrées racine de `package-lock.json`, régénère le module de version (`sync-version`) et les notes de version (`changelog`), relance `npm run build`, puis committe ces fichiers seuls avec le message `chore: bump version to X.Y.Z`. `THIRD-PARTY-NOTICES.md`, que le build régénère d'après les paquets installés, part dans ce même commit : il change quand une dépendance Fraza vient d'avancer. Un échec avant le commit remet ces fichiers dans leur état d'avant.
|
|
184
|
-
3. **Publication sur chaque registre**, par [`publish`](#publish) : `prepublishOnly` relance le build et les contrôles du paquet, puis le même tarball part vers
|
|
187
|
+
3. **Publication sur chaque registre**, par [`publish`](#publish) : `prepublishOnly` relance le build et les contrôles du paquet, puis le même tarball part vers `registry.fraza.ca`, précédé de npmjs avec `-g` pour un paquet `@fraza/*`.
|
|
185
188
|
4. **Étiquette et envoi, seulement si chaque registre a accepté la version.** `git tag -a v<version> -m v<version>`, puis `git push --atomic --follow-tags`, qui envoie la branche et l'étiquette ensemble ou aucune des deux.
|
|
186
189
|
|
|
187
190
|
Le lockfile est modifié comme un fichier JSON, pas par `npm install` : un module se construit souvent contre un core installé avec `--no-save`, qu'une installation inscrirait dans son lockfile.
|
|
188
191
|
|
|
189
|
-
Un échec après le commit ne s'annule pas en silence. La commande s'arrête et dit où en est la publication : commit de version fait en local, aucune étiquette, rien de poussé quand un registre a refusé la version, et la liste des registres qui l'ont et de ceux où elle manque. Elle affiche les commandes pour reprendre (`npm run release:publish`, qui ne publie que là où la version manque, puis l'étiquette et l'envoi), et `git reset --hard HEAD~1` pour annuler la montée de version tant qu'aucun registre ne l'a reçue. Quand seul l'envoi échoue, elle dit si l'étiquette a atteint le dépôt distant, et propose `git pull --no-rebase` avant de pousser à nouveau : un rebase réécrirait le commit de version, que l'étiquette publiée désigne. Relancer `npm run release` à ce stade monterait la version une deuxième fois : la commande refuse de partir quand `HEAD` est le commit de version de la version courante, pas encore sur le dépôt distant, et redonne les commandes pour reprendre ou annuler.
|
|
192
|
+
Un échec après le commit ne s'annule pas en silence. La commande s'arrête et dit où en est la publication : commit de version fait en local, aucune étiquette, rien de poussé quand un registre a refusé la version, et la liste des registres qui l'ont et de ceux où elle manque. Elle affiche les commandes pour reprendre (`npm run release:publish`, avec `-g` si la publication visait npmjs, qui ne publie que là où la version manque, puis l'étiquette et l'envoi), et `git reset --hard HEAD~1` pour annuler la montée de version tant qu'aucun registre ne l'a reçue. Quand seul l'envoi échoue, elle dit si l'étiquette a atteint le dépôt distant, et propose `git pull --no-rebase` avant de pousser à nouveau : un rebase réécrirait le commit de version, que l'étiquette publiée désigne. Relancer `npm run release` à ce stade monterait la version une deuxième fois : la commande refuse de partir quand `HEAD` est le commit de version de la version courante, pas encore sur le dépôt distant, et redonne les commandes pour reprendre ou annuler.
|
|
190
193
|
|
|
191
194
|
| Option | Effet |
|
|
192
195
|
|---|---|
|
|
193
196
|
| `patch`, `minor`, `major` | Niveau de la montée de version. `patch` par défaut. |
|
|
194
197
|
| `X.Y.Z` | Version exacte, à la place d'un niveau. |
|
|
195
198
|
| `--dry-run` | Fait les vérifications, build et tests compris, calcule la nouvelle version, puis affiche chaque étape qui aurait suivi. N'écrit rien dans le dépôt : aucun commit, aucune étiquette, aucun envoi, aucune publication. Seul le `git fetch` des vérifications met à jour les branches distantes suivies. |
|
|
199
|
+
| `-g`, `--global` | Publie aussi sur npmjs, en premier, un paquet `@fraza/*`. Les dépendances Fraza des vérifications viennent alors de npmjs. |
|
|
196
200
|
|
|
197
201
|
`npm run release --dry-run`, sans `--`, donne l'option à npm et non au script. La commande le détecte et simule aussi : sans cela, `npm publish` ne ferait que simuler alors que l'étiquette et l'envoi auraient lieu.
|
|
198
202
|
|
|
203
|
+
`npm run release -g` donne de même `-g` à npm, qui le transmet au script comme `npm_config_global`. La commande le lit comme une demande de publication sur npmjs, puis le retire de son environnement : chaque `npm` qu'elle lance en hériterait, et `npm install --no-save` installerait en global.
|
|
204
|
+
|
|
199
205
|
## `publish`
|
|
200
206
|
|
|
201
207
|
```bash
|
|
202
208
|
npx fraza-module publish
|
|
203
209
|
npx fraza-module publish --dry-run
|
|
210
|
+
npx fraza-module publish -g
|
|
204
211
|
```
|
|
205
212
|
|
|
206
213
|
Publie la version actuelle de `package.json`, sans la monter, sur chaque registre du paquet où elle manque. [`release`](#release) l'appelle à son étape 3. Chaque paquet Fraza l'expose aussi par son script `release:publish`, pour terminer une publication interrompue. Le core et `@fraza/start` n'installent pas `fraza-module` comme dépendance : `npm run release:publish` y lance le CLI du dépôt.
|
|
207
214
|
|
|
208
215
|
| Scope | Registres, dans l'ordre |
|
|
209
216
|
|---|---|
|
|
210
|
-
| `@fraza/*` | npmjs, avec `--access=public`, puis `https://registry.fraza.ca/`. |
|
|
211
|
-
| `@fraza-pro/*` | `https://registry.fraza.ca/` seulement. |
|
|
217
|
+
| `@fraza/*` | `https://registry.fraza.ca/`. Avec `-g` : npmjs, avec `--access=public`, puis `https://registry.fraza.ca/`. |
|
|
218
|
+
| `@fraza-pro/*` | `https://registry.fraza.ca/` seulement, `-g` ou non. |
|
|
212
219
|
| Autre | `npm publish` dans le dossier, vers le registre de sa propre configuration. |
|
|
213
220
|
|
|
214
|
-
npmjs passe en premier : c'est le registre d'où les sites installent, et le plus strict, puisqu'un numéro de version n'y est jamais réutilisable. Un refus de npmjs arrête la publication avant que le secours ne reçoive une version que npmjs n'a pas.
|
|
221
|
+
Avec `-g`, npmjs passe en premier : c'est le registre d'où les sites installent, et le plus strict, puisqu'un numéro de version n'y est jamais réutilisable. Un refus de npmjs arrête la publication avant que le secours ne reçoive une version que npmjs n'a pas.
|
|
215
222
|
|
|
216
223
|
Les étapes :
|
|
217
224
|
|
|
@@ -224,13 +231,14 @@ Les deux registres reçoivent ainsi le même fichier, octet pour octet. Le `pack
|
|
|
224
231
|
|
|
225
232
|
Le registre est passé par scope, `--@fraza:registry=<adresse>`, jamais par `--registry` : npm choisit une ligne de scope de `~/.npmrc` avant `--registry`, et la machine d'un mainteneur pointe souvent `@fraza` vers `registry.fraza.ca`. Les options de ligne de commande passent avant `publishConfig`.
|
|
226
233
|
|
|
227
|
-
La commande se relance sans risque : un registre qui a déjà la version est sauté. C'est aussi ainsi qu'une version publiée sur
|
|
234
|
+
La commande se relance sans risque : un registre qui a déjà la version est sauté. C'est aussi ainsi qu'une version publiée sur `registry.fraza.ca` seulement est portée sur npmjs, avec `-g` : son tarball est téléchargé et envoyé tel quel.
|
|
228
235
|
|
|
229
236
|
npm peut demander un code à usage unique quand le compte npmjs a la double authentification : la sortie de npm s'affiche telle quelle et le code se saisit dans le terminal.
|
|
230
237
|
|
|
231
238
|
| Option | Effet |
|
|
232
239
|
|---|---|
|
|
233
240
|
| `--dry-run` | Interroge les registres et dit où la version partirait, et depuis quel tarball. Ne construit et ne publie rien. |
|
|
241
|
+
| `-g`, `--global` | Ajoute npmjs, en premier, aux registres d'un paquet `@fraza/*`. `npm run release:publish -g` fonctionne sans `--`. |
|
|
234
242
|
|
|
235
243
|
### Dépendances Fraza
|
|
236
244
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Publication
|
|
3
|
-
description: Checklist avant publication, versionnage semver,
|
|
3
|
+
description: Checklist avant publication, versionnage semver, publication sur le registre Fraza par défaut, et sur npmjs avec -g.
|
|
4
4
|
related:
|
|
5
5
|
title: Étapes suivantes
|
|
6
6
|
links:
|
|
@@ -12,8 +12,8 @@ Les paquets Fraza vivent sur deux registres :
|
|
|
12
12
|
|
|
13
13
|
| Scope | Registres | Rôle |
|
|
14
14
|
|---|---|---|
|
|
15
|
-
| `@fraza/*` (core, `@fraza/start`, modules gratuits) |
|
|
16
|
-
| `@fraza-pro/*` (modules Pro) | `https://registry.fraza.ca/` seulement | Le registre est la barrière de la licence. |
|
|
15
|
+
| `@fraza/*` (core, `@fraza/start`, modules gratuits) | `https://registry.fraza.ca/` par défaut, npmjs en plus avec `-g` | npmjs est le registre d'où les sites installent. `registry.fraza.ca` reçoit chaque version, y compris celles qui servent à tester un changement dans un projet, et garde une copie complète de npmjs, en secours. |
|
|
16
|
+
| `@fraza-pro/*` (modules Pro) | `https://registry.fraza.ca/` seulement, `-g` ou non | Le registre est la barrière de la licence. |
|
|
17
17
|
|
|
18
18
|
Une seule commande publie aux bons endroits. La lecture est libre partout sauf pour `@fraza-pro`, la publication demande un compte sur chaque registre. Le dépôt source est hébergé sur Gitea, en dépôt privé.
|
|
19
19
|
|
|
@@ -73,17 +73,44 @@ Une seule commande, dans le paquet modifié :
|
|
|
73
73
|
npm run release
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
La commande ne publie que ce paquet.
|
|
76
|
+
La commande ne publie que ce paquet, et seulement sur `registry.fraza.ca`. La version est disponible tout de suite pour un projet de test dont `@fraza` pointe vers ce registre. Les sites, qui installent depuis npmjs, ne la voient pas.
|
|
77
|
+
|
|
78
|
+
Chaque dépôt de paquet Fraza (core, `@fraza/start`, `@fraza/icons`, modules) porte un `.npmrc` qui pointe `@fraza` vers le registre Fraza :
|
|
79
|
+
|
|
80
|
+
```ini
|
|
81
|
+
@fraza:registry=https://registry.fraza.ca/
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
En développement, `npm install` et `npm update` y prennent donc `@fraza/core` et `@fraza/icons`, versions de test comprises. npm n'inclut jamais un `.npmrc` dans un paquet publié, et `@fraza/start` écrit celui d'un nouveau projet sans copier le sien : cette ligne ne sort pas du dépôt. Un module Pro garde en plus sa ligne `@fraza-pro`. `@fraza/icons` ne suit pas son `.npmrc` dans git, parce qu'il porte le jeton Hugeicons : la ligne s'y ajoute à la main sur chaque machine.
|
|
85
|
+
|
|
86
|
+
Pour qu'un projet de test reçoive les versions de test, pointer aussi `@fraza` vers le registre Fraza dans son `.npmrc`, ou dans `~/.npmrc` pour tous les projets de la machine :
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npm config set "@fraza:registry" https://registry.fraza.ca/
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Sans cette ligne, `npm install` et `npx fraza-update` vont chercher `@fraza/*` sur npmjs et ne voient que les versions publiées avec `-g`. La publication, elle, ne dépend d'aucune de ces lignes : elle passe le registre visé à chaque appel.
|
|
93
|
+
|
|
94
|
+
Quand plusieurs changements sont prêts pour les sites, ajouter `-g` :
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npm run release -g
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
La version part alors sur npmjs, puis sur `registry.fraza.ca`. npmjs met plusieurs minutes à rendre une nouvelle version visible : c'est pourquoi les versions de test n'y vont pas. Les versions intermédiaires restent sur `registry.fraza.ca` seulement, et npmjs passe directement de la dernière version portée à la nouvelle.
|
|
101
|
+
|
|
102
|
+
Pour un autre niveau que `patch`, le donner en argument :
|
|
77
103
|
|
|
78
104
|
```bash
|
|
79
105
|
npm run release -- minor
|
|
106
|
+
npm run release -g -- minor
|
|
80
107
|
```
|
|
81
108
|
|
|
82
109
|
Le script `release` lance [`fraza-module release`](../03-reference/05-cli/fraza-module.md#release), qui monte la version, `patch` par défaut, et enchaîne quatre étapes dans cet ordre. Il s'arrête à la première qui échoue :
|
|
83
110
|
|
|
84
111
|
1. **Vérifications, avant toute écriture** : arbre de travail propre, branche courante affichée et suivie d'une branche distante, `git fetch` puis branche à jour avec elle, étiquette encore libre en local comme sur le dépôt distant, build, contrat pour un module, tests. Un échec laisse le dépôt intact.
|
|
85
112
|
2. **Montée de version** : la commande affiche `ancienne → nouvelle`, écrit la version dans `package.json` et `package-lock.json`, régénère le module de version, `CHANGELOG.md`, `changelog.json` et le résumé `package.json#fraza`, rebuild, puis committe ces fichiers seuls avec le message `chore: bump version to X.Y.Z`. Ce message est la borne de version que lit le générateur de notes : voir [Notes de version](./07-changelog.md).
|
|
86
|
-
3. **Publication** par [`fraza-module publish`](../03-reference/05-cli/fraza-module.md#publish) : `prepublishOnly` relance le build, puis `fraza-module check` pour un module. Le paquet est empaqueté une fois, et ce même tarball part vers
|
|
113
|
+
3. **Publication** par [`fraza-module publish`](../03-reference/05-cli/fraza-module.md#publish) : `prepublishOnly` relance le build, puis `fraza-module check` pour un module. Le paquet est empaqueté une fois, et ce même tarball part vers `registry.fraza.ca`. Avec `-g`, un paquet `@fraza/*` part d'abord vers npmjs, puis vers `registry.fraza.ca`. Les deux registres servent ainsi les mêmes octets, ce qui permet à un site de [basculer sur le registre de secours](../02-guides/basculer-sur-le-registre-de-secours.md).
|
|
87
114
|
4. **`git tag -a v<version>` puis `git push --atomic --follow-tags`**, seulement si chaque registre a accepté la version. `--atomic` envoie la branche et l'étiquette ensemble, ou aucune des deux : sans lui, git pousse l'étiquette même quand il refuse la branche, et le dépôt distant garde une étiquette sur un commit qu'aucune branche ne contient.
|
|
88
115
|
|
|
89
116
|
Pour voir la version calculée et vérifier le paquet sans rien écrire ni publier :
|
|
@@ -92,7 +119,7 @@ Pour voir la version calculée et vérifier le paquet sans rien écrire ni publi
|
|
|
92
119
|
npm run release -- --dry-run
|
|
93
120
|
```
|
|
94
121
|
|
|
95
|
-
L'étiquette vient après la publication : une publication refusée par un registre ne laisse pas d'étiquette sur une version incomplète, ni de commit poussé qui l'annonce. Dans ce cas, la commande s'arrête sur le commit de version, fait en local, dit sur quels registres la version est arrivée, et affiche les commandes pour reprendre : `npm run release:publish`, qui publie seulement là où elle manque, avec le même tarball, puis l'étiquette et l'envoi. Relancer `npm run release` monterait la version une deuxième fois, sur une version jamais publiée : la commande le refuse. Quand `HEAD` est le commit de version de la version courante et n'est pas encore sur le dépôt distant, elle s'arrête avant toute écriture et redonne les commandes pour reprendre, ou seulement l'envoi si l'étiquette est déjà posée. Pour annuler la montée de version, `git reset --hard HEAD~1`, seulement si aucun registre n'a reçu la version : un numéro publié sur npmjs n'est plus jamais réutilisable.
|
|
122
|
+
L'étiquette vient après la publication : une publication refusée par un registre ne laisse pas d'étiquette sur une version incomplète, ni de commit poussé qui l'annonce. Dans ce cas, la commande s'arrête sur le commit de version, fait en local, dit sur quels registres la version est arrivée, et affiche les commandes pour reprendre : `npm run release:publish`, avec `-g` si la publication visait npmjs, qui publie seulement là où elle manque, avec le même tarball, puis l'étiquette et l'envoi. Relancer `npm run release` monterait la version une deuxième fois, sur une version jamais publiée : la commande le refuse. Quand `HEAD` est le commit de version de la version courante et n'est pas encore sur le dépôt distant, elle s'arrête avant toute écriture et redonne les commandes pour reprendre, ou seulement l'envoi si l'étiquette est déjà posée. Pour annuler la montée de version, `git reset --hard HEAD~1`, seulement si aucun registre n'a reçu la version : un numéro publié sur npmjs n'est plus jamais réutilisable.
|
|
96
123
|
|
|
97
124
|
Si l'envoi échoue après la publication, la commande dit si l'étiquette a atteint le dépôt distant. Quand la branche distante a avancé entre-temps, lancer `git pull --no-rebase`, puis `git push --atomic --follow-tags`. Ne pas rebaser le commit de version : l'étiquette, déjà publiée, pointerait vers un commit qu'aucune branche ne contient.
|
|
98
125
|
|
|
@@ -117,15 +144,19 @@ Le build produit aussi `dist/docs/`, donc la documentation publiée correspond e
|
|
|
117
144
|
|
|
118
145
|
L'organisation `fraza-pro` est aussi réservée sur npmjs, vide : personne d'autre ne peut y publier un paquet du même nom qu'un module Pro. Un projet dont le `.npmrc` perdrait sa ligne `@fraza-pro` ne pourrait donc pas installer un faux module depuis npmjs.
|
|
119
146
|
|
|
120
|
-
###
|
|
147
|
+
### Porter une version existante sur npmjs
|
|
121
148
|
|
|
122
|
-
|
|
149
|
+
Pour envoyer sur npmjs la version actuelle d'un paquet gratuit, déjà publiée sur `registry.fraza.ca`, sans monter de version, lancer dans son dépôt, à jour sur l'étiquette de cette version :
|
|
123
150
|
|
|
124
151
|
```bash
|
|
125
|
-
npm run release:publish
|
|
152
|
+
npm run release:publish -g
|
|
126
153
|
```
|
|
127
154
|
|
|
128
|
-
La commande voit que la version manque sur npmjs, télécharge le tarball de `registry.fraza.ca` et l'envoie tel quel à npmjs. `--dry-run`
|
|
155
|
+
La commande voit que la version manque sur npmjs, télécharge le tarball de `registry.fraza.ca` et l'envoie tel quel à npmjs. `--dry-run` dit ce qui partirait, sans rien publier. C'est aussi ainsi qu'on porte sur npmjs une version publiée avant la mise en place de npmjs.
|
|
156
|
+
|
|
157
|
+
### Ordre entre paquets
|
|
158
|
+
|
|
159
|
+
Avec `-g`, un paquet qui dépend d'autres paquets Fraza est construit et testé contre leur dernière version **sur npmjs**, celle qu'un site recevra avec lui. Si un module utilise un changement du core publié seulement sur `registry.fraza.ca`, son build ou ses tests échouent avant toute écriture, et la commande rappelle de porter d'abord le core sur npmjs. Porter donc les paquets dans l'ordre de leurs dépendances : `@fraza/icons`, puis le core, puis les modules et `@fraza/start`.
|
|
129
160
|
|
|
130
161
|
## Modules externes
|
|
131
162
|
|
|
@@ -8,7 +8,7 @@ related:
|
|
|
8
8
|
- 03-reference/05-cli/fraza-key
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
Commandes de gestion du registre Verdaccio de Fraza, à `https://registry.fraza.ca/`. Il sert deux scopes. Les paquets de Fraza Libre sont publiés sous `@fraza/*` et se lisent sans compte : les sites les installent depuis npmjs, et ce registre en garde une copie complète, en secours. Les modules de Fraza Pro sont publiés sous `@fraza-pro/*`, ici seulement, et leur lecture demande un compte. La publication demande un compte sur les deux scopes.
|
|
11
|
+
Commandes de gestion du registre Verdaccio de Fraza, à `https://registry.fraza.ca/`. Il sert deux scopes. Les paquets de Fraza Libre sont publiés sous `@fraza/*` et se lisent sans compte : les sites les installent depuis npmjs, et ce registre en garde une copie complète, en secours. Il reçoit aussi les versions de test, que `npm run release` sans `-g` n'envoie pas sur npmjs. Les modules de Fraza Pro sont publiés sous `@fraza-pro/*`, ici seulement, et leur lecture demande un compte. La publication demande un compte sur les deux scopes.
|
|
12
12
|
|
|
13
13
|
Pour publier un package, voir [Publication](./05-publication.md). Pour synchroniser le token dans un projet, voir [fraza-key](../03-reference/05-cli/fraza-key.md).
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@ Ces pages s'adressent à qui modifie `@fraza/core` lui-même, un package `@fraza
|
|
|
16
16
|
| [Langue](./02-langue.md) | Ce qui s'écrit en anglais, ce qui s'écrit en français. |
|
|
17
17
|
| [Rédaction](./03-redaction.md) | Voix de l'interface, voix de la documentation, formules à éviter. |
|
|
18
18
|
| [Commits](./04-commits.md) | Format Conventional Commits, types, breaking changes. |
|
|
19
|
-
| [Publication](./05-publication.md) | Checklist, versionnage semver, publication sur
|
|
19
|
+
| [Publication](./05-publication.md) | Checklist, versionnage semver, publication sur le registre Fraza, et sur npmjs avec `-g`. |
|
|
20
20
|
| [Notes de version](./07-changelog.md) | Génération de `CHANGELOG.md` et `changelog.json`, pieds de commit, ce que `fraza-update` en tire. |
|
|
21
21
|
| [Tests](./08-tests.md) | `node:test`, tests unitaires, tests d'intégration PostgreSQL sur un schéma jetable. |
|
|
22
22
|
| [Registre Verdaccio](./06-registre-verdaccio.md) | Administration du registre : utilisateurs, packages, tags, droits. |
|
package/dist/tools/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import { generateNotices } from "./notices.server.js";
|
|
|
8
8
|
import { findPackageRoot, ToolError } from "./package.server.js";
|
|
9
9
|
import { publishPackage } from "./publish.server.js";
|
|
10
10
|
import { releaseCheck } from "./release-check.server.js";
|
|
11
|
-
import { parseReleaseArgs, releasePackage } from "./release.server.js";
|
|
11
|
+
import { NPMJS_FLAGS, parseReleaseArgs, releasePackage } from "./release.server.js";
|
|
12
12
|
import { syncVersion } from "./sync-version.server.js";
|
|
13
13
|
import { describeSchemaAge, parseTestCleanArgs, testClean } from "./test-clean.server.js";
|
|
14
14
|
function printHelp() {
|
|
@@ -30,10 +30,12 @@ Commandes:
|
|
|
30
30
|
release [niveau] V\xE9rifie, monte la version, commite, publie, puis \xE9tiquette et pousse
|
|
31
31
|
patch (d\xE9faut), minor, major ou un num\xE9ro X.Y.Z
|
|
32
32
|
--dry-run v\xE9rifie et calcule la version sans rien \xE9crire ni publier
|
|
33
|
+
-g publie aussi sur npmjs, pour un paquet @fraza
|
|
33
34
|
release-check V\xE9rifie que le paquet peut \xEAtre publi\xE9 tel quel, sans rien modifier
|
|
34
35
|
publish Publie la version actuelle sur chaque registre o\xF9 elle manque,
|
|
35
|
-
|
|
36
|
+
registry.fraza.ca pour @fraza et @fraza-pro
|
|
36
37
|
--dry-run dit o\xF9 la version partirait, sans rien publier
|
|
38
|
+
-g ajoute npmjs, en premier, pour un paquet @fraza
|
|
37
39
|
test-clean [options] Supprime les sch\xE9mas de test rest\xE9s sur FRAZA_TEST_DATABASE_URL
|
|
38
40
|
--older-than <heures> seulement ceux plus vieux que ce nombre d'heures
|
|
39
41
|
--prefix <pr\xE9fixe> fraza_test par d\xE9faut, pr\xE9fixes plus longs compris
|
|
@@ -45,6 +47,11 @@ Codes de sortie:
|
|
|
45
47
|
1 \xE9chec, d\xE9taill\xE9 sur la sortie d'erreur
|
|
46
48
|
`);
|
|
47
49
|
}
|
|
50
|
+
function takeNpmGlobal() {
|
|
51
|
+
const global = process.env.npm_config_global === "true";
|
|
52
|
+
delete process.env.npm_config_global;
|
|
53
|
+
return global;
|
|
54
|
+
}
|
|
48
55
|
const COMMANDS = {
|
|
49
56
|
build({ root }) {
|
|
50
57
|
buildPackage({ root });
|
|
@@ -84,15 +91,17 @@ const COMMANDS = {
|
|
|
84
91
|
async release({ root, args }) {
|
|
85
92
|
const options = parseReleaseArgs(args);
|
|
86
93
|
if (process.env.npm_config_dry_run === "true") options.dryRun = true;
|
|
94
|
+
if (takeNpmGlobal()) options.npmjs = true;
|
|
87
95
|
const result = await releasePackage({ root, ...options });
|
|
88
96
|
console.log(result.dryRun ? `\u2713 Simulation termin\xE9e : ${result.previous} \u2192 ${result.version}, rien n'a \xE9t\xE9 \xE9crit ni publi\xE9.` : `\u2713 ${result.version} publi\xE9e, \xE9tiquet\xE9e v${result.version} et pouss\xE9e.`);
|
|
89
97
|
return 0;
|
|
90
98
|
},
|
|
91
99
|
async publish({ root, args }) {
|
|
92
100
|
const dryRun = args.includes("--dry-run") || process.env.npm_config_dry_run === "true";
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
101
|
+
const npmjs = takeNpmGlobal() || args.some((arg) => NPMJS_FLAGS.includes(arg));
|
|
102
|
+
const unknown = args.filter((arg) => arg !== "--dry-run" && !NPMJS_FLAGS.includes(arg));
|
|
103
|
+
if (unknown.length > 0) throw new ToolError(`publish : argument inconnu \xAB ${unknown[0]} \xBB. Usage : fraza-module publish [--dry-run] [-g]`);
|
|
104
|
+
const result = await publishPackage({ root, dryRun, npmjs });
|
|
96
105
|
if (!dryRun && result.published.length > 0) console.log(`\u2713 ${result.version} publi\xE9e sur ${result.published.join(", ")}.`);
|
|
97
106
|
return 0;
|
|
98
107
|
},
|
|
@@ -13,12 +13,15 @@ function packageScope(name) {
|
|
|
13
13
|
var _a;
|
|
14
14
|
return ((_a = /^(@[^/]+)\//.exec(name ?? "")) == null ? void 0 : _a[1]) ?? null;
|
|
15
15
|
}
|
|
16
|
-
function publishTargets(name) {
|
|
16
|
+
function publishTargets(name, { npmjs = false } = {}) {
|
|
17
17
|
const scope = packageScope(name);
|
|
18
|
-
if (scope === "@fraza") return [NPMJS, FRAZA];
|
|
18
|
+
if (scope === "@fraza") return npmjs ? [NPMJS, FRAZA] : [FRAZA];
|
|
19
19
|
if (scope === "@fraza-pro") return [FRAZA];
|
|
20
20
|
return [{ label: "registre du paquet", url: null, access: null }];
|
|
21
21
|
}
|
|
22
|
+
function reachesNpmjs(name) {
|
|
23
|
+
return packageScope(name) === "@fraza";
|
|
24
|
+
}
|
|
22
25
|
function publishConfigProblems(pkg) {
|
|
23
26
|
const scope = packageScope(pkg.name);
|
|
24
27
|
const config = pkg.publishConfig ?? {};
|
|
@@ -28,7 +31,7 @@ function publishConfigProblems(pkg) {
|
|
|
28
31
|
problems.push(`package.json#publishConfig.access doit valoir \xAB public \xBB : npmjs refuse un paquet ${scope} en \xAB ${config.access ?? "restricted"} \xBB sans abonnement payant.`);
|
|
29
32
|
}
|
|
30
33
|
if (config.registry) {
|
|
31
|
-
problems.push(`package.json#publishConfig.registry (${config.registry}) doit \xEAtre retir\xE9 : la publication choisit elle-m\xEAme les registres de ${scope},
|
|
34
|
+
problems.push(`package.json#publishConfig.registry (${config.registry}) doit \xEAtre retir\xE9 : la publication choisit elle-m\xEAme les registres de ${scope}, ${REGISTRY_HOST}, et npmjs avec -g.`);
|
|
32
35
|
}
|
|
33
36
|
} else if (scope === "@fraza-pro") {
|
|
34
37
|
if (config.registry !== FRAZA_REGISTRY) {
|
|
@@ -37,9 +40,10 @@ function publishConfigProblems(pkg) {
|
|
|
37
40
|
}
|
|
38
41
|
return problems;
|
|
39
42
|
}
|
|
40
|
-
function publishCommand(pkg) {
|
|
43
|
+
function publishCommand(pkg, { npmjs = false } = {}) {
|
|
41
44
|
var _a;
|
|
42
|
-
|
|
45
|
+
const command = ((_a = pkg.scripts) == null ? void 0 : _a["release:publish"]) ? "npm run release:publish" : "npx fraza-module publish";
|
|
46
|
+
return npmjs && reachesNpmjs(pkg.name) ? `${command} -g` : command;
|
|
43
47
|
}
|
|
44
48
|
function registryFlags(scope, target) {
|
|
45
49
|
const flags = [];
|
|
@@ -71,6 +75,7 @@ function packedTarball(dir) {
|
|
|
71
75
|
async function publishPackage({
|
|
72
76
|
root,
|
|
73
77
|
dryRun = false,
|
|
78
|
+
npmjs = false,
|
|
74
79
|
log = console.log,
|
|
75
80
|
npm = (args) => run("npm", args, { cwd: root }),
|
|
76
81
|
query = npmCapture
|
|
@@ -79,7 +84,7 @@ async function publishPackage({
|
|
|
79
84
|
const pkg = readPackage(root);
|
|
80
85
|
const { name, version } = pkg;
|
|
81
86
|
const scope = packageScope(name);
|
|
82
|
-
const targets = publishTargets(name);
|
|
87
|
+
const targets = publishTargets(name, { npmjs });
|
|
83
88
|
const configProblems = publishConfigProblems(pkg);
|
|
84
89
|
if (configProblems.length > 0) {
|
|
85
90
|
throw new ToolError(`publication refus\xE9e :
|
|
@@ -135,7 +140,7 @@ async function publishPackage({
|
|
|
135
140
|
`npm publish vers ${target.label} a \xE9chou\xE9.
|
|
136
141
|
- ${name} ${version} est sur : ${has.length ? has.join(", ") : "aucun registre"} ;
|
|
137
142
|
- il manque sur : ${lacks.join(", ")}.
|
|
138
|
-
Une fois la cause corrig\xE9e (connexion, code 2FA, droits), \xAB ${publishCommand(pkg)} \xBB publie seulement l\xE0 o\xF9 il manque, avec le m\xEAme tarball.`
|
|
143
|
+
Une fois la cause corrig\xE9e (connexion, code 2FA, droits), \xAB ${publishCommand(pkg, { npmjs })} \xBB publie seulement l\xE0 o\xF9 il manque, avec le m\xEAme tarball.`
|
|
139
144
|
);
|
|
140
145
|
}
|
|
141
146
|
published.push(target.label);
|
|
@@ -152,5 +157,6 @@ export {
|
|
|
152
157
|
publishCommand,
|
|
153
158
|
publishConfigProblems,
|
|
154
159
|
publishPackage,
|
|
155
|
-
publishTargets
|
|
160
|
+
publishTargets,
|
|
161
|
+
reachesNpmjs
|
|
156
162
|
};
|
|
@@ -5,7 +5,7 @@ import { compare, parse } from "../shared/lib/semver.js";
|
|
|
5
5
|
import { generateChangelog } from "./changelog.server.js";
|
|
6
6
|
import { checkContract } from "./contract.server.js";
|
|
7
7
|
import { packageProfile, ToolError } from "./package.server.js";
|
|
8
|
-
import { publishCommand, publishConfigProblems, publishPackage, publishTargets } from "./publish.server.js";
|
|
8
|
+
import { FRAZA_REGISTRY, NPMJS_REGISTRY, publishCommand, publishConfigProblems, publishPackage, publishTargets, reachesNpmjs } from "./publish.server.js";
|
|
9
9
|
import { run } from "./run.server.js";
|
|
10
10
|
import { syncVersion } from "./sync-version.server.js";
|
|
11
11
|
const RELEASE_LEVELS = ["patch", "minor", "major"];
|
|
@@ -56,22 +56,25 @@ function checkExactVersion(previous, next) {
|
|
|
56
56
|
}
|
|
57
57
|
return next;
|
|
58
58
|
}
|
|
59
|
+
const NPMJS_FLAGS = ["-g", "--global"];
|
|
59
60
|
function parseReleaseArgs(args) {
|
|
60
61
|
let level = null;
|
|
61
62
|
let version = null;
|
|
62
63
|
let dryRun = false;
|
|
64
|
+
let npmjs = false;
|
|
63
65
|
for (const arg of args) {
|
|
64
66
|
if (arg === "--dry-run") dryRun = true;
|
|
67
|
+
else if (NPMJS_FLAGS.includes(arg)) npmjs = true;
|
|
65
68
|
else if (RELEASE_LEVELS.includes(arg) || /^\d+\.\d+\.\d+/.test(arg)) {
|
|
66
69
|
const chosen = level ?? version;
|
|
67
70
|
if (chosen && chosen !== arg) throw new ToolError(`release : un seul niveau ou num\xE9ro \xE0 la fois (${chosen} ou ${arg}).`);
|
|
68
71
|
if (RELEASE_LEVELS.includes(arg)) level = arg;
|
|
69
72
|
else version = arg;
|
|
70
73
|
} else {
|
|
71
|
-
throw new ToolError(`release : argument inconnu \xAB ${arg} \xBB. Usage : fraza-module release [patch|minor|major|X.Y.Z] [--dry-run]`);
|
|
74
|
+
throw new ToolError(`release : argument inconnu \xAB ${arg} \xBB. Usage : fraza-module release [patch|minor|major|X.Y.Z] [--dry-run] [-g]`);
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
|
-
return { level: level ?? (version ? null : "patch"), version, dryRun };
|
|
77
|
+
return { level: level ?? (version ? null : "patch"), version, dryRun, npmjs };
|
|
75
78
|
}
|
|
76
79
|
function gitQuery(root, args) {
|
|
77
80
|
try {
|
|
@@ -110,7 +113,7 @@ function remoteProblems({ root, branch, next }) {
|
|
|
110
113
|
}
|
|
111
114
|
return problems;
|
|
112
115
|
}
|
|
113
|
-
function unfinishedRelease({ root, version, pkg }) {
|
|
116
|
+
function unfinishedRelease({ root, version, pkg, npmjs }) {
|
|
114
117
|
var _a, _b, _c;
|
|
115
118
|
const subject = (_a = gitQuery(root, ["log", "-1", "--format=%s"])) == null ? void 0 : _a.trim();
|
|
116
119
|
if (subject !== `chore: bump version to ${version}`) return null;
|
|
@@ -122,7 +125,7 @@ function unfinishedRelease({ root, version, pkg }) {
|
|
|
122
125
|
Si la branche distante a avanc\xE9, lancer d'abord \xAB git pull --no-rebase \xBB, jamais un rebase : l'\xE9tiquette publi\xE9e d\xE9signe le commit de version.`;
|
|
123
126
|
}
|
|
124
127
|
return `Le commit \xAB ${subject} \xBB est fait en local, sans \xE9tiquette ${tag} ni envoi : une publication pr\xE9c\xE9dente s'est arr\xEAt\xE9e apr\xE8s lui. Relancer \xAB npm run release \xBB monterait la version une deuxi\xE8me fois, sur une version jamais publi\xE9e. Pour reprendre :
|
|
125
|
-
${publishCommand(pkg)}
|
|
128
|
+
${publishCommand(pkg, { npmjs })}
|
|
126
129
|
git tag -a ${tag} -m ${tag}
|
|
127
130
|
${PUSH_COMMAND}
|
|
128
131
|
La premi\xE8re commande publie seulement sur les registres o\xF9 ${version} manque. Pour annuler la mont\xE9e de version, si ${version} n'est publi\xE9e nulle part :
|
|
@@ -154,7 +157,11 @@ function frazaDependencies(pkg) {
|
|
|
154
157
|
}
|
|
155
158
|
return [...names].sort();
|
|
156
159
|
}
|
|
157
|
-
|
|
160
|
+
function npmjsHint(pkg, npmjs) {
|
|
161
|
+
if (!npmjs || !reachesNpmjs(pkg.name) || frazaDependencies(pkg).length === 0) return "";
|
|
162
|
+
return "\n Avec -g, le paquet est v\xE9rifi\xE9 contre les paquets Fraza publi\xE9s sur npmjs. Si l'un d'eux n'a sa derni\xE8re version que sur registry.fraza.ca, la porter d'abord sur npmjs : \xAB npm run release:publish -g \xBB dans son d\xE9p\xF4t.";
|
|
163
|
+
}
|
|
164
|
+
async function preflight({ root, profile, previous, next, npmjs, npm, log, contract = checkContract }) {
|
|
158
165
|
var _a, _b, _c, _d, _e;
|
|
159
166
|
const { pkg, kind } = profile;
|
|
160
167
|
const problems = [];
|
|
@@ -170,7 +177,7 @@ async function preflight({ root, profile, previous, next, npm, log, contract = c
|
|
|
170
177
|
problems.push(`La branche ${branch} ne suit aucune branche distante : \xAB ${PUSH_COMMAND} \xBB \xE9chouerait apr\xE8s la publication. Lancer d'abord \xAB git push -u origin ${branch} \xBB.`);
|
|
171
178
|
} else {
|
|
172
179
|
problems.push(...remoteProblems({ root, branch, next }));
|
|
173
|
-
const unfinished = unfinishedRelease({ root, version: previous, pkg });
|
|
180
|
+
const unfinished = unfinishedRelease({ root, version: previous, pkg, npmjs });
|
|
174
181
|
if (unfinished) problems.push(unfinished);
|
|
175
182
|
}
|
|
176
183
|
}
|
|
@@ -188,21 +195,24 @@ async function preflight({ root, profile, previous, next, npm, log, contract = c
|
|
|
188
195
|
const deps = frazaDependencies(pkg);
|
|
189
196
|
if (deps.length > 0) {
|
|
190
197
|
const specs = deps.map((name) => `${name}@latest`);
|
|
191
|
-
|
|
192
|
-
|
|
198
|
+
const fromNpmjs = npmjs && reachesNpmjs(pkg.name);
|
|
199
|
+
const flags = [`--@fraza:registry=${fromNpmjs ? NPMJS_REGISTRY : FRAZA_REGISTRY}`];
|
|
200
|
+
log(`\u25C6 npm install --no-save ${specs.join(" ")}, depuis ${fromNpmjs ? "npmjs" : "registry.fraza.ca"}`);
|
|
201
|
+
if (npm(["install", "--no-save", ...specs, ...flags]) !== 0) {
|
|
193
202
|
throw new ToolError(formatProblems([`npm install des derni\xE8res versions Fraza a \xE9chou\xE9 (${specs.join(", ")}).`]));
|
|
194
203
|
}
|
|
195
204
|
}
|
|
196
205
|
log("\u25C6 npm run build");
|
|
197
|
-
if (npm(["run", "build"]) !== 0) throw new ToolError(formatProblems([
|
|
206
|
+
if (npm(["run", "build"]) !== 0) throw new ToolError(formatProblems([`npm run build a \xE9chou\xE9.${npmjsHint(pkg, npmjs)}`]));
|
|
198
207
|
if (kind === "module") {
|
|
199
208
|
log("\u25C6 fraza-module check");
|
|
200
209
|
const { errors } = await contract({ root });
|
|
201
|
-
|
|
210
|
+
const hint = npmjsHint(pkg, npmjs).trim();
|
|
211
|
+
if (errors.length > 0) throw new ToolError(formatProblems(hint ? [...errors, hint] : errors));
|
|
202
212
|
}
|
|
203
213
|
if ((_e = pkg.scripts) == null ? void 0 : _e.test) {
|
|
204
214
|
log("\u25C6 npm test");
|
|
205
|
-
if (npm(["test"]) !== 0) throw new ToolError(formatProblems([
|
|
215
|
+
if (npm(["test"]) !== 0) throw new ToolError(formatProblems([`npm test a \xE9chou\xE9.${npmjsHint(pkg, npmjs)}`]));
|
|
206
216
|
}
|
|
207
217
|
const changed = dirtyPaths(root).filter((path) => !FROM_INSTALLED_TREE.includes(path));
|
|
208
218
|
if (changed.length > 0) {
|
|
@@ -278,6 +288,7 @@ async function releasePackage({
|
|
|
278
288
|
level = "patch",
|
|
279
289
|
version = null,
|
|
280
290
|
dryRun = false,
|
|
291
|
+
npmjs = false,
|
|
281
292
|
log = console.log,
|
|
282
293
|
npm = (args) => run("npm", args, { cwd: root }),
|
|
283
294
|
contract = checkContract,
|
|
@@ -296,8 +307,10 @@ async function releasePackage({
|
|
|
296
307
|
level = level ?? "patch";
|
|
297
308
|
}
|
|
298
309
|
const tag = `v${next}`;
|
|
310
|
+
const targets = publishTargets(profile.name, { npmjs }).map((t) => t.label).join(", puis ");
|
|
299
311
|
log(`${profile.name} : ${previous} \u2192 ${next} (${level})${dryRun ? ", simulation" : ""}`);
|
|
300
|
-
|
|
312
|
+
log(`Registres : ${targets}${npmjs && !reachesNpmjs(profile.name) ? " (-g ignor\xE9 : seul un paquet @fraza/* va sur npmjs)" : ""}`);
|
|
313
|
+
await preflight({ root, profile, previous, next, npmjs, npm, log, contract });
|
|
301
314
|
if (dryRun) {
|
|
302
315
|
const lock = existsSync(join(root, "package-lock.json")) ? ", package-lock.json" : "";
|
|
303
316
|
log("");
|
|
@@ -307,15 +320,15 @@ async function releasePackage({
|
|
|
307
320
|
log(" 3. changelog : CHANGELOG.md, changelog.json, package.json#fraza");
|
|
308
321
|
log(" 4. npm run build");
|
|
309
322
|
log(` 5. git commit \xAB chore: bump version to ${next} \xBB`);
|
|
310
|
-
log(` 6. publication : ${
|
|
323
|
+
log(` 6. publication : ${targets}`);
|
|
311
324
|
log(` 7. git tag -a ${tag} -m ${tag}`);
|
|
312
325
|
log(` 8. ${PUSH_COMMAND}`);
|
|
313
326
|
return { previous, version: next, dryRun: true };
|
|
314
327
|
}
|
|
315
328
|
const files = bumpAndCommit({ root, profile, next, npm, log });
|
|
316
|
-
log(`\u25C6 publication : ${
|
|
329
|
+
log(`\u25C6 publication : ${targets}`);
|
|
317
330
|
try {
|
|
318
|
-
await publish({ root, log });
|
|
331
|
+
await publish({ root, log, npmjs });
|
|
319
332
|
} catch (error) {
|
|
320
333
|
const reason = error instanceof ToolError ? error.message : String((error == null ? void 0 : error.stack) ?? error);
|
|
321
334
|
throw new ToolError(
|
|
@@ -326,7 +339,7 @@ O\xF9 en est la publication :
|
|
|
326
339
|
- aucune \xE9tiquette n'est pos\xE9e, rien n'est pouss\xE9.
|
|
327
340
|
|
|
328
341
|
Ne pas relancer \xAB npm run release \xBB : il monterait la version une deuxi\xE8me fois. Pour reprendre, une fois la cause corrig\xE9e, publier l\xE0 o\xF9 la version manque, puis poser l'\xE9tiquette :
|
|
329
|
-
${publishCommand(profile.pkg)}
|
|
342
|
+
${publishCommand(profile.pkg, { npmjs })}
|
|
330
343
|
git tag -a ${tag} -m ${tag}
|
|
331
344
|
${PUSH_COMMAND}
|
|
332
345
|
|
|
@@ -363,6 +376,7 @@ O\xF9 en est la publication :
|
|
|
363
376
|
return { previous, version: next, dryRun: false };
|
|
364
377
|
}
|
|
365
378
|
export {
|
|
379
|
+
NPMJS_FLAGS,
|
|
366
380
|
RELEASE_LEVELS,
|
|
367
381
|
bumpVersion,
|
|
368
382
|
checkExactVersion,
|