torch-glare 2.5.6 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/README.md +4 -3
  2. package/dist/bin/index.js +9 -24
  3. package/dist/bin/index.js.map +1 -1
  4. package/dist/src/commands/add.d.ts +2 -2
  5. package/dist/src/commands/add.d.ts.map +1 -1
  6. package/dist/src/commands/add.js +4 -70
  7. package/dist/src/commands/add.js.map +1 -1
  8. package/dist/src/commands/hook.d.ts +5 -4
  9. package/dist/src/commands/hook.d.ts.map +1 -1
  10. package/dist/src/commands/hook.js +7 -75
  11. package/dist/src/commands/hook.js.map +1 -1
  12. package/dist/src/commands/init.js +1 -1
  13. package/dist/src/commands/init.js.map +1 -1
  14. package/dist/src/commands/layout.d.ts +5 -4
  15. package/dist/src/commands/layout.d.ts.map +1 -1
  16. package/dist/src/commands/layout.js +7 -75
  17. package/dist/src/commands/layout.js.map +1 -1
  18. package/dist/src/commands/provider.d.ts +5 -4
  19. package/dist/src/commands/provider.d.ts.map +1 -1
  20. package/dist/src/commands/provider.js +7 -75
  21. package/dist/src/commands/provider.js.map +1 -1
  22. package/dist/src/commands/update.d.ts.map +1 -1
  23. package/dist/src/commands/update.js +78 -43
  24. package/dist/src/commands/update.js.map +1 -1
  25. package/dist/src/commands/utils.d.ts +5 -4
  26. package/dist/src/commands/utils.d.ts.map +1 -1
  27. package/dist/src/commands/utils.js +7 -80
  28. package/dist/src/commands/utils.js.map +1 -1
  29. package/dist/src/shared/addFromRegistry.d.ts +16 -0
  30. package/dist/src/shared/addFromRegistry.d.ts.map +1 -0
  31. package/dist/src/shared/addFromRegistry.js +88 -0
  32. package/dist/src/shared/addFromRegistry.js.map +1 -0
  33. package/dist/src/shared/getInstallCommand.d.ts.map +1 -1
  34. package/dist/src/shared/getInstallCommand.js +5 -0
  35. package/dist/src/shared/getInstallCommand.js.map +1 -1
  36. package/dist/src/shared/installDependencies.d.ts +0 -10
  37. package/dist/src/shared/installDependencies.d.ts.map +1 -1
  38. package/dist/src/shared/installDependencies.js +0 -17
  39. package/dist/src/shared/installDependencies.js.map +1 -1
  40. package/dist/src/shared/installFromPlan.d.ts +7 -5
  41. package/dist/src/shared/installFromPlan.d.ts.map +1 -1
  42. package/dist/src/shared/installFromPlan.js +103 -36
  43. package/dist/src/shared/installFromPlan.js.map +1 -1
  44. package/dist/src/shared/loadRegistry.d.ts +12 -3
  45. package/dist/src/shared/loadRegistry.d.ts.map +1 -1
  46. package/dist/src/shared/loadRegistry.js +19 -20
  47. package/dist/src/shared/loadRegistry.js.map +1 -1
  48. package/dist/src/shared/registryClient.d.ts +19 -0
  49. package/dist/src/shared/registryClient.d.ts.map +1 -0
  50. package/dist/src/shared/registryClient.js +128 -0
  51. package/dist/src/shared/registryClient.js.map +1 -0
  52. package/dist/src/shared/resolveEntry.d.ts +10 -7
  53. package/dist/src/shared/resolveEntry.d.ts.map +1 -1
  54. package/dist/src/shared/resolveEntry.js +18 -13
  55. package/dist/src/shared/resolveEntry.js.map +1 -1
  56. package/dist/src/shared/suggestOtherCommand.d.ts +7 -1
  57. package/dist/src/shared/suggestOtherCommand.d.ts.map +1 -1
  58. package/dist/src/shared/suggestOtherCommand.js +29 -23
  59. package/dist/src/shared/suggestOtherCommand.js.map +1 -1
  60. package/dist/src/types/main.d.ts +31 -2
  61. package/dist/src/types/main.d.ts.map +1 -1
  62. package/package.json +6 -11
  63. package/apps/lib/components/ActionButton.tsx +0 -93
  64. package/apps/lib/components/ActionsGroup.tsx +0 -27
  65. package/apps/lib/components/AlertDialog.tsx +0 -204
  66. package/apps/lib/components/Avatar.tsx +0 -46
  67. package/apps/lib/components/Badge.tsx +0 -250
  68. package/apps/lib/components/BadgeField.tsx +0 -403
  69. package/apps/lib/components/Breadcrumb.tsx +0 -280
  70. package/apps/lib/components/Button.tsx +0 -325
  71. package/apps/lib/components/ButtonGroup.tsx +0 -190
  72. package/apps/lib/components/Calendar.tsx +0 -115
  73. package/apps/lib/components/Card.tsx +0 -95
  74. package/apps/lib/components/Checkbox.tsx +0 -42
  75. package/apps/lib/components/ColorPicker.tsx +0 -441
  76. package/apps/lib/components/ConclusionHeader.tsx +0 -148
  77. package/apps/lib/components/ContextMenu.tsx +0 -571
  78. package/apps/lib/components/CountBadge.tsx +0 -52
  79. package/apps/lib/components/DataTable.tsx +0 -213
  80. package/apps/lib/components/DataViews/badge.ts +0 -49
  81. package/apps/lib/components/DataViews/cell.tsx +0 -324
  82. package/apps/lib/components/DataViews/context.ts +0 -144
  83. package/apps/lib/components/DataViews/data-views.tsx +0 -395
  84. package/apps/lib/components/DataViews/filters/children.tsx +0 -98
  85. package/apps/lib/components/DataViews/filters/custom.tsx +0 -34
  86. package/apps/lib/components/DataViews/filters/filters.tsx +0 -157
  87. package/apps/lib/components/DataViews/filters/index.ts +0 -4
  88. package/apps/lib/components/DataViews/filters/labelled.tsx +0 -20
  89. package/apps/lib/components/DataViews/filters/presets.tsx +0 -65
  90. package/apps/lib/components/DataViews/filters/sync.tsx +0 -35
  91. package/apps/lib/components/DataViews/filters/values.ts +0 -173
  92. package/apps/lib/components/DataViews/header.tsx +0 -220
  93. package/apps/lib/components/DataViews/hooks/index.ts +0 -5
  94. package/apps/lib/components/DataViews/hooks/useActiveRow.ts +0 -22
  95. package/apps/lib/components/DataViews/hooks/useControllable.ts +0 -52
  96. package/apps/lib/components/DataViews/index.ts +0 -88
  97. package/apps/lib/components/DataViews/panel/columns.tsx +0 -153
  98. package/apps/lib/components/DataViews/panel/controls.tsx +0 -106
  99. package/apps/lib/components/DataViews/panel/index.ts +0 -3
  100. package/apps/lib/components/DataViews/panel/panel.tsx +0 -164
  101. package/apps/lib/components/DataViews/panel/saved-views.tsx +0 -67
  102. package/apps/lib/components/DataViews/panel/section.tsx +0 -81
  103. package/apps/lib/components/DataViews/panel/sort.tsx +0 -42
  104. package/apps/lib/components/DataViews/panel/tab.tsx +0 -31
  105. package/apps/lib/components/DataViews/slots.ts +0 -72
  106. package/apps/lib/components/DataViews/states.tsx +0 -73
  107. package/apps/lib/components/DataViews/types.ts +0 -510
  108. package/apps/lib/components/DataViews/views/board-view.tsx +0 -381
  109. package/apps/lib/components/DataViews/views/card-rows.tsx +0 -36
  110. package/apps/lib/components/DataViews/views/inbox-view.tsx +0 -260
  111. package/apps/lib/components/DataViews/views/pane-views.tsx +0 -196
  112. package/apps/lib/components/DataViews/views/table-view.tsx +0 -493
  113. package/apps/lib/components/DataViews/views/tree-view.tsx +0 -367
  114. package/apps/lib/components/DatePicker.tsx +0 -232
  115. package/apps/lib/components/Dialog.tsx +0 -116
  116. package/apps/lib/components/Divider.tsx +0 -28
  117. package/apps/lib/components/Drawer.tsx +0 -451
  118. package/apps/lib/components/DropdownMenu.tsx +0 -554
  119. package/apps/lib/components/FieldHint.tsx +0 -69
  120. package/apps/lib/components/Form.tsx +0 -182
  121. package/apps/lib/components/FormBuilder/context.ts +0 -85
  122. package/apps/lib/components/FormBuilder/field-kind.ts +0 -28
  123. package/apps/lib/components/FormBuilder/fields/ChoiceFields.tsx +0 -60
  124. package/apps/lib/components/FormBuilder/fields/ColorField.tsx +0 -59
  125. package/apps/lib/components/FormBuilder/fields/CustomField.tsx +0 -11
  126. package/apps/lib/components/FormBuilder/fields/DateField.tsx +0 -32
  127. package/apps/lib/components/FormBuilder/fields/FieldArray.tsx +0 -74
  128. package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +0 -168
  129. package/apps/lib/components/FormBuilder/fields/FileField.tsx +0 -39
  130. package/apps/lib/components/FormBuilder/fields/OptionListFields.tsx +0 -132
  131. package/apps/lib/components/FormBuilder/fields/OtpField.tsx +0 -31
  132. package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +0 -109
  133. package/apps/lib/components/FormBuilder/fields/RichTextEditorField.tsx +0 -31
  134. package/apps/lib/components/FormBuilder/fields/SelectField.tsx +0 -114
  135. package/apps/lib/components/FormBuilder/fields/SignatureField.tsx +0 -157
  136. package/apps/lib/components/FormBuilder/fields/SliderField.tsx +0 -67
  137. package/apps/lib/components/FormBuilder/fields/SwitchBoxField.tsx +0 -41
  138. package/apps/lib/components/FormBuilder/fields/TableField.tsx +0 -336
  139. package/apps/lib/components/FormBuilder/fields/TextField.tsx +0 -213
  140. package/apps/lib/components/FormBuilder/fields/TreeSelectField.tsx +0 -43
  141. package/apps/lib/components/FormBuilder/fields/countries.ts +0 -303
  142. package/apps/lib/components/FormBuilder/fields/index.ts +0 -25
  143. package/apps/lib/components/FormBuilder/form-builder.tsx +0 -198
  144. package/apps/lib/components/FormBuilder/index.ts +0 -31
  145. package/apps/lib/components/FormBuilder/numberFormat.ts +0 -16
  146. package/apps/lib/components/FormBuilder/submit.tsx +0 -67
  147. package/apps/lib/components/FormBuilder/types.ts +0 -316
  148. package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -250
  149. package/apps/lib/components/FormRenderer/detail.tsx +0 -256
  150. package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -358
  151. package/apps/lib/components/FormRenderer/header.tsx +0 -88
  152. package/apps/lib/components/FormRenderer/index.ts +0 -17
  153. package/apps/lib/components/FormRenderer/notch-action.tsx +0 -64
  154. package/apps/lib/components/FormRenderer/section.tsx +0 -39
  155. package/apps/lib/components/FormRenderer/stepper.tsx +0 -393
  156. package/apps/lib/components/FormRenderer/types.ts +0 -115
  157. package/apps/lib/components/FormSummary.tsx +0 -282
  158. package/apps/lib/components/HeaderBar.tsx +0 -117
  159. package/apps/lib/components/ImageAttachment.tsx +0 -209
  160. package/apps/lib/components/InnerLabelField.tsx +0 -154
  161. package/apps/lib/components/Input.tsx +0 -224
  162. package/apps/lib/components/InputField.tsx +0 -147
  163. package/apps/lib/components/InputOTP.tsx +0 -84
  164. package/apps/lib/components/Label.tsx +0 -129
  165. package/apps/lib/components/LabelField.tsx +0 -76
  166. package/apps/lib/components/LabeledCheckBox.tsx +0 -51
  167. package/apps/lib/components/LabeledRadio.tsx +0 -51
  168. package/apps/lib/components/LinkButton.tsx +0 -94
  169. package/apps/lib/components/LoginButton.tsx +0 -51
  170. package/apps/lib/components/PasswordLevel.tsx +0 -58
  171. package/apps/lib/components/Popover.tsx +0 -312
  172. package/apps/lib/components/ProfileMenu.tsx +0 -85
  173. package/apps/lib/components/Radio.tsx +0 -59
  174. package/apps/lib/components/RadioCard.tsx +0 -50
  175. package/apps/lib/components/ScrollArea.tsx +0 -54
  176. package/apps/lib/components/SearchField.tsx +0 -62
  177. package/apps/lib/components/SearchableSelect.tsx +0 -318
  178. package/apps/lib/components/SearchableTable.tsx +0 -344
  179. package/apps/lib/components/SearchableTree.tsx +0 -485
  180. package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
  181. package/apps/lib/components/SectionBlock.tsx +0 -168
  182. package/apps/lib/components/Select.tsx +0 -347
  183. package/apps/lib/components/SimpleSelect.tsx +0 -225
  184. package/apps/lib/components/Skeleton.tsx +0 -12
  185. package/apps/lib/components/SlideDatePicker.tsx +0 -255
  186. package/apps/lib/components/SpinLoading.tsx +0 -174
  187. package/apps/lib/components/Stepper.tsx +0 -480
  188. package/apps/lib/components/Switch.tsx +0 -82
  189. package/apps/lib/components/TabFormItem.tsx +0 -153
  190. package/apps/lib/components/TabSwitch.tsx +0 -172
  191. package/apps/lib/components/Table.tsx +0 -597
  192. package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
  193. package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
  194. package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
  195. package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
  196. package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
  197. package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
  198. package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
  199. package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
  200. package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
  201. package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
  202. package/apps/lib/components/TextEditor/index.ts +0 -7
  203. package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
  204. package/apps/lib/components/Textarea.tsx +0 -117
  205. package/apps/lib/components/Timeline.tsx +0 -263
  206. package/apps/lib/components/Toast.tsx +0 -87
  207. package/apps/lib/components/Toggle.tsx +0 -125
  208. package/apps/lib/components/ToggleButton.tsx +0 -140
  209. package/apps/lib/components/Tooltip.tsx +0 -116
  210. package/apps/lib/components/TransparentLabel.tsx +0 -71
  211. package/apps/lib/components/TreeDropDown.tsx +0 -115
  212. package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
  213. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
  214. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
  215. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
  216. package/apps/lib/components/TreeFolder/icons.tsx +0 -60
  217. package/apps/lib/components/TreeFolder/index.ts +0 -24
  218. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
  219. package/apps/lib/components/TreeFolder/types.ts +0 -77
  220. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
  221. package/apps/lib/hooks/useActiveTreeItem.ts +0 -61
  222. package/apps/lib/hooks/useClickOutside.ts +0 -27
  223. package/apps/lib/hooks/useDragDrop.tsx +0 -365
  224. package/apps/lib/hooks/useHtmlDir.ts +0 -31
  225. package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
  226. package/apps/lib/hooks/useIsMobile.ts +0 -21
  227. package/apps/lib/hooks/useResize.ts +0 -67
  228. package/apps/lib/hooks/useTagSelection.ts +0 -300
  229. package/apps/lib/layouts/CNLayout.tsx +0 -372
  230. package/apps/lib/layouts/DataViewCard.tsx +0 -62
  231. package/apps/lib/layouts/FieldSection.tsx +0 -91
  232. package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
  233. package/apps/lib/providers/ThemeProvider.tsx +0 -84
  234. package/apps/lib/registry.json +0 -1217
  235. package/apps/lib/tsconfig.json +0 -9
  236. package/apps/lib/tsconfig.tsbuildinfo +0 -1
  237. package/apps/lib/utils/cn.ts +0 -6
  238. package/apps/lib/utils/color.ts +0 -175
  239. package/apps/lib/utils/dataViews/path.ts +0 -67
  240. package/apps/lib/utils/dataViews/query.ts +0 -73
  241. package/apps/lib/utils/dataViews/types.ts +0 -187
  242. package/apps/lib/utils/dateFormat.ts +0 -108
  243. package/apps/lib/utils/resize.ts +0 -31
  244. package/apps/lib/utils/scroller.ts +0 -26
  245. package/apps/lib/utils/types.ts +0 -16
  246. package/docs/BLOCKS.md +0 -129
  247. package/docs/CHANGELOG-1.1.16.md +0 -108
  248. package/docs/Cover.png +0 -0
  249. package/docs/README.md +0 -215
  250. package/docs/components/action-button.md +0 -638
  251. package/docs/components/actions-group.md +0 -708
  252. package/docs/components/alert-dialog.md +0 -920
  253. package/docs/components/avatar.md +0 -709
  254. package/docs/components/badge-field.md +0 -738
  255. package/docs/components/badge.md +0 -301
  256. package/docs/components/breadcrumb.md +0 -930
  257. package/docs/components/button-group.md +0 -650
  258. package/docs/components/button.md +0 -639
  259. package/docs/components/calendar.md +0 -555
  260. package/docs/components/card.md +0 -622
  261. package/docs/components/chart-block-tool.md +0 -129
  262. package/docs/components/checkbox.md +0 -699
  263. package/docs/components/cn-layout.md +0 -854
  264. package/docs/components/color-picker.md +0 -101
  265. package/docs/components/conclusion-header.md +0 -80
  266. package/docs/components/context-menu.md +0 -483
  267. package/docs/components/count-badge.md +0 -560
  268. package/docs/components/data-table.md +0 -854
  269. package/docs/components/data-views/backend-response.md +0 -324
  270. package/docs/components/data-views/examples/a11y-rtl.md +0 -250
  271. package/docs/components/data-views/examples/api-orders-route.md +0 -130
  272. package/docs/components/data-views/examples/fields.md +0 -362
  273. package/docs/components/data-views/examples/filters.md +0 -307
  274. package/docs/components/data-views/examples/inbox-routing.md +0 -218
  275. package/docs/components/data-views/examples/index.md +0 -29
  276. package/docs/components/data-views/examples/overview.md +0 -244
  277. package/docs/components/data-views/examples/panel.md +0 -212
  278. package/docs/components/data-views/examples/scale.md +0 -231
  279. package/docs/components/data-views/examples/server-side.md +0 -210
  280. package/docs/components/data-views/examples/state.md +0 -250
  281. package/docs/components/data-views/examples/tree-custom.md +0 -388
  282. package/docs/components/data-views/examples/view-registry.md +0 -313
  283. package/docs/components/data-views/examples/views.md +0 -534
  284. package/docs/components/data-views/guide.md +0 -405
  285. package/docs/components/data-views/index.md +0 -1521
  286. package/docs/components/data-views/migration.md +0 -81
  287. package/docs/components/date-picker.md +0 -857
  288. package/docs/components/dialog.md +0 -929
  289. package/docs/components/divider.md +0 -766
  290. package/docs/components/drawer.md +0 -654
  291. package/docs/components/dropdown-menu.md +0 -668
  292. package/docs/components/field-hint.md +0 -898
  293. package/docs/components/field-section.md +0 -781
  294. package/docs/components/form-builder.md +0 -284
  295. package/docs/components/form-renderer.md +0 -396
  296. package/docs/components/form-summary.md +0 -138
  297. package/docs/components/form.md +0 -785
  298. package/docs/components/header-bar.md +0 -188
  299. package/docs/components/image-attachment.md +0 -906
  300. package/docs/components/inner-label-field.md +0 -819
  301. package/docs/components/input-field.md +0 -623
  302. package/docs/components/input-otp.md +0 -756
  303. package/docs/components/input.md +0 -634
  304. package/docs/components/label-field.md +0 -770
  305. package/docs/components/label.md +0 -761
  306. package/docs/components/labeled-check-box.md +0 -642
  307. package/docs/components/labeled-radio.md +0 -796
  308. package/docs/components/link-button.md +0 -685
  309. package/docs/components/login-button.md +0 -872
  310. package/docs/components/password-level.md +0 -803
  311. package/docs/components/popover.md +0 -649
  312. package/docs/components/profile-menu.md +0 -656
  313. package/docs/components/radio-card.md +0 -801
  314. package/docs/components/radio.md +0 -735
  315. package/docs/components/scroll-area.md +0 -691
  316. package/docs/components/search-field.md +0 -702
  317. package/docs/components/searchable-select.md +0 -368
  318. package/docs/components/searchable-table.md +0 -438
  319. package/docs/components/searchable-tree-dialog.md +0 -190
  320. package/docs/components/searchable-tree.md +0 -200
  321. package/docs/components/section-block.md +0 -483
  322. package/docs/components/select.md +0 -709
  323. package/docs/components/simple-select.md +0 -741
  324. package/docs/components/skeleton.md +0 -706
  325. package/docs/components/slide-date-picker.md +0 -837
  326. package/docs/components/spin-loading.md +0 -696
  327. package/docs/components/stepper.md +0 -316
  328. package/docs/components/switch.md +0 -770
  329. package/docs/components/tab-form-item.md +0 -773
  330. package/docs/components/tab-switch.md +0 -170
  331. package/docs/components/table-dnd-wrapper.md +0 -107
  332. package/docs/components/table.md +0 -1088
  333. package/docs/components/text-editor.md +0 -735
  334. package/docs/components/textarea.md +0 -681
  335. package/docs/components/timeline.md +0 -254
  336. package/docs/components/toast.md +0 -773
  337. package/docs/components/toggle-button.md +0 -643
  338. package/docs/components/toggle.md +0 -882
  339. package/docs/components/tooltip.md +0 -513
  340. package/docs/components/transparent-label.md +0 -721
  341. package/docs/components/tree-drop-down.md +0 -740
  342. package/docs/components/tree-folder.md +0 -110
  343. package/docs/components/tree-sub-layout.md +0 -707
  344. package/docs/explanation/architecture.md +0 -54
  345. package/docs/explanation/design-system.md +0 -52
  346. package/docs/how-to/form-and-list-recipes.md +0 -386
  347. package/docs/how-to/forms-with-form-builder.md +0 -472
  348. package/docs/how-to/guides.md +0 -1027
  349. package/docs/migration/changelog.md +0 -60
  350. package/docs/migration/form-builder-2.5.2.md +0 -113
  351. package/docs/reference/cli.md +0 -112
  352. package/docs/reference/components.md +0 -572
  353. package/docs/reference/hooks.md +0 -1523
  354. package/docs/reference/providers.md +0 -866
  355. package/docs/reference/tailwind-plugins.md +0 -942
  356. package/docs/reference/theme.md +0 -85
  357. package/docs/reference/types.md +0 -1016
  358. package/docs/reference/utilities.md +0 -726
  359. package/docs/tutorials/building-first-form.md +0 -846
  360. package/docs/tutorials/component-composition.md +0 -882
  361. package/docs/tutorials/getting-started.md +0 -302
  362. package/docs/tutorials/theming-basics.md +0 -785
