wensity 0.1.8 → 0.1.10
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/LICENSE +21 -0
- package/README.md +15 -7
- package/dist/index.js +1582 -202
- package/package.json +26 -10
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/commands.ts
|
|
4
|
-
import { mkdir as
|
|
5
|
-
import { dirname as
|
|
4
|
+
import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
|
|
5
|
+
import { dirname as dirname7, join as join7 } from "path";
|
|
6
6
|
|
|
7
7
|
// src/constants.ts
|
|
8
8
|
var CLI_NAME = "wensity";
|
|
9
|
-
var CLI_VERSION = "0.1.
|
|
9
|
+
var CLI_VERSION = "0.1.9";
|
|
10
10
|
var CONFIG_FILE_NAME = "wensity.json";
|
|
11
11
|
var DEFAULT_API_ORIGIN = "https://ui.wensity.com";
|
|
12
12
|
var DEFAULT_REGISTRY_PATH = "/api/registry";
|
|
@@ -18,7 +18,9 @@ var INIT_PRIMITIVE_CSS_SLUG = "button";
|
|
|
18
18
|
var HELP_TEXT = `Wensity CLI ${CLI_VERSION}
|
|
19
19
|
|
|
20
20
|
Usage:
|
|
21
|
-
wensity init [--preset <code>] [--preset-file <path>] [options]
|
|
21
|
+
wensity init [--preset <code>] [--preset-file <path>] [--template next|vite|astro|react-router] [options]
|
|
22
|
+
wensity apply --preset <code> [options]
|
|
23
|
+
wensity preset inspect <code> [--json]
|
|
22
24
|
wensity login [options]
|
|
23
25
|
wensity logout
|
|
24
26
|
wensity whoami [--json]
|
|
@@ -28,7 +30,9 @@ Usage:
|
|
|
28
30
|
wensity version
|
|
29
31
|
|
|
30
32
|
Commands:
|
|
31
|
-
init Create wensity.json and local helper files (optional --preset applies style + CSS)
|
|
33
|
+
init Create wensity.json and local helper files (optional --preset applies style + CSS; optional --template scaffolds an app)
|
|
34
|
+
apply Apply a preset to an existing Wensity project
|
|
35
|
+
preset Inspect or work with shareable Wensity style presets
|
|
32
36
|
login Save a Wensity API token for premium component access
|
|
33
37
|
logout Remove saved CLI credentials
|
|
34
38
|
whoami Verify the saved token and print the authenticated account
|
|
@@ -44,6 +48,7 @@ Options:
|
|
|
44
48
|
--token <token> Provide a token non-interactively for login
|
|
45
49
|
--preset <code> Apply a shareable Wensity style preset (wsty1.\u2026); merges style when config exists
|
|
46
50
|
--preset-file <path> Read a preset code or JSON payload from a file
|
|
51
|
+
--template <name> Scaffold a new app before init: next, vite, astro, react-router
|
|
47
52
|
--force Overwrite generated files when adding or initializing
|
|
48
53
|
--no-install Write files without running the package manager
|
|
49
54
|
--dry-run Print planned writes and installs without changing files
|
|
@@ -52,9 +57,12 @@ Options:
|
|
|
52
57
|
--version Print the CLI version
|
|
53
58
|
|
|
54
59
|
Preset notes:
|
|
55
|
-
Generate codes at ${DEFAULT_API_ORIGIN}/docs/
|
|
60
|
+
Generate codes at ${DEFAULT_API_ORIGIN}/create-preset (guide: ${DEFAULT_API_ORIGIN}/docs/create-preset)
|
|
61
|
+
preset inspect decodes the token, font packages, and resolved primitive tokens
|
|
62
|
+
apply --preset updates existing style + primitive CSS without scaffolding helper files
|
|
56
63
|
Plain init refuses an existing wensity.json unless --force
|
|
57
64
|
init --preset merges style + primitive CSS; does not rewrite installed source
|
|
65
|
+
init --template writes a minimal app scaffold in the current directory before Wensity files
|
|
58
66
|
add/update read style.iconLibrary for UI primitives only (Tabler|Lucide)
|
|
59
67
|
Invalid/expired/unsupported codes exit non-zero with an actionable message
|
|
60
68
|
`;
|
|
@@ -118,7 +126,7 @@ function hasFlag(args, name) {
|
|
|
118
126
|
return args.options.get(name) === true;
|
|
119
127
|
}
|
|
120
128
|
function expectsValue(name) {
|
|
121
|
-
return ["api-url", "registry", "token", "type", "preset", "preset-file"].includes(name);
|
|
129
|
+
return ["api-url", "registry", "token", "type", "preset", "preset-file", "template"].includes(name);
|
|
122
130
|
}
|
|
123
131
|
function normalizeOptionName(name) {
|
|
124
132
|
if (name === "dry") return "dry-run";
|
|
@@ -138,9 +146,15 @@ var BASE_COLOR_IDS = [
|
|
|
138
146
|
"inherit",
|
|
139
147
|
"neutral",
|
|
140
148
|
"zinc",
|
|
149
|
+
"gray",
|
|
141
150
|
"slate",
|
|
151
|
+
"cool-gray",
|
|
142
152
|
"stone",
|
|
143
|
-
"taupe"
|
|
153
|
+
"taupe",
|
|
154
|
+
"mauve",
|
|
155
|
+
"olive",
|
|
156
|
+
"mist",
|
|
157
|
+
"black"
|
|
144
158
|
];
|
|
145
159
|
var THEME_COLOR_IDS = [
|
|
146
160
|
"ink",
|
|
@@ -148,16 +162,68 @@ var THEME_COLOR_IDS = [
|
|
|
148
162
|
"blue",
|
|
149
163
|
"violet",
|
|
150
164
|
"green",
|
|
151
|
-
"orange"
|
|
165
|
+
"orange",
|
|
166
|
+
"amber",
|
|
167
|
+
"cyan",
|
|
168
|
+
"emerald",
|
|
169
|
+
"indigo",
|
|
170
|
+
"pink",
|
|
171
|
+
"purple",
|
|
172
|
+
"rose",
|
|
173
|
+
"sky",
|
|
174
|
+
"teal",
|
|
175
|
+
"yellow",
|
|
176
|
+
"fuchsia",
|
|
177
|
+
"lime"
|
|
152
178
|
];
|
|
153
179
|
var CHART_PALETTE_IDS = [
|
|
154
180
|
"theme",
|
|
155
181
|
"warm",
|
|
156
182
|
"cool",
|
|
157
|
-
"mixed"
|
|
183
|
+
"mixed",
|
|
184
|
+
"neutral",
|
|
185
|
+
"zinc",
|
|
186
|
+
"stone",
|
|
187
|
+
"gray",
|
|
188
|
+
"amber",
|
|
189
|
+
"cyan",
|
|
190
|
+
"emerald",
|
|
191
|
+
"indigo",
|
|
192
|
+
"lime",
|
|
193
|
+
"pink",
|
|
194
|
+
"purple",
|
|
195
|
+
"rose",
|
|
196
|
+
"sky",
|
|
197
|
+
"teal",
|
|
198
|
+
"yellow",
|
|
199
|
+
"taupe"
|
|
200
|
+
];
|
|
201
|
+
var HEADING_FONT_IDS = [
|
|
202
|
+
"system",
|
|
203
|
+
"playfair",
|
|
204
|
+
"instrument-serif",
|
|
205
|
+
"fraunces",
|
|
206
|
+
"space-grotesk",
|
|
207
|
+
"noto-serif",
|
|
208
|
+
"eb-garamond",
|
|
209
|
+
"lora",
|
|
210
|
+
"montserrat",
|
|
211
|
+
"manrope",
|
|
212
|
+
"inter"
|
|
213
|
+
];
|
|
214
|
+
var BODY_FONT_IDS = [
|
|
215
|
+
"system",
|
|
216
|
+
"inter",
|
|
217
|
+
"geist",
|
|
218
|
+
"dm-sans",
|
|
219
|
+
"plus-jakarta-sans",
|
|
220
|
+
"figtree",
|
|
221
|
+
"noto-sans",
|
|
222
|
+
"public-sans",
|
|
223
|
+
"outfit",
|
|
224
|
+
"manrope",
|
|
225
|
+
"ibm-plex-sans"
|
|
158
226
|
];
|
|
159
|
-
var HEADING_FONT_IDS = ["system", "playfair"];
|
|
160
|
-
var BODY_FONT_IDS = ["system", "inter"];
|
|
161
227
|
var RADIUS_PRESET_CSS = {
|
|
162
228
|
none: "0px",
|
|
163
229
|
small: "0.5rem",
|
|
@@ -274,8 +340,8 @@ var DEFAULT_STYLE_CONFIG_CANONICAL = {
|
|
|
274
340
|
baseColor: "inherit",
|
|
275
341
|
themeColor: "ink",
|
|
276
342
|
chartPalette: "theme",
|
|
277
|
-
headingFont: "
|
|
278
|
-
bodyFont: "
|
|
343
|
+
headingFont: "inter",
|
|
344
|
+
bodyFont: "inter",
|
|
279
345
|
iconLibrary: "tabler",
|
|
280
346
|
radius: "medium"
|
|
281
347
|
};
|
|
@@ -604,7 +670,7 @@ function validateStyleConfigCanonicalPartial(value) {
|
|
|
604
670
|
if ("baseColor" in value) {
|
|
605
671
|
if (typeof value.baseColor !== "string" || !isBaseColorId(value.baseColor)) {
|
|
606
672
|
throw new PresetValidationError(
|
|
607
|
-
"Invalid style.baseColor. Expected
|
|
673
|
+
"Invalid style.baseColor. Expected a supported base color id.",
|
|
608
674
|
"style.baseColor"
|
|
609
675
|
);
|
|
610
676
|
}
|
|
@@ -613,7 +679,7 @@ function validateStyleConfigCanonicalPartial(value) {
|
|
|
613
679
|
if ("themeColor" in value) {
|
|
614
680
|
if (typeof value.themeColor !== "string" || !isThemeColorId(value.themeColor)) {
|
|
615
681
|
throw new PresetValidationError(
|
|
616
|
-
"Invalid style.themeColor. Expected
|
|
682
|
+
"Invalid style.themeColor. Expected a supported theme color id.",
|
|
617
683
|
"style.themeColor"
|
|
618
684
|
);
|
|
619
685
|
}
|
|
@@ -622,7 +688,7 @@ function validateStyleConfigCanonicalPartial(value) {
|
|
|
622
688
|
if ("chartPalette" in value) {
|
|
623
689
|
if (typeof value.chartPalette !== "string" || !isChartPaletteId(value.chartPalette)) {
|
|
624
690
|
throw new PresetValidationError(
|
|
625
|
-
"Invalid style.chartPalette. Expected
|
|
691
|
+
"Invalid style.chartPalette. Expected a supported chart palette id.",
|
|
626
692
|
"style.chartPalette"
|
|
627
693
|
);
|
|
628
694
|
}
|
|
@@ -631,7 +697,7 @@ function validateStyleConfigCanonicalPartial(value) {
|
|
|
631
697
|
if ("headingFont" in value) {
|
|
632
698
|
if (typeof value.headingFont !== "string" || !isHeadingFontId(value.headingFont)) {
|
|
633
699
|
throw new PresetValidationError(
|
|
634
|
-
"Invalid style.headingFont. Expected
|
|
700
|
+
"Invalid style.headingFont. Expected a supported heading font id.",
|
|
635
701
|
"style.headingFont"
|
|
636
702
|
);
|
|
637
703
|
}
|
|
@@ -640,7 +706,7 @@ function validateStyleConfigCanonicalPartial(value) {
|
|
|
640
706
|
if ("bodyFont" in value) {
|
|
641
707
|
if (typeof value.bodyFont !== "string" || !isBodyFontId(value.bodyFont)) {
|
|
642
708
|
throw new PresetValidationError(
|
|
643
|
-
"Invalid style.bodyFont. Expected
|
|
709
|
+
"Invalid style.bodyFont. Expected a supported body font id.",
|
|
644
710
|
"style.bodyFont"
|
|
645
711
|
);
|
|
646
712
|
}
|
|
@@ -769,9 +835,29 @@ function utf8ByteLength(text) {
|
|
|
769
835
|
return new TextEncoder().encode(text).byteLength;
|
|
770
836
|
}
|
|
771
837
|
var BASE64URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
772
|
-
var
|
|
838
|
+
var COMPACT_CANONICAL_LEGACY_PREFIX = "c";
|
|
839
|
+
var COMPACT_CANONICAL_PREFIX = "d";
|
|
840
|
+
var COMPACT_CANONICAL_EXPANDED_PREFIX = "e";
|
|
841
|
+
var COMPACT_CANONICAL_CHART_PREFIX = "f";
|
|
842
|
+
var COMPACT_CANONICAL_THEME_PREFIX = "g";
|
|
843
|
+
var COMPACT_CANONICAL_BASE_PREFIX = "h";
|
|
773
844
|
var COMPACT_CANONICAL_BODY_LENGTH = 3;
|
|
774
845
|
var COMPACT_CANONICAL_ENCODED_LENGTH = COMPACT_CANONICAL_PREFIX.length + COMPACT_CANONICAL_BODY_LENGTH;
|
|
846
|
+
var COMPACT_CANONICAL_EXPANDED_BODY_LENGTH = 4;
|
|
847
|
+
var COMPACT_CANONICAL_EXPANDED_ENCODED_LENGTH = COMPACT_CANONICAL_EXPANDED_PREFIX.length + COMPACT_CANONICAL_EXPANDED_BODY_LENGTH;
|
|
848
|
+
var COMPACT_CANONICAL_CHART_ENCODED_LENGTH = COMPACT_CANONICAL_CHART_PREFIX.length + COMPACT_CANONICAL_EXPANDED_BODY_LENGTH;
|
|
849
|
+
var COMPACT_CANONICAL_THEME_ENCODED_LENGTH = COMPACT_CANONICAL_THEME_PREFIX.length + COMPACT_CANONICAL_EXPANDED_BODY_LENGTH;
|
|
850
|
+
var COMPACT_CANONICAL_BASE_BODY_LENGTH = 5;
|
|
851
|
+
var COMPACT_CANONICAL_BASE_ENCODED_LENGTH = COMPACT_CANONICAL_BASE_PREFIX.length + COMPACT_CANONICAL_BASE_BODY_LENGTH;
|
|
852
|
+
var COMPACT_CANONICAL_LEGACY_BASE_MAX_INDEX = 7;
|
|
853
|
+
var COMPACT_CANONICAL_LEGACY_THEME_MAX_INDEX = 5;
|
|
854
|
+
var COMPACT_CANONICAL_LEGACY_CHART_MAX_INDEX = 3;
|
|
855
|
+
var COMPACT_CANONICAL_LEGACY_FONT_MAX_INDEX = 1;
|
|
856
|
+
var COMPACT_CANONICAL_FONT_MAX_INDEX = 7;
|
|
857
|
+
var COMPACT_CANONICAL_EXPANDED_FONT_MAX_INDEX = 15;
|
|
858
|
+
var COMPACT_CANONICAL_EXPANDED_CHART_MAX_INDEX = 31;
|
|
859
|
+
var COMPACT_CANONICAL_EXPANDED_THEME_MAX_INDEX = 31;
|
|
860
|
+
var COMPACT_CANONICAL_EXPANDED_BASE_MAX_INDEX = 31;
|
|
775
861
|
function toBase64Url(bytes) {
|
|
776
862
|
let out = "";
|
|
777
863
|
for (let i = 0; i < bytes.length; i += 3) {
|
|
@@ -823,40 +909,216 @@ function readCompactChar(char) {
|
|
|
823
909
|
return BASE64URL_ALPHABET.indexOf(char);
|
|
824
910
|
}
|
|
825
911
|
function encodeCompactCanonicalPayload(payload) {
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
912
|
+
const baseColorIndex = indexOfPresetValue(BASE_COLOR_IDS, payload.baseColor, "preset.baseColor");
|
|
913
|
+
const themeColorIndex = indexOfPresetValue(
|
|
914
|
+
THEME_COLOR_IDS,
|
|
915
|
+
payload.themeColor,
|
|
916
|
+
"preset.themeColor"
|
|
917
|
+
);
|
|
918
|
+
const chartPaletteIndex = indexOfPresetValue(
|
|
919
|
+
CHART_PALETTE_IDS,
|
|
920
|
+
payload.chartPalette,
|
|
921
|
+
"preset.chartPalette"
|
|
922
|
+
);
|
|
923
|
+
const headingFontIndex = indexOfPresetValue(
|
|
924
|
+
HEADING_FONT_IDS,
|
|
925
|
+
payload.headingFont,
|
|
926
|
+
"preset.headingFont"
|
|
927
|
+
);
|
|
928
|
+
const bodyFontIndex = indexOfPresetValue(BODY_FONT_IDS, payload.bodyFont, "preset.bodyFont");
|
|
929
|
+
const iconLibraryIndex = indexOfPresetValue(
|
|
930
|
+
ICON_LIBRARIES,
|
|
931
|
+
payload.iconLibrary,
|
|
932
|
+
"preset.iconLibrary"
|
|
933
|
+
);
|
|
934
|
+
const radiusIndex = indexOfPresetValue(RADIUS_PRESETS, payload.radius, "preset.radius");
|
|
935
|
+
if (baseColorIndex > 7) {
|
|
936
|
+
if (baseColorIndex > COMPACT_CANONICAL_EXPANDED_BASE_MAX_INDEX) {
|
|
937
|
+
throw new PresetValidationError(
|
|
938
|
+
"Too many curated base colors for compact preset encoding.",
|
|
939
|
+
"preset.baseColor"
|
|
940
|
+
);
|
|
941
|
+
}
|
|
942
|
+
if (themeColorIndex > COMPACT_CANONICAL_EXPANDED_THEME_MAX_INDEX) {
|
|
943
|
+
throw new PresetValidationError(
|
|
944
|
+
"Too many curated theme colors for compact preset encoding.",
|
|
945
|
+
"preset.themeColor"
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
if (chartPaletteIndex > COMPACT_CANONICAL_EXPANDED_CHART_MAX_INDEX) {
|
|
949
|
+
throw new PresetValidationError(
|
|
950
|
+
"Too many curated chart palettes for compact preset encoding.",
|
|
951
|
+
"preset.chartPalette"
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
if (headingFontIndex > COMPACT_CANONICAL_EXPANDED_FONT_MAX_INDEX || bodyFontIndex > COMPACT_CANONICAL_EXPANDED_FONT_MAX_INDEX) {
|
|
955
|
+
throw new PresetValidationError(
|
|
956
|
+
"Too many curated fonts for compact preset encoding.",
|
|
957
|
+
"preset.headingFont"
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
let baseValue = baseColorIndex;
|
|
961
|
+
baseValue = baseValue << 5 | themeColorIndex;
|
|
962
|
+
baseValue = baseValue << 5 | chartPaletteIndex;
|
|
963
|
+
baseValue = baseValue << 4 | headingFontIndex;
|
|
964
|
+
baseValue = baseValue << 4 | bodyFontIndex;
|
|
965
|
+
baseValue = baseValue << 1 | iconLibraryIndex;
|
|
966
|
+
baseValue = baseValue << 2 | radiusIndex;
|
|
967
|
+
return encodeCompactCanonicalValue(
|
|
968
|
+
COMPACT_CANONICAL_BASE_PREFIX,
|
|
969
|
+
baseValue,
|
|
970
|
+
COMPACT_CANONICAL_BASE_BODY_LENGTH
|
|
971
|
+
);
|
|
972
|
+
}
|
|
973
|
+
if (themeColorIndex > 7) {
|
|
974
|
+
if (themeColorIndex > COMPACT_CANONICAL_EXPANDED_THEME_MAX_INDEX) {
|
|
975
|
+
throw new PresetValidationError(
|
|
976
|
+
"Too many curated theme colors for compact preset encoding.",
|
|
977
|
+
"preset.themeColor"
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
if (chartPaletteIndex > COMPACT_CANONICAL_EXPANDED_CHART_MAX_INDEX) {
|
|
981
|
+
throw new PresetValidationError(
|
|
982
|
+
"Too many curated chart palettes for compact preset encoding.",
|
|
983
|
+
"preset.chartPalette"
|
|
984
|
+
);
|
|
985
|
+
}
|
|
986
|
+
if (headingFontIndex > COMPACT_CANONICAL_EXPANDED_FONT_MAX_INDEX || bodyFontIndex > COMPACT_CANONICAL_EXPANDED_FONT_MAX_INDEX) {
|
|
987
|
+
throw new PresetValidationError(
|
|
988
|
+
"Too many curated fonts for compact preset encoding.",
|
|
989
|
+
"preset.headingFont"
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
let themeValue = baseColorIndex;
|
|
993
|
+
themeValue = themeValue << 5 | themeColorIndex;
|
|
994
|
+
themeValue = themeValue << 5 | chartPaletteIndex;
|
|
995
|
+
themeValue = themeValue << 4 | headingFontIndex;
|
|
996
|
+
themeValue = themeValue << 4 | bodyFontIndex;
|
|
997
|
+
themeValue = themeValue << 1 | iconLibraryIndex;
|
|
998
|
+
themeValue = themeValue << 2 | radiusIndex;
|
|
999
|
+
return encodeCompactCanonicalValue(
|
|
1000
|
+
COMPACT_CANONICAL_THEME_PREFIX,
|
|
1001
|
+
themeValue,
|
|
1002
|
+
COMPACT_CANONICAL_EXPANDED_BODY_LENGTH
|
|
1003
|
+
);
|
|
1004
|
+
}
|
|
1005
|
+
if (baseColorIndex <= COMPACT_CANONICAL_LEGACY_BASE_MAX_INDEX && themeColorIndex <= COMPACT_CANONICAL_LEGACY_THEME_MAX_INDEX && chartPaletteIndex <= COMPACT_CANONICAL_LEGACY_CHART_MAX_INDEX && headingFontIndex <= COMPACT_CANONICAL_LEGACY_FONT_MAX_INDEX && bodyFontIndex <= COMPACT_CANONICAL_LEGACY_FONT_MAX_INDEX) {
|
|
1006
|
+
let legacyValue = baseColorIndex;
|
|
1007
|
+
legacyValue = legacyValue << 3 | themeColorIndex;
|
|
1008
|
+
legacyValue = legacyValue << 2 | chartPaletteIndex;
|
|
1009
|
+
legacyValue = legacyValue << 1 | headingFontIndex;
|
|
1010
|
+
legacyValue = legacyValue << 1 | bodyFontIndex;
|
|
1011
|
+
legacyValue = legacyValue << 1 | iconLibraryIndex;
|
|
1012
|
+
legacyValue = legacyValue << 2 | radiusIndex;
|
|
1013
|
+
return encodeCompactCanonicalValue(COMPACT_CANONICAL_LEGACY_PREFIX, legacyValue);
|
|
1014
|
+
}
|
|
1015
|
+
if (chartPaletteIndex > 3) {
|
|
1016
|
+
if (chartPaletteIndex > COMPACT_CANONICAL_EXPANDED_CHART_MAX_INDEX) {
|
|
1017
|
+
throw new PresetValidationError(
|
|
1018
|
+
"Too many curated chart palettes for compact preset encoding.",
|
|
1019
|
+
"preset.chartPalette"
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
if (headingFontIndex > COMPACT_CANONICAL_EXPANDED_FONT_MAX_INDEX || bodyFontIndex > COMPACT_CANONICAL_EXPANDED_FONT_MAX_INDEX) {
|
|
1023
|
+
throw new PresetValidationError(
|
|
1024
|
+
"Too many curated fonts for compact preset encoding.",
|
|
1025
|
+
"preset.headingFont"
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
let chartValue = baseColorIndex;
|
|
1029
|
+
chartValue = chartValue << 3 | themeColorIndex;
|
|
1030
|
+
chartValue = chartValue << 5 | chartPaletteIndex;
|
|
1031
|
+
chartValue = chartValue << 4 | headingFontIndex;
|
|
1032
|
+
chartValue = chartValue << 4 | bodyFontIndex;
|
|
1033
|
+
chartValue = chartValue << 1 | iconLibraryIndex;
|
|
1034
|
+
chartValue = chartValue << 2 | radiusIndex;
|
|
1035
|
+
return encodeCompactCanonicalValue(
|
|
1036
|
+
COMPACT_CANONICAL_CHART_PREFIX,
|
|
1037
|
+
chartValue,
|
|
1038
|
+
COMPACT_CANONICAL_EXPANDED_BODY_LENGTH
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
if (headingFontIndex > COMPACT_CANONICAL_FONT_MAX_INDEX || bodyFontIndex > COMPACT_CANONICAL_FONT_MAX_INDEX) {
|
|
1042
|
+
if (headingFontIndex > COMPACT_CANONICAL_EXPANDED_FONT_MAX_INDEX || bodyFontIndex > COMPACT_CANONICAL_EXPANDED_FONT_MAX_INDEX) {
|
|
1043
|
+
throw new PresetValidationError(
|
|
1044
|
+
"Too many curated fonts for compact preset encoding.",
|
|
1045
|
+
"preset.headingFont"
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
let expandedValue = baseColorIndex;
|
|
1049
|
+
expandedValue = expandedValue << 3 | themeColorIndex;
|
|
1050
|
+
expandedValue = expandedValue << 2 | chartPaletteIndex;
|
|
1051
|
+
expandedValue = expandedValue << 4 | headingFontIndex;
|
|
1052
|
+
expandedValue = expandedValue << 4 | bodyFontIndex;
|
|
1053
|
+
expandedValue = expandedValue << 1 | iconLibraryIndex;
|
|
1054
|
+
expandedValue = expandedValue << 2 | radiusIndex;
|
|
1055
|
+
return encodeCompactCanonicalValue(
|
|
1056
|
+
COMPACT_CANONICAL_EXPANDED_PREFIX,
|
|
1057
|
+
expandedValue,
|
|
1058
|
+
COMPACT_CANONICAL_EXPANDED_BODY_LENGTH
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
let value = baseColorIndex;
|
|
1062
|
+
value = value << 3 | themeColorIndex;
|
|
1063
|
+
value = value << 2 | chartPaletteIndex;
|
|
1064
|
+
value = value << 3 | headingFontIndex;
|
|
1065
|
+
value = value << 3 | bodyFontIndex;
|
|
1066
|
+
value = value << 1 | iconLibraryIndex;
|
|
1067
|
+
value = value << 2 | radiusIndex;
|
|
1068
|
+
return encodeCompactCanonicalValue(
|
|
1069
|
+
COMPACT_CANONICAL_PREFIX,
|
|
1070
|
+
value,
|
|
1071
|
+
COMPACT_CANONICAL_BODY_LENGTH
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
function encodeCompactCanonicalValue(prefix, value, bodyLength = 3) {
|
|
1075
|
+
let out = prefix;
|
|
1076
|
+
for (let shift = (bodyLength - 1) * 6; shift >= 0; shift -= 6) {
|
|
1077
|
+
out += BASE64URL_ALPHABET[value >> shift & 63];
|
|
1078
|
+
}
|
|
1079
|
+
return out;
|
|
834
1080
|
}
|
|
835
1081
|
function decodeCompactCanonicalPayload(encoded) {
|
|
836
|
-
|
|
1082
|
+
const isLegacyCompact = encoded.startsWith(COMPACT_CANONICAL_LEGACY_PREFIX);
|
|
1083
|
+
const isCurrentCompact = encoded.startsWith(COMPACT_CANONICAL_PREFIX);
|
|
1084
|
+
const isExpandedCompact = encoded.startsWith(COMPACT_CANONICAL_EXPANDED_PREFIX);
|
|
1085
|
+
const isChartCompact = encoded.startsWith(COMPACT_CANONICAL_CHART_PREFIX);
|
|
1086
|
+
const isThemeCompact = encoded.startsWith(COMPACT_CANONICAL_THEME_PREFIX);
|
|
1087
|
+
const isBaseCompact = encoded.startsWith(COMPACT_CANONICAL_BASE_PREFIX);
|
|
1088
|
+
const expectedLength = isExpandedCompact ? COMPACT_CANONICAL_EXPANDED_ENCODED_LENGTH : isChartCompact ? COMPACT_CANONICAL_CHART_ENCODED_LENGTH : isThemeCompact ? COMPACT_CANONICAL_THEME_ENCODED_LENGTH : isBaseCompact ? COMPACT_CANONICAL_BASE_ENCODED_LENGTH : COMPACT_CANONICAL_ENCODED_LENGTH;
|
|
1089
|
+
if (encoded.length !== expectedLength || !isCurrentCompact && !isLegacyCompact && !isExpandedCompact && !isChartCompact && !isThemeCompact && !isBaseCompact) {
|
|
837
1090
|
throw new PresetValidationError("Compact preset code has an invalid length.", "preset");
|
|
838
1091
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1092
|
+
let value = 0;
|
|
1093
|
+
for (let i = 1; i < encoded.length; i += 1) {
|
|
1094
|
+
const char = readCompactChar(encoded[i]);
|
|
1095
|
+
if (char < 0) {
|
|
1096
|
+
throw new PresetValidationError("Compact preset code is not valid base64url.", "preset");
|
|
1097
|
+
}
|
|
1098
|
+
value = value << 6 | char;
|
|
844
1099
|
}
|
|
845
|
-
let value = a << 12 | b << 6 | c;
|
|
846
1100
|
const radius = RADIUS_PRESETS[value & 3];
|
|
847
1101
|
value >>= 2;
|
|
848
1102
|
const iconLibrary = ICON_LIBRARIES[value & 1];
|
|
849
1103
|
value >>= 1;
|
|
850
|
-
const
|
|
851
|
-
|
|
852
|
-
const
|
|
853
|
-
value >>=
|
|
854
|
-
const
|
|
855
|
-
value >>=
|
|
856
|
-
const
|
|
857
|
-
|
|
858
|
-
const
|
|
859
|
-
value >>=
|
|
1104
|
+
const fontMask = isLegacyCompact ? 1 : isExpandedCompact || isChartCompact || isThemeCompact || isBaseCompact ? 15 : 7;
|
|
1105
|
+
const fontShift = isLegacyCompact ? 1 : isExpandedCompact || isChartCompact || isThemeCompact || isBaseCompact ? 4 : 3;
|
|
1106
|
+
const bodyFont = BODY_FONT_IDS[value & fontMask];
|
|
1107
|
+
value >>= fontShift;
|
|
1108
|
+
const headingFont = HEADING_FONT_IDS[value & fontMask];
|
|
1109
|
+
value >>= fontShift;
|
|
1110
|
+
const chartMask = isChartCompact || isThemeCompact || isBaseCompact ? 31 : 3;
|
|
1111
|
+
const chartShift = isChartCompact || isThemeCompact || isBaseCompact ? 5 : 2;
|
|
1112
|
+
const chartPalette = CHART_PALETTE_IDS[value & chartMask];
|
|
1113
|
+
value >>= chartShift;
|
|
1114
|
+
const themeMask = isThemeCompact || isBaseCompact ? 31 : 7;
|
|
1115
|
+
const themeShift = isThemeCompact || isBaseCompact ? 5 : 3;
|
|
1116
|
+
const themeColor = THEME_COLOR_IDS[value & themeMask];
|
|
1117
|
+
value >>= themeShift;
|
|
1118
|
+
const baseMask = isBaseCompact ? 31 : 7;
|
|
1119
|
+
const baseShift = isBaseCompact ? 5 : 3;
|
|
1120
|
+
const baseColor = BASE_COLOR_IDS[value & baseMask];
|
|
1121
|
+
value >>= baseShift;
|
|
860
1122
|
if (value !== 0 || !baseColor || !themeColor || !chartPalette || !headingFont || !bodyFont || !iconLibrary || !radius) {
|
|
861
1123
|
throw new PresetValidationError("Compact preset code contains an out-of-range value.", "preset");
|
|
862
1124
|
}
|
|
@@ -1051,31 +1313,31 @@ function validateCodecPayloadCanonical(value) {
|
|
|
1051
1313
|
}
|
|
1052
1314
|
if (typeof value.baseColor !== "string" || !isBaseColorId(value.baseColor)) {
|
|
1053
1315
|
throw new PresetValidationError(
|
|
1054
|
-
"Invalid preset.baseColor. Expected
|
|
1316
|
+
"Invalid preset.baseColor. Expected a supported base color id.",
|
|
1055
1317
|
"preset.baseColor"
|
|
1056
1318
|
);
|
|
1057
1319
|
}
|
|
1058
1320
|
if (typeof value.themeColor !== "string" || !isThemeColorId(value.themeColor)) {
|
|
1059
1321
|
throw new PresetValidationError(
|
|
1060
|
-
"Invalid preset.themeColor. Expected
|
|
1322
|
+
"Invalid preset.themeColor. Expected a supported theme color id.",
|
|
1061
1323
|
"preset.themeColor"
|
|
1062
1324
|
);
|
|
1063
1325
|
}
|
|
1064
1326
|
if (typeof value.chartPalette !== "string" || !isChartPaletteId(value.chartPalette)) {
|
|
1065
1327
|
throw new PresetValidationError(
|
|
1066
|
-
"Invalid preset.chartPalette. Expected
|
|
1328
|
+
"Invalid preset.chartPalette. Expected a supported chart palette id.",
|
|
1067
1329
|
"preset.chartPalette"
|
|
1068
1330
|
);
|
|
1069
1331
|
}
|
|
1070
1332
|
if (typeof value.headingFont !== "string" || !isHeadingFontId(value.headingFont)) {
|
|
1071
1333
|
throw new PresetValidationError(
|
|
1072
|
-
"Invalid preset.headingFont. Expected
|
|
1334
|
+
"Invalid preset.headingFont. Expected a supported heading font id.",
|
|
1073
1335
|
"preset.headingFont"
|
|
1074
1336
|
);
|
|
1075
1337
|
}
|
|
1076
1338
|
if (typeof value.bodyFont !== "string" || !isBodyFontId(value.bodyFont)) {
|
|
1077
1339
|
throw new PresetValidationError(
|
|
1078
|
-
"Invalid preset.bodyFont. Expected
|
|
1340
|
+
"Invalid preset.bodyFont. Expected a supported body font id.",
|
|
1079
1341
|
"preset.bodyFont"
|
|
1080
1342
|
);
|
|
1081
1343
|
}
|
|
@@ -1144,7 +1406,7 @@ function decodePresetEnvelope(code) {
|
|
|
1144
1406
|
if (!encoded) {
|
|
1145
1407
|
throw new PresetValidationError("Preset code payload is empty.", "preset");
|
|
1146
1408
|
}
|
|
1147
|
-
if (encoded.length === COMPACT_CANONICAL_ENCODED_LENGTH && encoded.startsWith(COMPACT_CANONICAL_PREFIX)) {
|
|
1409
|
+
if ((encoded.length === COMPACT_CANONICAL_ENCODED_LENGTH || encoded.length === COMPACT_CANONICAL_EXPANDED_ENCODED_LENGTH || encoded.length === COMPACT_CANONICAL_CHART_ENCODED_LENGTH || encoded.length === COMPACT_CANONICAL_THEME_ENCODED_LENGTH || encoded.length === COMPACT_CANONICAL_BASE_ENCODED_LENGTH) && (encoded.startsWith(COMPACT_CANONICAL_PREFIX) || encoded.startsWith(COMPACT_CANONICAL_LEGACY_PREFIX) || encoded.startsWith(COMPACT_CANONICAL_EXPANDED_PREFIX) || encoded.startsWith(COMPACT_CANONICAL_CHART_PREFIX) || encoded.startsWith(COMPACT_CANONICAL_THEME_PREFIX) || encoded.startsWith(COMPACT_CANONICAL_BASE_PREFIX))) {
|
|
1148
1410
|
return decodeCompactCanonicalPayload(encoded);
|
|
1149
1411
|
}
|
|
1150
1412
|
if (encoded.includes("=") || /[^A-Za-z0-9_-]/.test(encoded)) {
|
|
@@ -1275,82 +1537,225 @@ var LUCIDE_TO_TABLER = Object.fromEntries(
|
|
|
1275
1537
|
var BASE_COLOR_PALETTE = {
|
|
1276
1538
|
zinc: {
|
|
1277
1539
|
light: {
|
|
1278
|
-
surfaceElevated: "
|
|
1279
|
-
surfaceOverlay: "
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1540
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1541
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1542
|
+
surfaceHover: "oklch(0.967 0.001 286.375)",
|
|
1543
|
+
surfaceActive: "color-mix(in oklab, oklch(0.967 0.001 286.375) 92%, oklch(0.141 0.005 285.823) 8%)",
|
|
1544
|
+
borderSubtle: "oklch(0.92 0.004 286.32)",
|
|
1545
|
+
textSecondary: "oklch(0.552 0.016 285.938)",
|
|
1546
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.552 0.016 285.938) 78%, transparent)"
|
|
1283
1547
|
},
|
|
1284
1548
|
dark: {
|
|
1285
|
-
surfaceElevated: "
|
|
1286
|
-
surfaceOverlay: "
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1549
|
+
surfaceElevated: "oklch(0.21 0.006 285.885)",
|
|
1550
|
+
surfaceOverlay: "oklch(0.21 0.006 285.885)",
|
|
1551
|
+
surfaceHover: "oklch(0.274 0.006 286.033)",
|
|
1552
|
+
surfaceActive: "color-mix(in oklab, oklch(0.274 0.006 286.033) 88%, oklch(0.985 0 0) 12%)",
|
|
1553
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1554
|
+
textSecondary: "oklch(0.705 0.015 286.067)",
|
|
1555
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.705 0.015 286.067) 78%, transparent)"
|
|
1290
1556
|
}
|
|
1291
1557
|
},
|
|
1292
1558
|
neutral: {
|
|
1293
1559
|
light: {
|
|
1294
|
-
surfaceElevated: "
|
|
1295
|
-
surfaceOverlay: "
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1560
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1561
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1562
|
+
surfaceHover: "oklch(0.97 0 0)",
|
|
1563
|
+
surfaceActive: "color-mix(in oklab, oklch(0.97 0 0) 92%, oklch(0.145 0 0) 8%)",
|
|
1564
|
+
borderSubtle: "oklch(0.922 0 0)",
|
|
1565
|
+
textSecondary: "oklch(0.556 0 0)",
|
|
1566
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.556 0 0) 78%, transparent)"
|
|
1567
|
+
},
|
|
1568
|
+
dark: {
|
|
1569
|
+
surfaceElevated: "oklch(0.205 0 0)",
|
|
1570
|
+
surfaceOverlay: "oklch(0.205 0 0)",
|
|
1571
|
+
surfaceHover: "oklch(0.269 0 0)",
|
|
1572
|
+
surfaceActive: "color-mix(in oklab, oklch(0.269 0 0) 88%, oklch(0.985 0 0) 12%)",
|
|
1573
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1574
|
+
textSecondary: "oklch(0.708 0 0)",
|
|
1575
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.708 0 0) 78%, transparent)"
|
|
1576
|
+
}
|
|
1577
|
+
},
|
|
1578
|
+
gray: {
|
|
1579
|
+
light: {
|
|
1580
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1581
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1582
|
+
surfaceHover: "oklch(0.967 0.003 264.542)",
|
|
1583
|
+
surfaceActive: "color-mix(in oklab, oklch(0.967 0.003 264.542) 92%, oklch(0.13 0.028 261.692) 8%)",
|
|
1584
|
+
borderSubtle: "oklch(0.928 0.006 264.531)",
|
|
1585
|
+
textSecondary: "oklch(0.551 0.027 264.364)",
|
|
1586
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.551 0.027 264.364) 78%, transparent)"
|
|
1299
1587
|
},
|
|
1300
1588
|
dark: {
|
|
1301
|
-
surfaceElevated: "
|
|
1302
|
-
surfaceOverlay: "
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1589
|
+
surfaceElevated: "oklch(0.21 0.034 264.665)",
|
|
1590
|
+
surfaceOverlay: "oklch(0.21 0.034 264.665)",
|
|
1591
|
+
surfaceHover: "oklch(0.278 0.033 256.848)",
|
|
1592
|
+
surfaceActive: "color-mix(in oklab, oklch(0.278 0.033 256.848) 88%, oklch(0.985 0.002 247.839) 12%)",
|
|
1593
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1594
|
+
textSecondary: "oklch(0.707 0.022 261.325)",
|
|
1595
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.707 0.022 261.325) 78%, transparent)"
|
|
1306
1596
|
}
|
|
1307
1597
|
},
|
|
1308
1598
|
slate: {
|
|
1309
1599
|
light: {
|
|
1310
|
-
surfaceElevated: "
|
|
1311
|
-
surfaceOverlay: "
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1600
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1601
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1602
|
+
surfaceHover: "oklch(0.968 0.007 247.896)",
|
|
1603
|
+
surfaceActive: "color-mix(in oklab, oklch(0.968 0.007 247.896) 92%, oklch(0.129 0.042 264.695) 8%)",
|
|
1604
|
+
borderSubtle: "oklch(0.929 0.013 255.508)",
|
|
1605
|
+
textSecondary: "oklch(0.554 0.046 257.417)",
|
|
1606
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.554 0.046 257.417) 78%, transparent)"
|
|
1607
|
+
},
|
|
1608
|
+
dark: {
|
|
1609
|
+
surfaceElevated: "oklch(0.208 0.042 265.755)",
|
|
1610
|
+
surfaceOverlay: "oklch(0.208 0.042 265.755)",
|
|
1611
|
+
surfaceHover: "oklch(0.279 0.041 260.031)",
|
|
1612
|
+
surfaceActive: "color-mix(in oklab, oklch(0.279 0.041 260.031) 88%, oklch(0.984 0.003 247.858) 12%)",
|
|
1613
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1614
|
+
textSecondary: "oklch(0.704 0.04 256.788)",
|
|
1615
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.704 0.04 256.788) 78%, transparent)"
|
|
1616
|
+
}
|
|
1617
|
+
},
|
|
1618
|
+
"cool-gray": {
|
|
1619
|
+
light: {
|
|
1620
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1621
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1622
|
+
surfaceHover: "oklch(0.963 0.002 197.1)",
|
|
1623
|
+
surfaceActive: "color-mix(in oklab, oklch(0.963 0.002 197.1) 92%, oklch(0.148 0.004 228.8) 8%)",
|
|
1624
|
+
borderSubtle: "oklch(0.925 0.005 214.3)",
|
|
1625
|
+
textSecondary: "oklch(0.56 0.021 213.5)",
|
|
1626
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.56 0.021 213.5) 78%, transparent)"
|
|
1315
1627
|
},
|
|
1316
1628
|
dark: {
|
|
1317
|
-
surfaceElevated: "
|
|
1318
|
-
surfaceOverlay: "
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1629
|
+
surfaceElevated: "oklch(0.218 0.008 223.9)",
|
|
1630
|
+
surfaceOverlay: "oklch(0.218 0.008 223.9)",
|
|
1631
|
+
surfaceHover: "oklch(0.275 0.011 216.9)",
|
|
1632
|
+
surfaceActive: "color-mix(in oklab, oklch(0.275 0.011 216.9) 88%, oklch(0.987 0.002 197.1) 12%)",
|
|
1633
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1634
|
+
textSecondary: "oklch(0.723 0.014 214.4)",
|
|
1635
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.723 0.014 214.4) 78%, transparent)"
|
|
1322
1636
|
}
|
|
1323
1637
|
},
|
|
1324
1638
|
stone: {
|
|
1325
1639
|
light: {
|
|
1326
|
-
surfaceElevated: "
|
|
1327
|
-
surfaceOverlay: "
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1640
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1641
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1642
|
+
surfaceHover: "oklch(0.97 0.001 106.424)",
|
|
1643
|
+
surfaceActive: "color-mix(in oklab, oklch(0.97 0.001 106.424) 92%, oklch(0.147 0.004 49.25) 8%)",
|
|
1644
|
+
borderSubtle: "oklch(0.923 0.003 48.717)",
|
|
1645
|
+
textSecondary: "oklch(0.553 0.013 58.071)",
|
|
1646
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.553 0.013 58.071) 78%, transparent)"
|
|
1331
1647
|
},
|
|
1332
1648
|
dark: {
|
|
1333
|
-
surfaceElevated: "
|
|
1334
|
-
surfaceOverlay: "
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1649
|
+
surfaceElevated: "oklch(0.216 0.006 56.043)",
|
|
1650
|
+
surfaceOverlay: "oklch(0.216 0.006 56.043)",
|
|
1651
|
+
surfaceHover: "oklch(0.268 0.007 34.298)",
|
|
1652
|
+
surfaceActive: "color-mix(in oklab, oklch(0.268 0.007 34.298) 88%, oklch(0.985 0.001 106.423) 12%)",
|
|
1653
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1654
|
+
textSecondary: "oklch(0.709 0.01 56.259)",
|
|
1655
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.709 0.01 56.259) 78%, transparent)"
|
|
1338
1656
|
}
|
|
1339
1657
|
},
|
|
1340
1658
|
taupe: {
|
|
1341
1659
|
light: {
|
|
1342
|
-
surfaceElevated: "
|
|
1343
|
-
surfaceOverlay: "
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1660
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1661
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1662
|
+
surfaceHover: "oklch(0.96 0.002 17.2)",
|
|
1663
|
+
surfaceActive: "color-mix(in oklab, oklch(0.96 0.002 17.2) 92%, oklch(0.147 0.004 49.3) 8%)",
|
|
1664
|
+
borderSubtle: "oklch(0.922 0.005 34.3)",
|
|
1665
|
+
textSecondary: "oklch(0.547 0.021 43.1)",
|
|
1666
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.547 0.021 43.1) 78%, transparent)"
|
|
1667
|
+
},
|
|
1668
|
+
dark: {
|
|
1669
|
+
surfaceElevated: "oklch(0.214 0.009 43.1)",
|
|
1670
|
+
surfaceOverlay: "oklch(0.214 0.009 43.1)",
|
|
1671
|
+
surfaceHover: "oklch(0.268 0.011 36.5)",
|
|
1672
|
+
surfaceActive: "color-mix(in oklab, oklch(0.268 0.011 36.5) 88%, oklch(0.986 0.002 67.8) 12%)",
|
|
1673
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1674
|
+
textSecondary: "oklch(0.714 0.014 41.2)",
|
|
1675
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.714 0.014 41.2) 78%, transparent)"
|
|
1676
|
+
}
|
|
1677
|
+
},
|
|
1678
|
+
mauve: {
|
|
1679
|
+
light: {
|
|
1680
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1681
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1682
|
+
surfaceHover: "oklch(0.96 0.003 325.6)",
|
|
1683
|
+
surfaceActive: "color-mix(in oklab, oklch(0.96 0.003 325.6) 92%, oklch(0.145 0.008 326) 8%)",
|
|
1684
|
+
borderSubtle: "oklch(0.922 0.005 325.62)",
|
|
1685
|
+
textSecondary: "oklch(0.542 0.034 322.5)",
|
|
1686
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.542 0.034 322.5) 78%, transparent)"
|
|
1687
|
+
},
|
|
1688
|
+
dark: {
|
|
1689
|
+
surfaceElevated: "oklch(0.212 0.019 322.12)",
|
|
1690
|
+
surfaceOverlay: "oklch(0.212 0.019 322.12)",
|
|
1691
|
+
surfaceHover: "oklch(0.263 0.024 320.12)",
|
|
1692
|
+
surfaceActive: "color-mix(in oklab, oklch(0.263 0.024 320.12) 88%, oklch(0.985 0 0) 12%)",
|
|
1693
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1694
|
+
textSecondary: "oklch(0.711 0.019 323.02)",
|
|
1695
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.711 0.019 323.02) 78%, transparent)"
|
|
1696
|
+
}
|
|
1697
|
+
},
|
|
1698
|
+
olive: {
|
|
1699
|
+
light: {
|
|
1700
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1701
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1702
|
+
surfaceHover: "oklch(0.966 0.005 106.5)",
|
|
1703
|
+
surfaceActive: "color-mix(in oklab, oklch(0.966 0.005 106.5) 92%, oklch(0.153 0.006 107.1) 8%)",
|
|
1704
|
+
borderSubtle: "oklch(0.93 0.007 106.5)",
|
|
1705
|
+
textSecondary: "oklch(0.58 0.031 107.3)",
|
|
1706
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.58 0.031 107.3) 78%, transparent)"
|
|
1707
|
+
},
|
|
1708
|
+
dark: {
|
|
1709
|
+
surfaceElevated: "oklch(0.228 0.013 107.4)",
|
|
1710
|
+
surfaceOverlay: "oklch(0.228 0.013 107.4)",
|
|
1711
|
+
surfaceHover: "oklch(0.286 0.016 107.4)",
|
|
1712
|
+
surfaceActive: "color-mix(in oklab, oklch(0.286 0.016 107.4) 88%, oklch(0.988 0.003 106.5) 12%)",
|
|
1713
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1714
|
+
textSecondary: "oklch(0.737 0.021 106.9)",
|
|
1715
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.737 0.021 106.9) 78%, transparent)"
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
mist: {
|
|
1719
|
+
light: {
|
|
1720
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1721
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1722
|
+
surfaceHover: "oklch(0.963 0.002 197.1)",
|
|
1723
|
+
surfaceActive: "color-mix(in oklab, oklch(0.963 0.002 197.1) 92%, oklch(0.148 0.004 228.8) 8%)",
|
|
1724
|
+
borderSubtle: "oklch(0.925 0.005 214.3)",
|
|
1725
|
+
textSecondary: "oklch(0.56 0.021 213.5)",
|
|
1726
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.56 0.021 213.5) 78%, transparent)"
|
|
1727
|
+
},
|
|
1728
|
+
dark: {
|
|
1729
|
+
surfaceElevated: "oklch(0.218 0.008 223.9)",
|
|
1730
|
+
surfaceOverlay: "oklch(0.218 0.008 223.9)",
|
|
1731
|
+
surfaceHover: "oklch(0.275 0.011 216.9)",
|
|
1732
|
+
surfaceActive: "color-mix(in oklab, oklch(0.275 0.011 216.9) 88%, oklch(0.987 0.002 197.1) 12%)",
|
|
1733
|
+
borderSubtle: "oklch(1 0 0 / 10%)",
|
|
1734
|
+
textSecondary: "oklch(0.723 0.014 214.4)",
|
|
1735
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.723 0.014 214.4) 78%, transparent)"
|
|
1736
|
+
}
|
|
1737
|
+
},
|
|
1738
|
+
black: {
|
|
1739
|
+
light: {
|
|
1740
|
+
// Light stays light: white cards + soft grey chrome (same structure as
|
|
1741
|
+
// `neutral`), not a washed dark theme. Character lives in slightly
|
|
1742
|
+
// firmer secondary text / borders than neutral, not in tinted surfaces.
|
|
1743
|
+
surfaceElevated: "oklch(1 0 0)",
|
|
1744
|
+
surfaceOverlay: "oklch(1 0 0)",
|
|
1745
|
+
surfaceHover: "oklch(0.97 0 0)",
|
|
1746
|
+
surfaceActive: "color-mix(in oklab, oklch(0.97 0 0) 92%, oklch(0.145 0 0) 8%)",
|
|
1747
|
+
borderSubtle: "oklch(0.922 0 0)",
|
|
1748
|
+
textSecondary: "oklch(0.52 0 0)",
|
|
1749
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.52 0 0) 78%, transparent)"
|
|
1347
1750
|
},
|
|
1348
1751
|
dark: {
|
|
1349
|
-
surfaceElevated: "
|
|
1350
|
-
surfaceOverlay: "
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1752
|
+
surfaceElevated: "oklch(0.145 0 0)",
|
|
1753
|
+
surfaceOverlay: "oklch(0.165 0 0)",
|
|
1754
|
+
surfaceHover: "oklch(0.22 0 0)",
|
|
1755
|
+
surfaceActive: "color-mix(in oklab, oklch(0.22 0 0) 86%, oklch(0.985 0 0) 14%)",
|
|
1756
|
+
borderSubtle: "oklch(1 0 0 / 12%)",
|
|
1757
|
+
textSecondary: "oklch(0.68 0 0)",
|
|
1758
|
+
textPlaceholder: "color-mix(in oklab, oklch(0.68 0 0) 78%, transparent)"
|
|
1354
1759
|
}
|
|
1355
1760
|
}
|
|
1356
1761
|
};
|
|
@@ -1476,6 +1881,174 @@ var THEME_COLOR_PALETTE = {
|
|
|
1476
1881
|
controlSolidForeground: "#fff7ed"
|
|
1477
1882
|
// orange-50
|
|
1478
1883
|
}
|
|
1884
|
+
},
|
|
1885
|
+
amber: {
|
|
1886
|
+
light: {
|
|
1887
|
+
controlSolid: "#b45309",
|
|
1888
|
+
controlSolidHover: "#d97706",
|
|
1889
|
+
controlSolidActive: "#92400e",
|
|
1890
|
+
controlSolidForeground: "#fffbeb"
|
|
1891
|
+
},
|
|
1892
|
+
dark: {
|
|
1893
|
+
controlSolid: "#92400e",
|
|
1894
|
+
controlSolidHover: "#b45309",
|
|
1895
|
+
controlSolidActive: "#78350f",
|
|
1896
|
+
controlSolidForeground: "#fffbeb"
|
|
1897
|
+
}
|
|
1898
|
+
},
|
|
1899
|
+
cyan: {
|
|
1900
|
+
light: {
|
|
1901
|
+
controlSolid: "#0e7490",
|
|
1902
|
+
controlSolidHover: "#0891b2",
|
|
1903
|
+
controlSolidActive: "#155e75",
|
|
1904
|
+
controlSolidForeground: "#ecfeff"
|
|
1905
|
+
},
|
|
1906
|
+
dark: {
|
|
1907
|
+
controlSolid: "#155e75",
|
|
1908
|
+
controlSolidHover: "#0e7490",
|
|
1909
|
+
controlSolidActive: "#164e63",
|
|
1910
|
+
controlSolidForeground: "#ecfeff"
|
|
1911
|
+
}
|
|
1912
|
+
},
|
|
1913
|
+
emerald: {
|
|
1914
|
+
light: {
|
|
1915
|
+
controlSolid: "#047857",
|
|
1916
|
+
controlSolidHover: "#059669",
|
|
1917
|
+
controlSolidActive: "#065f46",
|
|
1918
|
+
controlSolidForeground: "#ecfdf5"
|
|
1919
|
+
},
|
|
1920
|
+
dark: {
|
|
1921
|
+
controlSolid: "#065f46",
|
|
1922
|
+
controlSolidHover: "#047857",
|
|
1923
|
+
controlSolidActive: "#064e3b",
|
|
1924
|
+
controlSolidForeground: "#ecfdf5"
|
|
1925
|
+
}
|
|
1926
|
+
},
|
|
1927
|
+
indigo: {
|
|
1928
|
+
light: {
|
|
1929
|
+
controlSolid: "#4338ca",
|
|
1930
|
+
controlSolidHover: "#4f46e5",
|
|
1931
|
+
controlSolidActive: "#3730a3",
|
|
1932
|
+
controlSolidForeground: "#eef2ff"
|
|
1933
|
+
},
|
|
1934
|
+
dark: {
|
|
1935
|
+
controlSolid: "#3730a3",
|
|
1936
|
+
controlSolidHover: "#4338ca",
|
|
1937
|
+
controlSolidActive: "#312e81",
|
|
1938
|
+
controlSolidForeground: "#eef2ff"
|
|
1939
|
+
}
|
|
1940
|
+
},
|
|
1941
|
+
pink: {
|
|
1942
|
+
light: {
|
|
1943
|
+
controlSolid: "#be185d",
|
|
1944
|
+
controlSolidHover: "#db2777",
|
|
1945
|
+
controlSolidActive: "#9d174d",
|
|
1946
|
+
controlSolidForeground: "#fdf2f8"
|
|
1947
|
+
},
|
|
1948
|
+
dark: {
|
|
1949
|
+
controlSolid: "#9d174d",
|
|
1950
|
+
controlSolidHover: "#be185d",
|
|
1951
|
+
controlSolidActive: "#831843",
|
|
1952
|
+
controlSolidForeground: "#fdf2f8"
|
|
1953
|
+
}
|
|
1954
|
+
},
|
|
1955
|
+
purple: {
|
|
1956
|
+
light: {
|
|
1957
|
+
controlSolid: "#7e22ce",
|
|
1958
|
+
controlSolidHover: "#9333ea",
|
|
1959
|
+
controlSolidActive: "#6b21a8",
|
|
1960
|
+
controlSolidForeground: "#faf5ff"
|
|
1961
|
+
},
|
|
1962
|
+
dark: {
|
|
1963
|
+
controlSolid: "#6b21a8",
|
|
1964
|
+
controlSolidHover: "#7e22ce",
|
|
1965
|
+
controlSolidActive: "#581c87",
|
|
1966
|
+
controlSolidForeground: "#faf5ff"
|
|
1967
|
+
}
|
|
1968
|
+
},
|
|
1969
|
+
rose: {
|
|
1970
|
+
light: {
|
|
1971
|
+
controlSolid: "#be123c",
|
|
1972
|
+
controlSolidHover: "#e11d48",
|
|
1973
|
+
controlSolidActive: "#9f1239",
|
|
1974
|
+
controlSolidForeground: "#fff1f2"
|
|
1975
|
+
},
|
|
1976
|
+
dark: {
|
|
1977
|
+
controlSolid: "#9f1239",
|
|
1978
|
+
controlSolidHover: "#be123c",
|
|
1979
|
+
controlSolidActive: "#881337",
|
|
1980
|
+
controlSolidForeground: "#fff1f2"
|
|
1981
|
+
}
|
|
1982
|
+
},
|
|
1983
|
+
sky: {
|
|
1984
|
+
light: {
|
|
1985
|
+
controlSolid: "#0369a1",
|
|
1986
|
+
controlSolidHover: "#0284c7",
|
|
1987
|
+
controlSolidActive: "#075985",
|
|
1988
|
+
controlSolidForeground: "#f0f9ff"
|
|
1989
|
+
},
|
|
1990
|
+
dark: {
|
|
1991
|
+
controlSolid: "#075985",
|
|
1992
|
+
controlSolidHover: "#0369a1",
|
|
1993
|
+
controlSolidActive: "#0c4a6e",
|
|
1994
|
+
controlSolidForeground: "#f0f9ff"
|
|
1995
|
+
}
|
|
1996
|
+
},
|
|
1997
|
+
teal: {
|
|
1998
|
+
light: {
|
|
1999
|
+
controlSolid: "#0f766e",
|
|
2000
|
+
controlSolidHover: "#0d9488",
|
|
2001
|
+
controlSolidActive: "#115e59",
|
|
2002
|
+
controlSolidForeground: "#f0fdfa"
|
|
2003
|
+
},
|
|
2004
|
+
dark: {
|
|
2005
|
+
controlSolid: "#115e59",
|
|
2006
|
+
controlSolidHover: "#0f766e",
|
|
2007
|
+
controlSolidActive: "#134e4a",
|
|
2008
|
+
controlSolidForeground: "#f0fdfa"
|
|
2009
|
+
}
|
|
2010
|
+
},
|
|
2011
|
+
yellow: {
|
|
2012
|
+
light: {
|
|
2013
|
+
controlSolid: "#a16207",
|
|
2014
|
+
controlSolidHover: "#ca8a04",
|
|
2015
|
+
controlSolidActive: "#854d0e",
|
|
2016
|
+
controlSolidForeground: "#fefce8"
|
|
2017
|
+
},
|
|
2018
|
+
dark: {
|
|
2019
|
+
controlSolid: "#854d0e",
|
|
2020
|
+
controlSolidHover: "#a16207",
|
|
2021
|
+
controlSolidActive: "#713f12",
|
|
2022
|
+
controlSolidForeground: "#fefce8"
|
|
2023
|
+
}
|
|
2024
|
+
},
|
|
2025
|
+
fuchsia: {
|
|
2026
|
+
light: {
|
|
2027
|
+
controlSolid: "#a21caf",
|
|
2028
|
+
controlSolidHover: "#c026d3",
|
|
2029
|
+
controlSolidActive: "#86198f",
|
|
2030
|
+
controlSolidForeground: "#fdf4ff"
|
|
2031
|
+
},
|
|
2032
|
+
dark: {
|
|
2033
|
+
controlSolid: "#86198f",
|
|
2034
|
+
controlSolidHover: "#a21caf",
|
|
2035
|
+
controlSolidActive: "#701a75",
|
|
2036
|
+
controlSolidForeground: "#fdf4ff"
|
|
2037
|
+
}
|
|
2038
|
+
},
|
|
2039
|
+
lime: {
|
|
2040
|
+
light: {
|
|
2041
|
+
controlSolid: "#4d7c0f",
|
|
2042
|
+
controlSolidHover: "#65a30d",
|
|
2043
|
+
controlSolidActive: "#3f6212",
|
|
2044
|
+
controlSolidForeground: "#f7fee7"
|
|
2045
|
+
},
|
|
2046
|
+
dark: {
|
|
2047
|
+
controlSolid: "#3f6212",
|
|
2048
|
+
controlSolidHover: "#4d7c0f",
|
|
2049
|
+
controlSolidActive: "#365314",
|
|
2050
|
+
controlSolidForeground: "#f7fee7"
|
|
2051
|
+
}
|
|
1479
2052
|
}
|
|
1480
2053
|
};
|
|
1481
2054
|
var DEFAULT_CHART_STOPS = {
|
|
@@ -1518,6 +2091,54 @@ var CHART_PALETTES = {
|
|
|
1518
2091
|
orange: {
|
|
1519
2092
|
light: ["#eda100", "#f97316", "#e34948", "#ca8a04", "#c2410c", "#db2777"],
|
|
1520
2093
|
dark: ["#c98500", "#fb923c", "#e66767", "#facc15", "#fdba74", "#f472b6"]
|
|
2094
|
+
},
|
|
2095
|
+
amber: {
|
|
2096
|
+
light: ["#d97706", "#f59e0b", "#b45309", "#fbbf24", "#92400e", "#f97316"],
|
|
2097
|
+
dark: ["#fbbf24", "#f59e0b", "#fcd34d", "#d97706", "#fde68a", "#fb923c"]
|
|
2098
|
+
},
|
|
2099
|
+
cyan: {
|
|
2100
|
+
light: ["#0891b2", "#06b6d4", "#0e7490", "#22d3ee", "#155e75", "#0284c7"],
|
|
2101
|
+
dark: ["#22d3ee", "#67e8f9", "#06b6d4", "#38bdf8", "#a5f3fc", "#0891b2"]
|
|
2102
|
+
},
|
|
2103
|
+
emerald: {
|
|
2104
|
+
light: ["#059669", "#10b981", "#047857", "#34d399", "#065f46", "#0d9488"],
|
|
2105
|
+
dark: ["#34d399", "#6ee7b7", "#10b981", "#2dd4bf", "#a7f3d0", "#059669"]
|
|
2106
|
+
},
|
|
2107
|
+
indigo: {
|
|
2108
|
+
light: ["#4f46e5", "#6366f1", "#4338ca", "#818cf8", "#3730a3", "#7c3aed"],
|
|
2109
|
+
dark: ["#818cf8", "#a5b4fc", "#6366f1", "#a78bfa", "#c7d2fe", "#4f46e5"]
|
|
2110
|
+
},
|
|
2111
|
+
pink: {
|
|
2112
|
+
light: ["#db2777", "#ec4899", "#be185d", "#f472b6", "#9d174d", "#e11d48"],
|
|
2113
|
+
dark: ["#f472b6", "#f9a8d4", "#ec4899", "#fb7185", "#fbcfe8", "#db2777"]
|
|
2114
|
+
},
|
|
2115
|
+
purple: {
|
|
2116
|
+
light: ["#9333ea", "#a855f7", "#7e22ce", "#c084fc", "#6b21a8", "#7c3aed"],
|
|
2117
|
+
dark: ["#c084fc", "#d8b4fe", "#a855f7", "#a78bfa", "#e9d5ff", "#9333ea"]
|
|
2118
|
+
},
|
|
2119
|
+
rose: {
|
|
2120
|
+
light: ["#e11d48", "#f43f5e", "#be123c", "#fb7185", "#9f1239", "#db2777"],
|
|
2121
|
+
dark: ["#fb7185", "#fda4af", "#f43f5e", "#f472b6", "#ffe4e6", "#e11d48"]
|
|
2122
|
+
},
|
|
2123
|
+
sky: {
|
|
2124
|
+
light: ["#0284c7", "#0ea5e9", "#0369a1", "#38bdf8", "#075985", "#2563eb"],
|
|
2125
|
+
dark: ["#38bdf8", "#7dd3fc", "#0ea5e9", "#60a5fa", "#bae6fd", "#0284c7"]
|
|
2126
|
+
},
|
|
2127
|
+
teal: {
|
|
2128
|
+
light: ["#0d9488", "#14b8a6", "#0f766e", "#2dd4bf", "#115e59", "#0891b2"],
|
|
2129
|
+
dark: ["#2dd4bf", "#5eead4", "#14b8a6", "#22d3ee", "#99f6e4", "#0d9488"]
|
|
2130
|
+
},
|
|
2131
|
+
yellow: {
|
|
2132
|
+
light: ["#ca8a04", "#eab308", "#a16207", "#facc15", "#854d0e", "#f59e0b"],
|
|
2133
|
+
dark: ["#facc15", "#fde047", "#eab308", "#fbbf24", "#fef08a", "#ca8a04"]
|
|
2134
|
+
},
|
|
2135
|
+
fuchsia: {
|
|
2136
|
+
light: ["#c026d3", "#d946ef", "#a21caf", "#e879f9", "#86198f", "#db2777"],
|
|
2137
|
+
dark: ["#e879f9", "#f0abfc", "#d946ef", "#f472b6", "#fae8ff", "#c026d3"]
|
|
2138
|
+
},
|
|
2139
|
+
lime: {
|
|
2140
|
+
light: ["#65a30d", "#84cc16", "#4d7c0f", "#a3e635", "#3f6212", "#16a34a"],
|
|
2141
|
+
dark: ["#a3e635", "#bef264", "#84cc16", "#4ade80", "#d9f99d", "#65a30d"]
|
|
1521
2142
|
}
|
|
1522
2143
|
},
|
|
1523
2144
|
warm: {
|
|
@@ -1531,31 +2152,137 @@ var CHART_PALETTES = {
|
|
|
1531
2152
|
mixed: {
|
|
1532
2153
|
light: ["#2a78d6", "#e34948", "#1baf7a", "#eda100", "#4a3aa7", "#db2777"],
|
|
1533
2154
|
dark: ["#3987e5", "#e66767", "#199e70", "#c98500", "#9085e9", "#f472b6"]
|
|
2155
|
+
},
|
|
2156
|
+
neutral: {
|
|
2157
|
+
light: ["#404040", "#737373", "#a3a3a3", "#525252", "#262626", "#d4d4d4"],
|
|
2158
|
+
dark: ["#d4d4d4", "#a3a3a3", "#737373", "#e5e5e5", "#f5f5f5", "#525252"]
|
|
2159
|
+
},
|
|
2160
|
+
zinc: {
|
|
2161
|
+
light: ["#3f3f46", "#71717a", "#a1a1aa", "#52525b", "#27272a", "#d4d4d8"],
|
|
2162
|
+
dark: ["#d4d4d8", "#a1a1aa", "#71717a", "#e4e4e7", "#f4f4f5", "#52525b"]
|
|
2163
|
+
},
|
|
2164
|
+
stone: {
|
|
2165
|
+
light: ["#44403c", "#78716c", "#a8a29e", "#57534e", "#292524", "#d6d3d1"],
|
|
2166
|
+
dark: ["#d6d3d1", "#a8a29e", "#78716c", "#e7e5e4", "#fafaf9", "#57534e"]
|
|
2167
|
+
},
|
|
2168
|
+
gray: {
|
|
2169
|
+
light: ["#374151", "#6b7280", "#9ca3af", "#4b5563", "#1f2937", "#d1d5db"],
|
|
2170
|
+
dark: ["#d1d5db", "#9ca3af", "#6b7280", "#e5e7eb", "#f9fafb", "#4b5563"]
|
|
2171
|
+
},
|
|
2172
|
+
amber: {
|
|
2173
|
+
light: ["#d97706", "#f59e0b", "#b45309", "#fbbf24", "#92400e", "#f97316"],
|
|
2174
|
+
dark: ["#fbbf24", "#f59e0b", "#fcd34d", "#d97706", "#fde68a", "#fb923c"]
|
|
2175
|
+
},
|
|
2176
|
+
cyan: {
|
|
2177
|
+
light: ["#0891b2", "#06b6d4", "#0e7490", "#22d3ee", "#155e75", "#0284c7"],
|
|
2178
|
+
dark: ["#22d3ee", "#67e8f9", "#06b6d4", "#38bdf8", "#a5f3fc", "#0891b2"]
|
|
2179
|
+
},
|
|
2180
|
+
emerald: {
|
|
2181
|
+
light: ["#059669", "#10b981", "#047857", "#34d399", "#065f46", "#0d9488"],
|
|
2182
|
+
dark: ["#34d399", "#6ee7b7", "#10b981", "#2dd4bf", "#a7f3d0", "#059669"]
|
|
2183
|
+
},
|
|
2184
|
+
indigo: {
|
|
2185
|
+
light: ["#4f46e5", "#6366f1", "#4338ca", "#818cf8", "#3730a3", "#7c3aed"],
|
|
2186
|
+
dark: ["#818cf8", "#a5b4fc", "#6366f1", "#a78bfa", "#c7d2fe", "#4f46e5"]
|
|
2187
|
+
},
|
|
2188
|
+
lime: {
|
|
2189
|
+
light: ["#65a30d", "#84cc16", "#4d7c0f", "#a3e635", "#3f6212", "#16a34a"],
|
|
2190
|
+
dark: ["#a3e635", "#bef264", "#84cc16", "#4ade80", "#d9f99d", "#65a30d"]
|
|
2191
|
+
},
|
|
2192
|
+
pink: {
|
|
2193
|
+
light: ["#db2777", "#ec4899", "#be185d", "#f472b6", "#9d174d", "#e11d48"],
|
|
2194
|
+
dark: ["#f472b6", "#f9a8d4", "#ec4899", "#fb7185", "#fbcfe8", "#db2777"]
|
|
2195
|
+
},
|
|
2196
|
+
purple: {
|
|
2197
|
+
light: ["#9333ea", "#a855f7", "#7e22ce", "#c084fc", "#6b21a8", "#7c3aed"],
|
|
2198
|
+
dark: ["#c084fc", "#d8b4fe", "#a855f7", "#a78bfa", "#e9d5ff", "#9333ea"]
|
|
2199
|
+
},
|
|
2200
|
+
rose: {
|
|
2201
|
+
light: ["#e11d48", "#f43f5e", "#be123c", "#fb7185", "#9f1239", "#db2777"],
|
|
2202
|
+
dark: ["#fb7185", "#fda4af", "#f43f5e", "#f472b6", "#ffe4e6", "#e11d48"]
|
|
2203
|
+
},
|
|
2204
|
+
sky: {
|
|
2205
|
+
light: ["#0284c7", "#0ea5e9", "#0369a1", "#38bdf8", "#075985", "#2563eb"],
|
|
2206
|
+
dark: ["#38bdf8", "#7dd3fc", "#0ea5e9", "#60a5fa", "#bae6fd", "#0284c7"]
|
|
2207
|
+
},
|
|
2208
|
+
teal: {
|
|
2209
|
+
light: ["#0d9488", "#14b8a6", "#0f766e", "#2dd4bf", "#115e59", "#0891b2"],
|
|
2210
|
+
dark: ["#2dd4bf", "#5eead4", "#14b8a6", "#22d3ee", "#99f6e4", "#0d9488"]
|
|
2211
|
+
},
|
|
2212
|
+
yellow: {
|
|
2213
|
+
light: ["#ca8a04", "#eab308", "#a16207", "#facc15", "#854d0e", "#f59e0b"],
|
|
2214
|
+
dark: ["#facc15", "#fde047", "#eab308", "#fbbf24", "#fef08a", "#ca8a04"]
|
|
2215
|
+
},
|
|
2216
|
+
taupe: {
|
|
2217
|
+
light: ["#8a6f55", "#a78b71", "#6f5a46", "#c4aa8f", "#4f4034", "#d97706"],
|
|
2218
|
+
dark: ["#c4aa8f", "#dcc8b2", "#a78b71", "#f3ede6", "#8a6f55", "#fbbf24"]
|
|
1534
2219
|
}
|
|
1535
2220
|
};
|
|
1536
2221
|
|
|
1537
2222
|
// ../wensity-preset/src/curated-fonts.ts
|
|
2223
|
+
var CURATED_FONT_UI_WEIGHTS = [400, 500, 600, 700];
|
|
2224
|
+
function curatedFontCssImportSpecifiers(pkg) {
|
|
2225
|
+
return pkg.weights.map((weight) => `${pkg.packageName}/${weight}.css`);
|
|
2226
|
+
}
|
|
2227
|
+
function fontPackage(packageName, familyName, weights = CURATED_FONT_UI_WEIGHTS) {
|
|
2228
|
+
return { packageName, familyName, weights };
|
|
2229
|
+
}
|
|
1538
2230
|
var HEADING_FONT_PACKAGES = {
|
|
1539
|
-
playfair:
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
2231
|
+
playfair: fontPackage("@fontsource/playfair-display", "Playfair Display"),
|
|
2232
|
+
"instrument-serif": fontPackage(
|
|
2233
|
+
"@fontsource/instrument-serif",
|
|
2234
|
+
"Instrument Serif",
|
|
2235
|
+
[400]
|
|
2236
|
+
),
|
|
2237
|
+
fraunces: fontPackage("@fontsource/fraunces", "Fraunces"),
|
|
2238
|
+
"space-grotesk": fontPackage("@fontsource/space-grotesk", "Space Grotesk"),
|
|
2239
|
+
"noto-serif": fontPackage("@fontsource/noto-serif", "Noto Serif"),
|
|
2240
|
+
"eb-garamond": fontPackage("@fontsource/eb-garamond", "EB Garamond"),
|
|
2241
|
+
lora: fontPackage("@fontsource/lora", "Lora"),
|
|
2242
|
+
montserrat: fontPackage("@fontsource/montserrat", "Montserrat"),
|
|
2243
|
+
manrope: fontPackage("@fontsource/manrope", "Manrope"),
|
|
2244
|
+
inter: fontPackage("@fontsource/inter", "Inter")
|
|
1544
2245
|
};
|
|
1545
2246
|
var BODY_FONT_PACKAGES = {
|
|
1546
|
-
inter:
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
2247
|
+
inter: fontPackage("@fontsource/inter", "Inter"),
|
|
2248
|
+
geist: fontPackage("@fontsource/geist", "Geist"),
|
|
2249
|
+
"dm-sans": fontPackage("@fontsource/dm-sans", "DM Sans"),
|
|
2250
|
+
"plus-jakarta-sans": fontPackage(
|
|
2251
|
+
"@fontsource/plus-jakarta-sans",
|
|
2252
|
+
"Plus Jakarta Sans"
|
|
2253
|
+
),
|
|
2254
|
+
figtree: fontPackage("@fontsource/figtree", "Figtree"),
|
|
2255
|
+
"noto-sans": fontPackage("@fontsource/noto-sans", "Noto Sans"),
|
|
2256
|
+
"public-sans": fontPackage("@fontsource/public-sans", "Public Sans"),
|
|
2257
|
+
outfit: fontPackage("@fontsource/outfit", "Outfit"),
|
|
2258
|
+
manrope: fontPackage("@fontsource/manrope", "Manrope"),
|
|
2259
|
+
"ibm-plex-sans": fontPackage("@fontsource/ibm-plex-sans", "IBM Plex Sans")
|
|
1551
2260
|
};
|
|
1552
2261
|
var HEADING_FONT_CSS = {
|
|
1553
2262
|
system: "var(--font-display)",
|
|
1554
|
-
playfair: "'Playfair Display', Georgia, 'Times New Roman', serif"
|
|
2263
|
+
playfair: "'Playfair Display', Georgia, 'Times New Roman', serif",
|
|
2264
|
+
"instrument-serif": "'Instrument Serif', Georgia, 'Times New Roman', serif",
|
|
2265
|
+
fraunces: "'Fraunces', Georgia, 'Times New Roman', serif",
|
|
2266
|
+
"space-grotesk": "'Space Grotesk', ui-sans-serif, system-ui, sans-serif",
|
|
2267
|
+
"noto-serif": "'Noto Serif', Georgia, 'Times New Roman', serif",
|
|
2268
|
+
"eb-garamond": "'EB Garamond', Georgia, 'Times New Roman', serif",
|
|
2269
|
+
lora: "'Lora', Georgia, 'Times New Roman', serif",
|
|
2270
|
+
montserrat: "'Montserrat', ui-sans-serif, system-ui, sans-serif",
|
|
2271
|
+
manrope: "'Manrope', ui-sans-serif, system-ui, sans-serif",
|
|
2272
|
+
inter: "'Inter', ui-sans-serif, system-ui, sans-serif"
|
|
1555
2273
|
};
|
|
1556
2274
|
var BODY_FONT_CSS = {
|
|
1557
2275
|
system: "var(--font-sans)",
|
|
1558
|
-
inter: "'Inter', ui-sans-serif, system-ui, sans-serif"
|
|
2276
|
+
inter: "'Inter', ui-sans-serif, system-ui, sans-serif",
|
|
2277
|
+
geist: "'Geist', ui-sans-serif, system-ui, sans-serif",
|
|
2278
|
+
"dm-sans": "'DM Sans', ui-sans-serif, system-ui, sans-serif",
|
|
2279
|
+
"plus-jakarta-sans": "'Plus Jakarta Sans', ui-sans-serif, system-ui, sans-serif",
|
|
2280
|
+
figtree: "'Figtree', ui-sans-serif, system-ui, sans-serif",
|
|
2281
|
+
"noto-sans": "'Noto Sans', ui-sans-serif, system-ui, sans-serif",
|
|
2282
|
+
"public-sans": "'Public Sans', ui-sans-serif, system-ui, sans-serif",
|
|
2283
|
+
outfit: "'Outfit', ui-sans-serif, system-ui, sans-serif",
|
|
2284
|
+
manrope: "'Manrope', ui-sans-serif, system-ui, sans-serif",
|
|
2285
|
+
"ibm-plex-sans": "'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif"
|
|
1559
2286
|
};
|
|
1560
2287
|
|
|
1561
2288
|
// ../wensity-preset/src/resolve.ts
|
|
@@ -1614,7 +2341,19 @@ var COLORED_THEME_IDS = /* @__PURE__ */ new Set([
|
|
|
1614
2341
|
"blue",
|
|
1615
2342
|
"violet",
|
|
1616
2343
|
"green",
|
|
1617
|
-
"orange"
|
|
2344
|
+
"orange",
|
|
2345
|
+
"amber",
|
|
2346
|
+
"cyan",
|
|
2347
|
+
"emerald",
|
|
2348
|
+
"indigo",
|
|
2349
|
+
"pink",
|
|
2350
|
+
"purple",
|
|
2351
|
+
"rose",
|
|
2352
|
+
"sky",
|
|
2353
|
+
"teal",
|
|
2354
|
+
"yellow",
|
|
2355
|
+
"fuchsia",
|
|
2356
|
+
"lime"
|
|
1618
2357
|
]);
|
|
1619
2358
|
function colorMix(source, percent) {
|
|
1620
2359
|
return `color-mix(in srgb, ${source} ${percent}%, transparent)`;
|
|
@@ -1641,16 +2380,15 @@ function baseFromInherit(mode) {
|
|
|
1641
2380
|
return { ...INHERIT_BASE_EXPRESSIONS[mode] };
|
|
1642
2381
|
}
|
|
1643
2382
|
function baseFromSeeds(seeds, mode) {
|
|
1644
|
-
|
|
1645
|
-
const activePercent = mode === "light" ? 7 : 10;
|
|
2383
|
+
void mode;
|
|
1646
2384
|
return {
|
|
1647
2385
|
surfaceElevated: seeds.surfaceElevated,
|
|
1648
2386
|
surfaceOverlay: seeds.surfaceOverlay,
|
|
1649
|
-
surfaceHover:
|
|
1650
|
-
surfaceActive:
|
|
1651
|
-
borderSubtle:
|
|
1652
|
-
textSecondary:
|
|
1653
|
-
textPlaceholder:
|
|
2387
|
+
surfaceHover: seeds.surfaceHover,
|
|
2388
|
+
surfaceActive: seeds.surfaceActive,
|
|
2389
|
+
borderSubtle: seeds.borderSubtle,
|
|
2390
|
+
textSecondary: seeds.textSecondary,
|
|
2391
|
+
textPlaceholder: seeds.textPlaceholder
|
|
1654
2392
|
};
|
|
1655
2393
|
}
|
|
1656
2394
|
function ringAndSelectedForInk(mode) {
|
|
@@ -1659,10 +2397,10 @@ function ringAndSelectedForInk(mode) {
|
|
|
1659
2397
|
surfaceSelected: FIXED_SURFACE_SELECTED[mode]
|
|
1660
2398
|
};
|
|
1661
2399
|
}
|
|
1662
|
-
function
|
|
2400
|
+
function ringFromAccentWithNeutralSelected(accent, mode) {
|
|
1663
2401
|
return {
|
|
1664
2402
|
ring: colorMix(accent, 45),
|
|
1665
|
-
surfaceSelected:
|
|
2403
|
+
surfaceSelected: FIXED_SURFACE_SELECTED[mode]
|
|
1666
2404
|
};
|
|
1667
2405
|
}
|
|
1668
2406
|
function buildModeTokens(args) {
|
|
@@ -1707,17 +2445,40 @@ function resolveStyleConfig(style) {
|
|
|
1707
2445
|
}
|
|
1708
2446
|
function resolveChartStops(chartPalette, themeColor, mode) {
|
|
1709
2447
|
if (chartPalette === "theme") {
|
|
1710
|
-
|
|
2448
|
+
const themeStops = CHART_PALETTES.theme[themeColor];
|
|
2449
|
+
if (!themeStops) {
|
|
2450
|
+
throw new Error(
|
|
2451
|
+
`Missing CHART_PALETTES.theme entry for themeColor "${themeColor}".`
|
|
2452
|
+
);
|
|
2453
|
+
}
|
|
2454
|
+
return themeStops[mode];
|
|
1711
2455
|
}
|
|
1712
|
-
|
|
2456
|
+
const stops = CHART_PALETTES[chartPalette];
|
|
2457
|
+
if (!stops) {
|
|
2458
|
+
throw new Error(
|
|
2459
|
+
`Missing CHART_PALETTES entry for chartPalette "${chartPalette}".`
|
|
2460
|
+
);
|
|
2461
|
+
}
|
|
2462
|
+
return stops[mode];
|
|
1713
2463
|
}
|
|
1714
2464
|
function resolveStyleConfigCanonical(style) {
|
|
1715
2465
|
const theme = THEME_COLOR_PALETTE[style.themeColor];
|
|
2466
|
+
if (!theme) {
|
|
2467
|
+
throw new Error(
|
|
2468
|
+
`Missing THEME_COLOR_PALETTE entry for themeColor "${style.themeColor}".`
|
|
2469
|
+
);
|
|
2470
|
+
}
|
|
2471
|
+
const namedBase = style.baseColor === "inherit" ? null : BASE_COLOR_PALETTE[style.baseColor];
|
|
2472
|
+
if (style.baseColor !== "inherit" && !namedBase) {
|
|
2473
|
+
throw new Error(
|
|
2474
|
+
`Missing BASE_COLOR_PALETTE entry for baseColor "${style.baseColor}".`
|
|
2475
|
+
);
|
|
2476
|
+
}
|
|
1716
2477
|
const useAccentRing = COLORED_THEME_IDS.has(style.themeColor);
|
|
1717
2478
|
const resolveMode = (mode) => {
|
|
1718
|
-
const base =
|
|
2479
|
+
const base = namedBase ? baseFromSeeds(namedBase[mode], mode) : baseFromInherit(mode);
|
|
1719
2480
|
const control = theme[mode];
|
|
1720
|
-
const ringSelected = useAccentRing ?
|
|
2481
|
+
const ringSelected = useAccentRing ? ringFromAccentWithNeutralSelected(control.controlSolid, mode) : ringAndSelectedForInk(mode);
|
|
1721
2482
|
const charts = resolveChartStops(style.chartPalette, style.themeColor, mode);
|
|
1722
2483
|
return buildModeTokens({ base, control, ringSelected, charts });
|
|
1723
2484
|
};
|
|
@@ -1732,6 +2493,34 @@ function resolveStyleConfigCanonical(style) {
|
|
|
1732
2493
|
dark: resolveMode("dark")
|
|
1733
2494
|
};
|
|
1734
2495
|
}
|
|
2496
|
+
function resolvedTokensToCssVars(tokens, mode) {
|
|
2497
|
+
const modeTokens = tokens[mode];
|
|
2498
|
+
return {
|
|
2499
|
+
[RESOLVED_TOKEN_CSS_VARS.surfaceElevated]: modeTokens.surfaceElevated,
|
|
2500
|
+
[RESOLVED_TOKEN_CSS_VARS.surfaceOverlay]: modeTokens.surfaceOverlay,
|
|
2501
|
+
[RESOLVED_TOKEN_CSS_VARS.surfaceHover]: modeTokens.surfaceHover,
|
|
2502
|
+
[RESOLVED_TOKEN_CSS_VARS.surfaceActive]: modeTokens.surfaceActive,
|
|
2503
|
+
[RESOLVED_TOKEN_CSS_VARS.surfaceSelected]: modeTokens.surfaceSelected,
|
|
2504
|
+
[RESOLVED_TOKEN_CSS_VARS.borderSubtle]: modeTokens.borderSubtle,
|
|
2505
|
+
[RESOLVED_TOKEN_CSS_VARS.ring]: modeTokens.ring,
|
|
2506
|
+
[RESOLVED_TOKEN_CSS_VARS.textSecondary]: modeTokens.textSecondary,
|
|
2507
|
+
[RESOLVED_TOKEN_CSS_VARS.textPlaceholder]: modeTokens.textPlaceholder,
|
|
2508
|
+
[RESOLVED_TOKEN_CSS_VARS.controlSolid]: modeTokens.controlSolid,
|
|
2509
|
+
[RESOLVED_TOKEN_CSS_VARS.controlSolidHover]: modeTokens.controlSolidHover,
|
|
2510
|
+
[RESOLVED_TOKEN_CSS_VARS.controlSolidActive]: modeTokens.controlSolidActive,
|
|
2511
|
+
[RESOLVED_TOKEN_CSS_VARS.controlSolidForeground]: modeTokens.controlSolidForeground,
|
|
2512
|
+
[RESOLVED_TOKEN_CSS_VARS.chart1]: modeTokens.chart1,
|
|
2513
|
+
[RESOLVED_TOKEN_CSS_VARS.chart2]: modeTokens.chart2,
|
|
2514
|
+
[RESOLVED_TOKEN_CSS_VARS.chart3]: modeTokens.chart3,
|
|
2515
|
+
[RESOLVED_TOKEN_CSS_VARS.chart4]: modeTokens.chart4,
|
|
2516
|
+
[RESOLVED_TOKEN_CSS_VARS.chart5]: modeTokens.chart5,
|
|
2517
|
+
[RESOLVED_TOKEN_CSS_VARS.chart6]: modeTokens.chart6,
|
|
2518
|
+
[RESOLVED_TOKEN_CSS_VARS.radius]: tokens.radius,
|
|
2519
|
+
[RESOLVED_TOKEN_CSS_VARS.fontSans]: tokens.fontSans,
|
|
2520
|
+
[RESOLVED_TOKEN_CSS_VARS.fontDisplay]: tokens.fontDisplay,
|
|
2521
|
+
[RESOLVED_TOKEN_CSS_VARS.fontMono]: tokens.fontMono
|
|
2522
|
+
};
|
|
2523
|
+
}
|
|
1735
2524
|
|
|
1736
2525
|
// src/paths.ts
|
|
1737
2526
|
import { dirname, isAbsolute, relative, resolve, sep } from "path";
|
|
@@ -2107,10 +2896,12 @@ function planFontInstall(headingFont, bodyFont) {
|
|
|
2107
2896
|
seenPackages.add(meta.packageName);
|
|
2108
2897
|
packages.push(meta.packageName);
|
|
2109
2898
|
}
|
|
2110
|
-
const
|
|
2111
|
-
|
|
2112
|
-
seenImports.
|
|
2113
|
-
|
|
2899
|
+
for (const specifier of curatedFontCssImportSpecifiers(meta)) {
|
|
2900
|
+
const line = `@import "${specifier}";`;
|
|
2901
|
+
if (!seenImports.has(line)) {
|
|
2902
|
+
seenImports.add(line);
|
|
2903
|
+
importLines.push(line);
|
|
2904
|
+
}
|
|
2114
2905
|
}
|
|
2115
2906
|
};
|
|
2116
2907
|
if (headingFont !== "system") {
|
|
@@ -2702,13 +3493,13 @@ function missingDependencies(projectRoot, dependencies) {
|
|
|
2702
3493
|
function readInstalledPackageNames(projectRoot) {
|
|
2703
3494
|
const packageJsonPath = join4(projectRoot, "package.json");
|
|
2704
3495
|
if (!existsSync2(packageJsonPath)) return void 0;
|
|
2705
|
-
const
|
|
3496
|
+
const packageJson2 = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
2706
3497
|
return new Set(
|
|
2707
3498
|
Object.keys({
|
|
2708
|
-
...
|
|
2709
|
-
...
|
|
2710
|
-
...
|
|
2711
|
-
...
|
|
3499
|
+
...packageJson2.dependencies,
|
|
3500
|
+
...packageJson2.devDependencies,
|
|
3501
|
+
...packageJson2.peerDependencies,
|
|
3502
|
+
...packageJson2.optionalDependencies
|
|
2712
3503
|
})
|
|
2713
3504
|
);
|
|
2714
3505
|
}
|
|
@@ -2851,6 +3642,109 @@ function toCliPresetError(error) {
|
|
|
2851
3642
|
return new CliError(`Invalid preset: ${message}`);
|
|
2852
3643
|
}
|
|
2853
3644
|
|
|
3645
|
+
// src/preset-inspect.ts
|
|
3646
|
+
function createPresetInspectSummary(input) {
|
|
3647
|
+
const tokens = resolveTokensForStyle(input.style);
|
|
3648
|
+
const fontPlan = fontPlanForStyle(input.style);
|
|
3649
|
+
return {
|
|
3650
|
+
presetCode: input.presetCode,
|
|
3651
|
+
kind: isCanonicalStyleShape(input.style) ? "canonical" : "legacy",
|
|
3652
|
+
style: input.style,
|
|
3653
|
+
fontPackages: fontPlan.packages,
|
|
3654
|
+
fontImports: fontPlan.importLines,
|
|
3655
|
+
tokens: {
|
|
3656
|
+
radius: tokens.radius,
|
|
3657
|
+
fonts: {
|
|
3658
|
+
sans: tokens.fontSans,
|
|
3659
|
+
display: tokens.fontDisplay,
|
|
3660
|
+
mono: tokens.fontMono
|
|
3661
|
+
},
|
|
3662
|
+
light: summarizeMode(tokens, "light"),
|
|
3663
|
+
dark: summarizeMode(tokens, "dark")
|
|
3664
|
+
}
|
|
3665
|
+
};
|
|
3666
|
+
}
|
|
3667
|
+
function formatPresetInspectSummary(summary) {
|
|
3668
|
+
return [
|
|
3669
|
+
panel("Preset", [
|
|
3670
|
+
`Code: ${summary.presetCode}`,
|
|
3671
|
+
`Shape: ${summary.kind}`,
|
|
3672
|
+
`Icon library: ${summary.style.iconLibrary}`,
|
|
3673
|
+
`Radius: ${summary.style.radius} (${summary.tokens.radius})`
|
|
3674
|
+
]),
|
|
3675
|
+
formatStylePanel(summary),
|
|
3676
|
+
formatFontPanel(summary),
|
|
3677
|
+
formatTokenPanel(summary)
|
|
3678
|
+
].join("\n");
|
|
3679
|
+
}
|
|
3680
|
+
function fontPlanForStyle(style) {
|
|
3681
|
+
if (!isCanonicalStyleShape(style)) {
|
|
3682
|
+
return { packages: [], importLines: [], block: null };
|
|
3683
|
+
}
|
|
3684
|
+
return planFontInstall(style.headingFont, style.bodyFont);
|
|
3685
|
+
}
|
|
3686
|
+
function summarizeMode(tokens, mode) {
|
|
3687
|
+
const cssVars = resolvedTokensToCssVars(tokens, mode);
|
|
3688
|
+
return {
|
|
3689
|
+
controlSolid: cssVars["--primitive-control-solid"] ?? tokens[mode].controlSolid,
|
|
3690
|
+
ring: cssVars["--primitive-ring"] ?? tokens[mode].ring,
|
|
3691
|
+
surfaceSelected: cssVars["--primitive-surface-selected"] ?? tokens[mode].surfaceSelected,
|
|
3692
|
+
chart: [
|
|
3693
|
+
cssVars["--primitive-chart-1"] ?? tokens[mode].chart1,
|
|
3694
|
+
cssVars["--primitive-chart-2"] ?? tokens[mode].chart2,
|
|
3695
|
+
cssVars["--primitive-chart-3"] ?? tokens[mode].chart3,
|
|
3696
|
+
cssVars["--primitive-chart-4"] ?? tokens[mode].chart4,
|
|
3697
|
+
cssVars["--primitive-chart-5"] ?? tokens[mode].chart5,
|
|
3698
|
+
cssVars["--primitive-chart-6"] ?? tokens[mode].chart6
|
|
3699
|
+
]
|
|
3700
|
+
};
|
|
3701
|
+
}
|
|
3702
|
+
function formatStylePanel(summary) {
|
|
3703
|
+
if (isCanonicalStyleShape(summary.style)) {
|
|
3704
|
+
return panel("Style", [
|
|
3705
|
+
`Base color: ${summary.style.baseColor}`,
|
|
3706
|
+
`Theme color: ${summary.style.themeColor}`,
|
|
3707
|
+
`Chart palette: ${summary.style.chartPalette}`,
|
|
3708
|
+
`Heading font: ${summary.style.headingFont}`,
|
|
3709
|
+
`Body font: ${summary.style.bodyFont}`
|
|
3710
|
+
]);
|
|
3711
|
+
}
|
|
3712
|
+
return panel("Style", [
|
|
3713
|
+
"Legacy payload",
|
|
3714
|
+
`Font sans: ${summary.style.fonts.sans}`,
|
|
3715
|
+
`Font display: ${summary.style.fonts.display}`,
|
|
3716
|
+
`Font mono: ${summary.style.fonts.mono}`
|
|
3717
|
+
]);
|
|
3718
|
+
}
|
|
3719
|
+
function formatFontPanel(summary) {
|
|
3720
|
+
const rows = [
|
|
3721
|
+
`--primitive-font-sans: ${summary.tokens.fonts.sans}`,
|
|
3722
|
+
`--primitive-font-display: ${summary.tokens.fonts.display}`,
|
|
3723
|
+
`--primitive-font-mono: ${summary.tokens.fonts.mono}`
|
|
3724
|
+
];
|
|
3725
|
+
const install = summary.fontPackages.length ? [
|
|
3726
|
+
"",
|
|
3727
|
+
action(`Install packages: ${summary.fontPackages.join(" ")}`),
|
|
3728
|
+
action(`CSS imports: ${summary.fontImports.join(" ")}`)
|
|
3729
|
+
].join("\n") : ["", action("No Fontsource packages required.")].join("\n");
|
|
3730
|
+
return `${panel("Fonts", rows)}${install}`;
|
|
3731
|
+
}
|
|
3732
|
+
function formatTokenPanel(summary) {
|
|
3733
|
+
return panel("Resolved primitive tokens", [
|
|
3734
|
+
"Light",
|
|
3735
|
+
` control: ${summary.tokens.light.controlSolid}`,
|
|
3736
|
+
` ring: ${summary.tokens.light.ring}`,
|
|
3737
|
+
` selected: ${summary.tokens.light.surfaceSelected}`,
|
|
3738
|
+
` chart: ${summary.tokens.light.chart.join(", ")}`,
|
|
3739
|
+
"",
|
|
3740
|
+
"Dark",
|
|
3741
|
+
` control: ${summary.tokens.dark.controlSolid}`,
|
|
3742
|
+
` ring: ${summary.tokens.dark.ring}`,
|
|
3743
|
+
` selected: ${summary.tokens.dark.surfaceSelected}`,
|
|
3744
|
+
` chart: ${summary.tokens.dark.chart.join(", ")}`
|
|
3745
|
+
]);
|
|
3746
|
+
}
|
|
3747
|
+
|
|
2854
3748
|
// src/preset-init-writes.ts
|
|
2855
3749
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
2856
3750
|
import { dirname as dirname4 } from "path";
|
|
@@ -2878,6 +3772,351 @@ async function commitPresetInitWrites(input) {
|
|
|
2878
3772
|
}
|
|
2879
3773
|
}
|
|
2880
3774
|
|
|
3775
|
+
// src/project-templates.ts
|
|
3776
|
+
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
3777
|
+
import { dirname as dirname5, join as join5 } from "path";
|
|
3778
|
+
var PROJECT_TEMPLATE_IDS = ["next", "vite", "astro", "react-router"];
|
|
3779
|
+
function parseProjectTemplate(value) {
|
|
3780
|
+
if (!value) return void 0;
|
|
3781
|
+
const normalized = value.toLowerCase();
|
|
3782
|
+
if (normalized === "nextjs" || normalized === "next.js") return "next";
|
|
3783
|
+
if (normalized === "reactrouter" || normalized === "react-router") return "react-router";
|
|
3784
|
+
if (isProjectTemplateId(normalized)) return normalized;
|
|
3785
|
+
throw new CliError(
|
|
3786
|
+
`Unsupported template "${value}". Use one of: ${PROJECT_TEMPLATE_IDS.join(", ")}.`
|
|
3787
|
+
);
|
|
3788
|
+
}
|
|
3789
|
+
function getProjectTemplateDefinition(id) {
|
|
3790
|
+
return templateDefinitions[id];
|
|
3791
|
+
}
|
|
3792
|
+
function applyTemplateToConfig(config, template) {
|
|
3793
|
+
return {
|
|
3794
|
+
...config,
|
|
3795
|
+
tailwind: {
|
|
3796
|
+
...config.tailwind,
|
|
3797
|
+
css: template.cssPath
|
|
3798
|
+
}
|
|
3799
|
+
};
|
|
3800
|
+
}
|
|
3801
|
+
async function scaffoldProjectTemplate(projectRoot, template, options) {
|
|
3802
|
+
const planned = template.files.map((file) => file.path);
|
|
3803
|
+
if (!options.force) {
|
|
3804
|
+
const conflicts = [];
|
|
3805
|
+
for (const file of template.files) {
|
|
3806
|
+
if (await fileExists(join5(projectRoot, file.path))) {
|
|
3807
|
+
conflicts.push(file.path);
|
|
3808
|
+
}
|
|
3809
|
+
}
|
|
3810
|
+
if (conflicts.length > 0) {
|
|
3811
|
+
throw new CliError(
|
|
3812
|
+
`Template "${template.id}" would overwrite existing files: ${conflicts.join(", ")}. Use --force to overwrite.`
|
|
3813
|
+
);
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
if (options.dryRun) return planned;
|
|
3817
|
+
for (const file of template.files) {
|
|
3818
|
+
await writeTemplateFile(projectRoot, file);
|
|
3819
|
+
}
|
|
3820
|
+
return planned;
|
|
3821
|
+
}
|
|
3822
|
+
async function writeTemplateFile(projectRoot, file) {
|
|
3823
|
+
const absolute = join5(projectRoot, file.path);
|
|
3824
|
+
await mkdir4(dirname5(absolute), { recursive: true });
|
|
3825
|
+
if (file.path === "package.json" && await fileExists(absolute)) {
|
|
3826
|
+
const existing = JSON.parse(await readFile4(absolute, "utf8"));
|
|
3827
|
+
const next = JSON.parse(file.content);
|
|
3828
|
+
await writeFile4(
|
|
3829
|
+
absolute,
|
|
3830
|
+
`${JSON.stringify(mergePackageJson(existing, next), null, 2)}
|
|
3831
|
+
`,
|
|
3832
|
+
"utf8"
|
|
3833
|
+
);
|
|
3834
|
+
return;
|
|
3835
|
+
}
|
|
3836
|
+
await writeFile4(absolute, file.content, "utf8");
|
|
3837
|
+
}
|
|
3838
|
+
function mergePackageJson(existing, next) {
|
|
3839
|
+
return {
|
|
3840
|
+
...existing,
|
|
3841
|
+
...next,
|
|
3842
|
+
scripts: {
|
|
3843
|
+
...isRecord(existing.scripts) ? existing.scripts : {},
|
|
3844
|
+
...isRecord(next.scripts) ? next.scripts : {}
|
|
3845
|
+
},
|
|
3846
|
+
dependencies: {
|
|
3847
|
+
...isRecord(existing.dependencies) ? existing.dependencies : {},
|
|
3848
|
+
...isRecord(next.dependencies) ? next.dependencies : {}
|
|
3849
|
+
},
|
|
3850
|
+
devDependencies: {
|
|
3851
|
+
...isRecord(existing.devDependencies) ? existing.devDependencies : {},
|
|
3852
|
+
...isRecord(next.devDependencies) ? next.devDependencies : {}
|
|
3853
|
+
}
|
|
3854
|
+
};
|
|
3855
|
+
}
|
|
3856
|
+
function isRecord(value) {
|
|
3857
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3858
|
+
}
|
|
3859
|
+
function isProjectTemplateId(value) {
|
|
3860
|
+
return PROJECT_TEMPLATE_IDS.includes(value);
|
|
3861
|
+
}
|
|
3862
|
+
function packageJson(name, input) {
|
|
3863
|
+
return `${JSON.stringify({
|
|
3864
|
+
name,
|
|
3865
|
+
private: true,
|
|
3866
|
+
version: "0.1.0",
|
|
3867
|
+
type: "module",
|
|
3868
|
+
scripts: input.scripts,
|
|
3869
|
+
dependencies: input.dependencies,
|
|
3870
|
+
devDependencies: input.devDependencies ?? {}
|
|
3871
|
+
}, null, 2)}
|
|
3872
|
+
`;
|
|
3873
|
+
}
|
|
3874
|
+
var templateDefinitions = {
|
|
3875
|
+
next: {
|
|
3876
|
+
id: "next",
|
|
3877
|
+
label: "Next.js",
|
|
3878
|
+
cssPath: "src/app/globals.css",
|
|
3879
|
+
files: [
|
|
3880
|
+
{
|
|
3881
|
+
path: "package.json",
|
|
3882
|
+
content: packageJson("wensity-next-app", {
|
|
3883
|
+
scripts: {
|
|
3884
|
+
dev: "next dev",
|
|
3885
|
+
build: "next build",
|
|
3886
|
+
start: "next start"
|
|
3887
|
+
},
|
|
3888
|
+
dependencies: {
|
|
3889
|
+
"next": "^16.2.4",
|
|
3890
|
+
"react": "^19.2.4",
|
|
3891
|
+
"react-dom": "^19.2.4"
|
|
3892
|
+
},
|
|
3893
|
+
devDependencies: {
|
|
3894
|
+
"@types/node": "^22.10.2",
|
|
3895
|
+
"@types/react": "^19.0.0",
|
|
3896
|
+
"@types/react-dom": "^19.0.0",
|
|
3897
|
+
"tailwindcss": "^4.0.0",
|
|
3898
|
+
"typescript": "^5.7.2"
|
|
3899
|
+
}
|
|
3900
|
+
})
|
|
3901
|
+
},
|
|
3902
|
+
{ path: "src/app/globals.css", content: '@import "tailwindcss";\n' },
|
|
3903
|
+
{
|
|
3904
|
+
path: "src/app/layout.tsx",
|
|
3905
|
+
content: `import type { ReactNode } from "react";
|
|
3906
|
+
import "./globals.css";
|
|
3907
|
+
|
|
3908
|
+
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
3909
|
+
return (
|
|
3910
|
+
<html lang="en">
|
|
3911
|
+
<body>{children}</body>
|
|
3912
|
+
</html>
|
|
3913
|
+
);
|
|
3914
|
+
}
|
|
3915
|
+
`
|
|
3916
|
+
},
|
|
3917
|
+
{
|
|
3918
|
+
path: "src/app/page.tsx",
|
|
3919
|
+
content: `export default function Page() {
|
|
3920
|
+
return <main className="min-h-screen bg-background text-foreground" />;
|
|
3921
|
+
}
|
|
3922
|
+
`
|
|
3923
|
+
},
|
|
3924
|
+
{
|
|
3925
|
+
path: "tsconfig.json",
|
|
3926
|
+
content: `${JSON.stringify({
|
|
3927
|
+
compilerOptions: {
|
|
3928
|
+
target: "ES2017",
|
|
3929
|
+
lib: ["dom", "dom.iterable", "esnext"],
|
|
3930
|
+
allowJs: true,
|
|
3931
|
+
skipLibCheck: true,
|
|
3932
|
+
strict: true,
|
|
3933
|
+
noEmit: true,
|
|
3934
|
+
esModuleInterop: true,
|
|
3935
|
+
module: "esnext",
|
|
3936
|
+
moduleResolution: "bundler",
|
|
3937
|
+
resolveJsonModule: true,
|
|
3938
|
+
isolatedModules: true,
|
|
3939
|
+
jsx: "preserve",
|
|
3940
|
+
incremental: true,
|
|
3941
|
+
paths: { "@/*": ["./src/*"] }
|
|
3942
|
+
},
|
|
3943
|
+
include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
3944
|
+
exclude: ["node_modules"]
|
|
3945
|
+
}, null, 2)}
|
|
3946
|
+
`
|
|
3947
|
+
}
|
|
3948
|
+
]
|
|
3949
|
+
},
|
|
3950
|
+
vite: {
|
|
3951
|
+
id: "vite",
|
|
3952
|
+
label: "Vite",
|
|
3953
|
+
cssPath: "src/index.css",
|
|
3954
|
+
files: [
|
|
3955
|
+
{
|
|
3956
|
+
path: "package.json",
|
|
3957
|
+
content: packageJson("wensity-vite-app", {
|
|
3958
|
+
scripts: {
|
|
3959
|
+
dev: "vite",
|
|
3960
|
+
build: "vite build",
|
|
3961
|
+
preview: "vite preview"
|
|
3962
|
+
},
|
|
3963
|
+
dependencies: {
|
|
3964
|
+
"vite": "^7.3.0",
|
|
3965
|
+
"react": "^19.2.4",
|
|
3966
|
+
"react-dom": "^19.2.4"
|
|
3967
|
+
},
|
|
3968
|
+
devDependencies: {
|
|
3969
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
3970
|
+
"@types/react": "^19.0.0",
|
|
3971
|
+
"@types/react-dom": "^19.0.0",
|
|
3972
|
+
"tailwindcss": "^4.0.0",
|
|
3973
|
+
"typescript": "^5.7.2"
|
|
3974
|
+
}
|
|
3975
|
+
})
|
|
3976
|
+
},
|
|
3977
|
+
{ path: "index.html", content: '<div id="root"></div><script type="module" src="/src/main.tsx"></script>\n' },
|
|
3978
|
+
{ path: "src/index.css", content: '@import "tailwindcss";\n' },
|
|
3979
|
+
{
|
|
3980
|
+
path: "src/main.tsx",
|
|
3981
|
+
content: `import { createRoot } from "react-dom/client";
|
|
3982
|
+
import "./index.css";
|
|
3983
|
+
|
|
3984
|
+
createRoot(document.getElementById("root")!).render(
|
|
3985
|
+
<main className="min-h-screen bg-background text-foreground" />,
|
|
3986
|
+
);
|
|
3987
|
+
`
|
|
3988
|
+
},
|
|
3989
|
+
{
|
|
3990
|
+
path: "vite.config.ts",
|
|
3991
|
+
content: `import { defineConfig } from "vite";
|
|
3992
|
+
import react from "@vitejs/plugin-react";
|
|
3993
|
+
|
|
3994
|
+
export default defineConfig({
|
|
3995
|
+
plugins: [react()],
|
|
3996
|
+
resolve: {
|
|
3997
|
+
alias: {
|
|
3998
|
+
"@": new URL("./src", import.meta.url).pathname,
|
|
3999
|
+
},
|
|
4000
|
+
},
|
|
4001
|
+
});
|
|
4002
|
+
`
|
|
4003
|
+
}
|
|
4004
|
+
]
|
|
4005
|
+
},
|
|
4006
|
+
astro: {
|
|
4007
|
+
id: "astro",
|
|
4008
|
+
label: "Astro",
|
|
4009
|
+
cssPath: "src/styles/global.css",
|
|
4010
|
+
files: [
|
|
4011
|
+
{
|
|
4012
|
+
path: "package.json",
|
|
4013
|
+
content: packageJson("wensity-astro-app", {
|
|
4014
|
+
scripts: {
|
|
4015
|
+
dev: "astro dev",
|
|
4016
|
+
build: "astro build",
|
|
4017
|
+
preview: "astro preview"
|
|
4018
|
+
},
|
|
4019
|
+
dependencies: {
|
|
4020
|
+
"@astrojs/react": "^4.4.0",
|
|
4021
|
+
"astro": "^5.16.0",
|
|
4022
|
+
"react": "^19.2.4",
|
|
4023
|
+
"react-dom": "^19.2.4"
|
|
4024
|
+
},
|
|
4025
|
+
devDependencies: {
|
|
4026
|
+
"tailwindcss": "^4.0.0",
|
|
4027
|
+
"typescript": "^5.7.2"
|
|
4028
|
+
}
|
|
4029
|
+
})
|
|
4030
|
+
},
|
|
4031
|
+
{ path: "src/styles/global.css", content: '@import "tailwindcss";\n' },
|
|
4032
|
+
{
|
|
4033
|
+
path: "astro.config.mjs",
|
|
4034
|
+
content: `import { defineConfig } from "astro/config";
|
|
4035
|
+
import react from "@astrojs/react";
|
|
4036
|
+
|
|
4037
|
+
export default defineConfig({
|
|
4038
|
+
integrations: [react()],
|
|
4039
|
+
});
|
|
4040
|
+
`
|
|
4041
|
+
},
|
|
4042
|
+
{
|
|
4043
|
+
path: "src/pages/index.astro",
|
|
4044
|
+
content: `---
|
|
4045
|
+
import "../styles/global.css";
|
|
4046
|
+
---
|
|
4047
|
+
|
|
4048
|
+
<main class="min-h-screen bg-background text-foreground"></main>
|
|
4049
|
+
`
|
|
4050
|
+
}
|
|
4051
|
+
]
|
|
4052
|
+
},
|
|
4053
|
+
"react-router": {
|
|
4054
|
+
id: "react-router",
|
|
4055
|
+
label: "React Router",
|
|
4056
|
+
cssPath: "src/app/globals.css",
|
|
4057
|
+
files: [
|
|
4058
|
+
{
|
|
4059
|
+
path: "package.json",
|
|
4060
|
+
content: packageJson("wensity-react-router-app", {
|
|
4061
|
+
scripts: {
|
|
4062
|
+
dev: "vite",
|
|
4063
|
+
build: "vite build",
|
|
4064
|
+
preview: "vite preview"
|
|
4065
|
+
},
|
|
4066
|
+
dependencies: {
|
|
4067
|
+
"vite": "^7.3.0",
|
|
4068
|
+
"react": "^19.2.4",
|
|
4069
|
+
"react-dom": "^19.2.4",
|
|
4070
|
+
"react-router": "^7.12.0"
|
|
4071
|
+
},
|
|
4072
|
+
devDependencies: {
|
|
4073
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
4074
|
+
"@types/react": "^19.0.0",
|
|
4075
|
+
"@types/react-dom": "^19.0.0",
|
|
4076
|
+
"tailwindcss": "^4.0.0",
|
|
4077
|
+
"typescript": "^5.7.2"
|
|
4078
|
+
}
|
|
4079
|
+
})
|
|
4080
|
+
},
|
|
4081
|
+
{ path: "index.html", content: '<div id="root"></div><script type="module" src="/src/main.tsx"></script>\n' },
|
|
4082
|
+
{ path: "src/app/globals.css", content: '@import "tailwindcss";\n' },
|
|
4083
|
+
{
|
|
4084
|
+
path: "src/main.tsx",
|
|
4085
|
+
content: `import { createRoot } from "react-dom/client";
|
|
4086
|
+
import { BrowserRouter, Route, Routes } from "react-router";
|
|
4087
|
+
import "./app/globals.css";
|
|
4088
|
+
|
|
4089
|
+
createRoot(document.getElementById("root")!).render(
|
|
4090
|
+
<BrowserRouter>
|
|
4091
|
+
<Routes>
|
|
4092
|
+
<Route path="/" element={<main className="min-h-screen bg-background text-foreground" />} />
|
|
4093
|
+
</Routes>
|
|
4094
|
+
</BrowserRouter>,
|
|
4095
|
+
);
|
|
4096
|
+
`
|
|
4097
|
+
},
|
|
4098
|
+
{
|
|
4099
|
+
path: "vite.config.ts",
|
|
4100
|
+
content: `import { defineConfig } from "vite";
|
|
4101
|
+
import react from "@vitejs/plugin-react";
|
|
4102
|
+
|
|
4103
|
+
export default defineConfig({
|
|
4104
|
+
plugins: [react()],
|
|
4105
|
+
resolve: {
|
|
4106
|
+
alias: {
|
|
4107
|
+
"@": new URL("./src", import.meta.url).pathname,
|
|
4108
|
+
},
|
|
4109
|
+
},
|
|
4110
|
+
});
|
|
4111
|
+
`
|
|
4112
|
+
}
|
|
4113
|
+
]
|
|
4114
|
+
}
|
|
4115
|
+
};
|
|
4116
|
+
function formatTemplateFiles(files) {
|
|
4117
|
+
return files.map(toPosixPath);
|
|
4118
|
+
}
|
|
4119
|
+
|
|
2881
4120
|
// src/style-css.ts
|
|
2882
4121
|
var ROOT_SELECTOR = ":root";
|
|
2883
4122
|
var DARK_SELECTOR = ".dark";
|
|
@@ -2963,8 +4202,8 @@ function escapeRegExp(value) {
|
|
|
2963
4202
|
}
|
|
2964
4203
|
|
|
2965
4204
|
// src/component-install.ts
|
|
2966
|
-
import { mkdir as
|
|
2967
|
-
import { dirname as
|
|
4205
|
+
import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
4206
|
+
import { dirname as dirname6, join as join6, relative as relative3 } from "path";
|
|
2968
4207
|
|
|
2969
4208
|
// src/templates.ts
|
|
2970
4209
|
function cnUtilityTemplate() {
|
|
@@ -3172,7 +4411,7 @@ async function prepareInstall(projectRoot, config, payload, options = {}) {
|
|
|
3172
4411
|
}
|
|
3173
4412
|
}
|
|
3174
4413
|
if (!hasGraphHelperFiles && helperNeeds.primitives) {
|
|
3175
|
-
const primitivesPath = toPosixPath(
|
|
4414
|
+
const primitivesPath = toPosixPath(join6(config.components, "primitives.tsx"));
|
|
3176
4415
|
if (!await fileExists(resolveInside(projectRoot, primitivesPath))) {
|
|
3177
4416
|
const primitives = primitivesTemplate(config.aliases.utils);
|
|
3178
4417
|
files.push({
|
|
@@ -3213,7 +4452,7 @@ async function planPrimitiveCssFile(projectRoot, config, payload) {
|
|
|
3213
4452
|
const cssRelative = config.tailwind?.css;
|
|
3214
4453
|
if (!cssRelative) return void 0;
|
|
3215
4454
|
const absolutePath = resolveInside(projectRoot, cssRelative);
|
|
3216
|
-
const existing = await fileExists(absolutePath) ? await
|
|
4455
|
+
const existing = await fileExists(absolutePath) ? await readFile5(absolutePath, "utf8") : "";
|
|
3217
4456
|
const withTokens = upsertPrimitiveCssBlock(existing, primitiveCss);
|
|
3218
4457
|
const fonts = curatedFontsFromStyle(style);
|
|
3219
4458
|
const fontPlan = planFontInstall(fonts.headingFont, fonts.bodyFont);
|
|
@@ -3262,8 +4501,8 @@ ${conflicts.map((path) => ` - ${path}`).join("\n")}`);
|
|
|
3262
4501
|
}
|
|
3263
4502
|
async function writePlannedFiles(files) {
|
|
3264
4503
|
for (const file of files) {
|
|
3265
|
-
await
|
|
3266
|
-
await
|
|
4504
|
+
await mkdir5(dirname6(file.absolutePath), { recursive: true });
|
|
4505
|
+
await writeFile5(file.absolutePath, file.content, "utf8");
|
|
3267
4506
|
}
|
|
3268
4507
|
}
|
|
3269
4508
|
function summarizeFiles(projectRoot, files) {
|
|
@@ -3288,13 +4527,13 @@ function getPayloadFileKind(payloadFile) {
|
|
|
3288
4527
|
}
|
|
3289
4528
|
function getPayloadOutputPath(payloadFile, fallbackFileName, config) {
|
|
3290
4529
|
if (isUtilsHelperFile(payloadFile)) return withSourceExtension(config.utils, "ts");
|
|
3291
|
-
if (isOverlayHelperFile(payloadFile)) return toPosixPath(
|
|
3292
|
-
if (isPrimitivesHelperFile(payloadFile)) return toPosixPath(
|
|
4530
|
+
if (isOverlayHelperFile(payloadFile)) return toPosixPath(join6(config.components, "overlay.tsx"));
|
|
4531
|
+
if (isPrimitivesHelperFile(payloadFile)) return toPosixPath(join6(config.components, "primitives.tsx"));
|
|
3293
4532
|
if (payloadFile.kind === "helper") {
|
|
3294
4533
|
throw new CliError(`Unsupported registry helper file path: ${payloadFile.path}`);
|
|
3295
4534
|
}
|
|
3296
4535
|
const safePayloadPath = sanitizePayloadPath(payloadFile.path, fallbackFileName);
|
|
3297
|
-
return toPosixPath(
|
|
4536
|
+
return toPosixPath(join6(config.components, safePayloadPath));
|
|
3298
4537
|
}
|
|
3299
4538
|
function isGraphHelperFile(payloadFile) {
|
|
3300
4539
|
return isUtilsHelperFile(payloadFile) || isOverlayHelperFile(payloadFile) || isPrimitivesHelperFile(payloadFile);
|
|
@@ -3391,7 +4630,7 @@ function normalizePackageName(specifier) {
|
|
|
3391
4630
|
function withSourceExtension(path, extension) {
|
|
3392
4631
|
const directory = parentDirectory(path);
|
|
3393
4632
|
const fileName = extensionlessPath(path.split("/").at(-1) ?? path);
|
|
3394
|
-
return toPosixPath(
|
|
4633
|
+
return toPosixPath(join6(directory === "." ? "" : directory, `${fileName}.${extension}`));
|
|
3395
4634
|
}
|
|
3396
4635
|
|
|
3397
4636
|
// src/commands.ts
|
|
@@ -3410,6 +4649,12 @@ async function run(context) {
|
|
|
3410
4649
|
case "init":
|
|
3411
4650
|
await initCommand(context, parsed);
|
|
3412
4651
|
return;
|
|
4652
|
+
case "apply":
|
|
4653
|
+
await applyCommand(context, parsed);
|
|
4654
|
+
return;
|
|
4655
|
+
case "preset":
|
|
4656
|
+
await presetCommand(context, parsed, positionals);
|
|
4657
|
+
return;
|
|
3413
4658
|
case "login":
|
|
3414
4659
|
await loginCommand(context, parsed);
|
|
3415
4660
|
return;
|
|
@@ -3437,6 +4682,35 @@ async function run(context) {
|
|
|
3437
4682
|
${HELP_TEXT.trimEnd()}`);
|
|
3438
4683
|
}
|
|
3439
4684
|
}
|
|
4685
|
+
async function presetCommand(_context, parsed, positionals) {
|
|
4686
|
+
const [subcommand, positionalCode, ...extra] = positionals;
|
|
4687
|
+
if (subcommand !== "inspect") {
|
|
4688
|
+
throw new CliError(
|
|
4689
|
+
`Unknown preset command: ${subcommand ?? ""}
|
|
4690
|
+
|
|
4691
|
+
Usage: wensity preset inspect <code> [--json]`
|
|
4692
|
+
);
|
|
4693
|
+
}
|
|
4694
|
+
if (extra.length > 0) {
|
|
4695
|
+
throw new CliError("Too many arguments.\n\nUsage: wensity preset inspect <code> [--json]");
|
|
4696
|
+
}
|
|
4697
|
+
const optionCode = getStringOption(parsed, "preset");
|
|
4698
|
+
const presetFile = getStringOption(parsed, "preset-file");
|
|
4699
|
+
if (positionalCode && optionCode) {
|
|
4700
|
+
throw new CliError("Use either a positional preset code or --preset <code>, not both.");
|
|
4701
|
+
}
|
|
4702
|
+
const { style, presetCode } = await resolvePresetStyle({
|
|
4703
|
+
presetCode: optionCode ?? positionalCode,
|
|
4704
|
+
presetFile
|
|
4705
|
+
});
|
|
4706
|
+
const summary = createPresetInspectSummary({ presetCode, style });
|
|
4707
|
+
if (hasFlag(parsed, "json")) {
|
|
4708
|
+
printJson(summary);
|
|
4709
|
+
return;
|
|
4710
|
+
}
|
|
4711
|
+
printTitle("Preset inspection");
|
|
4712
|
+
print(formatPresetInspectSummary(summary));
|
|
4713
|
+
}
|
|
3440
4714
|
async function initCommand(context, parsed) {
|
|
3441
4715
|
const dryRun = hasFlag(parsed, "dry-run");
|
|
3442
4716
|
const force = hasFlag(parsed, "force");
|
|
@@ -3444,6 +4718,8 @@ async function initCommand(context, parsed) {
|
|
|
3444
4718
|
const apiUrl = getStringOption(parsed, "api-url") ?? context.env.WENSITY_API_URL ?? DEFAULT_API_ORIGIN;
|
|
3445
4719
|
const presetCode = getStringOption(parsed, "preset");
|
|
3446
4720
|
const presetFile = getStringOption(parsed, "preset-file");
|
|
4721
|
+
const templateId = parseProjectTemplate(getStringOption(parsed, "template"));
|
|
4722
|
+
const template = templateId ? getProjectTemplateDefinition(templateId) : void 0;
|
|
3447
4723
|
const hasPreset = Boolean(presetCode || presetFile);
|
|
3448
4724
|
const dependencies = ["clsx", "tailwind-merge"];
|
|
3449
4725
|
if (hasPreset) {
|
|
@@ -3454,18 +4730,21 @@ async function initCommand(context, parsed) {
|
|
|
3454
4730
|
apiUrl,
|
|
3455
4731
|
presetCode,
|
|
3456
4732
|
presetFile,
|
|
3457
|
-
dependencies
|
|
4733
|
+
dependencies,
|
|
4734
|
+
template
|
|
3458
4735
|
});
|
|
3459
4736
|
return;
|
|
3460
4737
|
}
|
|
3461
|
-
const
|
|
3462
|
-
const
|
|
4738
|
+
const templateFiles = template ? await scaffoldProjectTemplate(context.cwd, template, { dryRun, force }) : [];
|
|
4739
|
+
const config = template ? applyTemplateToConfig(createDefaultConfig(context.cwd, apiUrl), template) : createDefaultConfig(context.cwd, apiUrl);
|
|
4740
|
+
const configPath = join7(context.cwd, CONFIG_FILE_NAME);
|
|
3463
4741
|
const utilityPath = resolveConfiguredFilePath(context.cwd, config.utils);
|
|
3464
4742
|
const utilityRelativePath = toPosixPath(config.utils.endsWith(".ts") ? config.utils : `${config.utils}.ts`);
|
|
3465
4743
|
if (dryRun) {
|
|
3466
4744
|
printTitle("Project initialization preview");
|
|
3467
4745
|
print(action("Would write:"));
|
|
3468
|
-
print(formatList([CONFIG_FILE_NAME, utilityRelativePath]));
|
|
4746
|
+
print(formatList([...formatTemplateFiles(templateFiles), CONFIG_FILE_NAME, utilityRelativePath]));
|
|
4747
|
+
if (template) print(action(`Template: ${template.label}`));
|
|
3469
4748
|
if (install) print(action(`Would install: ${dependencies.join(" ")}`));
|
|
3470
4749
|
return;
|
|
3471
4750
|
}
|
|
@@ -3493,13 +4772,17 @@ async function initWithPreset(context, options) {
|
|
|
3493
4772
|
presetCode: options.presetCode,
|
|
3494
4773
|
presetFile: options.presetFile
|
|
3495
4774
|
});
|
|
3496
|
-
const
|
|
3497
|
-
const fontPlan = planFontInstall(fonts.headingFont, fonts.bodyFont);
|
|
3498
|
-
const installDependencies = [...options.dependencies, ...fontPlan.packages];
|
|
3499
|
-
const configPath = join6(context.cwd, CONFIG_FILE_NAME);
|
|
4775
|
+
const configPath = join7(context.cwd, CONFIG_FILE_NAME);
|
|
3500
4776
|
const configExists = await fileExists(configPath);
|
|
4777
|
+
const templateFiles = options.template ? await scaffoldProjectTemplate(context.cwd, options.template, {
|
|
4778
|
+
dryRun: options.dryRun,
|
|
4779
|
+
force: options.force
|
|
4780
|
+
}) : [];
|
|
3501
4781
|
let config;
|
|
3502
4782
|
if (configExists && !options.force) {
|
|
4783
|
+
if (options.template) {
|
|
4784
|
+
throw new CliError(`${CONFIG_FILE_NAME} already exists. Omit --template for existing projects or use --force.`);
|
|
4785
|
+
}
|
|
3503
4786
|
const loaded = await loadConfig(context.cwd, { apiUrl: options.apiUrl });
|
|
3504
4787
|
config = {
|
|
3505
4788
|
...loaded.config,
|
|
@@ -3507,63 +4790,36 @@ async function initWithPreset(context, options) {
|
|
|
3507
4790
|
};
|
|
3508
4791
|
} else {
|
|
3509
4792
|
config = {
|
|
3510
|
-
...createDefaultConfig(context.cwd, options.apiUrl),
|
|
4793
|
+
...options.template ? applyTemplateToConfig(createDefaultConfig(context.cwd, options.apiUrl), options.template) : createDefaultConfig(context.cwd, options.apiUrl),
|
|
3511
4794
|
style
|
|
3512
4795
|
};
|
|
3513
4796
|
}
|
|
3514
4797
|
const utilityPath = resolveConfiguredFilePath(context.cwd, config.utils);
|
|
3515
4798
|
const utilityRelativePath = toPosixPath(config.utils.endsWith(".ts") ? config.utils : `${config.utils}.ts`);
|
|
3516
|
-
const
|
|
3517
|
-
|
|
3518
|
-
try {
|
|
3519
|
-
const payload = await withSpinner(
|
|
3520
|
-
`Fetching primitive tokens (${INIT_PRIMITIVE_CSS_SLUG})`,
|
|
3521
|
-
() => fetchComponentPayload({ slug: INIT_PRIMITIVE_CSS_SLUG, registry }),
|
|
3522
|
-
"Fetched primitive tokens"
|
|
3523
|
-
);
|
|
3524
|
-
if (typeof payload.primitiveCss !== "string" || !payload.primitiveCss.trim()) {
|
|
3525
|
-
throw new CliError(
|
|
3526
|
-
`Pinned slug "${INIT_PRIMITIVE_CSS_SLUG}" did not return primitiveCss. Cannot apply preset styles.`
|
|
3527
|
-
);
|
|
3528
|
-
}
|
|
3529
|
-
primitiveCss = applyStyleToPrimitiveCss(payload.primitiveCss, style).trim();
|
|
3530
|
-
} catch (error) {
|
|
3531
|
-
if (error instanceof CliError) throw error;
|
|
3532
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3533
|
-
throw new CliError(`Failed to fetch primitive CSS for preset init: ${message}`);
|
|
3534
|
-
}
|
|
3535
|
-
const cssRelative = config.tailwind?.css;
|
|
3536
|
-
if (!cssRelative) {
|
|
3537
|
-
throw new CliError("No Tailwind CSS path configured. Set tailwind.css in wensity.json.");
|
|
3538
|
-
}
|
|
3539
|
-
const cssAbsolute = resolveInside(context.cwd, cssRelative);
|
|
3540
|
-
const existingCss = await fileExists(cssAbsolute) ? await readFile5(cssAbsolute, "utf8") : "";
|
|
3541
|
-
const withTokens = upsertPrimitiveCssBlock(existingCss, primitiveCss);
|
|
3542
|
-
const nextCss = upsertFontImportBlock(withTokens, fontPlan.block);
|
|
3543
|
-
const cssChanged = nextCss !== existingCss;
|
|
3544
|
-
const installedPackages = readInstalledPackageNames(context.cwd);
|
|
3545
|
-
const unusedFontWarning = installedPackages ? warnUnusedFontPackageMessage(fonts.headingFont, fonts.bodyFont, installedPackages) : void 0;
|
|
4799
|
+
const prepared = await preparePresetStyleApplication(context.cwd, config, style, "preset init");
|
|
4800
|
+
const installDependencies = [...options.dependencies, ...prepared.fontPlan.packages];
|
|
3546
4801
|
if (options.dryRun) {
|
|
3547
4802
|
printTitle("Project initialization preview (preset)");
|
|
3548
4803
|
print(action("Would write:"));
|
|
3549
|
-
const planned = [CONFIG_FILE_NAME, utilityRelativePath];
|
|
3550
|
-
if (cssChanged) planned.push(toPosixPath(cssRelative));
|
|
4804
|
+
const planned = [...formatTemplateFiles(templateFiles), CONFIG_FILE_NAME, utilityRelativePath];
|
|
4805
|
+
if (prepared.cssChanged) planned.push(toPosixPath(prepared.cssRelative));
|
|
3551
4806
|
print(formatList(planned));
|
|
4807
|
+
if (options.template) print(action(`Template: ${options.template.label}`));
|
|
3552
4808
|
print(action(`Preset: ${presetCode.slice(0, 24)}\u2026`));
|
|
3553
4809
|
print(action(`Style: icon=${style.iconLibrary} radius=${style.radius}`));
|
|
3554
|
-
if (fontPlan.packages.length > 0) {
|
|
3555
|
-
print(action(`Fonts: ${fontPlan.packages.join(" ")}`));
|
|
4810
|
+
if (prepared.fontPlan.packages.length > 0) {
|
|
4811
|
+
print(action(`Fonts: ${prepared.fontPlan.packages.join(" ")}`));
|
|
3556
4812
|
}
|
|
3557
4813
|
if (options.install) print(action(`Would install: ${installDependencies.join(" ")}`));
|
|
3558
|
-
if (unusedFontWarning) warn(unusedFontWarning);
|
|
4814
|
+
if (prepared.unusedFontWarning) warn(prepared.unusedFontWarning);
|
|
3559
4815
|
return;
|
|
3560
4816
|
}
|
|
3561
4817
|
const shouldWriteUtility = options.force || !await fileExists(utilityPath);
|
|
3562
4818
|
await commitPresetInitWrites({
|
|
3563
|
-
cssAbsolute,
|
|
3564
|
-
existingCss,
|
|
3565
|
-
nextCss,
|
|
3566
|
-
cssChanged,
|
|
4819
|
+
cssAbsolute: prepared.cssAbsolute,
|
|
4820
|
+
existingCss: prepared.existingCss,
|
|
4821
|
+
nextCss: prepared.nextCss,
|
|
4822
|
+
cssChanged: prepared.cssChanged,
|
|
3567
4823
|
writeUtility: shouldWriteUtility,
|
|
3568
4824
|
utilityAbsolutePath: utilityPath,
|
|
3569
4825
|
utilityContent: cnUtilityTemplate(),
|
|
@@ -3580,26 +4836,150 @@ async function initWithPreset(context, options) {
|
|
|
3580
4836
|
}
|
|
3581
4837
|
printTitle("Project initialized");
|
|
3582
4838
|
const created = [
|
|
4839
|
+
...options.template ? [success(`template: ${options.template.label}`)] : [],
|
|
3583
4840
|
success(CONFIG_FILE_NAME),
|
|
3584
4841
|
success(utilityRelativePath),
|
|
3585
4842
|
success(`registry: ${options.apiUrl}`),
|
|
3586
4843
|
success(`preset applied (${style.iconLibrary}, radius=${style.radius})`)
|
|
3587
4844
|
];
|
|
3588
|
-
if (cssChanged) {
|
|
3589
|
-
created.push(success(`CSS tokens: ${toPosixPath(cssRelative)}`));
|
|
4845
|
+
if (prepared.cssChanged) {
|
|
4846
|
+
created.push(success(`CSS tokens: ${toPosixPath(prepared.cssRelative)}`));
|
|
3590
4847
|
} else {
|
|
3591
|
-
created.push(action(`CSS tokens unchanged: ${toPosixPath(cssRelative)}`));
|
|
4848
|
+
created.push(action(`CSS tokens unchanged: ${toPosixPath(prepared.cssRelative)}`));
|
|
3592
4849
|
}
|
|
3593
|
-
if (fontPlan.packages.length > 0) {
|
|
3594
|
-
created.push(success(`fonts: ${fontPlan.packages.join(", ")}`));
|
|
4850
|
+
if (prepared.fontPlan.packages.length > 0) {
|
|
4851
|
+
created.push(success(`fonts: ${prepared.fontPlan.packages.join(", ")}`));
|
|
3595
4852
|
}
|
|
3596
4853
|
print(panel("Created", created));
|
|
3597
|
-
if (unusedFontWarning) warn(unusedFontWarning);
|
|
4854
|
+
if (prepared.unusedFontWarning) warn(prepared.unusedFontWarning);
|
|
3598
4855
|
print(nextSteps([
|
|
3599
4856
|
"Browse available components: npx wensity list",
|
|
3600
4857
|
"Install a primitive: npx wensity add button"
|
|
3601
4858
|
]));
|
|
3602
4859
|
}
|
|
4860
|
+
async function applyCommand(context, parsed) {
|
|
4861
|
+
const dryRun = hasFlag(parsed, "dry-run");
|
|
4862
|
+
const install = !hasFlag(parsed, "no-install");
|
|
4863
|
+
const apiUrl = getStringOption(parsed, "api-url") ?? context.env.WENSITY_API_URL;
|
|
4864
|
+
const registryOverride = getStringOption(parsed, "registry");
|
|
4865
|
+
const presetCodeInput = getStringOption(parsed, "preset");
|
|
4866
|
+
const presetFile = getStringOption(parsed, "preset-file");
|
|
4867
|
+
if (!presetCodeInput && !presetFile) {
|
|
4868
|
+
throw new CliError("Missing preset. Pass --preset <code> or --preset-file <path>.");
|
|
4869
|
+
}
|
|
4870
|
+
const loaded = await loadConfig(context.cwd, { registry: registryOverride, apiUrl });
|
|
4871
|
+
if (!loaded.exists) {
|
|
4872
|
+
throw new CliError(`${CONFIG_FILE_NAME} not found. Run "wensity init" first, then "wensity apply --preset <code>".`);
|
|
4873
|
+
}
|
|
4874
|
+
const { style, presetCode } = await resolvePresetStyle({
|
|
4875
|
+
presetCode: presetCodeInput,
|
|
4876
|
+
presetFile
|
|
4877
|
+
});
|
|
4878
|
+
const prepared = await preparePresetStyleApplication(
|
|
4879
|
+
loaded.projectRoot,
|
|
4880
|
+
{
|
|
4881
|
+
...loaded.config,
|
|
4882
|
+
style
|
|
4883
|
+
},
|
|
4884
|
+
style,
|
|
4885
|
+
"preset apply"
|
|
4886
|
+
);
|
|
4887
|
+
const installDependencies = prepared.fontPlan.packages;
|
|
4888
|
+
if (dryRun) {
|
|
4889
|
+
printTitle("Preset apply preview");
|
|
4890
|
+
print(action("Would write:"));
|
|
4891
|
+
const planned = [CONFIG_FILE_NAME];
|
|
4892
|
+
if (prepared.cssChanged) planned.push(toPosixPath(prepared.cssRelative));
|
|
4893
|
+
print(formatList(planned));
|
|
4894
|
+
print(action(`Preset: ${presetCode.slice(0, 24)}\u2026`));
|
|
4895
|
+
print(action(`Style: icon=${style.iconLibrary} radius=${style.radius}`));
|
|
4896
|
+
if (prepared.fontPlan.packages.length > 0) {
|
|
4897
|
+
print(action(`Fonts: ${prepared.fontPlan.packages.join(" ")}`));
|
|
4898
|
+
}
|
|
4899
|
+
if (install && installDependencies.length > 0) {
|
|
4900
|
+
print(action(`Would install: ${installDependencies.join(" ")}`));
|
|
4901
|
+
}
|
|
4902
|
+
if (prepared.unusedFontWarning) warn(prepared.unusedFontWarning);
|
|
4903
|
+
return;
|
|
4904
|
+
}
|
|
4905
|
+
await commitPresetInitWrites({
|
|
4906
|
+
cssAbsolute: prepared.cssAbsolute,
|
|
4907
|
+
existingCss: prepared.existingCss,
|
|
4908
|
+
nextCss: prepared.nextCss,
|
|
4909
|
+
cssChanged: prepared.cssChanged,
|
|
4910
|
+
writeUtility: false,
|
|
4911
|
+
utilityAbsolutePath: resolveConfiguredFilePath(loaded.projectRoot, loaded.config.utils),
|
|
4912
|
+
utilityContent: cnUtilityTemplate(),
|
|
4913
|
+
commitConfig: async () => {
|
|
4914
|
+
await mergeStyleIntoConfigFile(loaded.configPath, style);
|
|
4915
|
+
}
|
|
4916
|
+
});
|
|
4917
|
+
if (install && installDependencies.length > 0) {
|
|
4918
|
+
runInstall(loaded.projectRoot, missingDependencies(loaded.projectRoot, installDependencies));
|
|
4919
|
+
}
|
|
4920
|
+
printTitle("Preset applied");
|
|
4921
|
+
const applied = [
|
|
4922
|
+
success(CONFIG_FILE_NAME),
|
|
4923
|
+
success(`preset applied (${style.iconLibrary}, radius=${style.radius})`)
|
|
4924
|
+
];
|
|
4925
|
+
if (prepared.cssChanged) {
|
|
4926
|
+
applied.push(success(`CSS tokens: ${toPosixPath(prepared.cssRelative)}`));
|
|
4927
|
+
} else {
|
|
4928
|
+
applied.push(action(`CSS tokens unchanged: ${toPosixPath(prepared.cssRelative)}`));
|
|
4929
|
+
}
|
|
4930
|
+
if (prepared.fontPlan.packages.length > 0) {
|
|
4931
|
+
applied.push(success(`fonts: ${prepared.fontPlan.packages.join(", ")}`));
|
|
4932
|
+
}
|
|
4933
|
+
print(panel("Updated", applied));
|
|
4934
|
+
if (prepared.unusedFontWarning) warn(prepared.unusedFontWarning);
|
|
4935
|
+
print(nextSteps([
|
|
4936
|
+
"Review your changed CSS tokens",
|
|
4937
|
+
"Run your app to verify the updated primitive theme"
|
|
4938
|
+
]));
|
|
4939
|
+
}
|
|
4940
|
+
async function preparePresetStyleApplication(projectRoot, config, style, operation) {
|
|
4941
|
+
const fonts = curatedFontsFromStyle(style);
|
|
4942
|
+
const fontPlan = planFontInstall(fonts.headingFont, fonts.bodyFont);
|
|
4943
|
+
const registry = config.registry;
|
|
4944
|
+
let primitiveCss;
|
|
4945
|
+
try {
|
|
4946
|
+
const payload = await withSpinner(
|
|
4947
|
+
`Fetching primitive tokens (${INIT_PRIMITIVE_CSS_SLUG})`,
|
|
4948
|
+
() => fetchComponentPayload({ slug: INIT_PRIMITIVE_CSS_SLUG, registry }),
|
|
4949
|
+
"Fetched primitive tokens"
|
|
4950
|
+
);
|
|
4951
|
+
if (typeof payload.primitiveCss !== "string" || !payload.primitiveCss.trim()) {
|
|
4952
|
+
throw new CliError(
|
|
4953
|
+
`Pinned slug "${INIT_PRIMITIVE_CSS_SLUG}" did not return primitiveCss. Cannot apply preset styles.`
|
|
4954
|
+
);
|
|
4955
|
+
}
|
|
4956
|
+
primitiveCss = applyStyleToPrimitiveCss(payload.primitiveCss, style).trim();
|
|
4957
|
+
} catch (error) {
|
|
4958
|
+
if (error instanceof CliError) throw error;
|
|
4959
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4960
|
+
throw new CliError(`Failed to fetch primitive CSS for ${operation}: ${message}`);
|
|
4961
|
+
}
|
|
4962
|
+
const cssRelative = config.tailwind?.css;
|
|
4963
|
+
if (!cssRelative) {
|
|
4964
|
+
throw new CliError("No Tailwind CSS path configured. Set tailwind.css in wensity.json.");
|
|
4965
|
+
}
|
|
4966
|
+
const cssAbsolute = resolveInside(projectRoot, cssRelative);
|
|
4967
|
+
const existingCss = await fileExists(cssAbsolute) ? await readFile6(cssAbsolute, "utf8") : "";
|
|
4968
|
+
const withTokens = upsertPrimitiveCssBlock(existingCss, primitiveCss);
|
|
4969
|
+
const nextCss = upsertFontImportBlock(withTokens, fontPlan.block);
|
|
4970
|
+
const cssChanged = nextCss !== existingCss;
|
|
4971
|
+
const installedPackages = readInstalledPackageNames(projectRoot);
|
|
4972
|
+
const unusedFontWarning = installedPackages ? warnUnusedFontPackageMessage(fonts.headingFont, fonts.bodyFont, installedPackages) : void 0;
|
|
4973
|
+
return {
|
|
4974
|
+
fontPlan,
|
|
4975
|
+
cssRelative,
|
|
4976
|
+
cssAbsolute,
|
|
4977
|
+
existingCss,
|
|
4978
|
+
nextCss,
|
|
4979
|
+
cssChanged,
|
|
4980
|
+
unusedFontWarning
|
|
4981
|
+
};
|
|
4982
|
+
}
|
|
3603
4983
|
async function loginCommand(context, parsed) {
|
|
3604
4984
|
const apiUrl = getStringOption(parsed, "api-url") ?? context.env.WENSITY_API_URL ?? DEFAULT_API_ORIGIN;
|
|
3605
4985
|
const apiBaseUrl = normalizeUrlOrigin(apiUrl);
|
|
@@ -3889,8 +5269,8 @@ function formatAccountPanel(whoami, savedPath) {
|
|
|
3889
5269
|
return panel(isPro ? "Wensity Pro" : "Wensity Free", lines);
|
|
3890
5270
|
}
|
|
3891
5271
|
async function writeTextFile(path, content) {
|
|
3892
|
-
await
|
|
3893
|
-
await
|
|
5272
|
+
await mkdir6(dirname7(path), { recursive: true });
|
|
5273
|
+
await writeFile6(path, content, "utf8");
|
|
3894
5274
|
}
|
|
3895
5275
|
|
|
3896
5276
|
// src/index.ts
|