@yahoo/uds-create-config 2.45.0 → 3.0.1

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 (376) hide show
  1. package/README.md +129 -0
  2. package/dist/ai-lanes.d.ts +23 -0
  3. package/dist/ai-lanes.js +34 -0
  4. package/dist/authoring/define-component.d.ts +85 -0
  5. package/dist/configs/CanvasConfig.d.ts +3237 -0
  6. package/dist/configs/CanvasConfig.js +332 -0
  7. package/dist/configs/build-options.d.ts +10 -0
  8. package/dist/configs/build-options.js +68 -0
  9. package/dist/configs/platform.d.ts +15 -0
  10. package/dist/configs/platform.js +17 -0
  11. package/dist/configs/react-native-system.d.ts +3026 -0
  12. package/dist/configs/react-native-system.js +64 -0
  13. package/dist/configs/system.d.ts +2771 -0
  14. package/dist/configs/system.js +74 -0
  15. package/dist/css/properties.generated.d.ts +14 -0
  16. package/dist/css/properties.generated.js +6260 -0
  17. package/dist/css/value-type.d.ts +48 -0
  18. package/dist/css/value-type.js +131 -0
  19. package/dist/css/values.d.ts +33 -0
  20. package/dist/css/values.js +116 -0
  21. package/dist/entities/native/NativeModifier.d.ts +25 -0
  22. package/dist/entities/native/NativeModifier.js +41 -0
  23. package/dist/entities/native/NativeSettings.d.ts +44 -0
  24. package/dist/entities/native/NativeSettings.js +39 -0
  25. package/dist/entities/native/NativeStyleProperty.d.ts +355 -0
  26. package/dist/entities/native/NativeStyleProperty.js +28 -0
  27. package/dist/entities/native/NativeToken.d.ts +31 -0
  28. package/dist/entities/native/NativeToken.js +49 -0
  29. package/dist/entities/system/CanvasRole.d.ts +34 -0
  30. package/dist/entities/system/CanvasRole.js +45 -0
  31. package/dist/entities/system/Component.d.ts +1287 -0
  32. package/dist/entities/system/Component.js +1840 -0
  33. package/dist/entities/system/Composite.d.ts +12 -0
  34. package/dist/entities/system/Composite.js +26 -0
  35. package/dist/entities/system/Device.d.ts +11 -0
  36. package/dist/entities/system/Device.js +18 -0
  37. package/dist/entities/system/File.d.ts +72 -0
  38. package/dist/entities/system/File.js +136 -0
  39. package/dist/entities/system/Font.d.ts +48 -0
  40. package/dist/entities/system/Font.js +56 -0
  41. package/dist/entities/system/GlobalStyle.d.ts +26 -0
  42. package/dist/entities/system/GlobalStyle.js +54 -0
  43. package/dist/entities/system/Guidance.d.ts +85 -0
  44. package/dist/entities/system/Guidance.js +59 -0
  45. package/dist/entities/system/GuidanceStyle.d.ts +14 -0
  46. package/dist/entities/system/GuidanceStyle.js +8 -0
  47. package/dist/entities/system/Icon.d.ts +46 -0
  48. package/dist/entities/system/Icon.js +46 -0
  49. package/dist/entities/system/LinkedSystem.d.ts +504 -0
  50. package/dist/entities/system/LinkedSystem.js +814 -0
  51. package/dist/entities/system/Modifier.d.ts +92 -0
  52. package/dist/entities/system/Modifier.js +120 -0
  53. package/dist/entities/system/Motion.d.ts +28 -0
  54. package/dist/entities/system/Motion.js +48 -0
  55. package/dist/entities/system/Operation.d.ts +100 -0
  56. package/dist/entities/system/Operation.js +236 -0
  57. package/dist/entities/system/Package.d.ts +42 -0
  58. package/dist/entities/system/Package.js +75 -0
  59. package/dist/entities/system/Settings.d.ts +94 -0
  60. package/dist/entities/system/Settings.js +166 -0
  61. package/dist/entities/system/StyleProperty.d.ts +135 -0
  62. package/dist/entities/system/StyleProperty.js +438 -0
  63. package/dist/entities/system/Token.d.ts +67 -0
  64. package/dist/entities/system/Token.js +129 -0
  65. package/dist/entities/system/Tool.d.ts +134 -0
  66. package/dist/entities/system/Tool.js +124 -0
  67. package/dist/entities/system/color.d.ts +64 -0
  68. package/dist/entities/system/color.js +123 -0
  69. package/dist/entities/system/component-module.d.ts +63 -0
  70. package/dist/entities/system/component-module.js +258 -0
  71. package/dist/entities/system/copy-plan.d.ts +98 -0
  72. package/dist/entities/system/copy-plan.js +451 -0
  73. package/dist/entities/system/defineComponent.d.ts +428 -0
  74. package/dist/entities/system/defineComponent.js +337 -0
  75. package/dist/entities/system/element.d.ts +101 -0
  76. package/dist/entities/system/element.js +171 -0
  77. package/dist/entities/system/icon-library.d.ts +64 -0
  78. package/dist/entities/system/icon-library.js +112 -0
  79. package/dist/entities/system/icon-metadata.d.ts +72 -0
  80. package/dist/entities/system/icon-metadata.js +111 -0
  81. package/dist/entities/system/link-declaration.d.ts +27 -0
  82. package/dist/entities/system/link-declaration.js +64 -0
  83. package/dist/entities/system/link-plan.d.ts +160 -0
  84. package/dist/entities/system/link-plan.js +770 -0
  85. package/dist/entities/system/runtime-modules.d.ts +25 -0
  86. package/dist/entities/system/runtime-modules.js +38 -0
  87. package/dist/entities/system/style-bag.d.ts +20 -0
  88. package/dist/entities/system/style-bag.js +246 -0
  89. package/dist/entities/system/token-index.d.ts +89 -0
  90. package/dist/entities/system/token-index.js +112 -0
  91. package/dist/framework/Config.d.ts +2472 -0
  92. package/dist/framework/Config.js +5023 -0
  93. package/dist/framework/Entity.d.ts +127 -0
  94. package/dist/framework/Entity.js +125 -0
  95. package/dist/framework/authoring.d.ts +24 -0
  96. package/dist/framework/authoring.js +7 -0
  97. package/dist/framework/change-hooks.d.ts +119 -0
  98. package/dist/framework/change-hooks.js +131 -0
  99. package/dist/framework/changes.d.ts +88 -0
  100. package/dist/framework/changes.js +246 -0
  101. package/dist/framework/class-names.d.ts +260 -0
  102. package/dist/framework/class-names.js +630 -0
  103. package/dist/framework/coalesce.d.ts +25 -0
  104. package/dist/framework/coalesce.js +60 -0
  105. package/dist/framework/config-op.d.ts +76 -0
  106. package/dist/framework/config-op.js +43 -0
  107. package/dist/framework/config-operation-kind.d.ts +14 -0
  108. package/dist/framework/config-operation-kind.js +14 -0
  109. package/dist/framework/config-ops.d.ts +34 -0
  110. package/dist/framework/config-ops.js +187 -0
  111. package/dist/framework/defineConfig.d.ts +196 -0
  112. package/dist/framework/defineConfig.js +100 -0
  113. package/dist/framework/defineDerivedEntity.d.ts +74 -0
  114. package/dist/framework/defineDerivedEntity.js +83 -0
  115. package/dist/framework/defineEntity.d.ts +318 -0
  116. package/dist/framework/defineEntity.js +183 -0
  117. package/dist/framework/defineSubEntity.d.ts +148 -0
  118. package/dist/framework/defineSubEntity.js +121 -0
  119. package/dist/framework/derived-mutations.d.ts +20 -0
  120. package/dist/framework/derived-mutations.js +38 -0
  121. package/dist/framework/entity-search.d.ts +29 -0
  122. package/dist/framework/entity-search.js +117 -0
  123. package/dist/framework/inline-sources.d.ts +49 -0
  124. package/dist/framework/inline-sources.js +388 -0
  125. package/dist/framework/layer-styles.d.ts +25 -0
  126. package/dist/framework/layer-styles.js +49 -0
  127. package/dist/framework/memo.d.ts +48 -0
  128. package/dist/framework/memo.js +84 -0
  129. package/dist/framework/overlay.d.ts +49 -0
  130. package/dist/framework/overlay.js +17 -0
  131. package/dist/framework/plan.d.ts +49 -0
  132. package/dist/framework/plan.js +73 -0
  133. package/dist/framework/projections.d.ts +480 -0
  134. package/dist/framework/projections.js +974 -0
  135. package/dist/framework/prop-surface.d.ts +132 -0
  136. package/dist/framework/prop-surface.js +278 -0
  137. package/dist/framework/ref-graph.d.ts +71 -0
  138. package/dist/framework/ref-graph.js +158 -0
  139. package/dist/framework/ref-integrity.d.ts +55 -0
  140. package/dist/framework/ref-integrity.js +171 -0
  141. package/dist/framework/registered.d.ts +95 -0
  142. package/dist/framework/registry-dir.d.ts +42 -0
  143. package/dist/framework/registry-dir.js +48 -0
  144. package/dist/framework/registry.d.ts +300 -0
  145. package/dist/framework/registry.js +104 -0
  146. package/dist/framework/rejection.d.ts +58 -0
  147. package/dist/framework/rejection.js +111 -0
  148. package/dist/framework/rename-inference.d.ts +26 -0
  149. package/dist/framework/rename-inference.js +50 -0
  150. package/dist/framework/render-spec.d.ts +296 -0
  151. package/dist/framework/render-spec.js +809 -0
  152. package/dist/framework/schema-version.d.ts +140 -0
  153. package/dist/framework/schema-version.js +214 -0
  154. package/dist/framework/schemas.d.ts +109 -0
  155. package/dist/framework/schemas.js +615 -0
  156. package/dist/framework/session.d.ts +196 -0
  157. package/dist/framework/session.js +367 -0
  158. package/dist/framework/signature.d.ts +15 -0
  159. package/dist/framework/signature.js +83 -0
  160. package/dist/framework/snapshot.d.ts +115 -0
  161. package/dist/framework/snapshot.js +277 -0
  162. package/dist/framework/source-integrity.d.ts +226 -0
  163. package/dist/framework/source-integrity.js +478 -0
  164. package/dist/framework/sources.d.ts +211 -0
  165. package/dist/framework/sources.js +89 -0
  166. package/dist/framework/utils/compiled-schema.d.ts +23 -0
  167. package/dist/framework/utils/compiled-schema.js +46 -0
  168. package/dist/framework/utils/content-key.d.ts +15 -0
  169. package/dist/framework/utils/content-key.js +33 -0
  170. package/dist/framework/utils/enumerated.d.ts +13 -0
  171. package/dist/framework/utils/enumerated.js +19 -0
  172. package/dist/framework/utils/field-path.d.ts +95 -0
  173. package/dist/framework/utils/field-path.js +136 -0
  174. package/dist/framework/utils/field-schema.d.ts +55 -0
  175. package/dist/framework/utils/field-schema.js +183 -0
  176. package/dist/framework/utils/group.d.ts +37 -0
  177. package/dist/framework/utils/group.js +13 -0
  178. package/dist/framework/utils/package-path.d.ts +37 -0
  179. package/dist/framework/utils/package-path.js +61 -0
  180. package/dist/framework/utils/refs.d.ts +194 -0
  181. package/dist/framework/utils/refs.js +403 -0
  182. package/dist/framework/validate-spec.d.ts +27 -0
  183. package/dist/framework/validate-spec.js +45 -0
  184. package/dist/framework/value-domain.d.ts +26 -0
  185. package/dist/framework/value-domain.js +202 -0
  186. package/dist/framework/views-facade.d.ts +15 -0
  187. package/dist/framework/views-facade.js +19 -0
  188. package/dist/index.d.ts +90 -42
  189. package/dist/index.js +86 -37
  190. package/dist/migrations/2.0.0/raw-css.d.ts +11 -0
  191. package/dist/migrations/2.0.0/raw-css.js +72 -0
  192. package/dist/migrations/2.0.0/v1-artifact.d.ts +1559 -0
  193. package/dist/migrations/2.0.0/v1-artifact.js +1018 -0
  194. package/dist/migrations/20260908171448_settings_as_kind.d.ts +22 -0
  195. package/dist/migrations/20260908171448_settings_as_kind.js +89 -0
  196. package/dist/migrations/20260908194245_visible_state_pointer.d.ts +19 -0
  197. package/dist/migrations/20260908194245_visible_state_pointer.js +115 -0
  198. package/dist/migrations/20260909183001_icon_knockout_variants.d.ts +18 -0
  199. package/dist/migrations/20260909183001_icon_knockout_variants.js +8 -0
  200. package/dist/migrations/20260910212453_linked_system_link_ops.d.ts +13 -0
  201. package/dist/migrations/20260910212453_linked_system_link_ops.js +8 -0
  202. package/dist/migrations/index.d.ts +2 -0
  203. package/dist/migrations/index.js +2 -0
  204. package/dist/react-native/style-keys.generated.d.ts +10 -0
  205. package/dist/react-native/style-keys.generated.js +167 -0
  206. package/dist/renderer/RendererErrorBoundary.d.ts +32 -5
  207. package/dist/renderer/RendererErrorBoundary.js +59 -10
  208. package/dist/renderer/UdsRenderer.d.ts +11 -10
  209. package/dist/renderer/UdsRenderer.js +1 -1
  210. package/dist/renderer/assetEntries.d.ts +37 -0
  211. package/dist/renderer/assetEntries.js +39 -0
  212. package/dist/renderer/assetRenderable.d.ts +14 -6
  213. package/dist/renderer/assetRenderable.js +8 -2
  214. package/dist/renderer/componentEntry.d.ts +58 -0
  215. package/dist/renderer/componentEntry.js +71 -0
  216. package/dist/renderer/icon-library.d.ts +20 -0
  217. package/dist/renderer/index.d.ts +7 -7
  218. package/dist/renderer/index.js +5 -5
  219. package/dist/renderer/primitives/SlotRenderer.d.ts +1 -1
  220. package/dist/renderer/primitives/SlotRenderer.js +1 -1
  221. package/dist/renderer/runtimeComponent.d.ts +33 -0
  222. package/dist/renderer/runtimeComponent.js +113 -0
  223. package/dist/renderer/spec-content.d.ts +43 -0
  224. package/dist/renderer/spec-content.js +95 -0
  225. package/dist/renderer/wrapRegistry.d.ts +22 -37
  226. package/dist/renderer/wrapRegistry.js +10 -20
  227. package/dist/renderer/wrappers/event-bridge.js +6 -5
  228. package/dist/renderer/wrappers/hex-normalize.js +6 -5
  229. package/dist/renderer/wrappers/html-aliases.d.ts +7 -2
  230. package/dist/renderer/wrappers/html-aliases.js +36 -19
  231. package/dist/renderer/wrappers/inline-styles.js +7 -6
  232. package/dist/spec/asset-jsx.d.ts +18 -5
  233. package/dist/spec/asset-jsx.js +27 -16
  234. package/dist/spec/collapse-text-labels.d.ts +5 -15
  235. package/dist/spec/collapse-text-labels.js +26 -19
  236. package/dist/spec/empty-node-slots.d.ts +56 -34
  237. package/dist/spec/empty-node-slots.js +87 -47
  238. package/dist/spec/index.d.ts +21 -10
  239. package/dist/spec/index.js +21 -10
  240. package/dist/spec/jsxToSpec.d.ts +14 -9
  241. package/dist/spec/jsxToSpec.js +20 -3
  242. package/dist/spec/preview-elements.d.ts +63 -0
  243. package/dist/spec/preview-elements.js +89 -0
  244. package/dist/spec/rewrite-refs.d.ts +58 -0
  245. package/dist/spec/rewrite-refs.js +250 -0
  246. package/dist/spec/specToJsx.js +18 -29
  247. package/dist/tsconfig.tsbuildinfo +1 -1
  248. package/package.json +39 -52
  249. package/dist/AssetGroup.d.ts +0 -77
  250. package/dist/AssetGroup.js +0 -125
  251. package/dist/Component.d.ts +0 -333
  252. package/dist/Component.js +0 -1061
  253. package/dist/ComponentGroup.d.ts +0 -22
  254. package/dist/ComponentGroup.js +0 -51
  255. package/dist/CompositeStyle.d.ts +0 -30
  256. package/dist/CompositeStyle.js +0 -59
  257. package/dist/Config.d.ts +0 -528
  258. package/dist/Config.js +0 -1712
  259. package/dist/Mode.d.ts +0 -41
  260. package/dist/Mode.js +0 -81
  261. package/dist/Modifier.d.ts +0 -51
  262. package/dist/Modifier.js +0 -97
  263. package/dist/MotionDef.d.ts +0 -81
  264. package/dist/MotionDef.js +0 -212
  265. package/dist/Props.d.ts +0 -332
  266. package/dist/Props.js +0 -35
  267. package/dist/Provider.d.ts +0 -20
  268. package/dist/Provider.js +0 -14
  269. package/dist/StyleProp.d.ts +0 -145
  270. package/dist/StyleProp.js +0 -239
  271. package/dist/Token.d.ts +0 -76
  272. package/dist/Token.js +0 -133
  273. package/dist/TokenGroup.d.ts +0 -33
  274. package/dist/TokenGroup.js +0 -69
  275. package/dist/asset-kind.d.ts +0 -55
  276. package/dist/asset-kind.js +0 -29
  277. package/dist/asset-value.d.ts +0 -23
  278. package/dist/asset-value.js +0 -40
  279. package/dist/brands.d.ts +0 -30
  280. package/dist/brands.js +0 -20
  281. package/dist/captureCallerPath.d.ts +0 -48
  282. package/dist/captureCallerPath.js +0 -95
  283. package/dist/colorExpressions.d.ts +0 -131
  284. package/dist/colorExpressions.js +0 -148
  285. package/dist/component-referrers.d.ts +0 -30
  286. package/dist/component-referrers.js +0 -40
  287. package/dist/config-diagnostics.d.ts +0 -21
  288. package/dist/config-diagnostics.js +0 -12
  289. package/dist/defineAssetGroup.d.ts +0 -200
  290. package/dist/defineAssetGroup.js +0 -323
  291. package/dist/defineProvider.d.ts +0 -29
  292. package/dist/defineProvider.js +0 -60
  293. package/dist/element-marker.d.ts +0 -63
  294. package/dist/element-marker.js +0 -113
  295. package/dist/entity-utils.d.ts +0 -56
  296. package/dist/entity-utils.js +0 -105
  297. package/dist/extension.d.ts +0 -55
  298. package/dist/extension.js +0 -214
  299. package/dist/factories.d.ts +0 -863
  300. package/dist/factories.js +0 -475
  301. package/dist/font-face.d.ts +0 -25
  302. package/dist/font-face.js +0 -72
  303. package/dist/foreign-component-name.d.ts +0 -21
  304. package/dist/foreign-component-name.js +0 -42
  305. package/dist/interpolate.d.ts +0 -20
  306. package/dist/interpolate.js +0 -10
  307. package/dist/jsx/__fixtures__/cross-component-preview.d.ts +0 -3
  308. package/dist/jsx/__fixtures__/cross-component-preview.js +0 -15
  309. package/dist/jsx/jsx-dev-runtime.d.ts +0 -15
  310. package/dist/jsx/jsx-dev-runtime.js +0 -11
  311. package/dist/jsx/jsx-runtime.d.ts +0 -48
  312. package/dist/jsx/jsx-runtime.js +0 -305
  313. package/dist/linked-system-pins.d.ts +0 -30
  314. package/dist/linked-system-pins.js +0 -45
  315. package/dist/linkedNodePrefixes.d.ts +0 -73
  316. package/dist/linkedNodePrefixes.js +0 -99
  317. package/dist/markers.d.ts +0 -235
  318. package/dist/markers.js +0 -70
  319. package/dist/motion-constants.d.ts +0 -37
  320. package/dist/motion-constants.js +0 -61
  321. package/dist/native/NativeConfig.d.ts +0 -56
  322. package/dist/native/NativeConfig.js +0 -162
  323. package/dist/native/assets.d.ts +0 -20
  324. package/dist/native/assets.js +0 -17
  325. package/dist/native/components.d.ts +0 -139
  326. package/dist/native/components.js +0 -67
  327. package/dist/native/index.d.ts +0 -18
  328. package/dist/native/index.js +0 -17
  329. package/dist/native/modes.d.ts +0 -10
  330. package/dist/native/modes.js +0 -11
  331. package/dist/native/types.d.ts +0 -95
  332. package/dist/native/types.js +0 -0
  333. package/dist/native/validation.d.ts +0 -8
  334. package/dist/native/validation.js +0 -885
  335. package/dist/native/values.d.ts +0 -7
  336. package/dist/native/values.js +0 -15
  337. package/dist/native.d.ts +0 -12
  338. package/dist/native.js +0 -10
  339. package/dist/refs.d.ts +0 -204
  340. package/dist/refs.js +0 -129
  341. package/dist/registry-aliases.d.ts +0 -33
  342. package/dist/registry-aliases.js +0 -35
  343. package/dist/registry-dir.d.ts +0 -22
  344. package/dist/registry-dir.js +0 -10
  345. package/dist/renderer/makeRegistry.d.ts +0 -34
  346. package/dist/renderer/makeRegistry.js +0 -52
  347. package/dist/renderer/makeUdsRenderer.d.ts +0 -13
  348. package/dist/renderer/makeUdsRenderer.js +0 -51
  349. package/dist/renderer/wrappers/component-slots.d.ts +0 -41
  350. package/dist/renderer/wrappers/component-slots.js +0 -66
  351. package/dist/renderer/wrappers/slot-resolution.d.ts +0 -25
  352. package/dist/renderer/wrappers/slot-resolution.js +0 -68
  353. package/dist/renderer/wrappers/void-elements.d.ts +0 -37
  354. package/dist/renderer/wrappers/void-elements.js +0 -40
  355. package/dist/spec/layer-props.d.ts +0 -52
  356. package/dist/spec/layer-props.js +0 -149
  357. package/dist/spec/preview-controls.d.ts +0 -44
  358. package/dist/spec/preview-controls.js +0 -139
  359. package/dist/spec/slot-refs.d.ts +0 -39
  360. package/dist/spec/slot-refs.js +0 -56
  361. package/dist/token-override-rows.d.ts +0 -68
  362. package/dist/token-override-rows.js +0 -233
  363. package/dist/tokenValueType.d.ts +0 -34
  364. package/dist/tokenValueType.js +0 -138
  365. package/dist/types/css-properties.d.ts +0 -233
  366. package/dist/types/css-properties.js +0 -14
  367. package/dist/types/css-property-keywords.d.ts +0 -156
  368. package/dist/types/css-property-keywords.js +0 -616
  369. package/dist/types/css-values.d.ts +0 -63
  370. package/dist/types/css-values.js +0 -16
  371. package/dist/types.d.ts +0 -1138
  372. package/dist/types.js +0 -12
  373. package/dist/units.d.ts +0 -14
  374. package/dist/units.js +0 -16
  375. package/dist/utils/index.d.ts +0 -4
  376. package/dist/utils/index.js +0 -4
