@lystech/core 3.0.121 → 3.0.123
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/bin/check-routes.cjs +141 -0
- package/dist/index.d.ts +3 -0
- package/dist/lystech-core-provider.es.js +2 -1
- package/dist/lystech-core-provider.umd.js +144 -144
- package/package.json +5 -2
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/* =====================================================================
|
|
4
|
+
LES ROUTES DE BASE SONT-ELLES BRANCHÉES DANS CETTE APPLICATION ?
|
|
5
|
+
|
|
6
|
+
Le serveur écrit des adresses dans les courriels qu'il envoie — lien
|
|
7
|
+
d'activation d'un compte, lien de réinitialisation de mot de passe.
|
|
8
|
+
Il les construit sur le domaine de l'application CONCERNÉE, pour que
|
|
9
|
+
le client reste chez le commerçant plutôt que d'atterrir sur la
|
|
10
|
+
console d'administration.
|
|
11
|
+
|
|
12
|
+
Rien ne vérifiait que l'application savait les recevoir. Résultat vu
|
|
13
|
+
en production : un client s'inscrit, clique son lien, et tombe sur
|
|
14
|
+
une page ENTIÈREMENT BLANCHE — React Router ne trouve pas de route,
|
|
15
|
+
ne rend rien, ne dit rien. Six applications avaient le trou, et la
|
|
16
|
+
réinitialisation de mot de passe était morte partout sans que
|
|
17
|
+
personne l'ait signalé.
|
|
18
|
+
|
|
19
|
+
Ce script transforme la consigne en vérification. Il lit le code des
|
|
20
|
+
routes et dit ce qui manque.
|
|
21
|
+
|
|
22
|
+
Usage : npx @lystech/core check-routes
|
|
23
|
+
npx @lystech/core check-routes --ci (sort en erreur)
|
|
24
|
+
===================================================================== */
|
|
25
|
+
|
|
26
|
+
const fs = require("fs");
|
|
27
|
+
const path = require("path");
|
|
28
|
+
|
|
29
|
+
const CI = process.argv.includes("--ci");
|
|
30
|
+
|
|
31
|
+
/* Les adresses que le serveur peut écrire dans un courriel, et ce qui
|
|
32
|
+
suffit pour les couvrir. `lystechAuthRoutes()` les couvre toutes. */
|
|
33
|
+
const ATTENDU = [
|
|
34
|
+
{
|
|
35
|
+
nom: "Activation d'un compte",
|
|
36
|
+
/* DEUX FORMES, parce que le serveur en écrit deux. L'app Finance
|
|
37
|
+
reçoit `/activate?token=` sur son propre domaine ; toutes les
|
|
38
|
+
autres reçoivent `/account/activation/:token`. Exiger une seule
|
|
39
|
+
forme signalerait Finance à tort — et un vérificateur qui crie au
|
|
40
|
+
loup finit par ne plus être lu. */
|
|
41
|
+
motifs: [
|
|
42
|
+
/account\/activation\/:token/,
|
|
43
|
+
/lystechAuthRoutes/,
|
|
44
|
+
/path=["'`]\/activate["'`]/,
|
|
45
|
+
],
|
|
46
|
+
pourquoi:
|
|
47
|
+
"un nouveau client clique le lien de son courriel d'inscription",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
nom: "Réinitialisation de mot de passe",
|
|
51
|
+
motifs: [
|
|
52
|
+
/account\/reset-password\/:token/,
|
|
53
|
+
/lystechAuthRoutes/,
|
|
54
|
+
/path=["'`]\/reset["'`]/,
|
|
55
|
+
],
|
|
56
|
+
pourquoi: "un client qui a oublié son mot de passe demande un lien",
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
const REPLI = {
|
|
61
|
+
nom: "Page de repli (route inconnue)",
|
|
62
|
+
motifs: [/path=["'`]\*["'`]/],
|
|
63
|
+
pourquoi:
|
|
64
|
+
"sans elle, une route manquante est une page blanche muette — c'est ce qui a caché le défaut pendant des mois",
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function fichiersDeRoutes(racine) {
|
|
68
|
+
const dossier = path.join(racine, "src");
|
|
69
|
+
if (!fs.existsSync(dossier)) return [];
|
|
70
|
+
const trouves = [];
|
|
71
|
+
const visiter = (d, profondeur) => {
|
|
72
|
+
if (profondeur > 4) return;
|
|
73
|
+
for (const e of fs.readdirSync(d, { withFileTypes: true })) {
|
|
74
|
+
if (e.name === "node_modules" || e.name.startsWith(".")) continue;
|
|
75
|
+
const p = path.join(d, e.name);
|
|
76
|
+
if (e.isDirectory()) visiter(p, profondeur + 1);
|
|
77
|
+
else if (/\.(tsx|jsx)$/.test(e.name)) {
|
|
78
|
+
const texte = fs.readFileSync(p, "utf8");
|
|
79
|
+
/* On ne garde que les fichiers qui DÉCLARENT des routes : chercher
|
|
80
|
+
partout produirait des faux positifs sur de simples liens. */
|
|
81
|
+
if (texte.includes("<Routes") || texte.includes("<Route ")) {
|
|
82
|
+
trouves.push({ chemin: p, texte });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
visiter(dossier, 0);
|
|
88
|
+
return trouves;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function main() {
|
|
92
|
+
const racine = process.cwd();
|
|
93
|
+
const nom = (() => {
|
|
94
|
+
try {
|
|
95
|
+
return JSON.parse(
|
|
96
|
+
fs.readFileSync(path.join(racine, "package.json"), "utf8"),
|
|
97
|
+
).name;
|
|
98
|
+
} catch {
|
|
99
|
+
return path.basename(racine);
|
|
100
|
+
}
|
|
101
|
+
})();
|
|
102
|
+
|
|
103
|
+
const fichiers = fichiersDeRoutes(racine);
|
|
104
|
+
if (!fichiers.length) {
|
|
105
|
+
console.log(`\n ${nom} : aucun fichier de routes trouvé — rien à vérifier.\n`);
|
|
106
|
+
return 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const tout = fichiers.map((f) => f.texte).join("\n");
|
|
110
|
+
const manquants = [];
|
|
111
|
+
|
|
112
|
+
console.log(`\n ROUTES DE BASE — ${nom}`);
|
|
113
|
+
console.log(` ${fichiers.length} fichier(s) de routes lu(s)\n`);
|
|
114
|
+
|
|
115
|
+
for (const cible of [...ATTENDU, REPLI]) {
|
|
116
|
+
const ok = cible.motifs.some((m) => m.test(tout));
|
|
117
|
+
console.log(` ${ok ? "OK " : "MANQUE"} ${cible.nom}`);
|
|
118
|
+
if (!ok) {
|
|
119
|
+
console.log(` ${cible.pourquoi}`);
|
|
120
|
+
manquants.push(cible);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!manquants.length) {
|
|
125
|
+
console.log("\n Tout est branché.\n");
|
|
126
|
+
return 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
console.log("\n À AJOUTER dans le <Routes> de l'application :\n");
|
|
130
|
+
console.log(' import { lystechAuthRoutes, LystechNotFoundPage } from "@lystech/core";');
|
|
131
|
+
console.log("");
|
|
132
|
+
console.log(" <Routes>");
|
|
133
|
+
console.log(" {lystechAuthRoutes()}");
|
|
134
|
+
console.log(" ... vos routes ...");
|
|
135
|
+
console.log(' <Route path="*" element={<LystechNotFoundPage />} />');
|
|
136
|
+
console.log(" </Routes>\n");
|
|
137
|
+
|
|
138
|
+
return CI ? 1 : 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
process.exit(main());
|
package/dist/index.d.ts
CHANGED
|
@@ -1468,4 +1468,7 @@ export declare const useUserRoleDetails: (authKey: string, organizationSubdomain
|
|
|
1468
1468
|
|
|
1469
1469
|
export declare function validatePromoCode(code: string, products: any[]): Promise<AppliedPromoCodeType>;
|
|
1470
1470
|
|
|
1471
|
+
|
|
1472
|
+
export * from "@lystech/sections";
|
|
1473
|
+
|
|
1471
1474
|
export { }
|
|
@@ -3,6 +3,7 @@ import ge, { createContext as pr, useMemo as Ft, useRef as ze, useEffect as We,
|
|
|
3
3
|
import { useLocation as iv, useNavigate as ov, useParams as xy, useSearchParams as U8, Route as fp, Link as G8 } from "react-router-dom";
|
|
4
4
|
import * as Ey from "react-dom";
|
|
5
5
|
import hp, { createPortal as Ay, unstable_batchedUpdates as K8, flushSync as fh } from "react-dom";
|
|
6
|
+
export * from "@lystech/sections";
|
|
6
7
|
var bi = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
|
|
7
8
|
function yi(e) {
|
|
8
9
|
return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
|
|
@@ -43084,7 +43085,7 @@ const eh = {
|
|
|
43084
43085
|
padding: 2,
|
|
43085
43086
|
lineHeight: 0,
|
|
43086
43087
|
flexShrink: 0
|
|
43087
|
-
}, uW = "@lystech/core", dW = "lystechcorenpmpackage:last-version", fW = "3.0.
|
|
43088
|
+
}, uW = "@lystech/core", dW = "lystechcorenpmpackage:last-version", fW = "3.0.123";
|
|
43088
43089
|
function hW(e = {}) {
|
|
43089
43090
|
const {
|
|
43090
43091
|
packageName: t = uW,
|