@yahoo/uds-create-config 2.44.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,100 @@
1
+ import { pathOf } from "./utils/refs.js";
2
+ import { Config } from "./Config.js";
3
+ //#region src/framework/defineConfig.ts
4
+ /**
5
+ * The kinds one or more config types own, as VALUES — the runtime half of {@link ConfigKind}.
6
+ *
7
+ * For the declaration whose honest content is "all of them": a section of the stylesheet whose reach
8
+ * is the whole config, a scan with no smaller answer. Written out as a literal that list is a copy of
9
+ * the config type, and a copy silently stops being every kind the day a kind is added — the new one
10
+ * is simply absent, and whatever keyed on the list serves a stale answer for exactly the edits that
11
+ * touch it. Derived, it cannot be short.
12
+ *
13
+ * Variadic because a declaration can span platforms: a web system and a native one are different
14
+ * config types, and an emitter asked to describe both wants the union.
15
+ */
16
+ function kindsOf(...configTypes) {
17
+ const kinds = /* @__PURE__ */ new Set();
18
+ for (const configType of configTypes) for (const entity of Object.values(configType.entities)) kinds.add(entity.kind);
19
+ return [...kinds];
20
+ }
21
+ function defineConfig(spec) {
22
+ const owned = spec.entities;
23
+ const sources = spec.sources ?? {};
24
+ for (const name of Object.keys(sources)) {
25
+ const cls = owned[name];
26
+ if (!cls) throw new Error(`${spec.name}: source "${name}" is not an owned entity of this config`);
27
+ const kindDef = cls.kindDef;
28
+ const kindName = kindDef?.name ?? name;
29
+ if (!kindDef?.sourceIdentity) throw new Error(`${spec.name}: source "${name}" names the kind "${kindName}", which declares no \`sourceIdentity\` — a source's items are the slugs refs qualify with, so the kind has to say which of its fields identify a source`);
30
+ if (!kindDef.sourceResolution) throw new Error(`${spec.name}: source "${name}" names the kind "${kindName}", which declares no \`sourceResolution\` — resolving a source has to be validated against the kind's OWN \`{ resolved, unavailable }\` schemas, because what an origin and a failure are is the kind's to say and not the framework's`);
31
+ }
32
+ const derived = spec.derivedEntities ?? {};
33
+ /** The read/link handle an accessor returns — kind-generic reads delegate to the config, so it works
34
+ * uniformly for owned and derived kinds. */
35
+ const makeCollection = (config, kind) => ({
36
+ __linkedKind: kind,
37
+ source: config.liveSource,
38
+ list: (opts) => config.list(kind, opts),
39
+ get: (pathOrRef) => config.resolve(kind, typeof pathOrRef === "string" ? pathOrRef : pathOf(pathOrRef.__ref)),
40
+ dependents: (path) => config.dependentsOf(kind, path),
41
+ tree: () => config.tree(kind)
42
+ });
43
+ class TypedConfig extends Config {
44
+ constructor() {
45
+ super(spec.name, spec.description);
46
+ for (const cls of Object.values(owned)) this.seedEntityInPlace(cls);
47
+ for (const cls of Object.values(derived)) this.seedEntityInPlace(cls);
48
+ }
49
+ /** Load items into a NEW config — like every other mutation, this returns rather than mutates,
50
+ * which is why the chained authoring form (`new System().register(…)`) is the idiom. */
51
+ register(records) {
52
+ let next = this;
53
+ for (const [name, record] of Object.entries(records)) {
54
+ const cls = owned[name];
55
+ if (!cls) throw new Error(`"${name}" is not an owned entity of config "${spec.name}"`);
56
+ next = next.registerEntity(cls, record);
57
+ }
58
+ return next.coerceOwned();
59
+ }
60
+ static fromJSON(json, options) {
61
+ return new TypedConfig().hydrateFrom(json, options);
62
+ }
63
+ static configName = spec.name;
64
+ static entities = owned;
65
+ static derivedEntities = derived;
66
+ static sources = sources;
67
+ /** Swap kinds by their accessor name, across owned / derived. */
68
+ static extend(swaps) {
69
+ const pick = (base) => {
70
+ const next = { ...base };
71
+ for (const [name, cls] of Object.entries(swaps)) if (name in base) next[name] = cls;
72
+ return next;
73
+ };
74
+ const unknownSlots = Object.keys(swaps).filter((name) => !(name in owned) && !(name in derived));
75
+ if (unknownSlots.length > 0) throw new Error(`${spec.name}.extend: no such entity ${unknownSlots.map((n) => `"${n}"`).join(", ")} — an extension may only replace a kind this config already declares`);
76
+ return defineConfig({
77
+ name: spec.name,
78
+ description: spec.description,
79
+ entities: pick(owned),
80
+ derivedEntities: pick(derived),
81
+ sources,
82
+ extendsBase: true
83
+ });
84
+ }
85
+ }
86
+ for (const [name, cls] of [...Object.entries(owned), ...Object.entries(derived)]) {
87
+ if (name in TypedConfig.prototype || name === "state") throw new Error(`${spec.name}: entity accessor "${name}" collides with a Config member — rename the accessor (the KIND itself is unaffected)`);
88
+ Object.defineProperty(TypedConfig.prototype, name, {
89
+ get() {
90
+ return makeCollection(this, cls.kind);
91
+ },
92
+ enumerable: false,
93
+ configurable: true
94
+ });
95
+ }
96
+ if (!spec.extendsBase) Config.registerConfigType(spec.name, TypedConfig);
97
+ return TypedConfig;
98
+ }
99
+ //#endregion
100
+ export { defineConfig, kindsOf };
@@ -0,0 +1,74 @@
1
+ import { Entity } from "./Entity.js";
2
+ import { Ref } from "./utils/refs.js";
3
+ import { TraverseOptions } from "./ref-graph.js";
4
+ import { FieldsSchema } from "./utils/field-schema.js";
5
+ import { Config } from "./Config.js";
6
+ import { ComputedInput, EntityKind } from "./registry.js";
7
+ import { z } from "zod";
8
+
9
+ //#region src/framework/defineDerivedEntity.d.ts
10
+ /** The zod schema an entity class IS — a ref to this entity. */
11
+ type RefSchema = z.ZodObject<{
12
+ __ref: z.ZodString;
13
+ }>;
14
+ /** Compute a kind's members from a source config, keyed by path. */
15
+ type DeriveMembers<F extends FieldsSchema> = (source: Config) => Record<string, z.infer<F>>;
16
+ /** Virtual, recomputed-on-read fields — a pure fn of {@link ComputedInput}, with `member` narrowed to
17
+ * this kind's own fields. Non-serializable is fine. */
18
+ type ComputedMap<F extends FieldsSchema> = Record<string, (input: Omit<ComputedInput, 'member'> & {
19
+ member: z.infer<F>;
20
+ }) => unknown>;
21
+ /** The read shape of a derived entity — its declared fields plus the return types of its computeds. */
22
+ type Computed<C extends ComputedMap<FieldsSchema>> = { [K in keyof C]: ReturnType<C[K]> };
23
+ /** A derived entity class — a ref schema (so `z.array(Tool)` type-checks a Tool ref array) plus the
24
+ * read/override toolkit. NO create/delete/rename: membership is derived, not authored.
25
+ *
26
+ * Zod's own `extend` is omitted before ours is declared, so the name resolves to one method rather
27
+ * than an overload pair — see {@link DerivedEntityClass.extend}. */
28
+ type DerivedEntityClass<F extends FieldsSchema, C extends ComputedMap<F> = Record<never, never>> = Omit<RefSchema, 'extend'> & {
29
+ readonly kind: string;
30
+ readonly isDerived: true;
31
+ /** The kind's immutable metadata, built once by `buildKind` (carries `derived` — the compute
32
+ * spec). `Config.register` copies this into the config's `#entities`. */
33
+ readonly kindDef: EntityKind; /** `Tool.ref('component/create')` → `{ __ref: 'tool:component/create' }`. */
34
+ ref(path: string): Ref; /** Resolve one member — accepts a path OR a `Ref` (ref-aware; rejects a wrong-kind ref). */
35
+ get(config: Config, pathOrRef: string | Ref): (Entity & z.infer<F> & Computed<C>) | undefined;
36
+ list(config: Config): (Entity & z.infer<F> & Computed<C>)[];
37
+ dependents(config: Config, path: string, opts?: TraverseOptions): string[]; /** Overridable kinds only — merges a sparse override of `overridable` fields. */
38
+ update<Cfg extends Config>(config: Cfg, path: string, data: Partial<z.infer<F>>): Cfg;
39
+ /**
40
+ * Extend this kind — the same kind with part of it replaced. The consumer difference becomes a
41
+ * different entity in a different config type (`ConfigClass.extend`) rather than a branch inside a
42
+ * shared derivation: a CLI's `Tool` describes the authoring API, Studio's describes the patch, and
43
+ * neither has to ask who's calling.
44
+ *
45
+ * `computed` MERGES over the base (replace one field, keep the rest); everything else replaces.
46
+ * `kind` is inherited and can't be changed — an extension stands in for its base in a config slot,
47
+ * so it has to answer to the same kind.
48
+ *
49
+ * SHADOWS `ZodObject.extend`, which this class inherits by being a zod schema. Deliberate, and it
50
+ * costs nothing: the schema an entity class IS is its REF schema (`{ __ref }`), and adding fields to
51
+ * a ref is meaningless for an entity — there's no legitimate call to displace. Shadowing writes an
52
+ * own property, so no other zod object is affected. A SUB-entity class must never do this: its
53
+ * schema is the member shape, and `deriveCreateSchema` really does call zod's `extend` on it.
54
+ */
55
+ extend<C2 extends ComputedMap<F> = C>(overrides: Partial<Omit<DerivedEntitySpec<F, C2>, 'kind'>>): DerivedEntityClass<F, C2>;
56
+ };
57
+ /** What `defineDerivedEntity` takes — named so {@link DerivedEntityClass.extend} can restate part of
58
+ * it without repeating the shape. Its keys are the extendable surface ({@link EXTENDABLE_KEYS}). */
59
+ interface DerivedEntitySpec<F extends FieldsSchema, C extends ComputedMap<F> = Record<never, never>> {
60
+ kind: string;
61
+ fields: F;
62
+ deriveMembers: DeriveMembers<F>;
63
+ /** Fields a user may override. Present → an `update`-only op + a sparse override store. */
64
+ overridable?: readonly (keyof z.infer<F> & string)[];
65
+ /** Virtual fields, recomputed on read, never serialized. Intersecting with `ComputedMap<F>` gives
66
+ * each fn's `member` param its contextual type (`z.infer<F>`) while still inferring `C` for the
67
+ * precise return types on `get`/`list`. */
68
+ computed?: C & ComputedMap<F>;
69
+ label?: string;
70
+ labelPlural?: string;
71
+ }
72
+ declare function defineDerivedEntity<F extends FieldsSchema, C extends ComputedMap<F> = Record<never, never>>(spec: DerivedEntitySpec<F, C>): DerivedEntityClass<F, C>;
73
+ //#endregion
74
+ export { ComputedMap, DeriveMembers, DerivedEntityClass, defineDerivedEntity };
@@ -0,0 +1,83 @@
1
+ import { isRef, kindOf, pathOf, ref } from "./utils/refs.js";
2
+ import { buildKind } from "./registry.js";
3
+ import { z } from "zod";
4
+ //#region src/framework/defineDerivedEntity.ts
5
+ /**
6
+ * `defineDerivedEntity({ kind, fields, deriveMembers, overridable?, computed? })` — a THIRD member
7
+ * source beside stored (`defineEntity`) and depended-on (a qualified ref). A derived kind's members are
8
+ * COMPUTED from a source config (`deriveMembers(source)`) — ref-able and resolvable like any entity,
9
+ * but read-only: no create/delete/rename. Two optional extensions:
10
+ *
11
+ * - `overridable` — the fields a user may overwrite; the kind gains an `update`-only op that writes a
12
+ * SPARSE override (only the diff persists; the base always re-derives). Everything else stays derived.
13
+ * - `computed` — VIRTUAL fields recomputed on read, never stored, never overridable — the home for a
14
+ * non-serializable projection (a zod schema, a function). Each fn declares its own provenance.
15
+ *
16
+ * A derived kind self-derives on registration, sourcing from the config it's registered into;
17
+ * `Config.register` routes it by whether the KIND is derived. See `docs/config-v2.md`.
18
+ */
19
+ /** What `extend` accepts. Checked at runtime because `extend` is shadowed: an unrecognized key is a
20
+ * typo, or a zod raw shape reaching this method expecting zod's `extend`. Either should say so
21
+ * rather than quietly build a kind missing half its derivation. `kind` is absent on purpose — an
22
+ * extension answers to its base's kind. */
23
+ const EXTENDABLE_KEYS = new Set([
24
+ "fields",
25
+ "deriveMembers",
26
+ "overridable",
27
+ "computed",
28
+ "label",
29
+ "labelPlural"
30
+ ]);
31
+ function defineDerivedEntity(spec) {
32
+ const kindDef = buildKind({
33
+ name: spec.kind,
34
+ fields: spec.fields,
35
+ groupFields: z.object({}),
36
+ label: spec.label,
37
+ labelPlural: spec.labelPlural,
38
+ derived: {
39
+ deriveMembers: spec.deriveMembers,
40
+ overridable: spec.overridable,
41
+ computed: spec.computed
42
+ }
43
+ });
44
+ const schema = z.object({ __ref: z.string().startsWith(ref(spec.kind, "").__ref) });
45
+ const toPath = (pathOrRef) => {
46
+ if (!isRef(pathOrRef)) return pathOrRef;
47
+ if (kindOf(pathOrRef) !== spec.kind) return void 0;
48
+ return pathOf(pathOrRef);
49
+ };
50
+ return Object.assign(schema, {
51
+ kind: spec.kind,
52
+ kindDef,
53
+ isDerived: true,
54
+ ref: (path) => ref(spec.kind, path),
55
+ get: (config, pathOrRef) => {
56
+ const path = toPath(pathOrRef);
57
+ return path === void 0 ? void 0 : config.resolve(spec.kind, path);
58
+ },
59
+ list: (config) => config.list(spec.kind),
60
+ dependents: (config, path, opts) => config.dependentsOf(spec.kind, path, opts),
61
+ update: (config, path, data) => config.apply({
62
+ kind: spec.kind,
63
+ operation: "update",
64
+ path,
65
+ data
66
+ }),
67
+ extend: (overrides) => {
68
+ const unknown = Object.keys(overrides).filter((key) => !EXTENDABLE_KEYS.has(key));
69
+ if (unknown.length > 0) throw new Error(`${spec.kind}.extend: unknown option ${unknown.map((key) => `"${key}"`).join(", ")} — expected one of ${[...EXTENDABLE_KEYS].join(", ")}. This is an entity extension, not \`ZodObject.extend\`.`);
70
+ return defineDerivedEntity({
71
+ ...spec,
72
+ ...overrides,
73
+ kind: spec.kind,
74
+ computed: {
75
+ ...spec.computed,
76
+ ...overrides.computed
77
+ }
78
+ });
79
+ }
80
+ });
81
+ }
82
+ //#endregion
83
+ export { defineDerivedEntity };
@@ -0,0 +1,318 @@
1
+ import { Entity } from "./Entity.js";
2
+ import { ExtendableRef, Ref } from "./utils/refs.js";
3
+ import { TraverseOptions } from "./ref-graph.js";
4
+ import { CreateInput, FieldsSchema } from "./utils/field-schema.js";
5
+ import { FieldsCtx, UserSchemas } from "./schemas.js";
6
+ import { SubEntityClass } from "./defineSubEntity.js";
7
+ import { PathOf } from "./registered.js";
8
+ import { BulkOverlayWrite, BulkQuery, SourceOverlay, SourceResolutionSchemas } from "./sources.js";
9
+ import { GroupBody } from "./utils/group.js";
10
+ import { Config, ListOptions, TreeNode } from "./Config.js";
11
+ import { ComputedFields, EntityKind, Linkable } from "./registry.js";
12
+ import { z } from "zod";
13
+
14
+ //#region src/framework/defineEntity.d.ts
15
+ /** Keys of any member of a (possibly union) type — distributes, so a union yields every
16
+ * member's keys, not just the ones shared by all (which is what `keyof` gives on a union). */
17
+ type KeysOfUnion<T> = T extends unknown ? keyof T : never;
18
+ /** The zod schema shape an entity class is — a ref to this entity: `{ __ref: '<kind>:<path>' }`. */
19
+ type RefSchema = z.ZodObject<{
20
+ __ref: z.ZodString;
21
+ }>;
22
+ /** What a `fields`/`groupFields` override may be: a plain record of schemas where `null` removes
23
+ * the named key, or a zod object as the merge-only sugar (a shape has no way to spell a removal). */
24
+ type ShapeOverride = z.ZodObject<z.ZodRawShape> | Record<string, z.ZodTypeAny | null>;
25
+ /** The keys-to-schemas (or null) view of an override, whichever form it was written in. */
26
+ type OverrideEntries<O extends ShapeOverride> = O extends z.ZodObject<infer S extends z.ZodRawShape> ? S : O;
27
+ /** The merged fields type an extension ends up with — the override's keys replace (or, via `null`,
28
+ * remove) the base's; everything unnamed is inherited. Type-level twin of `extendShape`. */
29
+ type ExtendedFields<F extends FieldsSchema, O extends ShapeOverride> = F extends z.ZodObject<infer Shape extends z.ZodRawShape> ? z.ZodObject<Omit<Shape, keyof OverrideEntries<O>> & { [K in keyof OverrideEntries<O> as OverrideEntries<O>[K] extends null ? never : K & string]: Extract<OverrideEntries<O>[K], z.ZodTypeAny> }> : never;
30
+ /** An entity class — the whole toolkit for a kind. It is a zod schema (a ref to this entity), so
31
+ * it can be used directly as another entity's field (`component: Component` = "a ref to a
32
+ * Component"), and it carries the authoring/resolution methods. `Component.ref('Card')` makes a
33
+ * specific member-ref value; `Component` itself is the entity-level ref schema.
34
+ *
35
+ * Zod's own `extend` is removed from this type so ours is the only `extend` TypeScript sees —
36
+ * see {@link EntityClass.extend} for why we shadow it. */
37
+ /**
38
+ * One resolved item of a kind — `ItemOf<typeof Mode>`.
39
+ *
40
+ * What `Token.get(config, path)` hands back: the entity (its path, leaf, `toJSON`) with its own fields
41
+ * on it. Consumers need to name that type constantly — a function taking a mode, a list of canvas
42
+ * roles — and the entity is exported as a value, so `Mode` in a type position is an error and
43
+ * `NonNullable<ReturnType<typeof Token.get>>` is what people were left writing.
44
+ *
45
+ * Read off `get` rather than off the fields schema, so it stays whatever `get` actually returns.
46
+ */
47
+ type ItemOf<E> = E extends {
48
+ get(config: Config, pathOrRef: string | Ref): infer R;
49
+ } ? NonNullable<R> : never;
50
+ /** An entity as a read returns it — its declared fields, plus the return type of every computed. */
51
+ type Read<F extends FieldsSchema, C extends ComputedFields> = Entity & z.infer<F> & { readonly [K in keyof C]: ReturnType<C[K]> };
52
+ type EntityClass<F extends FieldsSchema, G extends FieldsSchema,
53
+ /** The kind as a literal, so `ref` can narrow to the paths a consumer's config declares. Defaults
54
+ * to `string`, which is what every 2-argument use of this type keeps getting. */
55
+ K extends string = string,
56
+ /** The op schemas as written, so a consumer can infer an operation's input type off the entity
57
+ * instead of restating it. See {@link OpInput}. */
58
+ S extends UserSchemas = UserSchemas,
59
+ /** The kind's `computed` map as written, so `Token.get(...).link` is typed off the function that
60
+ * produces it rather than restated. Defaults to none. */
61
+ C extends ComputedFields = Record<never, never>,
62
+ /** Whether the kind has exactly one item — see `singleton` on `defineEntity`. Read off the spec so
63
+ * `get` can drop its path argument for exactly the kinds whose one item needs none. */
64
+ Single extends boolean = false> = Omit<RefSchema, 'extend'> & {
65
+ readonly kind: K;
66
+ /** Whether the kind has exactly one item — see `singleton` on `defineEntity`. A property rather than
67
+ * only a type parameter so a conditional type can tell the two apart: `get`'s signature differs by
68
+ * it, but methods compare bivariantly and a required parameter matches an optional one. */
69
+ readonly singleton: Single;
70
+ /**
71
+ * The entity's own op schemas, at the type level.
72
+ *
73
+ * Present so `OpInput<typeof Component, 'element-insert'>` resolves. Every consumer that wrote an
74
+ * operation used to hand-declare its input shape — 20 files did, because the zod schema was defined
75
+ * here and thrown away by this type — and a hand-declared shape is checked against nothing.
76
+ */
77
+ readonly schemas: S;
78
+ /** The kind's immutable metadata (field names, primary field, sub-entities, merged op `schemas`),
79
+ * built once by `buildKind`. `Config.register` copies this into the config's `#entities`. */
80
+ readonly kindDef: EntityKind;
81
+ /** The kind-bound member-ref maker — `Component.ref('Card')` → `{ __ref: 'component:Card' }`.
82
+ * Called on the entity itself; a kind never re-exports it under a second, lowercase name. A
83
+ * singleton's one item sits at the kind's own name, so its path may be left out: `Settings.ref()`. */
84
+ ref(...path: Single extends true ? [path?: PathOf<K>] : [path: PathOf<K>]): ExtendableRef<Partial<CreateInput<F>>>;
85
+ /** Typed constructor for one item — a full body, or a bare value/ref that's shorthand
86
+ * for the kind's primary field. Returned as-is; `register` normalizes the shorthand. */
87
+ item(def: CreateInput<F> | string | number | Ref): CreateInput<F> | string | number | Ref;
88
+ /** Typed constructor for a group node — branded so `register` routes it to the group
89
+ * store; input is the group fields' create body. */
90
+ group(meta: GroupBody<F, G>): GroupBody<F, G>;
91
+ /** Resolve one item, typed off the fields — `Component.get(config, 'Button')`. Ref-aware: also
92
+ * accepts a `Ref` (`Node.component` → `Component.get(config, node.component)`), rejecting a
93
+ * wrong-kind ref. A singleton's one item sits at the kind's own name, so its path may be left out:
94
+ * `Settings.get(config)`, which answers `undefined` on a config type that declares no such kind. */
95
+ get(config: Config, ...pathOrRef: Single extends true ? [pathOrRef?: string | Ref] : [pathOrRef: string | Ref]): Read<F, C> | undefined;
96
+ /** Every item of this kind, typed off the fields — `Component.list(config)`. Total by default;
97
+ * `{ retired: false }` is the offer surface's read (see `Config.list`). */
98
+ list(config: Config, opts?: ListOptions): Read<F, C>[]; /** This kind's items as a folder/file tree — `Component.tree(config)` (the sidebar). */
99
+ tree(config: Config): TreeNode[];
100
+ /** This kind's group nodes and their metadata — `Package.groups(config)`, the packages a system
101
+ * depends on. The enumeration `list`/`tree` can't give: both derive from item paths, so a group
102
+ * declared with no members yet (a package the host supplies, which no render names) is invisible
103
+ * to them. */
104
+ groups(config: Config, opts?: ListOptions): {
105
+ path: string;
106
+ meta: GroupBody<F, G>;
107
+ }[];
108
+ /** What references a given item (`kind:path` strings) — the reverse dependency graph.
109
+ * `{ transitive: true }` returns the whole closure rather than the direct edges, which is what
110
+ * a chain like `font → token → composite → component` needs: every hop is a different kind, so
111
+ * the one-hop answer names an intermediate rather than anything a person recognises as a use. */
112
+ dependents(config: Config, path: string, opts?: TraverseOptions): string[];
113
+ /** Create an item of this kind — `Component.create(config, 'Button', {…})`. Typed body; returns
114
+ * the config for chaining. (The typed twin of `config.apply({kind, operation:'create', …})`.) */
115
+ create<C extends Config>(config: C, path: string, data: CreateInput<F>): C; /** Update an item — a partial patch merged over the current value. */
116
+ update<C extends Config>(config: C, path: string, data: Partial<z.infer<F>>): C; /** Delete an item (refused while other entities still reference it). */
117
+ delete<C extends Config>(config: C, path: string): C; /** Rename an item's path — references cascade. */
118
+ rename<C extends Config>(config: C, path: string, to: string): C;
119
+ /**
120
+ * Make a variant of this kind — same kind, different rules, stating only the differences.
121
+ * `NativeToken = Token.extend({ fields: z.object({ value: nativeTokenValue }) })` is a token
122
+ * whose values must be native-legal; everything it doesn't mention works like the base. A
123
+ * Config type adopts the variant through `ConfigClass.extend`, and it takes the base's slot.
124
+ *
125
+ * One rule for how an override combines with the base: **merge per key, `null` removes,
126
+ * anything unmentioned is inherited.**
127
+ *
128
+ * - `fields` / `groupFields`: a named key replaces (or adds) that field; `null` removes it —
129
+ * `groupFields: { cssPrefix: null }` is how the native token drops a web-only setting. A zod
130
+ * object also works as the merge-only form (its shape can't spell a removal). Removal must be
131
+ * explicit because only declared fields survive save and load — an implicit wipe would
132
+ * silently drop stored data.
133
+ * - `subEntities`: same — name one to swap it, `null` to drop it, the rest are inherited. A
134
+ * collection must keep a field of the same name; extend refuses a half-swap.
135
+ * - `schemas`: same, per verb — `{ delete: null }` removes one (`UserSchemas`' own form).
136
+ * - `kind` cannot change. The variant stands in for the base everywhere, so refs, tool names
137
+ * and stored data keep working, and nothing downstream ever asks which variant it has.
138
+ *
139
+ * Shadows zod's `ZodObject.extend`, on purpose — this class doubles as a zod schema, but the
140
+ * schema it is is just the ref wrapper, and adding fields to a ref means nothing. A sub-entity
141
+ * class must never do the same: its schema is the member shape, and `deriveCreateSchema` really
142
+ * does call zod's `extend` on it.
143
+ */
144
+ extend<F2 extends ShapeOverride = Record<never, never>, G2 extends ShapeOverride = Record<never, never>, S2 extends UserSchemas = S>(overrides: {
145
+ fields?: F2;
146
+ groupFields?: G2;
147
+ subEntities?: Partial<Record<string, SubEntityClass | null>>;
148
+ schemas?: S2 & UserSchemas;
149
+ label?: string;
150
+ labelPlural?: string;
151
+ /** What a config file calls this variant. A variant keeps its base's `kind`, so nothing derived
152
+ * from the kind can name it — and a source writer that guesses emits the base's class into a
153
+ * Config that never imported it. See {@link EntityKind.entityName}. */
154
+ entityName?: string;
155
+ }): EntityClass<ExtendedFields<F, F2>, ExtendedFields<G, G2>, K, S2, C, Single>;
156
+ };
157
+ declare function defineEntity<F extends FieldsSchema, G extends FieldsSchema = z.ZodObject<Record<never, never>>, K extends string = string, const S extends UserSchemas = Record<never, never>, const C extends ComputedFields = Record<never, never>, Single extends boolean = false>(spec: {
158
+ kind: K;
159
+ /** The kind's fields, or a factory over the write's context (`config`, `body`) when a field's
160
+ * schema depends on the config or on its sibling fields. See {@link FieldsDeclaration}. */
161
+ fields: F | ((ctx: FieldsCtx) => F);
162
+ groupFields?: G; /** Human label for one item, for UI/docs surfaces (defaults to a title-cased `kind`). */
163
+ label?: string;
164
+ /** Human label for the collection (defaults to `label + 's'`) — set when the naive plural is
165
+ * wrong (`style-prop` → `Style Properties`). */
166
+ labelPlural?: string;
167
+ /** The class name a config file spells this entity through, when it isn't the one the kind derives.
168
+ * See {@link EntityKind.entityName} — a variant is the case that needs it. */
169
+ entityName?: string;
170
+ /** The keyed sub-entity collections — field name → its `defineSubEntity` definition (e.g. a
171
+ * Component's `{ layers: Layer, props: Prop }`). These are the fields sub-entity CRUD
172
+ * (`Config.apply` sub-ops) may target, and each definition declares its member's schema and
173
+ * labels rather than them being inferred from this entity's field type. Keys distribute over a
174
+ * union so a collection declared on just one variant (a composite's `layers`) is allowed —
175
+ * plain `keyof` on a union would only see the shared discriminant. */
176
+ subEntities?: Partial<Record<KeysOfUnion<z.infer<F>> & string, SubEntityClass>>;
177
+ /** Op-schema overrides/additions/removals, keyed by verb — merged over the derived defaults
178
+ * (CRUD + reads + sub-*). `{ create: { data } }` overrides a data schema; `{ resolve: { input,
179
+ * readOnly, handler } }` adds a custom op; `{ delete: null }` removes one. See {@link UserSchemas}. */
180
+ schemas?: S & UserSchemas;
181
+ /**
182
+ * Virtual fields, recomputed on every read and never serialized — `(the item's own fields, the config
183
+ * it lives in) => value`.
184
+ *
185
+ * For a fact that is a derivation of what the entity already holds, rather than something an author
186
+ * states. Declaring it here is what stops every consumer deriving its own: a token's provenance is
187
+ * read off the source qualifier in its `value`, and a UI, the CLI and the AI read tools would
188
+ * otherwise each carry a copy of that rule and drift.
189
+ *
190
+ * They read like any other field and are absent from `toJSON`, so nothing computed can be written
191
+ * into an artifact and then contradict the value it was derived from.
192
+ */
193
+ computed?: C;
194
+ /**
195
+ * For a kind whose items name an external source: the fields that decide which source.
196
+ *
197
+ * Declaring it is what lets the framework treat values recorded through this kind as belonging to
198
+ * the exact source they came from, without the framework naming this kind. See
199
+ * {@link EntityKind.sourceIdentity}.
200
+ */
201
+ sourceIdentity?: readonly string[];
202
+ /** The part of `sourceIdentity` that names the system and not its version. See
203
+ * {@link EntityKind.sourceOrigin}. */
204
+ sourceOrigin?: readonly string[];
205
+ /**
206
+ * Whether an author ever hand-writes a ref to this kind — default true. See
207
+ * {@link EntityKind.authoredRefs}; a kind the build populates from the source tree declares
208
+ * `false` so its paths stay out of the emitted authoring types.
209
+ */
210
+ authoredRefs?: boolean;
211
+ /**
212
+ * Whether this kind may be borrowed from a linked source — default true. See
213
+ * {@link EntityKind.linkable}; a kind that is about this config rather than about design (a `file`,
214
+ * a source pin) declares `false` and the borrow op leaves it alone. A kind whose answer depends on
215
+ * the two configs declares a predicate over them.
216
+ */
217
+ linkable?: Linkable;
218
+ /**
219
+ * Group fields that describe how THIS config emits, rather than what the group is — so a borrowed
220
+ * group does not inherit them. See {@link EntityKind.localGroupFields}.
221
+ */
222
+ localGroupFields?: readonly string[];
223
+ /**
224
+ * Whether a `/` in this kind's path is a folder boundary — default true.
225
+ *
226
+ * A kind declares `false` when the slash is part of the name rather than a hierarchy, and then no
227
+ * group is synthesized from a path prefix. `Package` is the case: its path is an npm specifier, so
228
+ * `@ariakit/react` is one identity and `@ariakit` is a scope that nothing installs and no import
229
+ * names. Synthesized anyway, those prefixes reached every surface that reads groups — including the
230
+ * emitted authoring types, which offered `Package.ref('@ariakit')` as though it were a module.
231
+ *
232
+ * The same statement `.claude/rules/config-authoring.md` makes about a name that contains a slash:
233
+ * `w/1/2` is the fraction one-half, not a folder named `1`. Declared here so the framework asks
234
+ * the kind rather than testing for one by name.
235
+ */
236
+ emergentGroups?: boolean;
237
+ /**
238
+ * Whether this kind has exactly one item, at a path equal to the kind's name — a config's settings.
239
+ * See {@link EntityKind.singleton} for what the framework does with it. Every field has to be
240
+ * optional or defaulted, since the item is seeded from `{}` when the kind is registered. Its `get`
241
+ * and `ref` take no path: `Settings.get(config)`.
242
+ */
243
+ singleton?: Single;
244
+ /**
245
+ * The collection a member ref addresses when it names no collection — `package:react-native#View`
246
+ * rather than `#View`.
247
+ *
248
+ * Declared, never inferred from "the kind has exactly one sub-entity": that rule would silently
249
+ * re-point every stored ref the day a second one is added. A kind that declares none keeps the
250
+ * qualified form, which is what `component:Input#props/disabled` needs, since several collections
251
+ * mean the ref has to say which.
252
+ */
253
+ bareMember?: string; /** Whether a leaf names an item on its own — see {@link EntityKind.uniqueLeaves}. */
254
+ uniqueLeaves?: boolean; /** Cross-item rules the kind holds — see {@link EntityKind.invariants}. */
255
+ invariants?: (config: Config) => string[];
256
+ /**
257
+ * For a source kind that can be resolved: the two schemas its resolutions are validated against —
258
+ * `{ resolved, unavailable }`. Declare it alongside `sourceIdentity` for a kind a config lists in its
259
+ * `sources`; that pairing is checked by `defineConfig`. See {@link EntityKind.sourceResolution}.
260
+ */
261
+ sourceResolution?: SourceResolutionSchemas;
262
+ /**
263
+ * For a source kind that records a bulk take: whether one of its pins still covers a borrowed
264
+ * Entity, which is what the delete gate refuses on. Declare it alongside `sourceIdentity` for a kind
265
+ * whose items declare what is drawn in bulk. See {@link EntityKind.bulkAdopts}.
266
+ */
267
+ bulkAdopts?: (args: BulkQuery) => boolean;
268
+ /**
269
+ * Whether the pin declines this path — the counterpart to {@link EntityKind.bulkAdopts}, and the
270
+ * tombstone `link`'s own note asks for. A declined path derives no row, so the name is free for
271
+ * this config to author, and the source's entity stays reachable qualified.
272
+ */
273
+ /**
274
+ * What the declared source lays over the entity at this path, when it declares anything — the
275
+ * bodies a minted row carries in place of an empty `extend`, so a bulk adjustment and a hand-written
276
+ * `.extend(...)` produce the same stored row, and whether the source still offers it.
277
+ */
278
+ bulkOverlay?: (args: BulkQuery) => SourceOverlay | undefined; /** See {@link EntityKind.bulkDirectives}. */
279
+ bulkDirectives?: (body: Record<string, unknown>) => {
280
+ accessor: string;
281
+ path: string;
282
+ }[];
283
+ /**
284
+ * The field-path delta that lands an overlay on this path — see {@link EntityKind.bulkOverlayWrite}.
285
+ * Declare it alongside `bulkOverlay` for a kind whose minted rows should stay editable; without it,
286
+ * an edit to one has nowhere to land.
287
+ */
288
+ bulkOverlayWrite?: (args: BulkOverlayWrite) => Record<string, unknown>;
289
+ /**
290
+ * Edges this kind's data implies by name rather than by ref, and how to rewrite one — the pair that
291
+ * makes a record keyed by another kind's item names behave like a reference: reported by
292
+ * `dependentsOf`, refused by a delete, and rewritten by a rename.
293
+ *
294
+ * Declared here because only the kind knows what its own keys mean. See
295
+ * {@link EntityKind.nameEdges} for why `nameEdges` must be pure in its argument.
296
+ */
297
+ nameEdges?: (data: unknown) => string[];
298
+ /** See {@link EntityKind.styleBags} — where this kind keeps its style bags, for a reader that has to
299
+ * find every one of them without knowing the kind. */
300
+ styleBags?: (data: unknown) => {
301
+ bag: Record<string, unknown>;
302
+ }[];
303
+ rewriteName?: (data: unknown, from: string, to: string) => unknown;
304
+ }): EntityClass<F, G, K, S, C, Single>;
305
+ /**
306
+ * The input type of one of an entity's operations — `OpInput<typeof Component, 'element-insert'>`.
307
+ *
308
+ * Inferred from the zod schema the entity declares, so a caller that writes an operation is checked
309
+ * against the thing that will validate it. Restating the shape by hand is how a gesture ends up carrying
310
+ * a field the op has no input for: the write is silently dropped, and nothing catches it until a merge.
311
+ */
312
+ type OpInput<E extends {
313
+ readonly schemas: UserSchemas;
314
+ }, V extends keyof E['schemas']> = E['schemas'][V] extends {
315
+ input: infer I extends z.ZodTypeAny;
316
+ } ? z.input<I> : never;
317
+ //#endregion
318
+ export { EntityClass, ItemOf, OpInput, defineEntity };