torch-glare 2.5.5 → 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 (359) 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 -338
  69. package/apps/lib/components/Breadcrumb.tsx +0 -280
  70. package/apps/lib/components/Button.tsx +0 -317
  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 -383
  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 -84
  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 -63
  106. package/apps/lib/components/DataViews/states.tsx +0 -38
  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 -420
  118. package/apps/lib/components/DropdownMenu.tsx +0 -540
  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 -73
  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 -163
  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 -91
  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 -47
  147. package/apps/lib/components/FormBuilder/types.ts +0 -311
  148. package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -128
  149. package/apps/lib/components/FormRenderer/detail.tsx +0 -207
  150. package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -297
  151. package/apps/lib/components/FormRenderer/header.tsx +0 -88
  152. package/apps/lib/components/FormRenderer/index.ts +0 -15
  153. package/apps/lib/components/FormRenderer/section.tsx +0 -39
  154. package/apps/lib/components/FormRenderer/stepper.tsx +0 -339
  155. package/apps/lib/components/FormRenderer/types.ts +0 -78
  156. package/apps/lib/components/FormSummary.tsx +0 -282
  157. package/apps/lib/components/HeaderBar.tsx +0 -117
  158. package/apps/lib/components/ImageAttachment.tsx +0 -209
  159. package/apps/lib/components/InnerLabelField.tsx +0 -154
  160. package/apps/lib/components/Input.tsx +0 -224
  161. package/apps/lib/components/InputField.tsx +0 -147
  162. package/apps/lib/components/InputOTP.tsx +0 -84
  163. package/apps/lib/components/Label.tsx +0 -129
  164. package/apps/lib/components/LabelField.tsx +0 -76
  165. package/apps/lib/components/LabeledCheckBox.tsx +0 -51
  166. package/apps/lib/components/LabeledRadio.tsx +0 -51
  167. package/apps/lib/components/LinkButton.tsx +0 -94
  168. package/apps/lib/components/LoginButton.tsx +0 -51
  169. package/apps/lib/components/PasswordLevel.tsx +0 -58
  170. package/apps/lib/components/Popover.tsx +0 -312
  171. package/apps/lib/components/ProfileMenu.tsx +0 -85
  172. package/apps/lib/components/Radio.tsx +0 -59
  173. package/apps/lib/components/RadioCard.tsx +0 -50
  174. package/apps/lib/components/ScrollArea.tsx +0 -54
  175. package/apps/lib/components/SearchField.tsx +0 -62
  176. package/apps/lib/components/SearchableSelect.tsx +0 -318
  177. package/apps/lib/components/SearchableTable.tsx +0 -344
  178. package/apps/lib/components/SearchableTree.tsx +0 -485
  179. package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
  180. package/apps/lib/components/SectionBlock.tsx +0 -147
  181. package/apps/lib/components/Select.tsx +0 -347
  182. package/apps/lib/components/SimpleSelect.tsx +0 -225
  183. package/apps/lib/components/Skeleton.tsx +0 -12
  184. package/apps/lib/components/SlideDatePicker.tsx +0 -253
  185. package/apps/lib/components/SpinLoading.tsx +0 -174
  186. package/apps/lib/components/Stepper.tsx +0 -480
  187. package/apps/lib/components/Switch.tsx +0 -82
  188. package/apps/lib/components/TabFormItem.tsx +0 -153
  189. package/apps/lib/components/TabSwitch.tsx +0 -172
  190. package/apps/lib/components/Table.tsx +0 -610
  191. package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
  192. package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
  193. package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
  194. package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
  195. package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
  196. package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
  197. package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
  198. package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
  199. package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
  200. package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
  201. package/apps/lib/components/TextEditor/index.ts +0 -7
  202. package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
  203. package/apps/lib/components/Textarea.tsx +0 -117
  204. package/apps/lib/components/Timeline.tsx +0 -263
  205. package/apps/lib/components/Toast.tsx +0 -87
  206. package/apps/lib/components/Toggle.tsx +0 -125
  207. package/apps/lib/components/ToggleButton.tsx +0 -140
  208. package/apps/lib/components/Tooltip.tsx +0 -116
  209. package/apps/lib/components/TransparentLabel.tsx +0 -71
  210. package/apps/lib/components/TreeDropDown.tsx +0 -115
  211. package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
  212. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
  213. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
  214. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
  215. package/apps/lib/components/TreeFolder/icons.tsx +0 -60
  216. package/apps/lib/components/TreeFolder/index.ts +0 -24
  217. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
  218. package/apps/lib/components/TreeFolder/types.ts +0 -77
  219. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
  220. package/apps/lib/hooks/useActiveTreeItem.ts +0 -58
  221. package/apps/lib/hooks/useClickOutside.ts +0 -27
  222. package/apps/lib/hooks/useDragDrop.tsx +0 -365
  223. package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
  224. package/apps/lib/hooks/useIsMobile.ts +0 -21
  225. package/apps/lib/hooks/useResize.ts +0 -67
  226. package/apps/lib/hooks/useTagSelection.ts +0 -214
  227. package/apps/lib/layouts/CNLayout.tsx +0 -372
  228. package/apps/lib/layouts/DataViewCard.tsx +0 -62
  229. package/apps/lib/layouts/FieldSection.tsx +0 -91
  230. package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
  231. package/apps/lib/providers/ThemeProvider.tsx +0 -84
  232. package/apps/lib/registry.json +0 -1201
  233. package/apps/lib/tsconfig.json +0 -9
  234. package/apps/lib/tsconfig.tsbuildinfo +0 -1
  235. package/apps/lib/utils/cn.ts +0 -6
  236. package/apps/lib/utils/color.ts +0 -175
  237. package/apps/lib/utils/dataViews/path.ts +0 -67
  238. package/apps/lib/utils/dataViews/query.ts +0 -73
  239. package/apps/lib/utils/dataViews/types.ts +0 -187
  240. package/apps/lib/utils/dateFormat.ts +0 -108
  241. package/apps/lib/utils/resize.ts +0 -31
  242. package/apps/lib/utils/types.ts +0 -16
  243. package/docs/BLOCKS.md +0 -129
  244. package/docs/CHANGELOG-1.1.16.md +0 -108
  245. package/docs/Cover.png +0 -0
  246. package/docs/README.md +0 -215
  247. package/docs/components/action-button.md +0 -638
  248. package/docs/components/actions-group.md +0 -708
  249. package/docs/components/alert-dialog.md +0 -920
  250. package/docs/components/avatar.md +0 -709
  251. package/docs/components/badge-field.md +0 -712
  252. package/docs/components/badge.md +0 -301
  253. package/docs/components/breadcrumb.md +0 -930
  254. package/docs/components/button-group.md +0 -650
  255. package/docs/components/button.md +0 -639
  256. package/docs/components/calendar.md +0 -555
  257. package/docs/components/card.md +0 -622
  258. package/docs/components/chart-block-tool.md +0 -129
  259. package/docs/components/checkbox.md +0 -699
  260. package/docs/components/cn-layout.md +0 -854
  261. package/docs/components/color-picker.md +0 -101
  262. package/docs/components/conclusion-header.md +0 -80
  263. package/docs/components/context-menu.md +0 -483
  264. package/docs/components/count-badge.md +0 -560
  265. package/docs/components/data-table.md +0 -854
  266. package/docs/components/data-views/backend-response.md +0 -324
  267. package/docs/components/data-views/examples/a11y-rtl.md +0 -250
  268. package/docs/components/data-views/examples/api-orders-route.md +0 -130
  269. package/docs/components/data-views/examples/fields.md +0 -362
  270. package/docs/components/data-views/examples/filters.md +0 -307
  271. package/docs/components/data-views/examples/inbox-routing.md +0 -218
  272. package/docs/components/data-views/examples/index.md +0 -29
  273. package/docs/components/data-views/examples/overview.md +0 -244
  274. package/docs/components/data-views/examples/panel.md +0 -212
  275. package/docs/components/data-views/examples/scale.md +0 -231
  276. package/docs/components/data-views/examples/server-side.md +0 -210
  277. package/docs/components/data-views/examples/state.md +0 -250
  278. package/docs/components/data-views/examples/tree-custom.md +0 -388
  279. package/docs/components/data-views/examples/view-registry.md +0 -313
  280. package/docs/components/data-views/examples/views.md +0 -534
  281. package/docs/components/data-views/guide.md +0 -405
  282. package/docs/components/data-views/index.md +0 -1495
  283. package/docs/components/data-views/migration.md +0 -79
  284. package/docs/components/date-picker.md +0 -857
  285. package/docs/components/dialog.md +0 -929
  286. package/docs/components/divider.md +0 -766
  287. package/docs/components/drawer.md +0 -654
  288. package/docs/components/dropdown-menu.md +0 -668
  289. package/docs/components/field-hint.md +0 -898
  290. package/docs/components/field-section.md +0 -781
  291. package/docs/components/form-builder.md +0 -276
  292. package/docs/components/form-renderer.md +0 -326
  293. package/docs/components/form-summary.md +0 -138
  294. package/docs/components/form.md +0 -785
  295. package/docs/components/header-bar.md +0 -188
  296. package/docs/components/image-attachment.md +0 -906
  297. package/docs/components/inner-label-field.md +0 -819
  298. package/docs/components/input-field.md +0 -623
  299. package/docs/components/input-otp.md +0 -756
  300. package/docs/components/input.md +0 -634
  301. package/docs/components/label-field.md +0 -770
  302. package/docs/components/label.md +0 -761
  303. package/docs/components/labeled-check-box.md +0 -642
  304. package/docs/components/labeled-radio.md +0 -796
  305. package/docs/components/link-button.md +0 -685
  306. package/docs/components/login-button.md +0 -872
  307. package/docs/components/password-level.md +0 -803
  308. package/docs/components/popover.md +0 -649
  309. package/docs/components/profile-menu.md +0 -656
  310. package/docs/components/radio-card.md +0 -801
  311. package/docs/components/radio.md +0 -735
  312. package/docs/components/scroll-area.md +0 -691
  313. package/docs/components/search-field.md +0 -702
  314. package/docs/components/searchable-select.md +0 -368
  315. package/docs/components/searchable-table.md +0 -438
  316. package/docs/components/searchable-tree-dialog.md +0 -190
  317. package/docs/components/searchable-tree.md +0 -200
  318. package/docs/components/section-block.md +0 -477
  319. package/docs/components/select.md +0 -709
  320. package/docs/components/simple-select.md +0 -741
  321. package/docs/components/skeleton.md +0 -706
  322. package/docs/components/slide-date-picker.md +0 -837
  323. package/docs/components/spin-loading.md +0 -696
  324. package/docs/components/stepper.md +0 -316
  325. package/docs/components/switch.md +0 -770
  326. package/docs/components/tab-form-item.md +0 -773
  327. package/docs/components/tab-switch.md +0 -170
  328. package/docs/components/table-dnd-wrapper.md +0 -107
  329. package/docs/components/table.md +0 -1088
  330. package/docs/components/text-editor.md +0 -735
  331. package/docs/components/textarea.md +0 -681
  332. package/docs/components/timeline.md +0 -254
  333. package/docs/components/toast.md +0 -773
  334. package/docs/components/toggle-button.md +0 -643
  335. package/docs/components/toggle.md +0 -882
  336. package/docs/components/tooltip.md +0 -513
  337. package/docs/components/transparent-label.md +0 -721
  338. package/docs/components/tree-drop-down.md +0 -740
  339. package/docs/components/tree-folder.md +0 -110
  340. package/docs/components/tree-sub-layout.md +0 -707
  341. package/docs/explanation/architecture.md +0 -54
  342. package/docs/explanation/design-system.md +0 -52
  343. package/docs/how-to/form-and-list-recipes.md +0 -386
  344. package/docs/how-to/forms-with-form-builder.md +0 -472
  345. package/docs/how-to/guides.md +0 -1027
  346. package/docs/migration/changelog.md +0 -54
  347. package/docs/migration/form-builder-2.5.2.md +0 -113
  348. package/docs/reference/cli.md +0 -112
  349. package/docs/reference/components.md +0 -572
  350. package/docs/reference/hooks.md +0 -1500
  351. package/docs/reference/providers.md +0 -866
  352. package/docs/reference/tailwind-plugins.md +0 -942
  353. package/docs/reference/theme.md +0 -85
  354. package/docs/reference/types.md +0 -1016
  355. package/docs/reference/utilities.md +0 -704
  356. package/docs/tutorials/building-first-form.md +0 -846
  357. package/docs/tutorials/component-composition.md +0 -882
  358. package/docs/tutorials/getting-started.md +0 -302
  359. 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
  }