@@ -1,66 +1,133 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { fileURLToPath } from "url";
4
- import { copyComponentsRecursively } from "./copyComponentsRecursively.js";
5
3
  import { ensureDirectoryExists } from "./ensureDirectoryExists.js";
6
4
  import { installNpmPackages } from "./installDependencies.js";
7
5
  import { isInstalled } from "./resolveEntry.js";
8
6
  import { loadRegistry } from "./loadRegistry.js";
7
+ import { fetchRegistryItems, RegistryError } from "./registryClient.js";
9
8
  import { resolveInstallPlan } from "./resolveInstallPlan.js";
10
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
- /** `apps/lib` in the published package — the root every registry `path` is relative to. */
12
- const LIB_DIR = path.resolve(__dirname, "../../../apps/lib");
9
+ /** Where this project's files live — `<cwd>/<glare.json path>`, with a leading "@/" stripped. */
10
+ export function installRoot(config) {
11
+ return path.join(process.cwd(), config.path.replace("@/", ""));
12
+ }
13
13
  /**
14
14
  * Install one registry item and everything it needs.
15
15
  *
16
- * Dependencies come from `apps/lib/registry.json` — the same generated graph the docs and the MCP
17
- * server read — rather than from scanning import statements as files are copied. The old walker had
18
- * no visited set and no cycle guard, and ran once per copied file, so a 35-file component triggered
19
- * 35 recursive walks; worse, a dependency skipped because its folder already existed was never
16
+ * Dependencies come from the registry index — the same generated graph the docs and the MCP server
17
+ * read — rather than from scanning import statements as files are written. The old walker had no
18
+ * visited set and no cycle guard, and ran once per copied file, so a 35-file component triggered 35
19
+ * recursive walks; worse, a dependency skipped because its folder already existed was never
20
20
  * descended into, which silently truncated the tree (`add DataViews` installed 16 of 55 items and
21
21
  * exited 0).
22
22
  *
23
23
  * Resolving up front also gives `force` a coherent meaning: it applies to **every** item in the
24
24
  * plan, not only the one you named.
25
25
  */