@@ -1,885 +0,0 @@
1
- import { isAssetRef, isTokenRef } from "../refs.js";
2
- import { isMixExpr } from "../colorExpressions.js";
3
- import { EXACT_SEMVER_RE, UUID_RE } from "../linked-system-pins.js";
4
- import { createModeBackedModifierLookup, modifierTreeToOverrideRows, resolveOverrideRow } from "../token-override-rows.js";
5
- import { isOperatingSystemValue } from "./values.js";
6
- import { validRange } from "semver";
7
- //#region src/native/validation.ts
8
- const TOP_LEVEL_KEYS = new Set([
9
- "schemaVersion",
10
- "platform",
11
- "builtAt",
12
- "namespace",
13
- "styleEngine",
14
- "buildOptions",
15
- "dependencyPolicy",
16
- "defaultModes",
17
- "modes",
18
- "tokenGroups",
19
- "assetGroups",
20
- "components",
21
- "componentGroups",
22
- "linkedSystems"
23
- ]);
24
- const LINKED_SYSTEM_PIN_KEYS = new Set(["name", "version"]);
25
- const BUILD_OPTIONS_KEYS = new Set(["componentsDir"]);
26
- const DEPENDENCY_POLICY_KEYS = new Set(["providedBy", "version"]);
27
- const COMPONENT_KEYS = new Set([
28
- "id",
29
- "layers",
30
- "props",
31
- "defaultProps",
32
- "styles",
33
- "label",
34
- "description"
35
- ]);
36
- const COMPONENT_CONFIG_KEYS = new Set([
37
- "base",
38
- "variants",
39
- "booleans",
40
- "runtimeStates",
41
- "values",
42
- "description"
43
- ]);
44
- const LAYER_KEYS = new Set(["kind", "styleProp"]);
45
- const COMPONENT_GROUP_KEYS = new Set([
46
- "components",
47
- "label",
48
- "description"
49
- ]);
50
- const GROUP_KEYS = new Set([
51
- "tokens",
52
- "label",
53
- "description"
54
- ]);
55
- const ASSET_GROUP_KEYS = new Set([
56
- "assetKind",
57
- "members",
58
- "label",
59
- "description"
60
- ]);
61
- const ASSET_MEMBER_KEYS = new Set(["fontFamily"]);
62
- const MODE_OPTION_KEYS = new Set([
63
- "modifier",
64
- "label",
65
- "description",
66
- "appearance",
67
- "minWidth",
68
- "css",
69
- "media"
70
- ]);
71
- const APPEARANCES = new Set(["light", "dark"]);
72
- const OS_KEYS = new Set([
73
- "__kind",
74
- "default",
75
- "ios",
76
- "android"
77
- ]);
78
- const TOKEN_REF_KEYS = new Set(["__kind", "ref"]);
79
- const MIX_KEYS = new Set([
80
- "__kind",
81
- "from",
82
- "to",
83
- "amount",
84
- "colorSpace"
85
- ]);
86
- const COLOR_SPACES = new Set([
87
- "srgb",
88
- "srgb-linear",
89
- "oklab",
90
- "oklch",
91
- "lab",
92
- "lch",
93
- "hsl",
94
- "hwb"
95
- ]);
96
- function validateSerializedNativeConfig(input, expectedSchemaVersion = 4) {
97
- const diagnostics = [];
98
- const configDefinition = { kind: "config" };
99
- if (!isRecord(input)) {
100
- push(diagnostics, "INVALID_SCHEMA", [], configDefinition, "Native config must be a plain object.");
101
- return diagnostics;
102
- }
103
- reportUnknownKeys(input, TOP_LEVEL_KEYS, [], configDefinition, diagnostics);
104
- if (input.schemaVersion !== expectedSchemaVersion) push(diagnostics, typeof input.schemaVersion === "number" ? "UNSUPPORTED_SCHEMA_VERSION" : "INVALID_SCHEMA", ["schemaVersion"], configDefinition, `Native config schema version must be ${expectedSchemaVersion}; received ${String(input.schemaVersion)}.`);
105
- if (input.platform !== "native") push(diagnostics, "PLATFORM_MISMATCH", ["platform"], configDefinition, "Native config must declare platform: \"native\".");
106
- if (input.builtAt !== void 0 && typeof input.builtAt !== "string") push(diagnostics, "INVALID_SCHEMA", ["builtAt"], configDefinition, "builtAt must be a string when present.");
107
- validateNamespace(input.namespace, diagnostics);
108
- validateStyleEngine(input.styleEngine, diagnostics);
109
- validateBuildOptions(input.buildOptions, diagnostics);
110
- validateDependencyPolicy(input.dependencyPolicy, diagnostics);
111
- validateModes(input.modes, diagnostics);
112
- validateDefaultModes(input.defaultModes, input.modes, diagnostics);
113
- validateAssetGroups(input.assetGroups, diagnostics);
114
- validateTokenGroups(input.tokenGroups, diagnostics);
115
- validateComponents(input.components, diagnostics);
116
- validateComponentGroups(input.componentGroups, input.components, diagnostics);
117
- validateLinkedSystems(input.linkedSystems, diagnostics);
118
- validateReferences(input, diagnostics);
119
- validateModifierOwnership(input, diagnostics);
120
- return dedupe(diagnostics);
121
- }
122
- function validateDependencyPolicy(value, diagnostics) {
123
- if (value === void 0) return;
124
- const definition = { kind: "config" };
125
- if (!isRecord(value)) {
126
- push(diagnostics, "INVALID_DEPENDENCY_POLICY", ["dependencyPolicy"], definition, "dependencyPolicy must be a record keyed by npm package name.");
127
- return;
128
- }
129
- for (const [name, policy] of Object.entries(value)) {
130
- const path = ["dependencyPolicy", name];
131
- if (!isValidPackageName(name)) push(diagnostics, "INVALID_DEPENDENCY_POLICY", path, definition, `"${name}" is not a valid npm package name.`);
132
- if (!isRecord(policy)) {
133
- push(diagnostics, "INVALID_DEPENDENCY_POLICY", path, definition, "Dependency policy entries must be plain objects.");
134
- continue;
135
- }
136
- reportUnknownKeys(policy, DEPENDENCY_POLICY_KEYS, path, definition, diagnostics);
137
- if (policy.providedBy !== "consumer" && policy.providedBy !== "registry") push(diagnostics, "INVALID_DEPENDENCY_POLICY", [...path, "providedBy"], definition, "providedBy must be either \"consumer\" or \"registry\".");
138
- if (typeof policy.version !== "string" || validRange(policy.version) === null) push(diagnostics, "INVALID_DEPENDENCY_POLICY", [...path, "version"], definition, "version must be a valid semver range.");
139
- }
140
- }
141
- function isValidPackageName(name) {
142
- if (name.length === 0 || name.length > 214 || name !== name.toLowerCase()) return false;
143
- return /^(?:@[a-z0-9~][a-z0-9._~-]*\/)?[a-z0-9~][a-z0-9._~-]*$/.test(name);
144
- }
145
- function validateLinkedSystems(value, diagnostics) {
146
- if (value === void 0) return;
147
- const definition = { kind: "config" };
148
- if (!isRecord(value)) {
149
- push(diagnostics, "INVALID_SCHEMA", ["linkedSystems"], definition, "linkedSystems must be a record keyed by source-system UUID.");
150
- return;
151
- }
152
- for (const [systemId, pin] of Object.entries(value)) {
153
- const path = ["linkedSystems", systemId];
154
- if (!UUID_RE.test(systemId)) push(diagnostics, "INVALID_SCHEMA", path, definition, "Linked-system pins are keyed by the source system UUID.");
155
- if (!isRecord(pin)) {
156
- push(diagnostics, "INVALID_SCHEMA", path, definition, "A linked-system pin must be an object with name and version.");
157
- continue;
158
- }
159
- reportUnknownKeys(pin, LINKED_SYSTEM_PIN_KEYS, path, definition, diagnostics);
160
- if (typeof pin.name !== "string" || pin.name.trim().length === 0) push(diagnostics, "INVALID_SCHEMA", [...path, "name"], definition, "A linked-system pin requires a non-empty display name.");
161
- if (typeof pin.version !== "string" || !EXACT_SEMVER_RE.test(pin.version)) push(diagnostics, "INVALID_SCHEMA", [...path, "version"], definition, "A linked-system pin requires an exact semver version (no ranges).");
162
- }
163
- }
164
- function validateBuildOptions(value, diagnostics) {
165
- if (value === void 0) return;
166
- if (!isRecord(value)) {
167
- push(diagnostics, "INVALID_SCHEMA", ["buildOptions"], { kind: "config" }, "Native buildOptions must be an object.");
168
- return;
169
- }
170
- reportUnknownKeys(value, BUILD_OPTIONS_KEYS, ["buildOptions"], { kind: "config" }, diagnostics);
171
- if (value.componentsDir !== void 0 && (typeof value.componentsDir !== "string" || value.componentsDir.length === 0)) push(diagnostics, "INVALID_SCHEMA", ["buildOptions", "componentsDir"], { kind: "config" }, "Native componentsDir must be a non-empty path string.");
172
- }
173
- function validateComponents(value, diagnostics) {
174
- if (value === void 0) return;
175
- if (!isRecord(value)) {
176
- push(diagnostics, "INVALID_SCHEMA", ["components"], { kind: "config" }, "Native components must be a record.");
177
- return;
178
- }
179
- const ids = /* @__PURE__ */ new Map();
180
- for (const [componentName, component] of Object.entries(value)) {
181
- const path = ["components", componentName];
182
- const definition = {
183
- kind: "component",
184
- name: componentName
185
- };
186
- if (!isRecord(component)) {
187
- push(diagnostics, "INVALID_SCHEMA", path, definition, `Native component "${componentName}" must be an object.`);
188
- continue;
189
- }
190
- reportUnknownKeys(component, COMPONENT_KEYS, path, definition, diagnostics);
191
- if (typeof component.id !== "string" || component.id.length === 0) push(diagnostics, "INVALID_SCHEMA", [...path, "id"], definition, `Native component "${componentName}" must declare a stable id.`);
192
- else {
193
- const owner = ids.get(component.id);
194
- if (owner !== void 0) push(diagnostics, "INVALID_SCHEMA", [...path, "id"], definition, `Native component id "${component.id}" is already registered as "${owner}".`);
195
- else ids.set(component.id, componentName);
196
- }
197
- const layerNames = validateComponentLayers(component.layers, [...path, "layers"], definition, diagnostics);
198
- validateComponentConfig(component.styles, [...path, "styles"], definition, layerNames, diagnostics);
199
- validateComponentProps(component.props, path, definition, diagnostics);
200
- validateComponentStyleProps(component, path, definition, diagnostics);
201
- }
202
- }
203
- function validateComponentStyleProps(component, path, definition, diagnostics) {
204
- const props = isRecord(component.props) ? component.props : {};
205
- const styles = isRecord(component.styles) ? component.styles : {};
206
- for (const [groupName, expectedKind] of [["variants", "variant"], ["booleans", "boolean"]]) {
207
- const groups = styles[groupName];
208
- if (!isRecord(groups)) continue;
209
- for (const [propName, options] of Object.entries(groups)) {
210
- const marker = props[propName];
211
- if (!isRecord(marker) || marker.__kind !== expectedKind) {
212
- push(diagnostics, "INVALID_REFERENCE", [
213
- ...path,
214
- "styles",
215
- groupName,
216
- propName
217
- ], definition, `Native ${groupName} styles must target a ${expectedKind} component prop.`);
218
- continue;
219
- }
220
- if (!isRecord(options)) continue;
221
- const allowedOptions = expectedKind === "variant" && Array.isArray(marker.values) ? new Set(marker.values.map(String)) : new Set(["true", "false"]);
222
- for (const optionName of Object.keys(options)) if (!allowedOptions.has(optionName)) push(diagnostics, "INVALID_REFERENCE", [
223
- ...path,
224
- "styles",
225
- groupName,
226
- propName,
227
- optionName
228
- ], definition, expectedKind === "variant" ? `Native variant style option "${optionName}" is not declared by prop "${propName}".` : `Native boolean style option "${optionName}" must be true or false.`);
229
- }
230
- }
231
- }
232
- function validateComponentProps(value, componentPath, definition, diagnostics) {
233
- if (!isRecord(value)) {
234
- push(diagnostics, "INVALID_SCHEMA", [...componentPath, "props"], definition, "Native component props must be a record.");
235
- return;
236
- }
237
- for (const [propName, marker] of Object.entries(value)) {
238
- if (!isRecord(marker) || ![
239
- "slot",
240
- "boolean",
241
- "string",
242
- "number",
243
- "variant"
244
- ].includes(String(marker.__kind))) {
245
- push(diagnostics, "INVALID_SCHEMA", [
246
- ...componentPath,
247
- "props",
248
- propName
249
- ], definition, `Unknown native component prop marker "${String(isRecord(marker) ? marker.__kind : marker)}".`);
250
- continue;
251
- }
252
- if (marker.__kind === "variant") {
253
- if (!Array.isArray(marker.values) || marker.values.length === 0 || marker.values.some((option) => typeof option !== "string" && typeof option !== "number" || typeof option === "number" && !Number.isFinite(option))) push(diagnostics, "INVALID_SCHEMA", [
254
- ...componentPath,
255
- "props",
256
- propName,
257
- "values"
258
- ], definition, "Native variant props require at least one finite number or string option.");
259
- else if (new Set(marker.values.map(String)).size !== marker.values.length) push(diagnostics, "INVALID_SCHEMA", [
260
- ...componentPath,
261
- "props",
262
- propName,
263
- "values"
264
- ], definition, "Native variant prop options must remain unique when serialized as object keys.");
265
- }
266
- }
267
- }
268
- function validateComponentLayers(value, path, definition, diagnostics) {
269
- const names = /* @__PURE__ */ new Set();
270
- if (!isRecord(value) || Object.keys(value).length === 0) {
271
- push(diagnostics, "INVALID_SCHEMA", path, definition, "A native component must declare at least one layer.");
272
- return names;
273
- }
274
- for (const [layerName, layer] of Object.entries(value)) {
275
- names.add(layerName);
276
- const layerPath = [...path, layerName];
277
- if (!isRecord(layer)) {
278
- push(diagnostics, "INVALID_SCHEMA", layerPath, definition, `Native layer "${layerName}" must be an object.`);
279
- continue;
280
- }
281
- reportUnknownKeys(layer, LAYER_KEYS, layerPath, definition, diagnostics);
282
- if (layer.kind !== "view" && layer.kind !== "text" && layer.kind !== "image") push(diagnostics, "INVALID_SCHEMA", [...layerPath, "kind"], definition, `Native layer "${layerName}" must use view, text, or image styles.`);
283
- if (layer.styleProp !== void 0 && (typeof layer.styleProp !== "string" || layer.styleProp.length === 0)) push(diagnostics, "INVALID_SCHEMA", [...layerPath, "styleProp"], definition, "A public style prop name must be a non-empty string.");
284
- }
285
- return names;
286
- }
287
- function validateComponentConfig(value, path, definition, layerNames, diagnostics) {
288
- if (!isRecord(value)) {
289
- push(diagnostics, "INVALID_SCHEMA", path, definition, "Native component styles must be an object.");
290
- return;
291
- }
292
- reportUnknownKeys(value, COMPONENT_CONFIG_KEYS, path, definition, diagnostics);
293
- validateLayerStyleMap(value.base, [...path, "base"], definition, layerNames, diagnostics);
294
- for (const key of ["variants", "booleans"]) {
295
- const groups = value[key];
296
- if (groups === void 0) continue;
297
- if (!isRecord(groups)) {
298
- push(diagnostics, "INVALID_SCHEMA", [...path, key], definition, `${key} must be a record.`);
299
- continue;
300
- }
301
- for (const [propName, values] of Object.entries(groups)) {
302
- if (!isRecord(values)) {
303
- push(diagnostics, "INVALID_SCHEMA", [
304
- ...path,
305
- key,
306
- propName
307
- ], definition, `${key} styles for "${propName}" must be an option record.`);
308
- continue;
309
- }
310
- for (const [optionName, styles] of Object.entries(values)) validateLayerStyleMap(styles, [
311
- ...path,
312
- key,
313
- propName,
314
- optionName
315
- ], definition, layerNames, diagnostics);
316
- }
317
- }
318
- if (value.runtimeStates !== void 0) if (!isRecord(value.runtimeStates)) push(diagnostics, "INVALID_SCHEMA", [...path, "runtimeStates"], definition, "Native runtimeStates must be a record.");
319
- else for (const [stateName, styles] of Object.entries(value.runtimeStates)) validateLayerStyleMap(styles, [
320
- ...path,
321
- "runtimeStates",
322
- stateName
323
- ], definition, layerNames, diagnostics);
324
- if (value.values !== void 0) if (!isRecord(value.values)) push(diagnostics, "INVALID_SCHEMA", [...path, "values"], definition, "Native named values must be a record.");
325
- else for (const [name, namedValue] of Object.entries(value.values)) validateNativeValue(namedValue, [
326
- ...path,
327
- "values",
328
- name
329
- ], definition, diagnostics, true);
330
- }
331
- function validateLayerStyleMap(value, path, definition, layerNames, diagnostics) {
332
- if (value === void 0) return;
333
- if (!isRecord(value)) {
334
- push(diagnostics, "INVALID_SCHEMA", path, definition, "Native component styles must be a layer record.");
335
- return;
336
- }
337
- for (const [layerName, styles] of Object.entries(value)) {
338
- if (!layerNames.has(layerName)) {
339
- push(diagnostics, "INVALID_REFERENCE", [...path, layerName], definition, `Native layer "${layerName}" is not declared by this component.`);
340
- continue;
341
- }
342
- if (!isRecord(styles)) {
343
- push(diagnostics, "INVALID_SCHEMA", [...path, layerName], definition, `Styles for layer "${layerName}" must be an object.`);
344
- continue;
345
- }
346
- for (const [property, styleValue] of Object.entries(styles)) validateComponentStyleValue(styleValue, [
347
- ...path,
348
- layerName,
349
- property
350
- ], definition, diagnostics);
351
- }
352
- }
353
- function validateComponentStyleValue(value, path, definition, diagnostics) {
354
- if (Array.isArray(value)) {
355
- value.forEach((entry, index) => {
356
- validateComponentStyleValue(entry, [...path, index], definition, diagnostics);
357
- });
358
- return;
359
- }
360
- if (isRecord(value) && !("__kind" in value)) {
361
- for (const [key, nested] of Object.entries(value)) validateComponentStyleValue(nested, [...path, key], definition, diagnostics);
362
- return;
363
- }
364
- validateNativeValue(value, path, definition, diagnostics, true);
365
- }
366
- function validateComponentGroups(value, components, diagnostics) {
367
- if (value === void 0) return;
368
- if (!isRecord(value)) {
369
- push(diagnostics, "INVALID_SCHEMA", ["componentGroups"], { kind: "config" }, "Native componentGroups must be a record.");
370
- return;
371
- }
372
- const registered = isRecord(components) ? components : {};
373
- for (const [groupName, group] of Object.entries(value)) {
374
- const path = ["componentGroups", groupName];
375
- const definition = {
376
- kind: "componentGroup",
377
- name: groupName
378
- };
379
- if (!isRecord(group)) {
380
- push(diagnostics, "INVALID_SCHEMA", path, definition, `Native component group "${groupName}" must be an object.`);
381
- continue;
382
- }
383
- reportUnknownKeys(group, COMPONENT_GROUP_KEYS, path, definition, diagnostics);
384
- if (!Array.isArray(group.components) || group.components.length === 0) push(diagnostics, "INVALID_SCHEMA", [...path, "components"], definition, "A native component group must contain at least one component.");
385
- else for (const [index, componentName] of group.components.entries()) if (typeof componentName !== "string" || !(componentName in registered)) push(diagnostics, "INVALID_REFERENCE", [
386
- ...path,
387
- "components",
388
- index
389
- ], definition, `Native component "${String(componentName)}" is not registered.`);
390
- for (const key of ["label", "description"]) if (group[key] !== void 0 && typeof group[key] !== "string") push(diagnostics, "INVALID_SCHEMA", [...path, key], definition, `${key} must be a string.`);
391
- }
392
- }
393
- function validateStyleEngine(value, diagnostics) {
394
- if (value !== void 0 && value !== "react-native" && value !== "unistyles") push(diagnostics, "INVALID_SCHEMA", ["styleEngine"], { kind: "config" }, "Native styleEngine must be \"react-native\" or \"unistyles\" when present.");
395
- }
396
- function validateNamespace(value, diagnostics) {
397
- if (value === void 0) return;
398
- if (typeof value !== "string" || value.length === 0 || value.includes(":") || /\s/.test(value)) push(diagnostics, "INVALID_NAMESPACE", ["namespace"], { kind: "config" }, "Native config namespace must be a non-empty string without whitespace or \":\".");
399
- }
400
- function validateModes(value, diagnostics) {
401
- if (value === void 0) return;
402
- if (!isRecord(value)) {
403
- push(diagnostics, "INVALID_SCHEMA", ["modes"], { kind: "config" }, "modes must be a record.");
404
- return;
405
- }
406
- const kindOwners = /* @__PURE__ */ new Map();
407
- const modifierOwners = /* @__PURE__ */ new Map();
408
- for (const [modeName, options] of Object.entries(value)) {
409
- const definition = {
410
- kind: "mode",
411
- name: modeName
412
- };
413
- const modePath = ["modes", modeName];
414
- if (!isRecord(options)) {
415
- push(diagnostics, "INVALID_SCHEMA", modePath, definition, `Mode "${modeName}" must be an option record.`);
416
- continue;
417
- }
418
- if (Object.keys(options).length === 0) push(diagnostics, "INVALID_MODE_CONDITION", modePath, definition, `Native mode "${modeName}" must define at least one appearance or viewport option.`);
419
- let modeKind;
420
- const conditionValues = /* @__PURE__ */ new Map();
421
- for (const [optionName, option] of Object.entries(options)) {
422
- const optionPath = [...modePath, optionName];
423
- if (!isRecord(option)) {
424
- push(diagnostics, "INVALID_SCHEMA", optionPath, definition, `Mode option "${modeName}/${optionName}" must be an object.`);
425
- continue;
426
- }
427
- reportUnknownKeys(option, MODE_OPTION_KEYS, optionPath, definition, diagnostics);
428
- for (const key of [
429
- "modifier",
430
- "label",
431
- "description"
432
- ]) if (option[key] !== void 0 && typeof option[key] !== "string") push(diagnostics, "INVALID_SCHEMA", [...optionPath, key], definition, `${key} must be a string when present.`);
433
- if (typeof option.modifier === "string" && !option.modifier.startsWith("_")) push(diagnostics, "INVALID_SCHEMA", [...optionPath, "modifier"], definition, "Native mode modifiers must start with \"_\".");
434
- for (const key of ["css", "media"]) if (option[key] !== void 0) push(diagnostics, "UNSUPPORTED_NATIVE_FIELD", [...optionPath, key], definition, `Mode option field "${key}" is web-only and is not supported by NativeConfig.`);
435
- const hasAppearance = option.appearance !== void 0;
436
- if (hasAppearance === (option.minWidth !== void 0)) {
437
- push(diagnostics, "INVALID_MODE_CONDITION", optionPath, definition, `Native mode option "${modeName}/${optionName}" must define exactly one condition: appearance or minWidth.`);
438
- continue;
439
- }
440
- const optionKind = hasAppearance ? "appearance" : "viewport";
441
- if (modeKind !== void 0 && modeKind !== optionKind) push(diagnostics, "INVALID_MODE_CONDITION", optionPath, definition, `Native mode "${modeName}" cannot mix appearance and viewport options.`);
442
- else modeKind = optionKind;
443
- let conditionValue;
444
- if (hasAppearance) if (typeof option.appearance !== "string" || !APPEARANCES.has(option.appearance)) push(diagnostics, "INVALID_MODE_CONDITION", [...optionPath, "appearance"], definition, "Native appearance must be \"light\" or \"dark\".");
445
- else conditionValue = option.appearance;
446
- else if (typeof option.minWidth !== "number" || !Number.isFinite(option.minWidth) || option.minWidth < 0) push(diagnostics, "INVALID_MODE_CONDITION", [...optionPath, "minWidth"], definition, "Native minWidth must be a finite, non-negative number.");
447
- else conditionValue = option.minWidth;
448
- if (conditionValue !== void 0) {
449
- const previous = conditionValues.get(conditionValue);
450
- if (previous !== void 0) push(diagnostics, "INVALID_MODE_CONDITION", optionPath, definition, `Native mode options "${modeName}/${previous}" and "${modeName}/${optionName}" describe the same condition.`);
451
- else conditionValues.set(conditionValue, optionName);
452
- }
453
- const modifier = typeof option.modifier === "string" ? option.modifier : `_${optionName}`;
454
- const previousModifierOwner = modifierOwners.get(modifier);
455
- if (previousModifierOwner !== void 0) push(diagnostics, "DUPLICATE_MODIFIER", [...optionPath, "modifier"], definition, `Modifier "${modifier}" is already owned by mode option "${previousModifierOwner}".`);
456
- else modifierOwners.set(modifier, `${modeName}/${optionName}`);
457
- }
458
- if (modeKind !== void 0) {
459
- const previousKindOwner = kindOwners.get(modeKind);
460
- if (previousKindOwner !== void 0) push(diagnostics, "INVALID_MODE_CONDITION", modePath, definition, `Native ${modeKind} conditions are already registered by mode "${previousKindOwner}".`);
461
- else kindOwners.set(modeKind, modeName);
462
- }
463
- }
464
- }
465
- function validateDefaultModes(value, modes, diagnostics) {
466
- if (value === void 0) return;
467
- if (!isRecord(value)) {
468
- push(diagnostics, "INVALID_DEFAULT_MODE", ["defaultModes"], { kind: "config" }, "defaultModes must be a record of registered mode selections.");
469
- return;
470
- }
471
- const registeredModes = isRecord(modes) ? modes : {};
472
- for (const [modeName, optionName] of Object.entries(value)) {
473
- const path = ["defaultModes", modeName];
474
- const options = registeredModes[modeName];
475
- if (!isRecord(options)) {
476
- push(diagnostics, "INVALID_DEFAULT_MODE", path, {
477
- kind: "mode",
478
- name: modeName
479
- }, `Default mode "${modeName}" is not registered.`);
480
- continue;
481
- }
482
- if (typeof optionName !== "string" || !isRecord(options[optionName])) push(diagnostics, "INVALID_DEFAULT_MODE", path, {
483
- kind: "mode",
484
- name: modeName
485
- }, `Default mode "${modeName}" must select a registered option.`);
486
- }
487
- }
488
- function validateAssetGroups(value, diagnostics) {
489
- if (value === void 0) return;
490
- if (!isRecord(value)) {
491
- push(diagnostics, "INVALID_SCHEMA", ["assetGroups"], { kind: "config" }, "assetGroups must be a record.");
492
- return;
493
- }
494
- for (const [groupName, group] of Object.entries(value)) {
495
- const definition = {
496
- kind: "asset-group",
497
- name: groupName
498
- };
499
- const groupPath = ["assetGroups", groupName];
500
- if (!isRecord(group)) {
501
- push(diagnostics, "INVALID_SCHEMA", groupPath, definition, `Asset group "${groupName}" must be an object.`);
502
- continue;
503
- }
504
- reportUnknownKeys(group, ASSET_GROUP_KEYS, groupPath, definition, diagnostics);
505
- if (group.assetKind !== "font") push(diagnostics, "INVALID_SCHEMA", [...groupPath, "assetKind"], definition, `Native asset group "${groupName}" must currently use assetKind "font".`);
506
- for (const key of ["label", "description"]) if (group[key] !== void 0 && typeof group[key] !== "string") push(diagnostics, "INVALID_SCHEMA", [...groupPath, key], definition, `${key} must be a string when present.`);
507
- if (!isRecord(group.members)) {
508
- push(diagnostics, "INVALID_SCHEMA", [...groupPath, "members"], definition, `Native font asset group "${groupName}" must have a members record.`);
509
- continue;
510
- }
511
- for (const [memberName, member] of Object.entries(group.members)) {
512
- const memberDefinition = {
513
- kind: "asset",
514
- name: `${groupName}/${memberName}`
515
- };
516
- const memberPath = [
517
- ...groupPath,
518
- "members",
519
- memberName
520
- ];
521
- if (!isRecord(member)) {
522
- push(diagnostics, "INVALID_SCHEMA", memberPath, memberDefinition, `Native font asset "${groupName}/${memberName}" must be an object.`);
523
- continue;
524
- }
525
- reportUnknownKeys(member, ASSET_MEMBER_KEYS, memberPath, memberDefinition, diagnostics);
526
- if (typeof member.fontFamily !== "string" || member.fontFamily.length === 0) push(diagnostics, "INVALID_SCHEMA", [...memberPath, "fontFamily"], memberDefinition, `Native font asset "${groupName}/${memberName}" requires a non-empty fontFamily.`);
527
- }
528
- }
529
- }
530
- function validateTokenGroups(value, diagnostics) {
531
- if (value === void 0) return;
532
- if (!isRecord(value)) {
533
- push(diagnostics, "INVALID_SCHEMA", ["tokenGroups"], { kind: "config" }, "tokenGroups must be a record.");
534
- return;
535
- }
536
- for (const [groupName, group] of Object.entries(value)) {
537
- const groupDefinition = {
538
- kind: "token-group",
539
- name: groupName
540
- };
541
- const groupPath = ["tokenGroups", groupName];
542
- if (!isRecord(group)) {
543
- push(diagnostics, "INVALID_SCHEMA", groupPath, groupDefinition, `Token group "${groupName}" must be an object.`);
544
- continue;
545
- }
546
- reportUnknownKeys(group, GROUP_KEYS, groupPath, groupDefinition, diagnostics);
547
- for (const key of ["label", "description"]) if (group[key] !== void 0 && typeof group[key] !== "string") push(diagnostics, "INVALID_SCHEMA", [...groupPath, key], groupDefinition, `${key} must be a string when present.`);
548
- if (!isRecord(group.tokens)) {
549
- push(diagnostics, "INVALID_SCHEMA", [...groupPath, "tokens"], groupDefinition, `Token group "${groupName}" must have a tokens record.`);
550
- continue;
551
- }
552
- for (const [tokenName, token] of Object.entries(group.tokens)) validateTokenDefinition(token, [
553
- ...groupPath,
554
- "tokens",
555
- tokenName
556
- ], {
557
- kind: "token",
558
- name: `${groupName}/${tokenName}`
559
- }, diagnostics);
560
- }
561
- }
562
- function validateTokenDefinition(value, path, definition, diagnostics) {
563
- if (!isRecord(value)) {
564
- push(diagnostics, "INVALID_SCHEMA", path, definition, `Native token "${definition.name ?? ""}" must be an object.`);
565
- return;
566
- }
567
- if (!("value" in value)) push(diagnostics, "INVALID_SCHEMA", [...path, "value"], definition, `Native token "${definition.name ?? ""}" requires a value.`);
568
- else validateNativeValue(value.value, [...path, "value"], definition, diagnostics, true);
569
- if (value.type !== void 0 && typeof value.type !== "string") push(diagnostics, "INVALID_SCHEMA", [...path, "type"], definition, "Token type must be a string when present.");
570
- validateSystemLink(value.link, [...path, "link"], definition, diagnostics);
571
- for (const [key, modifier] of Object.entries(value)) {
572
- if (key === "value" || key === "type" || key === "link") continue;
573
- if (!key.startsWith("_")) {
574
- push(diagnostics, "INVALID_SCHEMA", [...path, key], definition, `Unknown token definition field "${key}"; modifier fields must start with "_".`);
575
- continue;
576
- }
577
- if (looksLikeTokenDefinition(modifier)) validateTokenDefinition(modifier, [...path, key], definition, diagnostics);
578
- else validateNativeValue(modifier, [...path, key], definition, diagnostics, true);
579
- }
580
- }
581
- function validateSystemLink(value, path, definition, diagnostics) {
582
- if (value === void 0) return;
583
- if (!isRecord(value)) {
584
- push(diagnostics, "INVALID_SCHEMA", path, definition, "Token link provenance must be an object.");
585
- return;
586
- }
587
- reportUnknownKeys(value, new Set([
588
- "kind",
589
- "systemId",
590
- "systemVersion",
591
- "sourceKey"
592
- ]), path, definition, diagnostics);
593
- if (value.kind !== "token") push(diagnostics, "INVALID_SCHEMA", [...path, "kind"], definition, "Token link provenance must use kind \"token\".");
594
- for (const key of [
595
- "systemId",
596
- "systemVersion",
597
- "sourceKey"
598
- ]) if (typeof value[key] !== "string" || value[key].length === 0) push(diagnostics, "INVALID_SCHEMA", [...path, key], definition, `Token link provenance requires a non-empty ${key}.`);
599
- }
600
- function validateNativeValue(value, path, definition, diagnostics, allowOperatingSystem) {
601
- if (typeof value === "string" || typeof value === "boolean") return;
602
- if (typeof value === "number") {
603
- if (!Number.isFinite(value)) push(diagnostics, "INVALID_NATIVE_VALUE", path, definition, "Native numeric values must be finite.");
604
- return;
605
- }
606
- if (!isRecord(value)) {
607
- push(diagnostics, "INVALID_NATIVE_VALUE", path, definition, "Native token values must be serializable strings, numbers, booleans, references, supported color expressions, or operatingSystem() values.");
608
- return;
609
- }
610
- if (isTokenRef(value) || isAssetRef(value)) {
611
- reportUnknownKeys(value, TOKEN_REF_KEYS, path, definition, diagnostics);
612
- if (typeof value.ref !== "string" || value.ref.length === 0) push(diagnostics, "INVALID_REFERENCE", [...path, "ref"], definition, "Reference markers require a non-empty ref string.");
613
- return;
614
- }
615
- if (isOperatingSystemValue(value)) {
616
- if (!allowOperatingSystem) {
617
- push(diagnostics, "NESTED_OS_VALUE", path, definition, "An operatingSystem() branch cannot contain another operatingSystem() value.");
618
- return;
619
- }
620
- validateOperatingSystem(value, path, definition, diagnostics);
621
- return;
622
- }
623
- if (isMixExpr(value)) {
624
- validateMix(value, path, definition, diagnostics);
625
- return;
626
- }
627
- const kind = typeof value.__kind === "string" ? value.__kind : void 0;
628
- if (kind === "darken" || kind === "lighten" || kind === "linear-gradient" || kind === "radial-gradient") {
629
- push(diagnostics, "UNSUPPORTED_COLOR_EXPRESSION", path, definition, `Color expression "${kind}" does not yet have cross-platform native semantics; use mix(), alpha(), or a resolved native color.`);
630
- return;
631
- }
632
- push(diagnostics, "INVALID_NATIVE_VALUE", path, definition, "Native token values do not support arbitrary objects or arrays.");
633
- }
634
- function validateOperatingSystem(value, path, definition, diagnostics) {
635
- reportUnknownKeys(value, OS_KEYS, path, definition, diagnostics);
636
- if (value.default === void 0 && (value.ios === void 0 || value.android === void 0)) push(diagnostics, "INCOMPLETE_OS_VALUE", path, definition, "operatingSystem() requires a default value or explicit ios and android values.");
637
- for (const key of [
638
- "default",
639
- "ios",
640
- "android"
641
- ]) if (value[key] !== void 0) validateNativeValue(value[key], [...path, key], definition, diagnostics, false);
642
- }
643
- function validateMix(value, path, definition, diagnostics) {
644
- reportUnknownKeys(value, MIX_KEYS, path, definition, diagnostics);
645
- validateColorOperand(value.from, [...path, "from"], definition, diagnostics);
646
- validateColorOperand(value.to, [...path, "to"], definition, diagnostics);
647
- const amount = typeof value.amount === "string" ? /^(-?(?:\d+(?:\.\d+)?|\.\d+))%$/.exec(value.amount) : null;
648
- const amountNumber = amount ? Number(amount[1]) : NaN;
649
- if (!Number.isFinite(amountNumber) || amountNumber < 0 || amountNumber > 100) push(diagnostics, "INVALID_NATIVE_VALUE", [...path, "amount"], definition, "mix() amount must be a percentage between 0% and 100%.");
650
- if (value.colorSpace !== void 0 && !COLOR_SPACES.has(value.colorSpace)) push(diagnostics, "INVALID_NATIVE_VALUE", [...path, "colorSpace"], definition, `mix() colorSpace "${String(value.colorSpace)}" is unsupported.`);
651
- }
652
- function validateColorOperand(value, path, definition, diagnostics) {
653
- if (typeof value === "string") return;
654
- if (isTokenRef(value)) {
655
- validateNativeValue(value, path, definition, diagnostics, false);
656
- return;
657
- }
658
- if (isMixExpr(value)) {
659
- validateMix(value, path, definition, diagnostics);
660
- return;
661
- }
662
- push(diagnostics, "INVALID_NATIVE_VALUE", path, definition, "Native color expressions accept color strings, token references, or nested mix() expressions.");
663
- }
664
- function validateReferences(config, diagnostics) {
665
- const tokenGroups = isRecord(config.tokenGroups) ? config.tokenGroups : {};
666
- const tokens = /* @__PURE__ */ new Map();
667
- for (const [groupName, group] of Object.entries(tokenGroups)) {
668
- if (!isRecord(group) || !isRecord(group.tokens)) continue;
669
- for (const [tokenName, definition] of Object.entries(group.tokens)) {
670
- if (!isRecord(definition)) continue;
671
- tokens.set(`${groupName}/${tokenName}`, {
672
- definition,
673
- path: [
674
- "tokenGroups",
675
- groupName,
676
- "tokens",
677
- tokenName
678
- ]
679
- });
680
- }
681
- }
682
- const assets = isRecord(config.assetGroups) ? config.assetGroups : {};
683
- const modifierLookup = createNativeModifierLookup(config.modes);
684
- const contexts = buildModifierContexts(config.modes);
685
- for (const [tokenRef, token] of tokens) {
686
- collectAllReferences(token.definition, token.path, {
687
- kind: "token",
688
- name: tokenRef
689
- }, tokens, assets, diagnostics);
690
- for (const modifiers of contexts) resolveTokenContext(tokenRef, modifiers, modifierLookup, tokens, diagnostics, [], token.path);
691
- }
692
- for (const [componentName, component] of Object.entries(config.components ?? {})) collectComponentReferences(component, ["components", componentName], {
693
- kind: "component",
694
- name: componentName
695
- }, tokens, assets, diagnostics);
696
- }
697
- function collectComponentReferences(value, path, definition, tokens, assets, diagnostics) {
698
- if (Array.isArray(value)) {
699
- value.forEach((entry, index) => {
700
- collectComponentReferences(entry, [...path, index], definition, tokens, assets, diagnostics);
701
- });
702
- return;
703
- }
704
- if (!isRecord(value)) return;
705
- if (isTokenRef(value)) {
706
- if (typeof value.ref === "string" && !tokens.has(value.ref)) push(diagnostics, "UNRESOLVED_TOKEN_REFERENCE", path, definition, `Token reference "${value.ref}" does not resolve within this native config.`);
707
- return;
708
- }
709
- if (isAssetRef(value)) {
710
- collectAllReferences(value, path, definition, tokens, assets, diagnostics);
711
- return;
712
- }
713
- for (const [key, nested] of Object.entries(value)) collectComponentReferences(nested, [...path, key], definition, tokens, assets, diagnostics);
714
- }
715
- function collectAllReferences(value, path, definition, tokens, assets, diagnostics) {
716
- walkValues(value, path, (entry, entryPath) => {
717
- if (isTokenRef(entry)) {
718
- if (typeof entry.ref === "string" && !tokens.has(entry.ref)) push(diagnostics, "UNRESOLVED_TOKEN_REFERENCE", entryPath, definition, `Token reference "${entry.ref}" does not resolve within this native config.`);
719
- return;
720
- }
721
- if (!isAssetRef(entry) || typeof entry.ref !== "string") return;
722
- const slash = entry.ref.indexOf("/");
723
- const groupName = slash > 0 ? entry.ref.slice(0, slash) : "";
724
- const memberName = slash > 0 ? entry.ref.slice(slash + 1) : "";
725
- const group = assets[groupName];
726
- if (!groupName || !memberName || !group || group.assetKind !== "font" || !isRecord(group.members) || !group.members[memberName]) push(diagnostics, "UNRESOLVED_ASSET_REFERENCE", entryPath, definition, `Asset reference "${entry.ref}" does not resolve to a registered native font asset.`);
727
- });
728
- }
729
- function resolveTokenContext(ref, activeModes, modifierLookup, tokens, diagnostics, stack, sourcePath) {
730
- if (stack.includes(ref)) {
731
- const cycle = [...stack.slice(stack.indexOf(ref)), ref].join(" -> ");
732
- push(diagnostics, "TOKEN_REFERENCE_CYCLE", sourcePath, {
733
- kind: "token",
734
- name: stack[0] ?? ref
735
- }, `Native token reference cycle detected: ${cycle}.`);
736
- return;
737
- }
738
- const token = tokens.get(ref);
739
- if (!token) return;
740
- const selected = selectTokenValue(token.definition, token.path, activeModes, modifierLookup);
741
- const nextStack = [...stack, ref];
742
- walkValues(selected.value, selected.path, (entry, entryPath) => {
743
- if (isTokenRef(entry) && typeof entry.ref === "string") resolveTokenContext(entry.ref, activeModes, modifierLookup, tokens, diagnostics, nextStack, entryPath);
744
- });
745
- }
746
- function selectTokenValue(definition, path, activeModes, modifierLookup) {
747
- const selected = resolveOverrideRow(modifierTreeToOverrideRows(definition, modifierLookup), activeModes);
748
- if (!selected) return {
749
- value: definition.value,
750
- path: [...path, "value"]
751
- };
752
- let source = definition;
753
- for (const modifier of selected.sourceModifierPath) source = source[modifier];
754
- return {
755
- value: selected.value,
756
- path: [
757
- ...path,
758
- ...selected.sourceModifierPath,
759
- ...looksLikeTokenDefinition(source) ? ["value"] : []
760
- ]
761
- };
762
- }
763
- function buildModifierContexts(modes) {
764
- let contexts = [/* @__PURE__ */ new Set()];
765
- for (const [modeName, options] of Object.entries(modes ?? {})) {
766
- if (!isRecord(options)) continue;
767
- const modeRefs = Object.entries(options).filter((entry) => isRecord(entry[1])).map(([optionName]) => `${modeName}.${optionName}`);
768
- contexts = contexts.flatMap((context) => [context, ...modeRefs.map((modeRef) => new Set([...context, modeRef]))]);
769
- }
770
- return contexts;
771
- }
772
- function createNativeModifierLookup(modes) {
773
- return createModeBackedModifierLookup(Object.entries(modes ?? {}).flatMap(([modeName, options], modeOrder) => {
774
- if (!isRecord(options)) return [];
775
- return Object.entries(options).flatMap(([optionName, option], optionOrder) => {
776
- if (!isRecord(option)) return [];
777
- return [{
778
- modifier: typeof option.modifier === "string" ? option.modifier : `_${optionName}`,
779
- mode: modeName,
780
- option: optionName,
781
- label: typeof option.label === "string" ? option.label : void 0,
782
- modeOrder,
783
- optionOrder
784
- }];
785
- });
786
- }));
787
- }
788
- function validateModifierOwnership(config, diagnostics) {
789
- const owners = /* @__PURE__ */ new Map();
790
- if (isRecord(config.modes)) for (const [modeName, options] of Object.entries(config.modes)) {
791
- if (!isRecord(options)) continue;
792
- for (const [optionName, option] of Object.entries(options)) {
793
- if (!isRecord(option)) continue;
794
- const modifier = typeof option.modifier === "string" ? option.modifier : `_${optionName}`;
795
- if (!owners.has(modifier)) owners.set(modifier, modeName);
796
- }
797
- }
798
- if (!isRecord(config.tokenGroups)) return;
799
- for (const [groupName, group] of Object.entries(config.tokenGroups)) {
800
- if (!isRecord(group) || !isRecord(group.tokens)) continue;
801
- for (const [tokenName, definition] of Object.entries(group.tokens)) {
802
- if (!isRecord(definition)) continue;
803
- validateDefinitionModifiers(definition, [
804
- "tokenGroups",
805
- groupName,
806
- "tokens",
807
- tokenName
808
- ], {
809
- kind: "token",
810
- name: `${groupName}/${tokenName}`
811
- }, owners, /* @__PURE__ */ new Set(), diagnostics);
812
- }
813
- }
814
- }
815
- function validateDefinitionModifiers(definition, path, tokenDefinition, owners, activeModeGroups, diagnostics) {
816
- for (const [modifier, value] of Object.entries(definition)) {
817
- if (!modifier.startsWith("_")) continue;
818
- const modifierPath = [...path, modifier];
819
- const owner = owners.get(modifier);
820
- if (owner === void 0) {
821
- push(diagnostics, "UNOWNED_MODIFIER", modifierPath, tokenDefinition, `Modifier "${modifier}" is not owned by a registered mode option.`);
822
- continue;
823
- }
824
- if (activeModeGroups.has(owner)) push(diagnostics, "INVALID_MODE_COMBINATION", modifierPath, tokenDefinition, `Compound native token overrides cannot select more than one option from mode "${owner}".`);
825
- if (looksLikeTokenDefinition(value)) validateDefinitionModifiers(value, modifierPath, tokenDefinition, owners, new Set([...activeModeGroups, owner]), diagnostics);
826
- }
827
- }
828
- function walkValues(value, path, visit) {
829
- if (!isRecord(value)) return;
830
- if (isTokenRef(value) || isAssetRef(value)) {
831
- visit(value, path);
832
- return;
833
- }
834
- if (isOperatingSystemValue(value)) {
835
- for (const key of [
836
- "default",
837
- "ios",
838
- "android"
839
- ]) if (value[key] !== void 0) walkValues(value[key], [...path, key], visit);
840
- return;
841
- }
842
- if (isMixExpr(value)) {
843
- walkValues(value.from, [...path, "from"], visit);
844
- walkValues(value.to, [...path, "to"], visit);
845
- return;
846
- }
847
- if (looksLikeTokenDefinition(value)) {
848
- walkValues(value.value, [...path, "value"], visit);
849
- for (const [key, nested] of Object.entries(value)) if (key.startsWith("_")) walkValues(nested, [...path, key], visit);
850
- return;
851
- }
852
- for (const [key, nested] of Object.entries(value)) if (key.startsWith("_")) walkValues(nested, [...path, key], visit);
853
- }
854
- function looksLikeTokenDefinition(value) {
855
- return isRecord(value) && "value" in value && !("__kind" in value);
856
- }
857
- function reportUnknownKeys(value, allowed, path, definition, diagnostics) {
858
- for (const key of Object.keys(value)) {
859
- if (allowed.has(key)) continue;
860
- push(diagnostics, "INVALID_SCHEMA", [...path, key], definition, `Unknown native config field "${key}".`);
861
- }
862
- }
863
- function isRecord(value) {
864
- return typeof value === "object" && value !== null && !Array.isArray(value);
865
- }
866
- function push(diagnostics, code, path, definition, reason) {
867
- diagnostics.push({
868
- code,
869
- severity: "error",
870
- path,
871
- definition,
872
- reason
873
- });
874
- }
875
- function dedupe(diagnostics) {
876
- const seen = /* @__PURE__ */ new Set();
877
- return diagnostics.filter((diagnostic) => {
878
- const key = `${diagnostic.code}:${diagnostic.path.join(".")}:${diagnostic.reason}`;
879
- if (seen.has(key)) return false;
880
- seen.add(key);
881
- return true;
882
- });
883
- }
884
- //#endregion
885
- export { validateSerializedNativeConfig };