@caelo-cms/shared 0.10.22 → 0.10.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/dist/ai-tools.d.ts +289 -273
  2. package/dist/ai-tools.d.ts.map +1 -1
  3. package/dist/ai-tools.js +342 -323
  4. package/dist/ai-tools.js.map +1 -1
  5. package/dist/auth-forms.d.ts.map +1 -1
  6. package/dist/auth-forms.js +4 -1
  7. package/dist/auth-forms.js.map +1 -1
  8. package/dist/base-css.d.ts +35 -0
  9. package/dist/base-css.d.ts.map +1 -0
  10. package/dist/base-css.js +40 -0
  11. package/dist/base-css.js.map +1 -0
  12. package/dist/build-page.d.ts +330 -0
  13. package/dist/build-page.d.ts.map +1 -0
  14. package/dist/build-page.js +282 -0
  15. package/dist/build-page.js.map +1 -0
  16. package/dist/content.d.ts +322 -9
  17. package/dist/content.d.ts.map +1 -1
  18. package/dist/content.js +354 -11
  19. package/dist/content.js.map +1 -1
  20. package/dist/css-gradient-scan.d.ts +14 -0
  21. package/dist/css-gradient-scan.d.ts.map +1 -0
  22. package/dist/css-gradient-scan.js +81 -0
  23. package/dist/css-gradient-scan.js.map +1 -0
  24. package/dist/css-var-scan.d.ts +56 -0
  25. package/dist/css-var-scan.d.ts.map +1 -0
  26. package/dist/css-var-scan.js +97 -0
  27. package/dist/css-var-scan.js.map +1 -0
  28. package/dist/design-draft-shell.d.ts +21 -0
  29. package/dist/design-draft-shell.d.ts.map +1 -0
  30. package/dist/design-draft-shell.js +81 -0
  31. package/dist/design-draft-shell.js.map +1 -0
  32. package/dist/design-manifest.d.ts +36 -0
  33. package/dist/design-manifest.d.ts.map +1 -0
  34. package/dist/design-manifest.js +90 -0
  35. package/dist/design-manifest.js.map +1 -0
  36. package/dist/fonts.d.ts +89 -0
  37. package/dist/fonts.d.ts.map +1 -0
  38. package/dist/fonts.js +241 -0
  39. package/dist/fonts.js.map +1 -0
  40. package/dist/genesis-inventory.d.ts +32 -0
  41. package/dist/genesis-inventory.d.ts.map +1 -0
  42. package/dist/genesis-inventory.js +186 -0
  43. package/dist/genesis-inventory.js.map +1 -0
  44. package/dist/genesis.d.ts +102 -0
  45. package/dist/genesis.d.ts.map +1 -0
  46. package/dist/genesis.js +145 -0
  47. package/dist/genesis.js.map +1 -0
  48. package/dist/i18n.d.ts +29 -36
  49. package/dist/i18n.d.ts.map +1 -1
  50. package/dist/i18n.js +53 -128
  51. package/dist/i18n.js.map +1 -1
  52. package/dist/index.d.ts +28 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +28 -1
  55. package/dist/index.js.map +1 -1
  56. package/dist/interactions.d.ts +23 -0
  57. package/dist/interactions.d.ts.map +1 -0
  58. package/dist/interactions.js +44 -0
  59. package/dist/interactions.js.map +1 -0
  60. package/dist/media.d.ts +101 -16
  61. package/dist/media.d.ts.map +1 -1
  62. package/dist/media.js +126 -15
  63. package/dist/media.js.map +1 -1
  64. package/dist/page-log.d.ts +94 -0
  65. package/dist/page-log.d.ts.map +1 -0
  66. package/dist/page-log.js +111 -0
  67. package/dist/page-log.js.map +1 -0
  68. package/dist/preview-compose.d.ts +85 -12
  69. package/dist/preview-compose.d.ts.map +1 -1
  70. package/dist/preview-compose.js +157 -67
  71. package/dist/preview-compose.js.map +1 -1
  72. package/dist/proposal-status.d.ts +40 -0
  73. package/dist/proposal-status.d.ts.map +1 -0
  74. package/dist/proposal-status.js +34 -0
  75. package/dist/proposal-status.js.map +1 -0
  76. package/dist/responsive-images.d.ts +64 -0
  77. package/dist/responsive-images.d.ts.map +1 -0
  78. package/dist/responsive-images.js +98 -0
  79. package/dist/responsive-images.js.map +1 -0
  80. package/dist/safe-keys.d.ts +9 -0
  81. package/dist/safe-keys.d.ts.map +1 -0
  82. package/dist/safe-keys.js +20 -0
  83. package/dist/safe-keys.js.map +1 -0
  84. package/dist/seo.d.ts +11 -16
  85. package/dist/seo.d.ts.map +1 -1
  86. package/dist/seo.js +7 -23
  87. package/dist/seo.js.map +1 -1
  88. package/dist/skills.d.ts +14 -68
  89. package/dist/skills.d.ts.map +1 -1
  90. package/dist/skills.js +19 -113
  91. package/dist/skills.js.map +1 -1
  92. package/dist/strip-cdata.d.ts +7 -0
  93. package/dist/strip-cdata.d.ts.map +1 -0
  94. package/dist/strip-cdata.js +48 -0
  95. package/dist/strip-cdata.js.map +1 -0
  96. package/dist/structured-sets.d.ts +6 -52
  97. package/dist/structured-sets.d.ts.map +1 -1
  98. package/dist/structured-sets.js +6 -68
  99. package/dist/structured-sets.js.map +1 -1
  100. package/dist/subagents.d.ts +105 -3
  101. package/dist/subagents.d.ts.map +1 -1
  102. package/dist/subagents.js +224 -41
  103. package/dist/subagents.js.map +1 -1
  104. package/dist/template-engine.d.ts +85 -0
  105. package/dist/template-engine.d.ts.map +1 -0
  106. package/dist/template-engine.js +403 -0
  107. package/dist/template-engine.js.map +1 -0
  108. package/dist/theme-importers/auto-detect.d.ts +26 -0
  109. package/dist/theme-importers/auto-detect.d.ts.map +1 -0
  110. package/dist/theme-importers/auto-detect.js +42 -0
  111. package/dist/theme-importers/auto-detect.js.map +1 -0
  112. package/dist/theme-importers/css-comments.d.ts +12 -0
  113. package/dist/theme-importers/css-comments.d.ts.map +1 -0
  114. package/dist/theme-importers/css-comments.js +15 -0
  115. package/dist/theme-importers/css-comments.js.map +1 -0
  116. package/dist/theme-importers/dtcg.d.ts +46 -0
  117. package/dist/theme-importers/dtcg.d.ts.map +1 -0
  118. package/dist/theme-importers/dtcg.js +111 -0
  119. package/dist/theme-importers/dtcg.js.map +1 -0
  120. package/dist/theme-importers/loose.d.ts +3 -0
  121. package/dist/theme-importers/loose.d.ts.map +1 -0
  122. package/dist/theme-importers/loose.js +76 -0
  123. package/dist/theme-importers/loose.js.map +1 -0
  124. package/dist/theme-importers/shadcn.d.ts +24 -0
  125. package/dist/theme-importers/shadcn.d.ts.map +1 -0
  126. package/dist/theme-importers/shadcn.js +135 -0
  127. package/dist/theme-importers/shadcn.js.map +1 -0
  128. package/dist/theme-importers/style-dictionary.d.ts +17 -0
  129. package/dist/theme-importers/style-dictionary.d.ts.map +1 -0
  130. package/dist/theme-importers/style-dictionary.js +125 -0
  131. package/dist/theme-importers/style-dictionary.js.map +1 -0
  132. package/dist/theme-importers/tailwind.d.ts +3 -0
  133. package/dist/theme-importers/tailwind.d.ts.map +1 -0
  134. package/dist/theme-importers/tailwind.js +218 -0
  135. package/dist/theme-importers/tailwind.js.map +1 -0
  136. package/dist/theme-literal-binding.d.ts +37 -0
  137. package/dist/theme-literal-binding.d.ts.map +1 -0
  138. package/dist/theme-literal-binding.js +138 -0
  139. package/dist/theme-literal-binding.js.map +1 -0
  140. package/dist/theme-normalize.d.ts +31 -0
  141. package/dist/theme-normalize.d.ts.map +1 -0
  142. package/dist/theme-normalize.js +587 -0
  143. package/dist/theme-normalize.js.map +1 -0
  144. package/dist/theme-ramp.d.ts +55 -0
  145. package/dist/theme-ramp.d.ts.map +1 -0
  146. package/dist/theme-ramp.js +149 -0
  147. package/dist/theme-ramp.js.map +1 -0
  148. package/dist/theme-render.d.ts +105 -0
  149. package/dist/theme-render.d.ts.map +1 -0
  150. package/dist/theme-render.js +441 -0
  151. package/dist/theme-render.js.map +1 -0
  152. package/dist/themes-errors.d.ts +109 -0
  153. package/dist/themes-errors.d.ts.map +1 -0
  154. package/dist/themes-errors.js +170 -0
  155. package/dist/themes-errors.js.map +1 -0
  156. package/dist/themes.d.ts +343 -0
  157. package/dist/themes.d.ts.map +1 -0
  158. package/dist/themes.js +697 -0
  159. package/dist/themes.js.map +1 -0
  160. package/dist/version.d.ts +7 -4
  161. package/dist/version.d.ts.map +1 -1
  162. package/dist/version.js +6 -3
  163. package/dist/version.js.map +1 -1
  164. package/package.json +10 -2
  165. package/src/__tests__/redos-hardening.test.ts +160 -0
  166. package/src/ai-tools-add-module-modes.test.ts +106 -0
  167. package/src/ai-tools-position.test.ts +134 -0
  168. package/src/ai-tools.test.ts +81 -0
  169. package/src/ai-tools.ts +1105 -0
  170. package/src/auth-forms.ts +36 -0
  171. package/src/base-css.ts +42 -0
  172. package/src/build-page.test.ts +228 -0
  173. package/src/build-page.ts +319 -0
  174. package/src/cap-failures.ts +67 -0
  175. package/src/content.test.ts +170 -0
  176. package/src/content.ts +620 -0
  177. package/src/context.ts +43 -0
  178. package/src/css-gradient-scan.ts +88 -0
  179. package/src/css-var-scan.test.ts +96 -0
  180. package/src/css-var-scan.ts +144 -0
  181. package/src/derive-module-type.test.ts +80 -0
  182. package/src/design-draft-shell.test.ts +85 -0
  183. package/src/design-draft-shell.ts +109 -0
  184. package/src/design-manifest.ts +93 -0
  185. package/src/fonts.test.ts +157 -0
  186. package/src/fonts.ts +296 -0
  187. package/src/genesis-inventory.test.ts +86 -0
  188. package/src/genesis-inventory.ts +215 -0
  189. package/src/genesis-sanitize.test.ts +35 -0
  190. package/src/genesis.ts +158 -0
  191. package/src/i18n.test.ts +58 -0
  192. package/src/i18n.ts +91 -0
  193. package/src/index.test.ts +10 -0
  194. package/src/index.ts +59 -0
  195. package/src/interactions.ts +48 -0
  196. package/src/logger.ts +147 -0
  197. package/src/media.test.ts +160 -0
  198. package/src/media.ts +355 -0
  199. package/src/page-log.test.ts +163 -0
  200. package/src/page-log.ts +124 -0
  201. package/src/preview-compose.test.ts +637 -0
  202. package/src/preview-compose.ts +656 -0
  203. package/src/preview-scanner.test.ts +96 -0
  204. package/src/preview-scanner.ts +214 -0
  205. package/src/proposal-status.test.ts +69 -0
  206. package/src/proposal-status.ts +40 -0
  207. package/src/responsive-images.test.ts +104 -0
  208. package/src/responsive-images.ts +151 -0
  209. package/src/result.ts +29 -0
  210. package/src/safe-keys.ts +21 -0
  211. package/src/seo.test.ts +194 -0
  212. package/src/seo.ts +233 -0
  213. package/src/skills.ts +48 -0
  214. package/src/snapshots.test.ts +80 -0
  215. package/src/snapshots.ts +81 -0
  216. package/src/strip-cdata.test.ts +41 -0
  217. package/src/strip-cdata.ts +50 -0
  218. package/src/structured-sets.ts +114 -0
  219. package/src/subagents.test.ts +262 -0
  220. package/src/subagents.ts +432 -0
  221. package/src/template-engine.test.ts +379 -0
  222. package/src/template-engine.ts +520 -0
  223. package/src/theme-gradient.test.ts +92 -0
  224. package/src/theme-importers/__tests__/proto-pollution.test.ts +54 -0
  225. package/src/theme-importers/auto-detect.ts +84 -0
  226. package/src/theme-importers/css-comments.ts +15 -0
  227. package/src/theme-importers/dtcg.ts +106 -0
  228. package/src/theme-importers/loose.ts +76 -0
  229. package/src/theme-importers/shadcn.ts +133 -0
  230. package/src/theme-importers/style-dictionary.ts +125 -0
  231. package/src/theme-importers/tailwind.ts +217 -0
  232. package/src/theme-literal-binding.test.ts +71 -0
  233. package/src/theme-literal-binding.ts +159 -0
  234. package/src/theme-motion.test.ts +115 -0
  235. package/src/theme-normalize-envelope.test.ts +43 -0
  236. package/src/theme-normalize-gradient.test.ts +135 -0
  237. package/src/theme-normalize.ts +661 -0
  238. package/src/theme-ramp.ts +187 -0
  239. package/src/theme-render-sanitize.test.ts +45 -0
  240. package/src/theme-render.test.ts +119 -0
  241. package/src/theme-render.ts +487 -0
  242. package/src/theme-shadow.test.ts +56 -0
  243. package/src/themes-errors.ts +199 -0
  244. package/src/themes.ts +842 -0
  245. package/src/version.ts +66 -0
  246. package/dist/translation.d.ts +0 -127
  247. package/dist/translation.d.ts.map +0 -1
  248. package/dist/translation.js +0 -208
  249. package/dist/translation.js.map +0 -1