26
- export function installFromPlan(type, name, config, force) {
27
- const registry = loadRegistry();
26
+ export async function installFromPlan(type, name, config, force) {
27
+ const registry = await loadRegistry();
28
28
  const plan = resolveInstallPlan(registry, type, name);
29
29
  if (!plan)
30
30
  return null;
31
- const installed = [];
31
+ const root = installRoot(config);
32
+ // Work out what needs writing before fetching anything — there is no reason to pull 200KB over
33
+ // the network for 55 items only to skip 54 of them as already present.
34
+ const pending = [];
32
35
  const skipped = [];
33
36
  for (const item of plan.items) {
34
- const source = path.join(LIB_DIR, item.path);
35
- if (!fs.existsSync(source))
36
- continue;
37
- const entry = path.basename(item.path);
38
- const targetDir = path.join(process.cwd(), config.path.replace("@/", ""), item.type);
39
- if (isInstalled(targetDir, entry) && !force) {
37
+ if (isInstalled(path.join(root, item.type), entryOf(item.path)) && !force) {
40
38
  skipped.push(`${item.type}/${item.name}`);
41
- continue;
42
39
  }
43
- // Replacing: clear the old copy first, so a folder that lost files upstream does not keep
44
- // them locally.
45
- const target = path.join(targetDir, entry);
46
- if (force && fs.existsSync(target))
47
- fs.rmSync(target, { recursive: true, force: true });
48
- ensureDirectoryExists(targetDir);
49
- copyComponentsRecursively(source, targetDir);
50
- installed.push(`${item.type}/${item.name}`);
40
+ else {
41
+ pending.push(item);
42
+ }
43
+ }
44
+ const payloads = pending.length
45
+ ? await fetchRegistryItems(pending)
46
+ : new Map();
47
+ const installed = [];
48
+ for (const item of pending) {
49
+ const ref = `${item.type}/${item.name}`;
50
+ const payload = payloads.get(ref);
51
+ if (!payload) {
52
+ // The index listed it, so a gap here means the registry is internally inconsistent.
53
+ // The old code `continue`d past a missing source without a word, which is how a
54
+ // partial install passed for a complete one.
55
+ throw new RegistryError(`${ref} is in the registry index but could not be fetched.`);
56
+ }
57
+ writeItem(payload, item.path, root, force);
58
+ installed.push(ref);
51
59
  }
52
60
  // Once, for the union — not once per file, which is what produced five "cn.ts has been added"
53
61
  // lines and five separate npm invocations for a single `add`.
54
- //
55
- // Pinned to the range the library builds against. Unpinned, `add DataTable` pulled
56
- // @tanstack/react-table v9 against a component written for v8 — copied code that could not
57
- // compile on arrival.
58
- const pinned = [...plan.npmDependencies].map((name) => {
59
- const range = registry.npmVersions?.[name];
60
- return range ? `${name}@${range}` : name;
62
+ return {
63
+ installed,
64
+ skipped,
65
+ npm: installNpmPackages(pinRanges(plan.npmDependencies, payloads, registry)),
66
+ };
67
+ }
68
+ /**
69
+ * Resolve each npm dependency to a spec with its version range attached.
70
+ *
71
+ * Unpinned, `add DataTable` pulled @tanstack/react-table v9 against a component written for v8 —
72
+ * code that could not compile on arrival. Two sources carry the range, and both are consulted:
73
+ * a fetched item payload already has it inlined (`clsx@^2.1.1`), and the index hoists ranges into
74
+ * a shared `npmVersions` map. The payload is preferred because it is the more specific of the two;
75
+ * the index covers items that were skipped and so never fetched.
76
+ *
77
+ * Reading only the index — which is what this did — meant a registry with a sparse `npmVersions`
78
+ * installed everything unpinned in silence, which is the exact failure pinning exists to prevent.
79
+ */
80
+ function pinRanges(deps, payloads, registry) {
81
+ const fromPayloads = new Map();
82
+ for (const payload of payloads.values()) {
83
+ for (const spec of payload.dependencies ?? []) {
84
+ // The leading `@` of a scoped package is not a separator.
85
+ const at = spec.lastIndexOf("@");
86
+ if (at > 0)
87
+ fromPayloads.set(spec.slice(0, at), spec);
88
+ }
89
+ }
90
+ const unpinned = [];
91
+ const specs = [...deps].map((dep) => {
92
+ const fromPayload = fromPayloads.get(dep);
93
+ if (fromPayload)
94
+ return fromPayload;
95
+ const range = registry.npmVersions?.[dep];
96
+ if (range)
97
+ return `${dep}@${range}`;
98
+ unpinned.push(dep);
99
+ return dep;
61
100
  });
62
- const npm = installNpmPackages(pinned);
63
- return { installed, skipped, npm };
101
+ if (unpinned.length) {
102
+ console.warn(`⚠️ No version range for ${unpinned.join(", ")} — installing the latest. ` +
103
+ `The registry should pin these.`);
104
+ }
105
+ return specs;
106
+ }
107
+ /** The file or folder an item occupies, e.g. `Button.tsx` or `DataViews`, from its registry path. */
108
+ function entryOf(itemPath) {
109
+ return path.basename(itemPath);
110
+ }
111
+ /** Write one payload's files under `root`, replacing what is there when forced. */
112
+ function writeItem(payload, itemPath, root, force) {
113
+ const ref = `${payload.type}/${payload.name}`;
114
+ // Replacing: clear the old copy first, so a folder that lost files upstream does not keep
115
+ // them locally.
116
+ const target = path.join(root, payload.type, entryOf(itemPath));
117
+ if (force && fs.existsSync(target))
118
+ fs.rmSync(target, { recursive: true, force: true });
119
+ for (const file of payload.files) {
120
+ const dest = path.join(root, file.target);
121
+ // The target comes off the network, so it is not trusted to stay inside the project.
122
+ // Note there is no `dest !== root` escape hatch: a target of "" or "." normalises to the
123
+ // root itself, which is not a file we should ever write, and letting it through only
124
+ // turned a clear rejection into an EISDIR crash.
125
+ if (!dest.startsWith(root + path.sep)) {
126
+ throw new RegistryError(`${ref} wants to write outside the install directory: ${file.target}`);
127
+ }
128
+ ensureDirectoryExists(path.dirname(dest));
129
+ fs.writeFileSync(dest, file.content);
130
+ }
64
131
  }
65
132
  /** `✅ 55 installed, 0 skipped` — truncation has to be visible, not inferred from silence. */
66
133
  export function reportInstall(name, result, where) {
@@ -1 +1 @@
1
- {"version":3,"file":"installFromPlan.js","sourceRoot":"","sources":["../../../cli/src/shared/installFromPlan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"installFromPlan.js","sourceRoot":"","sources":["../../../cli/src/shared/installFromPlan.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,16 @@
1
1
  import { Registry } from "../types/main.js";
2
2
  /**
3
- * Load and cache the generated component registry.
4
- * @returns {Registry} The parsed registry manifest.
3
+ * Load and cache the component registry index.
4
+ *
5
+ * Fetched once per process and handed to `resolveInstallPlan`, which walks dependencies locally
6
+ * rather than recursing over the network per item.
7
+ *
8
+ * There is no local fallback. The CLI used to ship the whole library inside its own tarball and
9
+ * could quietly install from that when the network failed; it no longer carries it, so "the
10
+ * registry is unreachable" is a real failure and is reported as one. Silently succeeding from a
11
+ * stale bundle was how a project ended up with component source nobody could account for.
5
12
  */
6
- export declare function loadRegistry(): Registry;
13
+ export declare function loadRegistry(): Promise<Registry>;
14
+ /** Test seam — the module-level cache would otherwise leak between cases. */
15
+ export declare function resetRegistryCache(): void;
7
16
  //# sourceMappingURL=loadRegistry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loadRegistry.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/loadRegistry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAW5C;;;GAGG;AACH,wBAAgB,YAAY,IAAI,QAAQ,CAkBvC"}
1
+ {"version":3,"file":"loadRegistry.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/loadRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK5C;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAWtD;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -1,31 +1,30 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import { fileURLToPath } from "url";
4
- const __filename = fileURLToPath(import.meta.url);
5
- const __dirname = path.dirname(__filename);
6
- // registry.json ships alongside the library source (apps/lib), the same location the
7
- // command modules resolve their template dirs from.
8
- const REGISTRY_PATH = path.resolve(__dirname, "../../../apps/lib/registry.json");
1
+ import { fetchRegistryIndex, indexUrl, RegistryError } from "./registryClient.js";
9
2
  let cached = null;
10
3
  /**
11
- * Load and cache the generated component registry.
12
- * @returns {Registry} The parsed registry manifest.
4
+ * Load and cache the component registry index.
5
+ *
6
+ * Fetched once per process and handed to `resolveInstallPlan`, which walks dependencies locally
7
+ * rather than recursing over the network per item.
8
+ *
9
+ * There is no local fallback. The CLI used to ship the whole library inside its own tarball and
10
+ * could quietly install from that when the network failed; it no longer carries it, so "the
11
+ * registry is unreachable" is a real failure and is reported as one. Silently succeeding from a
12
+ * stale bundle was how a project ended up with component source nobody could account for.
13
13
  */
14
- export function loadRegistry() {
14
+ export async function loadRegistry() {
15
15
  if (cached)
16
16
  return cached;
17
- if (!fs.existsSync(REGISTRY_PATH)) {
18
- console.error("❌ registry.json not found. It is generated from library source via " +
19
- "`node scripts/bin/generateRegistry/index.js`.");
20
- process.exit(1);
21
- }
22
17
  try {
23
- cached = JSON.parse(fs.readFileSync(REGISTRY_PATH, "utf-8"));
24
- return cached;
18
+ cached = await fetchRegistryIndex();
25
19
  }
26
20
  catch (error) {
27
- console.error("❌ Error reading registry.json:", error.message);
28
- process.exit(1);
21
+ const reason = error instanceof RegistryError ? error.message : String(error);
22
+ throw new RegistryError(`${reason}\n Registry: ${indexUrl()}`);
29
23
  }
24
+ return cached;
25
+ }
26
+ /** Test seam — the module-level cache would otherwise leak between cases. */
27
+ export function resetRegistryCache() {
28
+ cached = null;
30
29
  }
31
30
  //# sourceMappingURL=loadRegistry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loadRegistry.js","sourceRoot":"","sources":["../../../cli/src/shared/loadRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAGpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,qFAAqF;AACrF,oDAAoD;AACpD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,iCAAiC,CAAC,CAAC;AAEjF,IAAI,MAAM,GAAoB,IAAI,CAAC;AAEnC;;;GAGG;AACH,MAAM,UAAU,YAAY;IACxB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CACT,qEAAqE;YACjE,+CAA+C,CACtD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,CAAC;QACD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAa,CAAC;QACzE,OAAO,MAAM,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAG,KAAe,CAAC,OAAO,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"loadRegistry.js","sourceRoot":"","sources":["../../../cli/src/shared/loadRegistry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAElF,IAAI,MAAM,GAAoB,IAAI,CAAC;AAEnC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAC9B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,IAAI,CAAC;QACD,MAAM,GAAG,MAAM,kBAAkB,EAAE,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,KAAK,YAAY,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9E,MAAM,IAAI,aAAa,CAAC,GAAG,MAAM,kBAAkB,QAAQ,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB;IAC9B,MAAM,GAAG,IAAI,CAAC;AAClB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { Registry, RegistryItem, RegistryItemPayload } from "../types/main.js";
2
+ export declare class RegistryError extends Error {
3
+ }
4
+ /** Fetch the registry index: every item, its dependencies and its file list, without content. */
5
+ export declare function fetchRegistryIndex(): Promise<Registry>;
6
+ /** The index URL, exported so an error can name it without re-deriving it. */
7
+ export declare function indexUrl(): string;
8
+ /** Test seam, and a guard against one command's fetches leaking into another's. */
9
+ export declare function resetItemMemo(): void;
10
+ /** Fetch one item payload by its absolute URL, memoised and validated. */
11
+ export declare function fetchItemByUrl(url: string): Promise<RegistryItemPayload>;
12
+ /**
13
+ * Fetch every item in an install plan, `CONCURRENCY` at a time.
14
+ *
15
+ * Serially this is the difference between roughly 15s and 2s for `add DataViews`; unbounded it is
16
+ * 55 simultaneous connections, which is how you get rate-limited by a registry host.
17
+ */
18
+ export declare function fetchRegistryItems(items: RegistryItem[]): Promise<Map<string, RegistryItemPayload>>;
19
+ //# sourceMappingURL=registryClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registryClient.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/registryClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAgCpF,qBAAa,aAAc,SAAQ,KAAK;CAAG;AAmC3C,iGAAiG;AACjG,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,QAAQ,CAAC,CAM5D;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAYD,mFAAmF;AACnF,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,0EAA0E;AAC1E,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA4B9E;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACpC,KAAK,EAAE,YAAY,EAAE,GACtB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAa3C"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * HTTP client for the hosted component registry.
3
+ *
4
+ * Until 2.5.7 the CLI shipped the whole library inside its own npm tarball and copied from there,
5
+ * which meant a one-line component fix required publishing a new version of the CLI. Components now
6
+ * come from a registry over HTTP, so source and tooling version independently.
7
+ *
8
+ * Everything here is fetch + JSON. `resolveInstallPlan` still does the dependency walk locally
9
+ * against a single fetched index, rather than recursing over the network per item — that keeps the
10
+ * resolver a pure, synchronous, testable function, and turns an N-deep request waterfall into one
11
+ * request plus one parallel batch.
12
+ */
13
+ /**
14
+ * Where components come from: the `registry/` directory on the Glare repo's default branch,
15
+ * served by raw.githubusercontent.com.
16
+ *
17
+ * Fetched straight from the repo rather than through a branded URL on the docs site. The site was
18
+ * proxying this exact origin, and measuring it made the case plain: the proxy was *slower* than
19
+ * what it proxied (0.31-0.67s vs 0.27s), traded a CDN for a single VPS, and coupled every install
20
+ * to a website deploy. raw already sends `access-control-allow-origin: *`, which was the one thing
21
+ * the route added that could not be got for free.
22
+ */
23
+ const REGISTRY_URL = "https://raw.githubusercontent.com/TORCH-Corp/TORCH-Glare/main/registry";
24
+ /** Parallel item fetches. Measured ~275ms per request; `add DataViews` is 55 items. */
25
+ const CONCURRENCY = 8;
26
+ const REQUEST_TIMEOUT_MS = 20000;
27
+ export class RegistryError extends Error {
28
+ }
29
+ async function getJson(url) {
30
+ let response;
31
+ try {
32
+ response = await fetch(url, {
33
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
34
+ headers: { Accept: "application/json" },
35
+ });
36
+ }
37
+ catch (error) {
38
+ // Offline, DNS failure, timeout. Deliberately distinguished from a 404 below: conflating
39
+ // them sends people hunting for a typo in a component name when the network is at fault.
40
+ throw new RegistryError(`Could not reach the registry at ${url}\n ${error.message}`);
41
+ }
42
+ if (response.status === 404) {
43
+ throw new RegistryError(`Not found in the registry: ${url}`);
44
+ }
45
+ if (!response.ok) {
46
+ throw new RegistryError(`Registry returned ${response.status} for ${url}`);
47
+ }
48
+ const body = await response.text();
49
+ try {
50
+ return JSON.parse(body);
51
+ }
52
+ catch {
53
+ throw new RegistryError(`Registry returned invalid JSON from ${url} ` +
54
+ `(${body.slice(0, 80).replace(/\s+/g, " ")}…)`);
55
+ }
56
+ }
57
+ /** Fetch the registry index: every item, its dependencies and its file list, without content. */
58
+ export async function fetchRegistryIndex() {
59
+ const registry = await getJson(indexUrl());
60
+ if (!registry || !Array.isArray(registry.items)) {
61
+ throw new RegistryError(`Registry index at ${indexUrl()} has no items array.`);
62
+ }
63
+ return registry;
64
+ }
65
+ /** The index URL, exported so an error can name it without re-deriving it. */
66
+ export function indexUrl() {
67
+ return `${REGISTRY_URL}/index.json`;
68
+ }
69
+ /**
70
+ * Payloads already fetched in this process, keyed by absolute URL.
71
+ *
72
+ * `update` is what makes this matter. It calls `add` once per installed item, and each call
73
+ * resolves its own dependency closure — which overlap heavily. Measured with 55 items installed:
74
+ * 287 item fetches for 55 distinct items, every one a request the registry host has to serve.
75
+ * With this, 55.
76
+ */
77
+ const memo = new Map();
78
+ /** Test seam, and a guard against one command's fetches leaking into another's. */
79
+ export function resetItemMemo() {
80
+ memo.clear();
81
+ }
82
+ /** Fetch one item payload by its absolute URL, memoised and validated. */
83
+ export async function fetchItemByUrl(url) {
84
+ const hit = memo.get(url);
85
+ if (hit)
86
+ return hit;
87
+ const pending = (async () => {
88
+ const payload = await getJson(url);
89
+ if (!Array.isArray(payload.files) || payload.files.length === 0) {
90
+ throw new RegistryError(`Registry item at ${url} has no files.`);
91
+ }
92
+ for (const file of payload.files) {
93
+ if (typeof file?.target !== "string" || typeof file?.content !== "string") {
94
+ throw new RegistryError(`Registry item at ${url} has a malformed file entry.`);
95
+ }
96
+ }
97
+ return payload;
98
+ })();
99
+ memo.set(url, pending);
100
+ try {
101
+ return await pending;
102
+ }
103
+ catch (error) {
104
+ // Do not memoise a failure — a transient network error should not poison the rest of
105
+ // the run, and `update` would otherwise repeat one blip across every remaining item.
106
+ memo.delete(url);
107
+ throw error;
108
+ }
109
+ }
110
+ /**
111
+ * Fetch every item in an install plan, `CONCURRENCY` at a time.
112
+ *
113
+ * Serially this is the difference between roughly 15s and 2s for `add DataViews`; unbounded it is
114
+ * 55 simultaneous connections, which is how you get rate-limited by a registry host.
115
+ */
116
+ export async function fetchRegistryItems(items) {
117
+ const out = new Map();
118
+ const queue = [...items];
119
+ const workers = Array.from({ length: Math.min(CONCURRENCY, queue.length) }, async () => {
120
+ for (let next = queue.shift(); next; next = queue.shift()) {
121
+ const url = `${REGISTRY_URL}/${next.type}/${next.name}.json`;
122
+ out.set(`${next.type}/${next.name}`, await fetchItemByUrl(url));
123
+ }
124
+ });
125
+ await Promise.all(workers);
126
+ return out;
127
+ }
128
+ //# sourceMappingURL=registryClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registryClient.js","sourceRoot":"","sources":["../../../cli/src/shared/registryClient.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,17 @@
1
1
  /**
2
- * Resolve a user-provided name to an actual entry in a templates directory.
2
+ * Resolve a user-provided name to a registry item name.
3
3
  *
4
- * `readdirSync` returns names **with** their extensions, so comparing a bare `useDragDrop` against
5
- * that list never matches — which is why `torch-glare hook useDragDrop` used to do nothing at all.
6
- * Every command resolves through here now, so a bare name, a name with an extension, and a folder
7
- * component all work the same way whichever command you reach for.
4
+ * `available` is now the registry's own list of item names, not a `readdirSync` of a templates
5
+ * directory. That inversion matters: resolution used to be filesystem-first, so a name the local
6
+ * listing did not contain was rejected before the registry was ever consulted — which made every
7
+ * component that exists only in the hosted registry unreachable.
8
8
  *
9
- * Tries, in order: exact match · `.tsx` · `.ts` · anything on disk the listing missed.
9
+ * Registry names carry no extension, so a user typing `Button.tsx` (or copying it out of a file
10
+ * tree) has it stripped rather than failing to match.
11
+ *
12
+ * Tries, in order: exact · extension stripped · case-insensitive.
10
13
  */
11
- export declare function resolveEntry(input: string, available: string[], dir: string): string | null;
14
+ export declare function resolveEntry(input: string, available: string[]): string | null;
12
15
  /**
13
16
  * Is this item actually installed?
14
17
  *
@@ -1 +1 @@
1
- {"version":3,"file":"resolveEntry.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/resolveEntry.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU3F;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAQrE"}
1
+ {"version":3,"file":"resolveEntry.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/resolveEntry.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAc9E;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAQrE"}
@@ -1,25 +1,30 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  /**
4
- * Resolve a user-provided name to an actual entry in a templates directory.
4
+ * Resolve a user-provided name to a registry item name.
5
5
  *
6
- * `readdirSync` returns names **with** their extensions, so comparing a bare `useDragDrop` against
7
- * that list never matches — which is why `torch-glare hook useDragDrop` used to do nothing at all.
8
- * Every command resolves through here now, so a bare name, a name with an extension, and a folder
9
- * component all work the same way whichever command you reach for.
6
+ * `available` is now the registry's own list of item names, not a `readdirSync` of a templates
7
+ * directory. That inversion matters: resolution used to be filesystem-first, so a name the local
8
+ * listing did not contain was rejected before the registry was ever consulted — which made every
9
+ * component that exists only in the hosted registry unreachable.
10
10
  *
11
- * Tries, in order: exact match · `.tsx` · `.ts` · anything on disk the listing missed.
11
+ * Registry names carry no extension, so a user typing `Button.tsx` (or copying it out of a file
12
+ * tree) has it stripped rather than failing to match.
13
+ *
14
+ * Tries, in order: exact · extension stripped · case-insensitive.
12
15
  */
13
- export function resolveEntry(input, available, dir) {
14
- if (available.includes(input))
15
- return input;
16
- for (const candidate of [`${input}.tsx`, `${input}.ts`]) {
16
+ export function resolveEntry(input, available) {
17
+ const candidates = [input, input.replace(/\.(tsx|ts)$/, "")];
18
+ for (const candidate of candidates) {
17
19
  if (available.includes(candidate))
18
20
  return candidate;
19
21
  }
20
- // Last-ditch: a folder component, or something the listing filtered out.
21
- if (fs.existsSync(path.join(dir, input)))
22
- return input;
22
+ // `torch-glare add button` should not be a dead end when `Button` is right there.
23
+ for (const candidate of candidates) {
24
+ const match = available.find((name) => name.toLowerCase() === candidate.toLowerCase());
25
+ if (match)
26
+ return match;
27
+ }
23
28
  return null;
24
29
  }
25
30
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"resolveEntry.js","sourceRoot":"","sources":["../../../cli/src/shared/resolveEntry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,SAAmB,EAAE,GAAW;IACxE,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,KAAK,MAAM,EAAE,GAAG,KAAK,KAAK,CAAC,EAAE,CAAC;QACtD,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IACxD,CAAC;IAED,yEAAyE;IACzE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACvD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,KAAa;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzC,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACrC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC3B,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC3D,CAAC;aAAM,CAAC;YACJ,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"resolveEntry.js","sourceRoot":"","sources":["../../../cli/src/shared/resolveEntry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,SAAmB;IAC3D,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC;IAE7D,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACjC,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IACxD,CAAC;IAED,kFAAkF;IAClF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;QACvF,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,KAAa;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzC,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACrC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC3B,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC3D,CAAC;aAAM,CAAC;YACJ,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}
@@ -1,8 +1,14 @@
1
+ import type { Registry, RegistryItem } from "../types/main.js";
2
+ type ItemType = RegistryItem["type"];
1
3
  /**
2
4
  * A name that is not a component may still be something we ship.
3
5
  *
4
6
  * `torch-glare add useDragDrop` answering only "Component not found" is technically correct and
5
7
  * practically useless — it *is* installable, just by a different command. Look before saying no.
8
+ *
9
+ * Reads the registry index rather than scanning sibling directories in the installed package, so
10
+ * it keeps working once the library stops shipping in the tarball.
6
11
  */
7
- export declare function suggestOtherCommand(input: string): string | null;
12
+ export declare function suggestOtherCommand(registry: Registry, input: string, exclude: ItemType): string | null;
13
+ export {};
8
14
  //# sourceMappingURL=suggestOtherCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"suggestOtherCommand.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/suggestOtherCommand.ts"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAehE"}
1
+ {"version":3,"file":"suggestOtherCommand.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/suggestOtherCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE/D,KAAK,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAWrC;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,QAAQ,GAClB,MAAM,GAAG,IAAI,CA2Bf"}
@@ -1,33 +1,39 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import { fileURLToPath } from "url";
4
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
5
- const LIB_DIR = path.resolve(__dirname, "../../../apps/lib");
6
- /** Which command installs which folder. */
7
- const KINDS = [
8
- { dir: "hooks", command: "hook", label: "hook" },
9
- { dir: "utils", command: "util", label: "utility" },
10
- { dir: "layouts", command: "layout", label: "layout" },
11
- { dir: "providers", command: "provider", label: "provider" },
12
- ];
1
+ /** Which command installs which type, and what to call it in a sentence. */
2
+ const KINDS = {
3
+ components: { command: "add", label: "component" },
4
+ hooks: { command: "hook", label: "hook" },
5
+ utils: { command: "util", label: "utility" },
6
+ layouts: { command: "layout", label: "layout" },
7
+ providers: { command: "provider", label: "provider" },
8
+ };
13
9
  /**
14
10
  * A name that is not a component may still be something we ship.
15
11
  *
16
12
  * `torch-glare add useDragDrop` answering only "Component not found" is technically correct and
17
13
  * practically useless — it *is* installable, just by a different command. Look before saying no.
14
+ *
15
+ * Reads the registry index rather than scanning sibling directories in the installed package, so
16
+ * it keeps working once the library stops shipping in the tarball.
18
17
  */
19
- export function suggestOtherCommand(input) {
18
+ export function suggestOtherCommand(registry, input, exclude) {
20
19
  const bare = input.replace(/\.(tsx|ts)$/, "").toLowerCase();
21
- for (const kind of KINDS) {
22
- const dir = path.join(LIB_DIR, kind.dir);
23
- if (!fs.existsSync(dir))
24
- continue;
25
- for (const entry of fs.readdirSync(dir)) {
26
- if (entry.replace(/\.(tsx|ts)$/, "").toLowerCase() === bare) {
27
- const name = entry.replace(/\.(tsx|ts)$/, "");
28
- return `"${name}" is a ${kind.label} — try \`torch-glare ${kind.command} ${name}\`.`;
29
- }
30
- }
20
+ const match = registry.items.find((item) => item.type !== exclude && item.name.toLowerCase() === bare);
21
+ if (match) {
22
+ const kind = KINDS[match.type];
23
+ return `"${match.name}" is a ${kind.label} — try \`torch-glare ${kind.command} ${match.name}\`.`;
24
+ }
25
+ // No exact match anywhere: offer the closest names of the type they asked for, which catches
26
+ // the ordinary case of a typo or half-remembered name.
27
+ const near = registry.items
28
+ .filter((item) => item.type === exclude)
29
+ .map((item) => item.name)
30
+ .filter((name) => {
31
+ const lower = name.toLowerCase();
32
+ return lower.includes(bare) || bare.includes(lower);
33
+ })
34
+ .slice(0, 3);
35
+ if (near.length) {
36
+ return `Did you mean: ${near.join(", ")}?`;
31
37
  }
32
38
  return null;
33
39
  }