@sia-ui/cli 0.4.0 → 0.6.0
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 +58 -0
- package/README.md +58 -0
- package/dist/index.js +30 -11
- package/dist/lifecycle.mjs +189 -4
- package/dist/lock.mjs +16 -2
- package/dist/registry/package/components/ActivityLog/index.tsx +241 -0
- package/dist/registry/package/components/ActivityLog/styles.css +31 -0
- package/dist/registry/package/components/Badge/index.tsx +58 -0
- package/dist/registry/package/components/Calendar/index.tsx +4 -4
- package/dist/registry/package/components/CrudPage/dialogs.tsx +35 -22
- package/dist/registry/package/components/CrudPage/index.tsx +58 -26
- package/dist/registry/package/components/CrudPage/styles.css +7 -6
- package/dist/registry/package/components/DataTable/index.tsx +5 -1
- package/dist/registry/package/components/DataTable/query.ts +23 -3
- package/dist/registry/package/components/DataTable/row-actions.tsx +1 -1
- package/dist/registry/package/components/DataTable/types.ts +8 -0
- package/dist/registry/package/components/Drawer/index.tsx +9 -3
- package/dist/registry/package/components/Form/index.tsx +69 -3
- package/dist/registry/package/components/Icons/index.tsx +88 -4
- package/dist/registry/package/components/PageHeader/index.tsx +28 -4
- package/dist/registry/package/components/PageHeader/styles.css +14 -2
- package/dist/registry/package/components/Pagination/index.tsx +168 -61
- package/dist/registry/package/components/Pagination/styles.css +133 -38
- package/dist/registry/package/components/PhoneInput/index.tsx +46 -29
- package/dist/registry/package/components/PhoneInput/styles.css +7 -21
- package/dist/registry/package/components/Resource/index.tsx +69 -19
- package/dist/registry/package/components/SecretFields/index.tsx +193 -0
- package/dist/registry/package/components/SecretFields/styles.css +84 -0
- package/dist/registry/package/components/Select/index.tsx +34 -8
- package/dist/registry/package/components/Select/styles.css +18 -0
- package/dist/registry/package/components/Timer/index.tsx +1 -1
- package/dist/registry/package/lib/form-adapter-rhf.tsx +23 -10
- package/dist/registry/registry.json +71 -16
- package/dist/registry/styles/sia-ui.css +7 -1
- package/dist/source.mjs +10 -0
- package/dist/styles.mjs +111 -0
- package/package.json +5 -5
|
@@ -22,11 +22,21 @@ import {
|
|
|
22
22
|
type UseFormProps,
|
|
23
23
|
type UseFormReturn,
|
|
24
24
|
} from "react-hook-form";
|
|
25
|
-
import
|
|
25
|
+
import {
|
|
26
|
+
hasFormErrors,
|
|
27
|
+
type FieldBindOptions,
|
|
28
|
+
type FieldBinding,
|
|
29
|
+
type FormAdapter,
|
|
30
|
+
type FormErrors,
|
|
31
|
+
type FormState,
|
|
32
|
+
type FormSubmitResult,
|
|
33
|
+
} from "@sia-ui/headless";
|
|
26
34
|
|
|
27
35
|
export interface RhfAdapterOptions<TValues extends FieldValues>
|
|
28
36
|
extends UseFormProps<TValues> {
|
|
29
|
-
onSubmit?: (
|
|
37
|
+
onSubmit?: (
|
|
38
|
+
values: TValues,
|
|
39
|
+
) => FormSubmitResult<TValues> | Promise<FormSubmitResult<TValues>>;
|
|
30
40
|
}
|
|
31
41
|
|
|
32
42
|
export interface RhfAdapter<TValues extends FieldValues>
|
|
@@ -94,6 +104,12 @@ export function useRhfFormAdapter<TValues extends FieldValues>(
|
|
|
94
104
|
[formOptions.mode, formState.errors, setValue, trigger, watch],
|
|
95
105
|
);
|
|
96
106
|
|
|
107
|
+
const poserErreurs = (next: FormErrors<TValues>) => {
|
|
108
|
+
for (const [key, message] of Object.entries(next)) {
|
|
109
|
+
if (message) setError(key as Path<TValues>, { message: String(message) });
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
97
113
|
const state: FormState<TValues> = {
|
|
98
114
|
values: values as TValues,
|
|
99
115
|
errors,
|
|
@@ -123,17 +139,14 @@ export function useRhfFormAdapter<TValues extends FieldValues>(
|
|
|
123
139
|
if (message) setError(name as Path<TValues>, { message });
|
|
124
140
|
else clearErrors(name as Path<TValues>);
|
|
125
141
|
},
|
|
126
|
-
// Ce que rend `HttpError.
|
|
127
|
-
// les erreurs du serveur se posent sous les champs, pas dans un bandeau.
|
|
128
|
-
setErrors:
|
|
129
|
-
for (const [key, message] of Object.entries(next)) {
|
|
130
|
-
if (message) setError(key as Path<TValues>, { message: String(message) });
|
|
131
|
-
}
|
|
132
|
-
},
|
|
142
|
+
// Ce que rend `HttpError.toFormErrors()` de `@sia-ui/api` entre directement
|
|
143
|
+
// ici : les erreurs du serveur se posent sous les champs, pas dans un bandeau.
|
|
144
|
+
setErrors: poserErreurs,
|
|
133
145
|
reset: (next) => reset(next as TValues | undefined),
|
|
134
146
|
submit: async () => {
|
|
135
147
|
await handleSubmit(async (formValues) => {
|
|
136
|
-
await onSubmit?.(formValues);
|
|
148
|
+
const result = await onSubmit?.(formValues);
|
|
149
|
+
if (hasFormErrors(result)) poserErreurs(result);
|
|
137
150
|
})();
|
|
138
151
|
},
|
|
139
152
|
validate: () => trigger(),
|
|
@@ -22,6 +22,32 @@
|
|
|
22
22
|
"icons"
|
|
23
23
|
]
|
|
24
24
|
},
|
|
25
|
+
{
|
|
26
|
+
"name": "activity-log",
|
|
27
|
+
"description": "Server-filtered activity log: declared filters, debounced search, pagination and page size.",
|
|
28
|
+
"type": "pattern",
|
|
29
|
+
"version": "0.3.0",
|
|
30
|
+
"status": "experimental",
|
|
31
|
+
"source": "package",
|
|
32
|
+
"files": [
|
|
33
|
+
"components/ActivityLog/index.tsx",
|
|
34
|
+
"components/ActivityLog/styles.css"
|
|
35
|
+
],
|
|
36
|
+
"dependencies": [
|
|
37
|
+
"@sia-ui/headless",
|
|
38
|
+
"@sia-ui/tokens",
|
|
39
|
+
"@sia-ui/utils"
|
|
40
|
+
],
|
|
41
|
+
"registryDependencies": [
|
|
42
|
+
"badge",
|
|
43
|
+
"data-table",
|
|
44
|
+
"filters-bar",
|
|
45
|
+
"page-header",
|
|
46
|
+
"pagination",
|
|
47
|
+
"search-input",
|
|
48
|
+
"select"
|
|
49
|
+
]
|
|
50
|
+
},
|
|
25
51
|
{
|
|
26
52
|
"name": "alert",
|
|
27
53
|
"description": "Semantic feedback alert with tones, action and dismissal.",
|
|
@@ -179,7 +205,7 @@
|
|
|
179
205
|
"name": "badge",
|
|
180
206
|
"description": "Compact semantic status label with side content and loading state.",
|
|
181
207
|
"type": "primitive",
|
|
182
|
-
"version": "0.
|
|
208
|
+
"version": "0.3.0",
|
|
183
209
|
"status": "stable",
|
|
184
210
|
"source": "package",
|
|
185
211
|
"files": [
|
|
@@ -240,7 +266,7 @@
|
|
|
240
266
|
"name": "calendar",
|
|
241
267
|
"description": "Localized month and year calendar with range selection and custom cells.",
|
|
242
268
|
"type": "component",
|
|
243
|
-
"version": "0.1.
|
|
269
|
+
"version": "0.1.1",
|
|
244
270
|
"status": "stable",
|
|
245
271
|
"source": "package",
|
|
246
272
|
"files": [
|
|
@@ -383,7 +409,7 @@
|
|
|
383
409
|
"name": "crud-page",
|
|
384
410
|
"description": "List page for a declared resource: create, view, edit and delete open their own dialogs, each removable and permission-aware.",
|
|
385
411
|
"type": "pattern",
|
|
386
|
-
"version": "0.
|
|
412
|
+
"version": "0.4.0",
|
|
387
413
|
"status": "stable",
|
|
388
414
|
"source": "package",
|
|
389
415
|
"files": [
|
|
@@ -426,7 +452,7 @@
|
|
|
426
452
|
"name": "data-table",
|
|
427
453
|
"description": "Data table: row actions with permissions and confirmation, selection, card view, density and sorting.",
|
|
428
454
|
"type": "component",
|
|
429
|
-
"version": "0.
|
|
455
|
+
"version": "0.4.0",
|
|
430
456
|
"status": "stable",
|
|
431
457
|
"source": "package",
|
|
432
458
|
"files": [
|
|
@@ -566,17 +592,21 @@
|
|
|
566
592
|
"name": "drawer",
|
|
567
593
|
"description": "Accessible side panel with focus management and portal rendering.",
|
|
568
594
|
"type": "component",
|
|
569
|
-
"version": "0.1.
|
|
595
|
+
"version": "0.1.1",
|
|
570
596
|
"status": "stable",
|
|
571
597
|
"source": "package",
|
|
572
598
|
"files": [
|
|
573
599
|
"components/Drawer/index.tsx",
|
|
600
|
+
"components/Drawer/context.ts",
|
|
574
601
|
"components/Drawer/styles.css"
|
|
575
602
|
],
|
|
576
603
|
"dependencies": [
|
|
577
604
|
"@sia-ui/headless",
|
|
578
605
|
"@sia-ui/react",
|
|
579
606
|
"@sia-ui/utils"
|
|
607
|
+
],
|
|
608
|
+
"registryDependencies": [
|
|
609
|
+
"icons"
|
|
580
610
|
]
|
|
581
611
|
},
|
|
582
612
|
{
|
|
@@ -755,7 +785,7 @@
|
|
|
755
785
|
"name": "form",
|
|
756
786
|
"description": "Declarative form driven by a field list, wired to any FormAdapter.",
|
|
757
787
|
"type": "pattern",
|
|
758
|
-
"version": "0.
|
|
788
|
+
"version": "0.3.0",
|
|
759
789
|
"status": "stable",
|
|
760
790
|
"source": "package",
|
|
761
791
|
"files": [
|
|
@@ -767,6 +797,7 @@
|
|
|
767
797
|
"@sia-ui/utils"
|
|
768
798
|
],
|
|
769
799
|
"registryDependencies": [
|
|
800
|
+
"alert",
|
|
770
801
|
"button",
|
|
771
802
|
"field"
|
|
772
803
|
]
|
|
@@ -775,7 +806,7 @@
|
|
|
775
806
|
"name": "form-adapter-rhf",
|
|
776
807
|
"description": "react-hook-form adapter for the FormAdapter contract. Requires react-hook-form.",
|
|
777
808
|
"type": "primitive",
|
|
778
|
-
"version": "0.
|
|
809
|
+
"version": "0.3.0",
|
|
779
810
|
"status": "stable",
|
|
780
811
|
"source": "package",
|
|
781
812
|
"files": [
|
|
@@ -841,7 +872,7 @@
|
|
|
841
872
|
"name": "icons",
|
|
842
873
|
"description": "Jeu d'icônes SVG sans dépendance, servi par le package.",
|
|
843
874
|
"type": "primitive",
|
|
844
|
-
"version": "0.
|
|
875
|
+
"version": "0.3.0",
|
|
845
876
|
"status": "stable",
|
|
846
877
|
"source": "package",
|
|
847
878
|
"files": [
|
|
@@ -1075,7 +1106,7 @@
|
|
|
1075
1106
|
"name": "page-header",
|
|
1076
1107
|
"description": "Consistent page title, description and action area.",
|
|
1077
1108
|
"type": "pattern",
|
|
1078
|
-
"version": "0.
|
|
1109
|
+
"version": "0.3.0",
|
|
1079
1110
|
"status": "stable",
|
|
1080
1111
|
"source": "package",
|
|
1081
1112
|
"files": [
|
|
@@ -1090,7 +1121,7 @@
|
|
|
1090
1121
|
"name": "pagination",
|
|
1091
1122
|
"description": "Accessible controlled pagination with compact page ranges.",
|
|
1092
1123
|
"type": "component",
|
|
1093
|
-
"version": "0.
|
|
1124
|
+
"version": "0.3.0",
|
|
1094
1125
|
"status": "stable",
|
|
1095
1126
|
"source": "package",
|
|
1096
1127
|
"files": [
|
|
@@ -1102,7 +1133,8 @@
|
|
|
1102
1133
|
"@sia-ui/utils"
|
|
1103
1134
|
],
|
|
1104
1135
|
"registryDependencies": [
|
|
1105
|
-
"icons"
|
|
1136
|
+
"icons",
|
|
1137
|
+
"select"
|
|
1106
1138
|
]
|
|
1107
1139
|
},
|
|
1108
1140
|
{
|
|
@@ -1140,7 +1172,7 @@
|
|
|
1140
1172
|
"name": "phone-input",
|
|
1141
1173
|
"description": "International phone input with dial code and grouping.",
|
|
1142
1174
|
"type": "component",
|
|
1143
|
-
"version": "0.
|
|
1175
|
+
"version": "0.3.0",
|
|
1144
1176
|
"status": "stable",
|
|
1145
1177
|
"source": "package",
|
|
1146
1178
|
"files": [
|
|
@@ -1152,7 +1184,8 @@
|
|
|
1152
1184
|
"@sia-ui/utils"
|
|
1153
1185
|
],
|
|
1154
1186
|
"registryDependencies": [
|
|
1155
|
-
"input"
|
|
1187
|
+
"input",
|
|
1188
|
+
"select"
|
|
1156
1189
|
]
|
|
1157
1190
|
},
|
|
1158
1191
|
{
|
|
@@ -1309,7 +1342,7 @@
|
|
|
1309
1342
|
"name": "resource",
|
|
1310
1343
|
"description": "Declare a resource once: table columns, form fields, detail view, validation, search keys and permissions are all derived from it.",
|
|
1311
1344
|
"type": "pattern",
|
|
1312
|
-
"version": "0.
|
|
1345
|
+
"version": "0.3.0",
|
|
1313
1346
|
"status": "stable",
|
|
1314
1347
|
"source": "package",
|
|
1315
1348
|
"files": [
|
|
@@ -1378,11 +1411,33 @@
|
|
|
1378
1411
|
"icons"
|
|
1379
1412
|
]
|
|
1380
1413
|
},
|
|
1414
|
+
{
|
|
1415
|
+
"name": "secret-fields",
|
|
1416
|
+
"description": "Write-only key/value secrets editor: stored names shown, values never read back.",
|
|
1417
|
+
"type": "component",
|
|
1418
|
+
"version": "0.3.0",
|
|
1419
|
+
"status": "experimental",
|
|
1420
|
+
"source": "package",
|
|
1421
|
+
"files": [
|
|
1422
|
+
"components/SecretFields/index.tsx",
|
|
1423
|
+
"components/SecretFields/styles.css"
|
|
1424
|
+
],
|
|
1425
|
+
"dependencies": [
|
|
1426
|
+
"@sia-ui/utils"
|
|
1427
|
+
],
|
|
1428
|
+
"registryDependencies": [
|
|
1429
|
+
"button",
|
|
1430
|
+
"icon-button",
|
|
1431
|
+
"icons",
|
|
1432
|
+
"input",
|
|
1433
|
+
"password-input"
|
|
1434
|
+
]
|
|
1435
|
+
},
|
|
1381
1436
|
{
|
|
1382
1437
|
"name": "select",
|
|
1383
1438
|
"description": "Accessible searchable select with positioned overlay and async option loading.",
|
|
1384
1439
|
"type": "component",
|
|
1385
|
-
"version": "0.
|
|
1440
|
+
"version": "0.3.0",
|
|
1386
1441
|
"status": "stable",
|
|
1387
1442
|
"source": "package",
|
|
1388
1443
|
"files": [
|
|
@@ -1647,7 +1702,7 @@
|
|
|
1647
1702
|
"name": "timer",
|
|
1648
1703
|
"description": "Reliable count-up or count-down timer based on absolute time.",
|
|
1649
1704
|
"type": "component",
|
|
1650
|
-
"version": "0.1.
|
|
1705
|
+
"version": "0.1.1",
|
|
1651
1706
|
"status": "stable",
|
|
1652
1707
|
"source": "package",
|
|
1653
1708
|
"files": [
|
|
@@ -144,6 +144,12 @@
|
|
|
144
144
|
--sia-elevation-modal: 0 24px 60px rgb(15 23 42 / 0.22);
|
|
145
145
|
}
|
|
146
146
|
/* @end:theme */
|
|
147
|
+
/* Les composants sont écrits en `border-box` : `width:100%` plus un padding
|
|
148
|
+
ne doit pas déborder. Sans ce reset, un projet qui n'en pose pas lui-même
|
|
149
|
+
gagnait 32 px de défilement horizontal sous `AppShell`, et des champs plus
|
|
150
|
+
larges que leur colonne. Spécificité nulle : la moindre règle de l'hôte
|
|
151
|
+
l'emporte, et un composant qui veut `content-box` le déclare (Chart). */
|
|
152
|
+
:where(*), :where(*)::before, :where(*)::after { box-sizing:border-box; }
|
|
147
153
|
/* Scrollbars SIA UI globales : faibles en spécificité, donc surchargeables. */
|
|
148
154
|
:root {
|
|
149
155
|
--sia-scrollbar-size:.625rem;
|
|
@@ -203,7 +209,7 @@
|
|
|
203
209
|
/* Wave 2 business components */
|
|
204
210
|
@media (max-width:900px) { .sia-kpi-grid--3,.sia-kpi-grid--4 { grid-template-columns:repeat(2,minmax(0,1fr)); } }
|
|
205
211
|
@media (max-width:560px) { .sia-kpi-grid--2,.sia-kpi-grid--3,.sia-kpi-grid--4 { grid-template-columns:1fr; } .sia-filters-bar { align-items:stretch; }.sia-filters-bar__main,.sia-filters-bar__actions { width:100%; } }
|
|
206
|
-
@media (max-width:640px) { .sia-
|
|
212
|
+
@media (max-width:640px) { .sia-entity-meta__grid { grid-template-columns:1fr; } }
|
|
207
213
|
.sia-month-picker,.sia-year-picker,.sia-week-picker { min-height:2.5rem; padding:0 .75rem; border:1px solid var(--sia-border); border-radius:var(--sia-radius); color:var(--sia-foreground); background:var(--sia-background); font:inherit; }
|
|
208
214
|
.sia-picker--invalid { border-color:var(--sia-danger); }
|
|
209
215
|
.sia-tone--neutral { --sia-accent:var(--sia-muted); --sia-accent-foreground:var(--sia-background); }
|
package/dist/source.mjs
CHANGED
|
@@ -40,6 +40,7 @@ export async function sourceLocale(racine) {
|
|
|
40
40
|
origine: "embarqué",
|
|
41
41
|
registre,
|
|
42
42
|
lire: (fichier) => readFile(join(racine, "package", fichier)),
|
|
43
|
+
lireStyles: () => readFile(join(racine, "styles/sia-ui.css")),
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -78,6 +79,15 @@ export async function sourceDistante(base) {
|
|
|
78
79
|
}
|
|
79
80
|
return Buffer.from(await r.arrayBuffer());
|
|
80
81
|
},
|
|
82
|
+
// La feuille vient du même registre que les composants : servis par une
|
|
83
|
+
// URL, ils ne doivent pas dépendre de la feuille figée dans la CLI.
|
|
84
|
+
lireStyles: async () => {
|
|
85
|
+
const r = await fetch(new URL("styles/sia-ui.css", racine));
|
|
86
|
+
if (!r.ok) {
|
|
87
|
+
throw new Error(`styles/sia-ui.css a répondu ${r.status} sur ${racine}`);
|
|
88
|
+
}
|
|
89
|
+
return Buffer.from(await r.arrayBuffer());
|
|
90
|
+
},
|
|
81
91
|
};
|
|
82
92
|
}
|
|
83
93
|
|
package/dist/styles.mjs
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { empreinte } from "./lock.mjs";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* La feuille commune, suivie comme un composant.
|
|
7
|
+
*
|
|
8
|
+
* Copiée une fois par `init`, puis plus rien ne la touchait : les composants
|
|
9
|
+
* se mettaient à jour sans elle. Or un composant peut dépendre d'une règle
|
|
10
|
+
* nouvelle de la feuille — le reset `box-sizing` en est un — et
|
|
11
|
+
* l'utilisateur recevait le composant sans ce qui le fait tenir.
|
|
12
|
+
*
|
|
13
|
+
* Son empreinte à la copie est notée dans le verrou (`styles`). Non
|
|
14
|
+
* retouchée, elle suit le registre ; retouchée, elle n'est remplacée que sur
|
|
15
|
+
* demande (`update --force`). Elle est lue à la même source que les
|
|
16
|
+
* composants : copie embarquée ou registre HTTP.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
async function lire(chemin) {
|
|
20
|
+
try {
|
|
21
|
+
return await readFile(chemin);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (error.code === "ENOENT") return null;
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* L'état de la feuille du projet.
|
|
30
|
+
*
|
|
31
|
+
* `absente`, `à jour`, `en retard` (non retouchée, le registre a plus
|
|
32
|
+
* récent), `modifiée` (retouchée depuis la copie), ou `non suivie` (copiée
|
|
33
|
+
* par une CLI qui ne notait pas son empreinte, et différente de l'actuelle).
|
|
34
|
+
*/
|
|
35
|
+
export async function etatStyles({ cwd, config, lock, lireStyles }) {
|
|
36
|
+
const cible = join(cwd, config.styles);
|
|
37
|
+
const contenu = await lireStyles();
|
|
38
|
+
const actuelle = { contenu, empreinte: empreinte(contenu) };
|
|
39
|
+
const presente = await lire(cible);
|
|
40
|
+
|
|
41
|
+
if (presente === null) return { etat: "absente", cible, actuelle };
|
|
42
|
+
|
|
43
|
+
const locale = empreinte(presente);
|
|
44
|
+
if (locale === actuelle.empreinte) return { etat: "à jour", cible, actuelle };
|
|
45
|
+
|
|
46
|
+
const notee = lock.styles?.hash;
|
|
47
|
+
if (!notee) return { etat: "non suivie", cible, actuelle };
|
|
48
|
+
return {
|
|
49
|
+
etat: locale === notee ? "en retard" : "modifiée",
|
|
50
|
+
cible,
|
|
51
|
+
actuelle,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const RAISON = {
|
|
56
|
+
modifiée: "modifiée localement",
|
|
57
|
+
"non suivie": "copiée avant le suivi des versions",
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Met la feuille à jour selon ce que la commande autorise, et le dit.
|
|
62
|
+
*
|
|
63
|
+
* - `creer` — `init` : seulement si elle est absente.
|
|
64
|
+
* - `sur` — `add` : absente ou en retard ; jamais une feuille retouchée.
|
|
65
|
+
* - `forcer` — `update --force` : même retouchée.
|
|
66
|
+
*
|
|
67
|
+
* Complète le verrou (`styles`) sans l'écrire : l'appelant l'écrit une fois,
|
|
68
|
+
* avec le reste. `dryRun` annonce sans rien toucher.
|
|
69
|
+
*/
|
|
70
|
+
export async function synchroniserStyles(
|
|
71
|
+
{ cwd, config, lock, lireStyles },
|
|
72
|
+
{ mode = "sur", dryRun = false } = {},
|
|
73
|
+
) {
|
|
74
|
+
const { etat, cible, actuelle } = await etatStyles({
|
|
75
|
+
cwd,
|
|
76
|
+
config,
|
|
77
|
+
lock,
|
|
78
|
+
lireStyles,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const noter = () => {
|
|
82
|
+
if (!dryRun) lock.styles = { file: config.styles, hash: actuelle.empreinte };
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
if (etat === "à jour") {
|
|
86
|
+
noter();
|
|
87
|
+
return { etat, action: "rien" };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const ecrire =
|
|
91
|
+
etat === "absente" ||
|
|
92
|
+
(mode !== "creer" && etat === "en retard") ||
|
|
93
|
+
mode === "forcer";
|
|
94
|
+
|
|
95
|
+
if (ecrire) {
|
|
96
|
+
if (!dryRun) {
|
|
97
|
+
await mkdir(dirname(cible), { recursive: true });
|
|
98
|
+
await writeFile(cible, actuelle.contenu);
|
|
99
|
+
}
|
|
100
|
+
noter();
|
|
101
|
+
console.log(`${etat === "absente" ? "add " : "update"} ${config.styles}`);
|
|
102
|
+
return { etat, action: "écrite" };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
console.log(
|
|
106
|
+
mode === "creer"
|
|
107
|
+
? `skip ${config.styles} (déjà présente — sia-ui update pour la mettre à jour)`
|
|
108
|
+
: `keep ${config.styles} (${RAISON[etat]} — sia-ui update --force pour la remplacer)`,
|
|
109
|
+
);
|
|
110
|
+
return { etat, action: "gardée" };
|
|
111
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sia-ui/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Install SIA UI components progressively into an application.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sia-ui",
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"react-dom": "^19.2.3",
|
|
40
40
|
"typescript": "^5.9.3",
|
|
41
41
|
"vitest": "^4.0.16",
|
|
42
|
-
"@sia-ui/headless": "0.
|
|
43
|
-
"@sia-ui/
|
|
44
|
-
"@sia-ui/
|
|
45
|
-
"@sia-ui/
|
|
42
|
+
"@sia-ui/headless": "0.6.0",
|
|
43
|
+
"@sia-ui/react": "0.6.0",
|
|
44
|
+
"@sia-ui/utils": "0.6.0",
|
|
45
|
+
"@sia-ui/tokens": "0.6.0"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "node scripts/build.mjs",
|