@@ -0,0 +1,111 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * v0.11.0 — DTCG (W3C Design Tokens Format) import / export for the
4
+ * `themes` primitive (#45 Phase 7 slice 1).
5
+ *
6
+ * The full format-auto-detect (Style Dictionary / Tailwind 4 @theme /
7
+ * shadcn `:root` / loose key-value) is v0.11.2 — see the follow-up
8
+ * comment §4 on #45. This slice ships the DTCG side only so design
9
+ * tooling (Figma, Tokens Studio, Style Dictionary) round-trips cleanly
10
+ * from day one.
11
+ *
12
+ * The shape we accept IS the same shape `themes.tokens` jsonb carries,
13
+ * because `themes.ts`'s Zod schema mirrors DTCG. So `importDtcg` is
14
+ * essentially `JSON.parse + validateThemeTokens`; `exportDtcg` returns
15
+ * the stored tokens jsonb after stable-stringification. The wrappers
16
+ * exist so we have explicit entry points to grow Style-Dictionary /
17
+ * Tailwind / shadcn / loose parsers next to in v0.11.2 without
18
+ * widening `themes.ts`.
19
+ */
20
+ import { validateThemeTokens } from "../themes.js";
21
+ import { NotDtcgShape } from "../themes-errors.js";
22
+ /**
23
+ * Parse a DTCG JSON document into a validated tokens tree. Three
24
+ * failure surfaces:
25
+ *
26
+ * 1. Malformed JSON → `DTCG parse failed: <SyntaxError msg>`
27
+ * 2. Valid JSON, no `$value` anywhere → `NotDtcgShape` (round-2
28
+ * opt §2: pre-Zod sniff for the common case where the operator
29
+ * pastes a Tailwind / Style Dictionary / Figma export and the
30
+ * AI sees a deeply-nested Zod path mismatch instead of a clear
31
+ * "this isn't DTCG" hint).
32
+ * 3. Valid JSON, has $value leaves, but Zod rejects something → the
33
+ * ZodError surfaces verbatim (per-token path mismatch, missing
34
+ * composite sub-field, etc.).
35
+ */
36
+ export function importDtcg(body) {
37
+ let parsed;
38
+ try {
39
+ parsed = JSON.parse(body);
40
+ }
41
+ catch (e) {
42
+ const msg = e instanceof Error ? e.message : String(e);
43
+ throw new Error(`DTCG parse failed: ${msg}`);
44
+ }
45
+ if (!hasAnyDollarValue(parsed)) {
46
+ throw new NotDtcgShape();
47
+ }
48
+ return validateThemeTokens(parsed);
49
+ }
50
+ /**
51
+ * Walks the parsed tree once, returns true as soon as ANY leaf object
52
+ * carries a `$value` key. Cheap O(n) over the parsed structure — same
53
+ * shape Zod will walk anyway during full validation, just early-exits.
54
+ * Treats arrays as nested containers so a shadow-layer array of
55
+ * composite values still sniffs as DTCG.
56
+ */
57
+ function hasAnyDollarValue(node) {
58
+ if (node === null || typeof node !== "object")
59
+ return false;
60
+ if (Array.isArray(node))
61
+ return node.some(hasAnyDollarValue);
62
+ const obj = node;
63
+ if ("$value" in obj)
64
+ return true;
65
+ for (const v of Object.values(obj)) {
66
+ if (hasAnyDollarValue(v))
67
+ return true;
68
+ }
69
+ return false;
70
+ }
71
+ /**
72
+ * Emit a stable DTCG JSON document for the given theme. Keys are
73
+ * sorted alphabetically at every nesting level so the output is
74
+ * byte-for-byte deterministic — Style Dictionary / Tokens Studio diff
75
+ * cleanly under git.
76
+ *
77
+ * Only `tokens` is exported; asset URLs and the `is_active` flag are
78
+ * Caelo-specific and have no DTCG representation. Operators bind
79
+ * assets through `set_theme_asset`, not through an exported JSON file.
80
+ */
81
+ export function exportDtcg(theme) {
82
+ return `${JSON.stringify(sortDeep(theme.tokens), null, 2)}\n`;
83
+ }
84
+ function sortDeep(value) {
85
+ if (value === null)
86
+ return null;
87
+ if (Array.isArray(value))
88
+ return value.map(sortDeep);
89
+ if (typeof value !== "object")
90
+ return value;
91
+ const obj = value;
92
+ const sortedKeys = Object.keys(obj).sort((a, b) => {
93
+ // DTCG convention: $-prefixed metadata keys ($value, $type,
94
+ // $description, $extensions) sort BEFORE plain group keys so a
95
+ // leaf renders with its metadata up top, then its sub-references
96
+ // (if any) below. Within each tier keys sort alphabetically.
97
+ const aDollar = a.startsWith("$");
98
+ const bDollar = b.startsWith("$");
99
+ if (aDollar && !bDollar)
100
+ return -1;
101
+ if (!aDollar && bDollar)
102
+ return 1;
103
+ return a.localeCompare(b);
104
+ });
105
+ const out = {};
106
+ for (const k of sortedKeys) {
107
+ out[k] = sortDeep(obj[k]);
108
+ }
109
+ return out;
110
+ }
111
+ //# sourceMappingURL=dtcg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dtcg.js","sourceRoot":"","sources":["../../src/theme-importers/dtcg.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type ThemeDocument } from "../themes.js";
2
+ export declare function importLoose(body: string): ThemeDocument;
3
+ //# sourceMappingURL=loose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loose.d.ts","sourceRoot":"","sources":["../../src/theme-importers/loose.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAmB,KAAK,aAAa,EAAuB,MAAM,cAAc,CAAC;AAGxF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CA6BvD"}
@@ -0,0 +1,76 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * v0.11.1 (issue #76) — loose key-value JSON object importer.
4
+ *
5
+ * Accepts a flat JSON object of `{looseName: value}` pairs and runs
6
+ * each entry through `normalizeTokens` + `applyDtcgWrites` so the
7
+ * result lands at canonical DTCG paths. This is the same path
8
+ * `themes.update_tokens` uses for AI-supplied input — extracted here
9
+ * so `import_theme` can offer a "paste a flat object, server figures
10
+ * out where each one goes" surface.
11
+ *
12
+ * The importer starts from an empty document so it produces a complete
13
+ * tokens tree (no existing tokens merged in). Callers wanting a patch
14
+ * use `themes.update_tokens` directly.
15
+ */
16
+ import { normalizeTokens } from "../theme-normalize.js";
17
+ import { applyDtcgWrites, validateThemeTokens } from "../themes.js";
18
+ import { NotLooseShape } from "../themes-errors.js";
19
+ export function importLoose(body) {
20
+ let parsed;
21
+ try {
22
+ parsed = JSON.parse(body);
23
+ }
24
+ catch (e) {
25
+ const msg = e instanceof Error ? e.message : String(e);
26
+ throw new NotLooseShape(`loose-format parse failed: ${msg}`);
27
+ }
28
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
29
+ throw new NotLooseShape("loose-format input must be a JSON object");
30
+ }
31
+ // Reject inputs that are clearly other formats so auto-detect doesn't
32
+ // accidentally swallow them at the last hop.
33
+ if (hasNestedDollarValue(parsed) || hasNestedPlainValue(parsed)) {
34
+ throw new NotLooseShape("input has nested `$value` / `value` leaves — looks like DTCG or Style Dictionary, not loose");
35
+ }
36
+ const obj = parsed;
37
+ if (Object.keys(obj).length === 0) {
38
+ throw new NotLooseShape("loose-format input is an empty object");
39
+ }
40
+ // Normalize loose names → canonical paths (throws UnknownTokenName on
41
+ // ambiguity, per the v0.11.0 normalizer's failure surface).
42
+ const normalized = normalizeTokens(obj);
43
+ // Apply to an empty document so the result is a complete tokens tree.
44
+ const written = applyDtcgWrites({}, normalized.set, normalized.types);
45
+ return validateThemeTokens(written);
46
+ }
47
+ function hasNestedDollarValue(node) {
48
+ if (node === null || typeof node !== "object" || Array.isArray(node))
49
+ return false;
50
+ const obj = node;
51
+ for (const [k, v] of Object.entries(obj)) {
52
+ if (k === "$value")
53
+ return true;
54
+ if (typeof v === "object" && v !== null && hasNestedDollarValue(v))
55
+ return true;
56
+ }
57
+ return false;
58
+ }
59
+ function hasNestedPlainValue(node) {
60
+ if (node === null || typeof node !== "object" || Array.isArray(node))
61
+ return false;
62
+ const obj = node;
63
+ // A "Style Dictionary leaf" looks like `{value: <primitive>, ...}` —
64
+ // not a top-level flat key whose value is a primitive.
65
+ for (const v of Object.values(obj)) {
66
+ if (v && typeof v === "object" && !Array.isArray(v)) {
67
+ const inner = v;
68
+ if ("value" in inner && typeof inner.value !== "object")
69
+ return true;
70
+ if (hasNestedPlainValue(v))
71
+ return true;
72
+ }
73
+ }
74
+ return false;
75
+ }
76
+ //# sourceMappingURL=loose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loose.js","sourceRoot":"","sources":["../../src/theme-importers/loose.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * v0.11.1 (issue #76) — shadcn CSS-variable importer.
3
+ *
4
+ * shadcn-style themes ship as a `:root { … }` (+ optional `.dark { … }`)
5
+ * block of unprefixed CSS variables:
6
+ *
7
+ * :root {
8
+ * --background: 0 0% 100%;
9
+ * --primary: 222.2 47.4% 11.2%;
10
+ * --primary-foreground: 210 40% 98%;
11
+ * }
12
+ * .dark {
13
+ * --background: 222.2 84% 4.9%;
14
+ * --primary: 210 40% 98%;
15
+ * }
16
+ *
17
+ * Each unprefixed name maps to `color.<name>` (shadcn variables are
18
+ * exclusively colors today — typography/spacing live in Tailwind config).
19
+ * When both blocks exist, paired names land as `{light, dark}` composite
20
+ * color values; lone names emit flat values.
21
+ */
22
+ import { type ThemeDocument } from "../themes.js";
23
+ export declare function importShadcn(body: string): ThemeDocument;
24
+ //# sourceMappingURL=shadcn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadcn.d.ts","sourceRoot":"","sources":["../../src/theme-importers/shadcn.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,cAAc,CAAC;AAQvE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAuCxD"}
@@ -0,0 +1,135 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * v0.11.1 (issue #76) — shadcn CSS-variable importer.
4
+ *
5
+ * shadcn-style themes ship as a `:root { … }` (+ optional `.dark { … }`)
6
+ * block of unprefixed CSS variables:
7
+ *
8
+ * :root {
9
+ * --background: 0 0% 100%;
10
+ * --primary: 222.2 47.4% 11.2%;
11
+ * --primary-foreground: 210 40% 98%;
12
+ * }
13
+ * .dark {
14
+ * --background: 222.2 84% 4.9%;
15
+ * --primary: 210 40% 98%;
16
+ * }
17
+ *
18
+ * Each unprefixed name maps to `color.<name>` (shadcn variables are
19
+ * exclusively colors today — typography/spacing live in Tailwind config).
20
+ * When both blocks exist, paired names land as `{light, dark}` composite
21
+ * color values; lone names emit flat values.
22
+ */
23
+ import { validateThemeTokens } from "../themes.js";
24
+ import { NotShadcnShape } from "../themes-errors.js";
25
+ import { stripCssComments } from "./css-comments.js";
26
+ export function importShadcn(body) {
27
+ // Quick rejections so the auto-detect chain can fall through fast.
28
+ if (/"value"\s*:/i.test(body)) {
29
+ throw new NotShadcnShape('input contains `"value":` — looks like Style Dictionary JSON');
30
+ }
31
+ const lightBlock = extractBlock(body, ":root");
32
+ if (lightBlock === null) {
33
+ throw new NotShadcnShape();
34
+ }
35
+ const lightVars = parseCssVars(lightBlock);
36
+ if (Object.keys(lightVars).length === 0) {
37
+ throw new NotShadcnShape(":root block found but no `--name: value;` pairs inside");
38
+ }
39
+ const darkBlock = extractBlock(body, ".dark");
40
+ const darkVars = darkBlock === null ? null : parseCssVars(darkBlock);
41
+ const color = {};
42
+ for (const [name, lightVal] of Object.entries(lightVars)) {
43
+ const wrapped = wrapColorValue(lightVal);
44
+ if (darkVars && darkVars[name] !== undefined) {
45
+ color[name] = {
46
+ $value: { light: wrapped, dark: wrapColorValue(darkVars[name]) },
47
+ $type: "color",
48
+ };
49
+ }
50
+ else {
51
+ color[name] = { $value: wrapped, $type: "color" };
52
+ }
53
+ }
54
+ // Surface dark-only names too (no light counterpart). Rare but real
55
+ // when an operator splits brand variants across blocks.
56
+ if (darkVars) {
57
+ for (const [name, darkVal] of Object.entries(darkVars)) {
58
+ if (name in color)
59
+ continue;
60
+ color[name] = { $value: wrapColorValue(darkVal), $type: "color" };
61
+ }
62
+ }
63
+ const doc = { color };
64
+ return validateThemeTokens(doc);
65
+ }
66
+ /**
67
+ * Find a selector block (e.g. `:root` or `.dark`) and return the body
68
+ * inside the matching braces. Strips block comments before matching.
69
+ */
70
+ function extractBlock(body, selector) {
71
+ const stripped = stripCssComments(body);
72
+ // Escape regex specials in the selector (`.` for `.dark`).
73
+ const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
74
+ const match = new RegExp(`${escaped}\\s*\\{`).exec(stripped);
75
+ if (!match)
76
+ return null;
77
+ const start = match.index + match[0].length;
78
+ let depth = 1;
79
+ let i = start;
80
+ while (i < stripped.length && depth > 0) {
81
+ const ch = stripped[i];
82
+ if (ch === "{")
83
+ depth += 1;
84
+ else if (ch === "}")
85
+ depth -= 1;
86
+ if (depth === 0)
87
+ break;
88
+ i += 1;
89
+ }
90
+ if (depth !== 0)
91
+ return null;
92
+ return stripped.slice(start, i);
93
+ }
94
+ function parseCssVars(block) {
95
+ const out = {};
96
+ for (const raw of block.split(";")) {
97
+ const line = raw.trim();
98
+ if (line.length === 0 || !line.startsWith("--"))
99
+ continue;
100
+ const colonIdx = line.indexOf(":");
101
+ if (colonIdx <= 0)
102
+ continue;
103
+ const name = line.slice(2, colonIdx).trim();
104
+ const value = line.slice(colonIdx + 1).trim();
105
+ if (name.length === 0 || value.length === 0)
106
+ continue;
107
+ out[name] = value;
108
+ }
109
+ return out;
110
+ }
111
+ /**
112
+ * shadcn often stores HSL channels without the `hsl(...)` wrapper
113
+ * (`--primary: 222.2 47.4% 11.2%`). Detect that shape and wrap so the
114
+ * resulting value is a valid CSS color string the renderer / browser
115
+ * can use directly. Hex / oklch / rgb / hsl(...) values pass through
116
+ * unchanged.
117
+ */
118
+ function wrapColorValue(raw) {
119
+ const trimmed = raw.trim();
120
+ // Already a recognised CSS color → pass through.
121
+ if (/^#[0-9a-fA-F]{3,8}$/.test(trimmed))
122
+ return trimmed;
123
+ if (/^(oklch|rgb|rgba|hsl|hsla|lab|lch|color|hwb)\s*\(/i.test(trimmed))
124
+ return trimmed;
125
+ if (/^(transparent|currentColor)$/i.test(trimmed))
126
+ return trimmed;
127
+ // Three space-separated tokens with a `%` somewhere → shadcn HSL triple.
128
+ if (/^\d+(\.\d+)?\s+\d+(\.\d+)?%\s+\d+(\.\d+)?%$/.test(trimmed)) {
129
+ return `hsl(${trimmed})`;
130
+ }
131
+ // Bare named color or anything else — pass through; the Zod schema
132
+ // will catch genuinely-broken inputs at validateThemeTokens.
133
+ return trimmed;
134
+ }
135
+ //# sourceMappingURL=shadcn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadcn.js","sourceRoot":"","sources":["../../src/theme-importers/shadcn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * v0.11.1 (issue #76) — Style Dictionary v3/v4 importer.
3
+ *
4
+ * Style Dictionary stores tokens as `{ value: "…", attributes?: {…} }`
5
+ * leaves instead of DTCG's `$value` / `$type`. This importer walks the
6
+ * tree, rewrites `value` → `$value` (and `type` → `$type` where set),
7
+ * preserves `attributes` blocks under `$extensions.styleDictionary`,
8
+ * and feeds the result through `validateThemeTokens` for round-trip
9
+ * compatibility with the DTCG storage shape.
10
+ *
11
+ * Recognition heuristic: input must be valid JSON with at least one
12
+ * nested `{ value: … }` leaf and NO `$value` keys (the latter would
13
+ * indicate DTCG — the auto-detect chain handles priority).
14
+ */
15
+ import { type ThemeDocument } from "../themes.js";
16
+ export declare function importStyleDictionary(body: string): ThemeDocument;
17
+ //# sourceMappingURL=style-dictionary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-dictionary.d.ts","sourceRoot":"","sources":["../../src/theme-importers/style-dictionary.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,cAAc,CAAC;AAGvE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CA2BjE"}
@@ -0,0 +1,125 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * v0.11.1 (issue #76) — Style Dictionary v3/v4 importer.
4
+ *
5
+ * Style Dictionary stores tokens as `{ value: "…", attributes?: {…} }`
6
+ * leaves instead of DTCG's `$value` / `$type`. This importer walks the
7
+ * tree, rewrites `value` → `$value` (and `type` → `$type` where set),
8
+ * preserves `attributes` blocks under `$extensions.styleDictionary`,
9
+ * and feeds the result through `validateThemeTokens` for round-trip
10
+ * compatibility with the DTCG storage shape.
11
+ *
12
+ * Recognition heuristic: input must be valid JSON with at least one
13
+ * nested `{ value: … }` leaf and NO `$value` keys (the latter would
14
+ * indicate DTCG — the auto-detect chain handles priority).
15
+ */
16
+ import { validateThemeTokens } from "../themes.js";
17
+ import { NotStyleDictionaryShape } from "../themes-errors.js";
18
+ export function importStyleDictionary(body) {
19
+ let parsed;
20
+ try {
21
+ parsed = JSON.parse(body);
22
+ }
23
+ catch (e) {
24
+ const msg = e instanceof Error ? e.message : String(e);
25
+ throw new NotStyleDictionaryShape(`Style Dictionary parse failed: ${msg}`);
26
+ }
27
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
28
+ throw new NotStyleDictionaryShape("Style Dictionary input must be a JSON object");
29
+ }
30
+ if (hasDollarValue(parsed)) {
31
+ throw new NotStyleDictionaryShape("input has `$value` leaves — looks like DTCG, not Style Dictionary");
32
+ }
33
+ if (!hasPlainValue(parsed)) {
34
+ throw new NotStyleDictionaryShape("input has no `{ value: … }` leaves typical of Style Dictionary");
35
+ }
36
+ const dtcg = rewriteSdToDtcg(parsed);
37
+ // Top-level Style Dictionary categories may not exactly match DTCG
38
+ // (e.g. `size` instead of `spacing`); rename common cases so the
39
+ // resulting document validates and renders correctly.
40
+ const renamed = renameTopLevelCategories(dtcg);
41
+ return validateThemeTokens(renamed);
42
+ }
43
+ function hasDollarValue(node) {
44
+ if (node === null || typeof node !== "object")
45
+ return false;
46
+ if (Array.isArray(node))
47
+ return node.some(hasDollarValue);
48
+ const obj = node;
49
+ if ("$value" in obj)
50
+ return true;
51
+ for (const v of Object.values(obj)) {
52
+ if (hasDollarValue(v))
53
+ return true;
54
+ }
55
+ return false;
56
+ }
57
+ function hasPlainValue(node) {
58
+ if (node === null || typeof node !== "object")
59
+ return false;
60
+ if (Array.isArray(node))
61
+ return node.some(hasPlainValue);
62
+ const obj = node;
63
+ // A leaf in Style Dictionary has `value` AND no nested object siblings
64
+ // carrying their own value. Detecting "has value somewhere" is enough
65
+ // for the auto-detect sniff; full validation happens in rewriteSdToDtcg.
66
+ if ("value" in obj && typeof obj.value !== "object")
67
+ return true;
68
+ for (const v of Object.values(obj)) {
69
+ if (hasPlainValue(v))
70
+ return true;
71
+ }
72
+ return false;
73
+ }
74
+ function rewriteSdToDtcg(node) {
75
+ if (node === null || typeof node !== "object" || Array.isArray(node))
76
+ return node;
77
+ const obj = node;
78
+ // Leaf detection: has `value` but no nested children that themselves
79
+ // have `value` (deepest-first rewrite).
80
+ if ("value" in obj && typeof obj.value !== "object") {
81
+ const leaf = { $value: obj.value };
82
+ if ("type" in obj && typeof obj.type === "string") {
83
+ leaf.$type = obj.type;
84
+ }
85
+ if ("description" in obj && typeof obj.description === "string") {
86
+ leaf.$description = obj.description;
87
+ }
88
+ if ("attributes" in obj && obj.attributes && typeof obj.attributes === "object") {
89
+ leaf.$extensions = { styleDictionary: { attributes: obj.attributes } };
90
+ }
91
+ return leaf;
92
+ }
93
+ const out = {};
94
+ for (const [k, v] of Object.entries(obj)) {
95
+ out[k] = rewriteSdToDtcg(v);
96
+ }
97
+ return out;
98
+ }
99
+ /**
100
+ * Common Style Dictionary category name → DTCG category map. Only
101
+ * applied at the root; nested groups keep their original names.
102
+ */
103
+ const SD_TO_DTCG_CATEGORY = {
104
+ size: "spacing",
105
+ sizes: "spacing",
106
+ spaces: "spacing",
107
+ colors: "color",
108
+ fonts: "typography",
109
+ font: "typography",
110
+ shadows: "shadow",
111
+ radii: "radius",
112
+ borderRadius: "radius",
113
+ };
114
+ function renameTopLevelCategories(doc) {
115
+ if (!doc || typeof doc !== "object" || Array.isArray(doc))
116
+ return doc;
117
+ const obj = doc;
118
+ const out = {};
119
+ for (const [k, v] of Object.entries(obj)) {
120
+ const renamed = SD_TO_DTCG_CATEGORY[k];
121
+ out[renamed ?? k] = v;
122
+ }
123
+ return out;
124
+ }
125
+ //# sourceMappingURL=style-dictionary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-dictionary.js","sourceRoot":"","sources":["../../src/theme-importers/style-dictionary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type ThemeDocument } from "../themes.js";
2
+ export declare function importTailwind(body: string): ThemeDocument;
3
+ //# sourceMappingURL=tailwind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailwind.d.ts","sourceRoot":"","sources":["../../src/theme-importers/tailwind.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,cAAc,CAAC;AASvE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAW1D"}