@pattern-stack/frontend-patterns 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (627) hide show
  1. package/dist/atoms/composed/Accordion/Accordion.d.ts.map +1 -0
  2. package/dist/atoms/composed/Accordion/index.d.ts.map +1 -0
  3. package/dist/atoms/composed/Alert/Alert.d.ts.map +1 -0
  4. package/dist/atoms/composed/Alert/index.d.ts.map +1 -0
  5. package/dist/atoms/composed/Breadcrumb/Breadcrumb.d.ts.map +1 -0
  6. package/dist/atoms/composed/Breadcrumb/index.d.ts.map +1 -0
  7. package/dist/atoms/{components/data → composed}/Chart/Chart.d.ts +2 -2
  8. package/dist/atoms/composed/Chart/Chart.d.ts.map +1 -0
  9. package/dist/atoms/composed/Chart/index.d.ts.map +1 -0
  10. package/dist/atoms/composed/ColorSwatch/ColorSwatch.d.ts.map +1 -0
  11. package/dist/atoms/composed/ColorSwatch/index.d.ts.map +1 -0
  12. package/dist/atoms/composed/DarkModeToggle.d.ts.map +1 -0
  13. package/dist/atoms/composed/DataBadge/DataBadge.d.ts +13 -0
  14. package/dist/atoms/composed/DataBadge/DataBadge.d.ts.map +1 -0
  15. package/dist/atoms/composed/DataBadge/index.d.ts.map +1 -0
  16. package/dist/atoms/composed/DataTable/DataTable.d.ts +28 -0
  17. package/dist/atoms/composed/DataTable/DataTable.d.ts.map +1 -0
  18. package/dist/atoms/composed/DataTable/TableCellWithTooltip.d.ts.map +1 -0
  19. package/dist/atoms/composed/DataTable/index.d.ts.map +1 -0
  20. package/dist/atoms/composed/DateTimePicker/DateTimePicker.d.ts.map +1 -0
  21. package/dist/atoms/composed/DateTimePicker/index.d.ts.map +1 -0
  22. package/dist/atoms/composed/DetailedCard/DetailedCard.d.ts.map +1 -0
  23. package/dist/atoms/composed/DetailedCard/index.d.ts.map +1 -0
  24. package/dist/atoms/composed/EmptyState/EmptyState.d.ts.map +1 -0
  25. package/dist/atoms/composed/EmptyState/index.d.ts.map +1 -0
  26. package/dist/atoms/composed/FileUpload/FileUpload.d.ts.map +1 -0
  27. package/dist/atoms/composed/FileUpload/index.d.ts.map +1 -0
  28. package/dist/atoms/composed/FormField/FormField.d.ts.map +1 -0
  29. package/dist/atoms/composed/FormField/index.d.ts.map +1 -0
  30. package/dist/atoms/composed/GlobalSearch/GlobalSearch.d.ts.map +1 -0
  31. package/dist/atoms/composed/GlobalSearch/index.d.ts.map +1 -0
  32. package/dist/atoms/{components/data → composed}/IconBadge/IconBadge.d.ts +1 -2
  33. package/dist/atoms/composed/IconBadge/IconBadge.d.ts.map +1 -0
  34. package/dist/atoms/composed/IconBadge/index.d.ts.map +1 -0
  35. package/dist/atoms/composed/Modal/Modal.d.ts.map +1 -0
  36. package/dist/atoms/composed/Modal/index.d.ts.map +1 -0
  37. package/dist/atoms/composed/PaletteSwitcher.d.ts.map +1 -0
  38. package/dist/atoms/composed/ProgressBar/ProgressBar.d.ts.map +1 -0
  39. package/dist/atoms/composed/ProgressBar/index.d.ts.map +1 -0
  40. package/dist/atoms/{components/data → composed}/StatCard/StatCard.d.ts +1 -1
  41. package/dist/atoms/composed/StatCard/StatCard.d.ts.map +1 -0
  42. package/dist/atoms/composed/StatCard/index.d.ts.map +1 -0
  43. package/dist/atoms/composed/StyleGuide.d.ts.map +1 -0
  44. package/dist/atoms/composed/Toast/Toast.d.ts.map +1 -0
  45. package/dist/atoms/composed/Toast/index.d.ts.map +1 -0
  46. package/dist/atoms/composed/Tooltip/Tooltip.d.ts.map +1 -0
  47. package/dist/atoms/composed/Tooltip/index.d.ts +2 -0
  48. package/dist/atoms/composed/Tooltip/index.d.ts.map +1 -0
  49. package/dist/atoms/composed/UserAvatar/UserAvatar.d.ts.map +1 -0
  50. package/dist/atoms/composed/UserAvatar/index.d.ts.map +1 -0
  51. package/dist/atoms/composed/UserMenu/UserMenu.d.ts.map +1 -0
  52. package/dist/atoms/composed/UserMenu/index.d.ts.map +1 -0
  53. package/dist/atoms/composed/index.d.ts +25 -0
  54. package/dist/atoms/composed/index.d.ts.map +1 -0
  55. package/dist/atoms/index.d.ts +5 -4
  56. package/dist/atoms/index.d.ts.map +1 -1
  57. package/dist/atoms/shared/index.d.ts +0 -1
  58. package/dist/atoms/shared/index.d.ts.map +1 -1
  59. package/dist/atoms/types/index.d.ts +0 -3
  60. package/dist/atoms/types/index.d.ts.map +1 -1
  61. package/dist/atoms/ui/Badge.d.ts.map +1 -0
  62. package/dist/atoms/ui/ErrorBoundary.d.ts.map +1 -0
  63. package/dist/atoms/ui/Select.d.ts.map +1 -0
  64. package/dist/atoms/ui/Switch.d.ts.map +1 -0
  65. package/dist/atoms/ui/Tabs.d.ts.map +1 -0
  66. package/dist/atoms/ui/avatar.d.ts.map +1 -0
  67. package/dist/atoms/{primitives → ui}/button.d.ts +3 -3
  68. package/dist/atoms/ui/button.d.ts.map +1 -0
  69. package/dist/atoms/ui/card.d.ts.map +1 -0
  70. package/dist/atoms/ui/dropdown-menu.d.ts.map +1 -0
  71. package/dist/atoms/{primitives → ui}/index.d.ts +0 -2
  72. package/dist/atoms/ui/index.d.ts.map +1 -0
  73. package/dist/atoms/ui/input.d.ts.map +1 -0
  74. package/dist/atoms/ui/label.d.ts.map +1 -0
  75. package/dist/atoms/ui/skeleton.d.ts.map +1 -0
  76. package/dist/atoms/ui/spinner.d.ts.map +1 -0
  77. package/dist/atoms/ui/table.d.ts.map +1 -0
  78. package/dist/atoms/utils/utils.d.ts +0 -5
  79. package/dist/atoms/utils/utils.d.ts.map +1 -1
  80. package/dist/features/auth/components/LoginForm.d.ts.map +1 -1
  81. package/dist/features/auth/hooks/index.d.ts +0 -1
  82. package/dist/features/auth/hooks/index.d.ts.map +1 -1
  83. package/dist/features/auth/index.d.ts +0 -1
  84. package/dist/features/auth/index.d.ts.map +1 -1
  85. package/dist/frontend-patterns.css +1 -4417
  86. package/dist/index.d.ts +0 -8
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.es.js +8507 -27524
  89. package/dist/index.es.js.map +1 -1
  90. package/dist/index.js +8466 -27505
  91. package/dist/index.js.map +1 -1
  92. package/dist/molecules/forms/SearchInput.d.ts.map +1 -1
  93. package/dist/molecules/layout/AppHeader/AppHeader.d.ts.map +1 -1
  94. package/dist/molecules/layout/Sidebar.d.ts.map +1 -1
  95. package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts +0 -2
  96. package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts.map +1 -1
  97. package/dist/molecules/layout/index.d.ts +0 -4
  98. package/dist/molecules/layout/index.d.ts.map +1 -1
  99. package/dist/organisms/showcase/ComponentShowcasePage.d.ts.map +1 -1
  100. package/dist/templates/DataTemplate.d.ts +1 -1
  101. package/dist/templates/DataTemplate.d.ts.map +1 -1
  102. package/dist/templates/admin/AdminCRUDTemplate.d.ts.map +1 -1
  103. package/dist/templates/admin/AdminDashboardTemplate.d.ts +9 -6
  104. package/dist/templates/admin/AdminDashboardTemplate.d.ts.map +1 -1
  105. package/dist/templates/admin/AdminDetailTemplate.d.ts +1 -1
  106. package/dist/templates/admin/AdminDetailTemplate.d.ts.map +1 -1
  107. package/dist/templates/factory.d.ts +1 -2
  108. package/dist/templates/factory.d.ts.map +1 -1
  109. package/dist/templates/index.d.ts +0 -2
  110. package/dist/templates/index.d.ts.map +1 -1
  111. package/package.json +10 -35
  112. package/src/App.css +42 -0
  113. package/src/App.tsx +54 -0
  114. package/src/__tests__/README.md +221 -0
  115. package/src/__tests__/atoms/hooks/simple-hooks.test.ts +44 -0
  116. package/src/__tests__/atoms/ui/button.test.tsx +68 -0
  117. package/src/__tests__/atoms/utils/simple.test.ts +18 -0
  118. package/src/__tests__/atoms/utils/utils.test.ts +77 -0
  119. package/src/__tests__/features/auth/simple-auth.test.tsx +40 -0
  120. package/src/__tests__/molecules/layout/simple-layout.test.tsx +81 -0
  121. package/src/__tests__/organisms/showcase/simple-showcase.test.tsx +167 -0
  122. package/src/__tests__/setup.ts +51 -0
  123. package/src/__tests__/utils.tsx +123 -0
  124. package/src/atoms/composed/Accordion/Accordion.tsx +271 -0
  125. package/src/atoms/composed/Accordion/index.ts +1 -0
  126. package/src/atoms/composed/Alert/Alert.tsx +132 -0
  127. package/src/atoms/composed/Alert/index.ts +1 -0
  128. package/src/atoms/composed/Breadcrumb/Breadcrumb.tsx +83 -0
  129. package/src/atoms/composed/Breadcrumb/index.ts +1 -0
  130. package/src/atoms/composed/Chart/Chart.tsx +425 -0
  131. package/src/atoms/composed/Chart/index.ts +2 -0
  132. package/src/atoms/composed/ColorSwatch/ColorSwatch.tsx +72 -0
  133. package/src/atoms/composed/ColorSwatch/index.ts +1 -0
  134. package/src/atoms/composed/DarkModeToggle.tsx +66 -0
  135. package/src/atoms/composed/DataBadge/DataBadge.tsx +81 -0
  136. package/src/atoms/composed/DataBadge/index.ts +1 -0
  137. package/src/atoms/composed/DataTable/DataTable.tsx +394 -0
  138. package/src/atoms/composed/DataTable/TableCellWithTooltip.tsx +41 -0
  139. package/src/atoms/composed/DataTable/index.ts +2 -0
  140. package/src/atoms/composed/DateTimePicker/DateTimePicker.tsx +611 -0
  141. package/src/atoms/composed/DateTimePicker/index.ts +2 -0
  142. package/src/atoms/composed/DetailedCard/DetailedCard.tsx +181 -0
  143. package/src/atoms/composed/DetailedCard/index.ts +2 -0
  144. package/src/atoms/composed/EmptyState/EmptyState.tsx +90 -0
  145. package/src/atoms/composed/EmptyState/index.ts +1 -0
  146. package/src/atoms/composed/FileUpload/FileUpload.tsx +477 -0
  147. package/src/atoms/composed/FileUpload/index.ts +2 -0
  148. package/src/atoms/composed/FormField/FormField.tsx +92 -0
  149. package/src/atoms/composed/FormField/index.ts +1 -0
  150. package/src/atoms/composed/GlobalSearch/GlobalSearch.tsx +37 -0
  151. package/src/atoms/composed/GlobalSearch/index.ts +1 -0
  152. package/src/atoms/composed/IconBadge/IconBadge.tsx +95 -0
  153. package/src/atoms/composed/IconBadge/index.ts +2 -0
  154. package/src/atoms/composed/Modal/Modal.tsx +223 -0
  155. package/src/atoms/composed/Modal/index.ts +2 -0
  156. package/src/atoms/composed/PaletteSwitcher.tsx +386 -0
  157. package/src/atoms/composed/ProgressBar/ProgressBar.tsx +116 -0
  158. package/src/atoms/composed/ProgressBar/index.ts +1 -0
  159. package/src/atoms/composed/StatCard/StatCard.tsx +219 -0
  160. package/src/atoms/composed/StatCard/index.ts +1 -0
  161. package/src/atoms/composed/StyleGuide.tsx +717 -0
  162. package/src/atoms/composed/Toast/Toast.tsx +219 -0
  163. package/src/atoms/composed/Toast/index.ts +1 -0
  164. package/src/atoms/composed/Tooltip/Tooltip.tsx +213 -0
  165. package/src/atoms/composed/Tooltip/index.ts +1 -0
  166. package/src/atoms/composed/UserAvatar/UserAvatar.tsx +139 -0
  167. package/src/atoms/composed/UserAvatar/index.ts +1 -0
  168. package/src/atoms/composed/UserMenu/UserMenu.tsx +16 -0
  169. package/src/atoms/composed/UserMenu/index.ts +1 -0
  170. package/src/atoms/composed/index.ts +29 -0
  171. package/src/atoms/hooks/useApi.ts +80 -0
  172. package/src/atoms/hooks/useHealth.ts +17 -0
  173. package/src/atoms/index.ts +13 -0
  174. package/src/atoms/services/api/client.ts +134 -0
  175. package/src/atoms/services/auth-service.ts +248 -0
  176. package/src/atoms/services/health.ts +15 -0
  177. package/src/atoms/services/index.ts +3 -0
  178. package/src/atoms/shared/config/constants.ts +17 -0
  179. package/src/atoms/shared/config/dashboard-sizes.ts +111 -0
  180. package/src/atoms/shared/config/environment.ts +10 -0
  181. package/src/atoms/shared/index.ts +4 -0
  182. package/src/atoms/shared/styles/color-palettes.css +566 -0
  183. package/src/atoms/types/auth.ts +62 -0
  184. package/src/atoms/types/generated.ts +1469 -0
  185. package/src/atoms/types/index.ts +4 -0
  186. package/src/atoms/types/loading.ts +28 -0
  187. package/src/atoms/ui/Badge.tsx +30 -0
  188. package/src/atoms/ui/ErrorBoundary.tsx +59 -0
  189. package/src/atoms/ui/Select.tsx +53 -0
  190. package/src/atoms/ui/Switch.tsx +42 -0
  191. package/src/atoms/ui/Tabs.tsx +118 -0
  192. package/src/atoms/ui/avatar.tsx +48 -0
  193. package/src/atoms/ui/button.tsx +70 -0
  194. package/src/atoms/ui/card.tsx +76 -0
  195. package/src/atoms/ui/dropdown-menu.tsx +199 -0
  196. package/src/atoms/ui/index.ts +39 -0
  197. package/src/atoms/ui/input.tsx +23 -0
  198. package/src/atoms/ui/label.tsx +23 -0
  199. package/src/atoms/ui/skeleton.tsx +13 -0
  200. package/src/atoms/ui/spinner.tsx +49 -0
  201. package/src/atoms/ui/table.tsx +116 -0
  202. package/src/atoms/utils/animations.ts +135 -0
  203. package/src/atoms/utils/tooltip-helpers.ts +140 -0
  204. package/src/atoms/utils/utils.ts +9 -0
  205. package/src/features/auth/components/LoginForm.tsx +168 -0
  206. package/src/features/auth/components/LogoutButton.tsx +19 -0
  207. package/src/features/auth/components/ProtectedRoute.tsx +60 -0
  208. package/src/features/auth/components/index.ts +4 -0
  209. package/src/features/auth/hooks/index.ts +2 -0
  210. package/src/features/auth/hooks/useAuth.tsx +205 -0
  211. package/src/features/auth/hooks/usePermissions.ts +35 -0
  212. package/src/features/auth/index.ts +2 -0
  213. package/src/features/index.ts +2 -0
  214. package/src/index.css +704 -0
  215. package/src/index.ts +13 -0
  216. package/src/main.tsx +48 -0
  217. package/src/molecules/.gitkeep +0 -0
  218. package/src/molecules/forms/FormGroup.tsx +75 -0
  219. package/src/molecules/forms/SearchInput.tsx +259 -0
  220. package/src/molecules/forms/index.ts +4 -0
  221. package/src/molecules/index.ts +4 -0
  222. package/src/molecules/layout/AppHeader/AppHeader.tsx +42 -0
  223. package/src/molecules/layout/AppHeader/index.ts +1 -0
  224. package/src/molecules/layout/AppLayout.tsx +29 -0
  225. package/src/molecules/layout/PageTemplate.tsx +87 -0
  226. package/src/molecules/layout/SectionHeader/SectionHeader.tsx +87 -0
  227. package/src/molecules/layout/SectionHeader/index.ts +1 -0
  228. package/src/molecules/layout/ShowcaseSection.tsx +57 -0
  229. package/src/molecules/layout/Sidebar.tsx +144 -0
  230. package/src/molecules/layout/SidebarButton/SidebarButton.tsx +99 -0
  231. package/src/molecules/layout/SidebarButton/index.ts +1 -0
  232. package/src/molecules/layout/SidebarContext.tsx +31 -0
  233. package/src/molecules/layout/index.ts +7 -0
  234. package/src/molecules/navigation/NavMenu.tsx +188 -0
  235. package/src/molecules/navigation/Pagination.tsx +172 -0
  236. package/src/molecules/navigation/index.ts +4 -0
  237. package/src/organisms/index.ts +5 -0
  238. package/src/organisms/showcase/ComponentShowcasePage.tsx +2496 -0
  239. package/src/organisms/showcase/index.ts +1 -0
  240. package/src/pages/AdminShowcase/AdminCRUDShowcase.tsx +242 -0
  241. package/src/pages/AdminShowcase/AdminDashboardShowcase.tsx +171 -0
  242. package/src/pages/AdminShowcase/AdminDetailShowcase.tsx +385 -0
  243. package/src/pages/AdminShowcase/index.tsx +3 -0
  244. package/src/pages/ComponentShowcase/BadgesShowcase.tsx +188 -0
  245. package/src/pages/ComponentShowcase/CardsShowcase.tsx +392 -0
  246. package/src/pages/ComponentShowcase/PalettesShowcase.tsx +207 -0
  247. package/src/pages/ComponentShowcase/StatesShowcase.tsx +485 -0
  248. package/src/pages/ComponentShowcase/TablesShowcase.tsx +134 -0
  249. package/src/pages/ComponentShowcase/TypographyShowcase.tsx +255 -0
  250. package/src/pages/ComponentShowcase/index.tsx +188 -0
  251. package/src/pages/index.ts +2 -0
  252. package/src/templates/AuthTemplate.tsx +216 -0
  253. package/src/templates/ComponentShowcaseTemplate.tsx +173 -0
  254. package/src/templates/DashboardTemplate.tsx +232 -0
  255. package/src/templates/DataTemplate.tsx +319 -0
  256. package/src/templates/admin/AdminCRUDTemplate.tsx +630 -0
  257. package/src/templates/admin/AdminDashboardTemplate.tsx +351 -0
  258. package/src/templates/admin/AdminDetailTemplate.tsx +563 -0
  259. package/src/templates/admin/index.ts +29 -0
  260. package/src/templates/factory.tsx +169 -0
  261. package/src/templates/index.ts +37 -0
  262. package/src/vite-env.d.ts +1 -0
  263. package/CHANGELOG.md +0 -63
  264. package/LICENSE +0 -19
  265. package/cli/cli/commands/generate-hooks.js +0 -291
  266. package/cli/cli/commands/init.js +0 -25
  267. package/cli/cli/commands/scaffold.js +0 -201
  268. package/cli/cli/index.js +0 -113
  269. package/cli/commands/generate-hooks.js +0 -288
  270. package/cli/commands/generate-hooks.ts +0 -316
  271. package/cli/commands/init.js +0 -22
  272. package/cli/commands/init.ts +0 -33
  273. package/cli/commands/scaffold.js +0 -198
  274. package/cli/commands/scaffold.ts +0 -224
  275. package/cli/index.js +0 -3210
  276. package/cli/index.ts +0 -122
  277. package/cli/src/codegen/openapi/bulk-hook-generator.js +0 -252
  278. package/cli/src/codegen/openapi/bulk-types.js +0 -89
  279. package/cli/src/codegen/openapi/client-generator.js +0 -672
  280. package/cli/src/codegen/openapi/confidence-scorer.js +0 -204
  281. package/cli/src/codegen/openapi/hook-config.js +0 -66
  282. package/cli/src/codegen/openapi/hook-generator.js +0 -1057
  283. package/cli/src/codegen/openapi/parser.js +0 -279
  284. package/cli/src/codegen/openapi/type-generator.js +0 -339
  285. package/dist/atoms/components/core/Avatar/Avatar.d.ts +0 -41
  286. package/dist/atoms/components/core/Avatar/Avatar.d.ts.map +0 -1
  287. package/dist/atoms/components/core/Avatar/index.d.ts +0 -2
  288. package/dist/atoms/components/core/Avatar/index.d.ts.map +0 -1
  289. package/dist/atoms/components/core/Badge/Badge.d.ts +0 -38
  290. package/dist/atoms/components/core/Badge/Badge.d.ts.map +0 -1
  291. package/dist/atoms/components/core/Badge/index.d.ts +0 -2
  292. package/dist/atoms/components/core/Badge/index.d.ts.map +0 -1
  293. package/dist/atoms/components/core/Button/Button.d.ts +0 -28
  294. package/dist/atoms/components/core/Button/Button.d.ts.map +0 -1
  295. package/dist/atoms/components/core/Button/index.d.ts +0 -3
  296. package/dist/atoms/components/core/Button/index.d.ts.map +0 -1
  297. package/dist/atoms/components/core/Card/Card.d.ts +0 -41
  298. package/dist/atoms/components/core/Card/Card.d.ts.map +0 -1
  299. package/dist/atoms/components/core/Card/index.d.ts +0 -3
  300. package/dist/atoms/components/core/Card/index.d.ts.map +0 -1
  301. package/dist/atoms/components/core/Checkbox/Checkbox.d.ts +0 -28
  302. package/dist/atoms/components/core/Checkbox/Checkbox.d.ts.map +0 -1
  303. package/dist/atoms/components/core/Checkbox/index.d.ts +0 -3
  304. package/dist/atoms/components/core/Checkbox/index.d.ts.map +0 -1
  305. package/dist/atoms/components/core/Input/Input.d.ts +0 -37
  306. package/dist/atoms/components/core/Input/Input.d.ts.map +0 -1
  307. package/dist/atoms/components/core/Input/index.d.ts +0 -3
  308. package/dist/atoms/components/core/Input/index.d.ts.map +0 -1
  309. package/dist/atoms/components/core/Label/Label.d.ts +0 -23
  310. package/dist/atoms/components/core/Label/Label.d.ts.map +0 -1
  311. package/dist/atoms/components/core/Label/index.d.ts +0 -3
  312. package/dist/atoms/components/core/Label/index.d.ts.map +0 -1
  313. package/dist/atoms/components/core/Select/Select.d.ts +0 -42
  314. package/dist/atoms/components/core/Select/Select.d.ts.map +0 -1
  315. package/dist/atoms/components/core/Select/index.d.ts +0 -3
  316. package/dist/atoms/components/core/Select/index.d.ts.map +0 -1
  317. package/dist/atoms/components/core/Spinner/Spinner.d.ts +0 -25
  318. package/dist/atoms/components/core/Spinner/Spinner.d.ts.map +0 -1
  319. package/dist/atoms/components/core/Spinner/index.d.ts +0 -3
  320. package/dist/atoms/components/core/Spinner/index.d.ts.map +0 -1
  321. package/dist/atoms/components/core/Switch/Switch.d.ts +0 -35
  322. package/dist/atoms/components/core/Switch/Switch.d.ts.map +0 -1
  323. package/dist/atoms/components/core/Switch/index.d.ts +0 -2
  324. package/dist/atoms/components/core/Switch/index.d.ts.map +0 -1
  325. package/dist/atoms/components/core/index.d.ts +0 -11
  326. package/dist/atoms/components/core/index.d.ts.map +0 -1
  327. package/dist/atoms/components/data/ActivityFeed/ActivityFeed.d.ts +0 -4
  328. package/dist/atoms/components/data/ActivityFeed/ActivityFeed.d.ts.map +0 -1
  329. package/dist/atoms/components/data/ActivityFeed/ActivityFeed.stories.d.ts +0 -38
  330. package/dist/atoms/components/data/ActivityFeed/ActivityFeed.stories.d.ts.map +0 -1
  331. package/dist/atoms/components/data/ActivityFeed/ActivityFeedItem.d.ts +0 -9
  332. package/dist/atoms/components/data/ActivityFeed/ActivityFeedItem.d.ts.map +0 -1
  333. package/dist/atoms/components/data/ActivityFeed/index.d.ts +0 -4
  334. package/dist/atoms/components/data/ActivityFeed/index.d.ts.map +0 -1
  335. package/dist/atoms/components/data/ActivityFeed/types.d.ts +0 -26
  336. package/dist/atoms/components/data/ActivityFeed/types.d.ts.map +0 -1
  337. package/dist/atoms/components/data/ActivityFeed/utils.d.ts +0 -5
  338. package/dist/atoms/components/data/ActivityFeed/utils.d.ts.map +0 -1
  339. package/dist/atoms/components/data/Chart/Chart.d.ts.map +0 -1
  340. package/dist/atoms/components/data/Chart/index.d.ts.map +0 -1
  341. package/dist/atoms/components/data/DataBadge/DataBadge.d.ts +0 -18
  342. package/dist/atoms/components/data/DataBadge/DataBadge.d.ts.map +0 -1
  343. package/dist/atoms/components/data/DataBadge/index.d.ts.map +0 -1
  344. package/dist/atoms/components/data/DataTable/DataTable.d.ts +0 -5
  345. package/dist/atoms/components/data/DataTable/DataTable.d.ts.map +0 -1
  346. package/dist/atoms/components/data/DataTable/DataTable.types.d.ts +0 -51
  347. package/dist/atoms/components/data/DataTable/DataTable.types.d.ts.map +0 -1
  348. package/dist/atoms/components/data/DataTable/TableCellWithTooltip.d.ts.map +0 -1
  349. package/dist/atoms/components/data/DataTable/index.d.ts.map +0 -1
  350. package/dist/atoms/components/data/DetailedCard/DetailedCard.d.ts.map +0 -1
  351. package/dist/atoms/components/data/DetailedCard/index.d.ts.map +0 -1
  352. package/dist/atoms/components/data/EntityIcon/EntityIcon.d.ts +0 -24
  353. package/dist/atoms/components/data/EntityIcon/EntityIcon.d.ts.map +0 -1
  354. package/dist/atoms/components/data/EntityIcon/index.d.ts +0 -2
  355. package/dist/atoms/components/data/EntityIcon/index.d.ts.map +0 -1
  356. package/dist/atoms/components/data/IconBadge/IconBadge.d.ts.map +0 -1
  357. package/dist/atoms/components/data/IconBadge/index.d.ts.map +0 -1
  358. package/dist/atoms/components/data/ListCard/ListCard.d.ts +0 -32
  359. package/dist/atoms/components/data/ListCard/ListCard.d.ts.map +0 -1
  360. package/dist/atoms/components/data/ListCard/index.d.ts +0 -2
  361. package/dist/atoms/components/data/ListCard/index.d.ts.map +0 -1
  362. package/dist/atoms/components/data/ProgressBar/ProgressBar.d.ts.map +0 -1
  363. package/dist/atoms/components/data/ProgressBar/index.d.ts.map +0 -1
  364. package/dist/atoms/components/data/StatCard/StatCard.d.ts.map +0 -1
  365. package/dist/atoms/components/data/StatCard/index.d.ts.map +0 -1
  366. package/dist/atoms/components/data/Table/Table.d.ts +0 -41
  367. package/dist/atoms/components/data/Table/Table.d.ts.map +0 -1
  368. package/dist/atoms/components/data/Table/index.d.ts +0 -2
  369. package/dist/atoms/components/data/Table/index.d.ts.map +0 -1
  370. package/dist/atoms/components/data/TruncatedText/TruncatedText.d.ts +0 -26
  371. package/dist/atoms/components/data/TruncatedText/TruncatedText.d.ts.map +0 -1
  372. package/dist/atoms/components/data/TruncatedText/index.d.ts +0 -2
  373. package/dist/atoms/components/data/TruncatedText/index.d.ts.map +0 -1
  374. package/dist/atoms/components/data/index.d.ts +0 -13
  375. package/dist/atoms/components/data/index.d.ts.map +0 -1
  376. package/dist/atoms/components/domain/SalesPanel/SalesPanel.d.ts +0 -19
  377. package/dist/atoms/components/domain/SalesPanel/SalesPanel.d.ts.map +0 -1
  378. package/dist/atoms/components/domain/SalesPanel/index.d.ts +0 -2
  379. package/dist/atoms/components/domain/SalesPanel/index.d.ts.map +0 -1
  380. package/dist/atoms/components/domain/SalesPanel/mockSalesData.d.ts +0 -63
  381. package/dist/atoms/components/domain/SalesPanel/mockSalesData.d.ts.map +0 -1
  382. package/dist/atoms/components/domain/index.d.ts +0 -2
  383. package/dist/atoms/components/domain/index.d.ts.map +0 -1
  384. package/dist/atoms/components/feedback/Alert/Alert.d.ts.map +0 -1
  385. package/dist/atoms/components/feedback/Alert/index.d.ts.map +0 -1
  386. package/dist/atoms/components/feedback/EmptyState/EmptyState.d.ts.map +0 -1
  387. package/dist/atoms/components/feedback/EmptyState/index.d.ts.map +0 -1
  388. package/dist/atoms/components/feedback/ErrorBoundary/ErrorBoundary.d.ts +0 -61
  389. package/dist/atoms/components/feedback/ErrorBoundary/ErrorBoundary.d.ts.map +0 -1
  390. package/dist/atoms/components/feedback/ErrorBoundary/index.d.ts +0 -2
  391. package/dist/atoms/components/feedback/ErrorBoundary/index.d.ts.map +0 -1
  392. package/dist/atoms/components/feedback/Skeleton/Skeleton.d.ts +0 -41
  393. package/dist/atoms/components/feedback/Skeleton/Skeleton.d.ts.map +0 -1
  394. package/dist/atoms/components/feedback/Skeleton/index.d.ts +0 -2
  395. package/dist/atoms/components/feedback/Skeleton/index.d.ts.map +0 -1
  396. package/dist/atoms/components/feedback/Toast/Toast.d.ts.map +0 -1
  397. package/dist/atoms/components/feedback/Toast/index.d.ts.map +0 -1
  398. package/dist/atoms/components/feedback/index.d.ts +0 -6
  399. package/dist/atoms/components/feedback/index.d.ts.map +0 -1
  400. package/dist/atoms/components/forms/DateTimePicker/DateTimePicker.d.ts.map +0 -1
  401. package/dist/atoms/components/forms/DateTimePicker/index.d.ts.map +0 -1
  402. package/dist/atoms/components/forms/FileUpload/FileUpload.d.ts.map +0 -1
  403. package/dist/atoms/components/forms/FileUpload/index.d.ts.map +0 -1
  404. package/dist/atoms/components/forms/FormField/FormField.d.ts.map +0 -1
  405. package/dist/atoms/components/forms/FormField/index.d.ts.map +0 -1
  406. package/dist/atoms/components/forms/index.d.ts +0 -4
  407. package/dist/atoms/components/forms/index.d.ts.map +0 -1
  408. package/dist/atoms/components/index.d.ts +0 -10
  409. package/dist/atoms/components/index.d.ts.map +0 -1
  410. package/dist/atoms/components/layout/Accordion/Accordion.d.ts.map +0 -1
  411. package/dist/atoms/components/layout/Accordion/index.d.ts.map +0 -1
  412. package/dist/atoms/components/layout/Breadcrumb/Breadcrumb.d.ts.map +0 -1
  413. package/dist/atoms/components/layout/Breadcrumb/index.d.ts.map +0 -1
  414. package/dist/atoms/components/layout/Dialog/index.d.ts +0 -3
  415. package/dist/atoms/components/layout/Dialog/index.d.ts.map +0 -1
  416. package/dist/atoms/components/layout/Dropdown/Dropdown.d.ts +0 -40
  417. package/dist/atoms/components/layout/Dropdown/Dropdown.d.ts.map +0 -1
  418. package/dist/atoms/components/layout/Dropdown/index.d.ts +0 -3
  419. package/dist/atoms/components/layout/Dropdown/index.d.ts.map +0 -1
  420. package/dist/atoms/components/layout/Modal/Modal.d.ts.map +0 -1
  421. package/dist/atoms/components/layout/Modal/index.d.ts.map +0 -1
  422. package/dist/atoms/components/layout/Tabs/index.d.ts +0 -2
  423. package/dist/atoms/components/layout/Tabs/index.d.ts.map +0 -1
  424. package/dist/atoms/components/layout/Tooltip/Tooltip.d.ts.map +0 -1
  425. package/dist/atoms/components/layout/Tooltip/index.d.ts +0 -2
  426. package/dist/atoms/components/layout/Tooltip/index.d.ts.map +0 -1
  427. package/dist/atoms/components/layout/index.d.ts +0 -8
  428. package/dist/atoms/components/layout/index.d.ts.map +0 -1
  429. package/dist/atoms/components/navigation/GlobalSearch/GlobalSearch.d.ts.map +0 -1
  430. package/dist/atoms/components/navigation/GlobalSearch/index.d.ts.map +0 -1
  431. package/dist/atoms/components/navigation/index.d.ts +0 -2
  432. package/dist/atoms/components/navigation/index.d.ts.map +0 -1
  433. package/dist/atoms/components/theme/ColorSwatch/ColorSwatch.d.ts.map +0 -1
  434. package/dist/atoms/components/theme/ColorSwatch/index.d.ts.map +0 -1
  435. package/dist/atoms/components/theme/DarkModeToggle.d.ts.map +0 -1
  436. package/dist/atoms/components/theme/PaletteSwitcher.d.ts.map +0 -1
  437. package/dist/atoms/components/theme/StyleGuide.d.ts.map +0 -1
  438. package/dist/atoms/components/theme/index.d.ts +0 -5
  439. package/dist/atoms/components/theme/index.d.ts.map +0 -1
  440. package/dist/atoms/components/user/UserAvatar/UserAvatar.d.ts.map +0 -1
  441. package/dist/atoms/components/user/UserAvatar/index.d.ts.map +0 -1
  442. package/dist/atoms/components/user/UserMenu/UserMenu.d.ts.map +0 -1
  443. package/dist/atoms/components/user/UserMenu/index.d.ts.map +0 -1
  444. package/dist/atoms/components/user/index.d.ts +0 -3
  445. package/dist/atoms/components/user/index.d.ts.map +0 -1
  446. package/dist/atoms/config/responsive.d.ts +0 -147
  447. package/dist/atoms/config/responsive.d.ts.map +0 -1
  448. package/dist/atoms/hooks/index.d.ts +0 -5
  449. package/dist/atoms/hooks/index.d.ts.map +0 -1
  450. package/dist/atoms/hooks/use-toast.d.ts +0 -16
  451. package/dist/atoms/hooks/use-toast.d.ts.map +0 -1
  452. package/dist/atoms/hooks/useResponsive.d.ts +0 -42
  453. package/dist/atoms/hooks/useResponsive.d.ts.map +0 -1
  454. package/dist/atoms/primitives/Badge.d.ts.map +0 -1
  455. package/dist/atoms/primitives/ErrorBoundary.d.ts.map +0 -1
  456. package/dist/atoms/primitives/Select.d.ts.map +0 -1
  457. package/dist/atoms/primitives/Switch.d.ts.map +0 -1
  458. package/dist/atoms/primitives/Tabs.d.ts.map +0 -1
  459. package/dist/atoms/primitives/avatar.d.ts.map +0 -1
  460. package/dist/atoms/primitives/button.d.ts.map +0 -1
  461. package/dist/atoms/primitives/card.d.ts.map +0 -1
  462. package/dist/atoms/primitives/checkbox.d.ts +0 -12
  463. package/dist/atoms/primitives/checkbox.d.ts.map +0 -1
  464. package/dist/atoms/primitives/dialog.d.ts +0 -34
  465. package/dist/atoms/primitives/dialog.d.ts.map +0 -1
  466. package/dist/atoms/primitives/dropdown-menu.d.ts.map +0 -1
  467. package/dist/atoms/primitives/index.d.ts.map +0 -1
  468. package/dist/atoms/primitives/input.d.ts.map +0 -1
  469. package/dist/atoms/primitives/label.d.ts.map +0 -1
  470. package/dist/atoms/primitives/skeleton.d.ts.map +0 -1
  471. package/dist/atoms/primitives/spinner.d.ts.map +0 -1
  472. package/dist/atoms/primitives/table.d.ts.map +0 -1
  473. package/dist/atoms/types/entity-config.d.ts +0 -117
  474. package/dist/atoms/types/entity-config.d.ts.map +0 -1
  475. package/dist/atoms/types/navigation.d.ts +0 -30
  476. package/dist/atoms/types/navigation.d.ts.map +0 -1
  477. package/dist/atoms/types/ui-config.d.ts +0 -50
  478. package/dist/atoms/types/ui-config.d.ts.map +0 -1
  479. package/dist/atoms/utils/color-manager.d.ts +0 -68
  480. package/dist/atoms/utils/color-manager.d.ts.map +0 -1
  481. package/dist/atoms/utils/debounce.d.ts +0 -6
  482. package/dist/atoms/utils/debounce.d.ts.map +0 -1
  483. package/dist/atoms/utils/field-detection.d.ts +0 -15
  484. package/dist/atoms/utils/field-detection.d.ts.map +0 -1
  485. package/dist/atoms/utils/icon-resolver.d.ts +0 -76
  486. package/dist/atoms/utils/icon-resolver.d.ts.map +0 -1
  487. package/dist/atoms/utils/index.d.ts +0 -5
  488. package/dist/atoms/utils/index.d.ts.map +0 -1
  489. package/dist/atoms/utils/metric-engine.d.ts +0 -30
  490. package/dist/atoms/utils/metric-engine.d.ts.map +0 -1
  491. package/dist/atoms/utils/ui-mapping.d.ts +0 -17
  492. package/dist/atoms/utils/ui-mapping.d.ts.map +0 -1
  493. package/dist/codegen/index.d.ts +0 -7
  494. package/dist/codegen/index.d.ts.map +0 -1
  495. package/dist/codegen/openapi/bulk-hook-generator.d.ts +0 -40
  496. package/dist/codegen/openapi/bulk-hook-generator.d.ts.map +0 -1
  497. package/dist/codegen/openapi/bulk-types.d.ts +0 -142
  498. package/dist/codegen/openapi/bulk-types.d.ts.map +0 -1
  499. package/dist/codegen/openapi/client-generator.d.ts +0 -52
  500. package/dist/codegen/openapi/client-generator.d.ts.map +0 -1
  501. package/dist/codegen/openapi/confidence-scorer.d.ts +0 -30
  502. package/dist/codegen/openapi/confidence-scorer.d.ts.map +0 -1
  503. package/dist/codegen/openapi/hook-config.d.ts +0 -50
  504. package/dist/codegen/openapi/hook-config.d.ts.map +0 -1
  505. package/dist/codegen/openapi/hook-generator.d.ts +0 -108
  506. package/dist/codegen/openapi/hook-generator.d.ts.map +0 -1
  507. package/dist/codegen/openapi/index.d.ts +0 -27
  508. package/dist/codegen/openapi/index.d.ts.map +0 -1
  509. package/dist/codegen/openapi/parser.d.ts +0 -107
  510. package/dist/codegen/openapi/parser.d.ts.map +0 -1
  511. package/dist/codegen/openapi/type-generator.d.ts +0 -53
  512. package/dist/codegen/openapi/type-generator.d.ts.map +0 -1
  513. package/dist/features/auth/hooks/useAuthContext.d.ts +0 -7
  514. package/dist/features/auth/hooks/useAuthContext.d.ts.map +0 -1
  515. package/dist/features/auth/providers/MockAuthProvider.d.ts +0 -9
  516. package/dist/features/auth/providers/MockAuthProvider.d.ts.map +0 -1
  517. package/dist/features/auth/providers/index.d.ts +0 -2
  518. package/dist/features/auth/providers/index.d.ts.map +0 -1
  519. package/dist/features/auth/services/mock-auth-service.d.ts +0 -17
  520. package/dist/features/auth/services/mock-auth-service.d.ts.map +0 -1
  521. package/dist/generated/client/client.d.ts +0 -23
  522. package/dist/generated/client/client.d.ts.map +0 -1
  523. package/dist/generated/client/config.d.ts +0 -10
  524. package/dist/generated/client/config.d.ts.map +0 -1
  525. package/dist/generated/client/index.d.ts +0 -12
  526. package/dist/generated/client/index.d.ts.map +0 -1
  527. package/dist/generated/client/methods.d.ts +0 -591
  528. package/dist/generated/client/methods.d.ts.map +0 -1
  529. package/dist/generated/client/types.d.ts +0 -37
  530. package/dist/generated/client/types.d.ts.map +0 -1
  531. package/dist/generated/example.d.ts +0 -8
  532. package/dist/generated/example.d.ts.map +0 -1
  533. package/dist/generated/hooks/index.d.ts +0 -11
  534. package/dist/generated/hooks/index.d.ts.map +0 -1
  535. package/dist/generated/hooks/keys.d.ts +0 -59
  536. package/dist/generated/hooks/keys.d.ts.map +0 -1
  537. package/dist/generated/hooks/mutations.d.ts +0 -551
  538. package/dist/generated/hooks/mutations.d.ts.map +0 -1
  539. package/dist/generated/hooks/queries.d.ts +0 -426
  540. package/dist/generated/hooks/queries.d.ts.map +0 -1
  541. package/dist/generated/hooks/types.d.ts +0 -318
  542. package/dist/generated/hooks/types.d.ts.map +0 -1
  543. package/dist/generated/index.d.ts +0 -13
  544. package/dist/generated/index.d.ts.map +0 -1
  545. package/dist/generated/types/endpoints.d.ts +0 -1364
  546. package/dist/generated/types/endpoints.d.ts.map +0 -1
  547. package/dist/generated/types/index.d.ts +0 -11
  548. package/dist/generated/types/index.d.ts.map +0 -1
  549. package/dist/generated/types/parameters.d.ts +0 -8
  550. package/dist/generated/types/parameters.d.ts.map +0 -1
  551. package/dist/generated/types/responses.d.ts +0 -8
  552. package/dist/generated/types/responses.d.ts.map +0 -1
  553. package/dist/generated/types/schemas.d.ts +0 -652
  554. package/dist/generated/types/schemas.d.ts.map +0 -1
  555. package/dist/molecules/feedback/index.d.ts +0 -2
  556. package/dist/molecules/feedback/index.d.ts.map +0 -1
  557. package/dist/molecules/layout/BulkSelectionBar.d.ts +0 -15
  558. package/dist/molecules/layout/BulkSelectionBar.d.ts.map +0 -1
  559. package/dist/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.d.ts +0 -16
  560. package/dist/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.d.ts.map +0 -1
  561. package/dist/molecules/layout/DashboardWithSidePanel/index.d.ts +0 -2
  562. package/dist/molecules/layout/DashboardWithSidePanel/index.d.ts.map +0 -1
  563. package/dist/molecules/layout/NavigationContext.d.ts +0 -15
  564. package/dist/molecules/layout/NavigationContext.d.ts.map +0 -1
  565. package/dist/templates/EnhancedDataTemplate.d.ts +0 -188
  566. package/dist/templates/EnhancedDataTemplate.d.ts.map +0 -1
  567. package/dist/templates/EnhancedDataTemplate.hooks.bulk.d.ts +0 -18
  568. package/dist/templates/EnhancedDataTemplate.hooks.bulk.d.ts.map +0 -1
  569. package/dist/templates/EnhancedDataTemplate.hooks.d.ts +0 -22
  570. package/dist/templates/EnhancedDataTemplate.hooks.d.ts.map +0 -1
  571. package/dist/templates/api/APIDataTemplate.d.ts +0 -66
  572. package/dist/templates/api/APIDataTemplate.d.ts.map +0 -1
  573. package/dist/templates/api/index.d.ts +0 -8
  574. package/dist/templates/api/index.d.ts.map +0 -1
  575. /package/dist/atoms/{components/layout → composed}/Accordion/Accordion.d.ts +0 -0
  576. /package/dist/atoms/{components/layout → composed}/Accordion/index.d.ts +0 -0
  577. /package/dist/atoms/{components/feedback → composed}/Alert/Alert.d.ts +0 -0
  578. /package/dist/atoms/{components/feedback → composed}/Alert/index.d.ts +0 -0
  579. /package/dist/atoms/{components/layout → composed}/Breadcrumb/Breadcrumb.d.ts +0 -0
  580. /package/dist/atoms/{components/layout → composed}/Breadcrumb/index.d.ts +0 -0
  581. /package/dist/atoms/{components/data → composed}/Chart/index.d.ts +0 -0
  582. /package/dist/atoms/{components/theme → composed}/ColorSwatch/ColorSwatch.d.ts +0 -0
  583. /package/dist/atoms/{components/theme → composed}/ColorSwatch/index.d.ts +0 -0
  584. /package/dist/atoms/{components/theme → composed}/DarkModeToggle.d.ts +0 -0
  585. /package/dist/atoms/{components/data → composed}/DataBadge/index.d.ts +0 -0
  586. /package/dist/atoms/{components/data → composed}/DataTable/TableCellWithTooltip.d.ts +0 -0
  587. /package/dist/atoms/{components/data → composed}/DataTable/index.d.ts +0 -0
  588. /package/dist/atoms/{components/forms → composed}/DateTimePicker/DateTimePicker.d.ts +0 -0
  589. /package/dist/atoms/{components/forms → composed}/DateTimePicker/index.d.ts +0 -0
  590. /package/dist/atoms/{components/data → composed}/DetailedCard/DetailedCard.d.ts +0 -0
  591. /package/dist/atoms/{components/data → composed}/DetailedCard/index.d.ts +0 -0
  592. /package/dist/atoms/{components/feedback → composed}/EmptyState/EmptyState.d.ts +0 -0
  593. /package/dist/atoms/{components/feedback → composed}/EmptyState/index.d.ts +0 -0
  594. /package/dist/atoms/{components/forms → composed}/FileUpload/FileUpload.d.ts +0 -0
  595. /package/dist/atoms/{components/forms → composed}/FileUpload/index.d.ts +0 -0
  596. /package/dist/atoms/{components/forms → composed}/FormField/FormField.d.ts +0 -0
  597. /package/dist/atoms/{components/forms → composed}/FormField/index.d.ts +0 -0
  598. /package/dist/atoms/{components/navigation → composed}/GlobalSearch/GlobalSearch.d.ts +0 -0
  599. /package/dist/atoms/{components/navigation → composed}/GlobalSearch/index.d.ts +0 -0
  600. /package/dist/atoms/{components/data → composed}/IconBadge/index.d.ts +0 -0
  601. /package/dist/atoms/{components/layout → composed}/Modal/Modal.d.ts +0 -0
  602. /package/dist/atoms/{components/layout → composed}/Modal/index.d.ts +0 -0
  603. /package/dist/atoms/{components/theme → composed}/PaletteSwitcher.d.ts +0 -0
  604. /package/dist/atoms/{components/data → composed}/ProgressBar/ProgressBar.d.ts +0 -0
  605. /package/dist/atoms/{components/data → composed}/ProgressBar/index.d.ts +0 -0
  606. /package/dist/atoms/{components/data → composed}/StatCard/index.d.ts +0 -0
  607. /package/dist/atoms/{components/theme → composed}/StyleGuide.d.ts +0 -0
  608. /package/dist/atoms/{components/feedback → composed}/Toast/Toast.d.ts +0 -0
  609. /package/dist/atoms/{components/feedback → composed}/Toast/index.d.ts +0 -0
  610. /package/dist/atoms/{components/layout → composed}/Tooltip/Tooltip.d.ts +0 -0
  611. /package/dist/atoms/{components/user → composed}/UserAvatar/UserAvatar.d.ts +0 -0
  612. /package/dist/atoms/{components/user → composed}/UserAvatar/index.d.ts +0 -0
  613. /package/dist/atoms/{components/user → composed}/UserMenu/UserMenu.d.ts +0 -0
  614. /package/dist/atoms/{components/user → composed}/UserMenu/index.d.ts +0 -0
  615. /package/dist/atoms/{primitives → ui}/Badge.d.ts +0 -0
  616. /package/dist/atoms/{primitives → ui}/ErrorBoundary.d.ts +0 -0
  617. /package/dist/atoms/{primitives → ui}/Select.d.ts +0 -0
  618. /package/dist/atoms/{primitives → ui}/Switch.d.ts +0 -0
  619. /package/dist/atoms/{primitives → ui}/Tabs.d.ts +0 -0
  620. /package/dist/atoms/{primitives → ui}/avatar.d.ts +0 -0
  621. /package/dist/atoms/{primitives → ui}/card.d.ts +0 -0
  622. /package/dist/atoms/{primitives → ui}/dropdown-menu.d.ts +0 -0
  623. /package/dist/atoms/{primitives → ui}/input.d.ts +0 -0
  624. /package/dist/atoms/{primitives → ui}/label.d.ts +0 -0
  625. /package/dist/atoms/{primitives → ui}/skeleton.d.ts +0 -0
  626. /package/dist/atoms/{primitives → ui}/spinner.d.ts +0 -0
  627. /package/dist/atoms/{primitives → ui}/table.d.ts +0 -0
package/cli/index.js DELETED
@@ -1,3210 +0,0 @@
1
- #!/usr/bin/env node
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // cli/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- default: () => index_default
24
- });
25
- module.exports = __toCommonJS(index_exports);
26
- var import_commander = require("commander");
27
-
28
- // cli/commands/generate-hooks.ts
29
- var import_fs3 = require("fs");
30
- var import_path3 = require("path");
31
-
32
- // src/codegen/openapi/parser.js
33
- var import_fs = require("fs");
34
- var import_path = require("path");
35
- var OpenAPIParser = class {
36
- spec;
37
- refs = /* @__PURE__ */ new Map();
38
- constructor(spec) {
39
- this.spec = spec;
40
- this.buildRefsMap();
41
- }
42
- /**
43
- * Parse the OpenAPI specification into our intermediate representation
44
- */
45
- parse() {
46
- return {
47
- info: this.parseInfo(),
48
- servers: this.parseServers(),
49
- endpoints: this.parseEndpoints(),
50
- schemas: this.parseSchemas(),
51
- security: this.parseSecurity()
52
- };
53
- }
54
- parseInfo() {
55
- return {
56
- title: this.spec.info.title,
57
- version: this.spec.info.version,
58
- description: this.spec.info.description
59
- };
60
- }
61
- parseServers() {
62
- if (!this.spec.servers)
63
- return [];
64
- return this.spec.servers.map((server) => ({
65
- url: server.url,
66
- description: server.description,
67
- variables: server.variables ? Object.fromEntries(Object.entries(server.variables).map(([key, variable]) => [
68
- key,
69
- variable.default || ""
70
- ])) : void 0
71
- }));
72
- }
73
- parseEndpoints() {
74
- const endpoints = [];
75
- for (const [path, pathItem] of Object.entries(this.spec.paths || {})) {
76
- if (!pathItem)
77
- continue;
78
- const methods = ["get", "post", "put", "patch", "delete", "head", "options"];
79
- for (const method of methods) {
80
- const operation = pathItem[method];
81
- if (!operation)
82
- continue;
83
- endpoints.push({
84
- path,
85
- method,
86
- operationId: operation.operationId,
87
- summary: operation.summary,
88
- description: operation.description,
89
- tags: operation.tags,
90
- parameters: this.parseParameters(operation.parameters),
91
- requestBody: operation.requestBody ? this.parseRequestBody(operation.requestBody) : void 0,
92
- responses: this.parseResponses(operation.responses),
93
- security: operation.security ? this.parseOperationSecurity(operation.security) : void 0
94
- });
95
- }
96
- }
97
- return endpoints;
98
- }
99
- parseParameters(parameters) {
100
- if (!parameters)
101
- return [];
102
- return parameters.map((param) => {
103
- const resolved = this.resolveRef(param);
104
- return {
105
- name: resolved.name,
106
- in: resolved.in,
107
- required: resolved.required || false,
108
- schema: this.parseSchema(resolved.schema),
109
- description: resolved.description
110
- };
111
- });
112
- }
113
- parseRequestBody(requestBody) {
114
- const resolved = this.resolveRef(requestBody);
115
- return {
116
- required: resolved.required || false,
117
- description: resolved.description,
118
- content: Object.fromEntries(Object.entries(resolved.content || {}).map(([mediaType, mediaTypeObj]) => [
119
- mediaType,
120
- { schema: this.parseSchema(mediaTypeObj.schema) }
121
- ]))
122
- };
123
- }
124
- parseResponses(responses) {
125
- return Object.entries(responses).map(([statusCode, response]) => {
126
- const resolved = this.resolveRef(response);
127
- return {
128
- statusCode,
129
- description: resolved.description,
130
- content: resolved.content ? Object.fromEntries(Object.entries(resolved.content).map(([mediaType, mediaTypeObj]) => [
131
- mediaType,
132
- { schema: this.parseSchema(mediaTypeObj.schema) }
133
- ])) : void 0,
134
- headers: resolved.headers ? Object.fromEntries(Object.entries(resolved.headers).map(([headerName, header]) => [
135
- headerName,
136
- this.parseSchema(this.resolveRef(header).schema)
137
- ])) : void 0
138
- };
139
- });
140
- }
141
- parseSchema(schema) {
142
- if (!schema) {
143
- return { type: "any" };
144
- }
145
- if ("$ref" in schema) {
146
- return {
147
- type: "any",
148
- // Will be resolved later
149
- ref: schema.$ref,
150
- originalRef: schema.$ref
151
- };
152
- }
153
- const resolved = schema;
154
- if (resolved.type === "array") {
155
- return {
156
- type: "array",
157
- items: this.parseSchema(resolved.items),
158
- description: resolved.description,
159
- nullable: resolved.nullable
160
- };
161
- }
162
- if (resolved.type === "object" || resolved.properties) {
163
- return {
164
- type: "object",
165
- properties: resolved.properties ? Object.fromEntries(Object.entries(resolved.properties).map(([propName, propSchema]) => [
166
- propName,
167
- this.parseSchema(propSchema)
168
- ])) : void 0,
169
- required: resolved.required,
170
- description: resolved.description,
171
- nullable: resolved.nullable
172
- };
173
- }
174
- const type = this.mapOpenAPIType(resolved.type);
175
- return {
176
- type,
177
- format: resolved.format,
178
- enum: resolved.enum,
179
- description: resolved.description,
180
- example: resolved.example,
181
- nullable: resolved.nullable
182
- };
183
- }
184
- parseSchemas() {
185
- if (!this.spec.components?.schemas)
186
- return [];
187
- return Object.entries(this.spec.components.schemas).map(([name, schema]) => ({
188
- ...this.parseSchema(schema),
189
- ref: `#/components/schemas/${name}`
190
- }));
191
- }
192
- parseSecurity() {
193
- if (!this.spec.components?.securitySchemes)
194
- return [];
195
- return Object.entries(this.spec.components.securitySchemes).map(([_name, scheme]) => {
196
- const resolved = this.resolveRef(scheme);
197
- return {
198
- type: resolved.type,
199
- scheme: "scheme" in resolved ? resolved.scheme : void 0,
200
- bearerFormat: "bearerFormat" in resolved ? resolved.bearerFormat : void 0,
201
- in: "in" in resolved ? resolved.in : void 0,
202
- name: "name" in resolved ? resolved.name : void 0,
203
- flows: "flows" in resolved ? resolved.flows : void 0,
204
- openIdConnectUrl: "openIdConnectUrl" in resolved ? resolved.openIdConnectUrl : void 0
205
- };
206
- });
207
- }
208
- parseOperationSecurity(_security) {
209
- return [];
210
- }
211
- mapOpenAPIType(type) {
212
- switch (type) {
213
- case "string":
214
- return "string";
215
- case "number":
216
- return "number";
217
- case "integer":
218
- return "integer";
219
- case "boolean":
220
- return "boolean";
221
- case "array":
222
- return "array";
223
- case "object":
224
- return "object";
225
- case "null":
226
- return "null";
227
- default:
228
- return "any";
229
- }
230
- }
231
- buildRefsMap() {
232
- this.traverseAndMapRefs(this.spec, "");
233
- }
234
- traverseAndMapRefs(obj, currentPath) {
235
- if (typeof obj !== "object" || obj === null)
236
- return;
237
- for (const [key, value] of Object.entries(obj)) {
238
- const path = currentPath ? `${currentPath}/${key}` : key;
239
- if (key === "$ref" && typeof value === "string") {
240
- continue;
241
- }
242
- if (typeof value === "object") {
243
- if (currentPath.includes("/components/")) {
244
- this.refs.set(`#/${path}`, value);
245
- }
246
- this.traverseAndMapRefs(value, path);
247
- }
248
- }
249
- }
250
- resolveRef(item) {
251
- if (typeof item === "object" && item !== null && "$ref" in item) {
252
- const ref = item.$ref;
253
- const resolved = this.refs.get(ref);
254
- if (!resolved) {
255
- throw new Error(`Could not resolve reference: ${ref}`);
256
- }
257
- return resolved;
258
- }
259
- return item;
260
- }
261
- };
262
- async function parseOpenAPI(spec) {
263
- const parser = new OpenAPIParser(spec);
264
- return parser.parse();
265
- }
266
- async function loadOpenAPISpec(source) {
267
- if (source.startsWith("http://") || source.startsWith("https://")) {
268
- const response = await fetch(source);
269
- if (!response.ok) {
270
- throw new Error(`Failed to load OpenAPI spec from ${source}: ${response.statusText}`);
271
- }
272
- return response.json();
273
- } else {
274
- try {
275
- return JSON.parse(source);
276
- } catch {
277
- try {
278
- const absolutePath = (0, import_path.resolve)(source);
279
- const content = await import_fs.promises.readFile(absolutePath, "utf8");
280
- return JSON.parse(content);
281
- } catch (fileError) {
282
- throw new Error(`Failed to load OpenAPI spec: Not a valid URL, JSON string, or file path. ${fileError}`);
283
- }
284
- }
285
- }
286
- }
287
-
288
- // src/codegen/openapi/type-generator.js
289
- var TypeScriptGenerator = class {
290
- options;
291
- generatedTypes = /* @__PURE__ */ new Set();
292
- refMap = /* @__PURE__ */ new Map();
293
- constructor(options = {}) {
294
- this.options = {
295
- prefix: options.prefix || "",
296
- suffix: options.suffix || "",
297
- enumStyle: options.enumStyle || "union",
298
- nullableStyle: options.nullableStyle || "undefined",
299
- includeJSDoc: options.includeJSDoc !== false,
300
- includeExamples: options.includeExamples !== false
301
- };
302
- }
303
- generate(parsedAPI) {
304
- this.generatedTypes.clear();
305
- this.refMap.clear();
306
- this.buildRefMap(parsedAPI);
307
- return {
308
- schemas: this.generateSchemas(parsedAPI.schemas),
309
- endpoints: this.generateEndpointTypes(parsedAPI.endpoints),
310
- parameters: this.generateParameterTypes(parsedAPI.endpoints),
311
- responses: this.generateResponseTypes(parsedAPI.endpoints),
312
- index: this.generateIndexFile()
313
- };
314
- }
315
- buildRefMap(parsedAPI) {
316
- parsedAPI.schemas.forEach((schema) => {
317
- if (schema.ref) {
318
- const typeName = this.extractTypeNameFromRef(schema.ref);
319
- this.refMap.set(schema.ref, typeName);
320
- }
321
- });
322
- }
323
- generateSchemas(schemas) {
324
- const types = [];
325
- types.push(this.generateFileHeader("Schema Types"));
326
- for (const schema of schemas) {
327
- if (!schema.ref)
328
- continue;
329
- const typeName = this.refMap.get(schema.ref);
330
- if (!typeName || this.generatedTypes.has(typeName))
331
- continue;
332
- const typeDefinition = this.generateSchemaType(schema, typeName);
333
- types.push(typeDefinition);
334
- this.generatedTypes.add(typeName);
335
- }
336
- return types.join("\n\n");
337
- }
338
- generateSchemaType(schema, typeName) {
339
- const lines = [];
340
- if (this.options.includeJSDoc && schema.description) {
341
- lines.push(`/**`);
342
- lines.push(` * ${schema.description}`);
343
- if (this.options.includeExamples && schema.example) {
344
- lines.push(` * @example ${JSON.stringify(schema.example)}`);
345
- }
346
- lines.push(` */`);
347
- }
348
- const typeContent = this.generateTypeContent(schema);
349
- if (schema.type === "object" && !schema.enum) {
350
- lines.push(`export interface ${typeName} ${typeContent}`);
351
- } else {
352
- lines.push(`export type ${typeName} = ${typeContent}`);
353
- }
354
- return lines.join("\n");
355
- }
356
- generateTypeContent(schema) {
357
- switch (schema.type) {
358
- case "object":
359
- return this.generateObjectType(schema);
360
- case "array":
361
- return `${this.generateTypeContent(schema.items)}[]`;
362
- case "string":
363
- if (schema.enum) {
364
- return this.generateEnumType(schema.enum);
365
- }
366
- return this.addNullable("string", schema.nullable);
367
- case "number":
368
- case "integer":
369
- return this.addNullable("number", schema.nullable);
370
- case "boolean":
371
- return this.addNullable("boolean", schema.nullable);
372
- case "null":
373
- return "null";
374
- case "any":
375
- if (schema.ref) {
376
- const refType = this.refMap.get(schema.ref);
377
- return refType || "unknown";
378
- }
379
- return "unknown";
380
- default:
381
- return "unknown";
382
- }
383
- }
384
- generateObjectType(schema) {
385
- if (!schema.properties) {
386
- return "{ [key: string]: unknown }";
387
- }
388
- const properties = [];
389
- for (const [propName, propSchema] of Object.entries(schema.properties)) {
390
- const isRequired = schema.required?.includes(propName) || false;
391
- const isOptional = !isRequired ? "?" : "";
392
- const propType = this.generateTypeContent(propSchema);
393
- let propDoc = "";
394
- if (this.options.includeJSDoc && propSchema.description) {
395
- propDoc = ` /** ${propSchema.description} */
396
- `;
397
- }
398
- properties.push(`${propDoc}${propName}${isOptional}: ${propType}`);
399
- }
400
- return `{
401
- ${properties.join("\n ")}
402
- }`;
403
- }
404
- generateEnumType(enumValues) {
405
- if (this.options.enumStyle === "enum") {
406
- return enumValues.map((val) => `'${val}'`).join(" | ");
407
- } else {
408
- return enumValues.map((val) => `'${val}'`).join(" | ");
409
- }
410
- }
411
- addNullable(type, nullable) {
412
- if (!nullable)
413
- return type;
414
- switch (this.options.nullableStyle) {
415
- case "null":
416
- return `${type} | null`;
417
- case "both":
418
- return `${type} | null | undefined`;
419
- case "undefined":
420
- default:
421
- return `${type} | undefined`;
422
- }
423
- }
424
- generateEndpointTypes(endpoints) {
425
- const types = [];
426
- types.push(this.generateFileHeader("Endpoint Types"));
427
- const endpointTypes = /* @__PURE__ */ new Set();
428
- for (const endpoint of endpoints) {
429
- const operationName = this.getOperationName(endpoint);
430
- if (endpointTypes.has(operationName))
431
- continue;
432
- endpointTypes.add(operationName);
433
- const requestType = this.generateRequestType(endpoint, operationName);
434
- if (requestType) {
435
- types.push(requestType);
436
- }
437
- const responseType = this.generateResponseType(endpoint, operationName);
438
- if (responseType) {
439
- types.push(responseType);
440
- }
441
- }
442
- return types.join("\n\n");
443
- }
444
- generateRequestType(endpoint, operationName) {
445
- const hasParams = endpoint.parameters.length > 0;
446
- const hasBody = endpoint.requestBody !== void 0;
447
- if (!hasParams && !hasBody)
448
- return null;
449
- const lines = [];
450
- if (this.options.includeJSDoc) {
451
- lines.push(`/**`);
452
- lines.push(` * Request type for ${endpoint.method.toUpperCase()} ${endpoint.path}`);
453
- if (endpoint.summary) {
454
- lines.push(` * ${endpoint.summary}`);
455
- }
456
- lines.push(` */`);
457
- }
458
- const properties = [];
459
- if (hasParams) {
460
- const paramsByType = this.groupParametersByType(endpoint.parameters);
461
- for (const [paramType, params] of Object.entries(paramsByType)) {
462
- if (params.length === 0)
463
- continue;
464
- const paramProps = params.map((param) => {
465
- const optional = param.required ? "" : "?";
466
- const type = this.generateTypeContent(param.schema);
467
- return ` ${param.name}${optional}: ${type}`;
468
- });
469
- properties.push(` ${paramType}: {
470
- ${paramProps.join("\n")}
471
- }`);
472
- }
473
- }
474
- if (hasBody && endpoint.requestBody) {
475
- const bodyType = this.generateRequestBodyType(endpoint.requestBody);
476
- const optional = endpoint.requestBody.required ? "" : "?";
477
- properties.push(` body${optional}: ${bodyType}`);
478
- }
479
- const typeName = `${this.formatTypeName(operationName)}Request`;
480
- lines.push(`export interface ${typeName} {`);
481
- lines.push(properties.join("\n"));
482
- lines.push(`}`);
483
- return lines.join("\n");
484
- }
485
- generateResponseType(endpoint, operationName) {
486
- if (endpoint.responses.length === 0)
487
- return null;
488
- const lines = [];
489
- if (this.options.includeJSDoc) {
490
- lines.push(`/**`);
491
- lines.push(` * Response type for ${endpoint.method.toUpperCase()} ${endpoint.path}`);
492
- if (endpoint.summary) {
493
- lines.push(` * ${endpoint.summary}`);
494
- }
495
- lines.push(` */`);
496
- }
497
- const responseTypes = [];
498
- for (const response of endpoint.responses) {
499
- if (response.content) {
500
- for (const [mediaType, content] of Object.entries(response.content)) {
501
- if (mediaType.includes("json")) {
502
- const type = this.generateTypeContent(content.schema);
503
- responseTypes.push(`{ status: ${response.statusCode}; data: ${type} }`);
504
- }
505
- }
506
- } else {
507
- responseTypes.push(`{ status: ${response.statusCode}; data: void }`);
508
- }
509
- }
510
- const typeName = `${this.formatTypeName(operationName)}Response`;
511
- const unionType = responseTypes.length > 1 ? responseTypes.join(" | ") : responseTypes[0] || "void";
512
- lines.push(`export type ${typeName} = ${unionType}`);
513
- return lines.join("\n");
514
- }
515
- generateRequestBodyType(requestBody) {
516
- const jsonContent = requestBody.content["application/json"] || requestBody.content["application/vnd.api+json"] || Object.values(requestBody.content)[0];
517
- if (!jsonContent)
518
- return "unknown";
519
- return this.generateTypeContent(jsonContent.schema);
520
- }
521
- generateParameterTypes(_endpoints) {
522
- const types = [];
523
- types.push(this.generateFileHeader("Parameter Types"));
524
- return types.join("\n\n");
525
- }
526
- generateResponseTypes(_endpoints) {
527
- const types = [];
528
- types.push(this.generateFileHeader("Response Types"));
529
- return types.join("\n\n");
530
- }
531
- generateIndexFile() {
532
- const lines = [];
533
- lines.push(this.generateFileHeader("Generated API Types"));
534
- lines.push("");
535
- lines.push("// Schema exports");
536
- lines.push("export * from './schemas'");
537
- lines.push("");
538
- lines.push("// Endpoint exports");
539
- lines.push("export * from './endpoints'");
540
- lines.push("");
541
- lines.push("// Parameter exports");
542
- lines.push("export * from './parameters'");
543
- lines.push("");
544
- lines.push("// Response exports");
545
- lines.push("export * from './responses'");
546
- return lines.join("\n");
547
- }
548
- generateFileHeader(title) {
549
- return `/**
550
- * ${title}
551
- *
552
- * Auto-generated from OpenAPI specification
553
- * Do not edit manually - regenerate using the OpenAPI type generator
554
- */`;
555
- }
556
- getOperationName(endpoint) {
557
- if (endpoint.operationId) {
558
- return endpoint.operationId;
559
- }
560
- const pathParts = endpoint.path.split("/").filter((part) => part && !part.startsWith("{")).map((part) => this.capitalize(part));
561
- return `${endpoint.method}${pathParts.join("")}`;
562
- }
563
- formatTypeName(name) {
564
- const formatted = this.capitalize(name);
565
- return `${this.options.prefix}${formatted}${this.options.suffix}`;
566
- }
567
- extractTypeNameFromRef(ref) {
568
- const parts = ref.split("/");
569
- const name = parts[parts.length - 1];
570
- return this.formatTypeName(name);
571
- }
572
- groupParametersByType(parameters) {
573
- const grouped = {
574
- path: [],
575
- query: [],
576
- header: [],
577
- cookie: []
578
- };
579
- for (const param of parameters) {
580
- grouped[param.in].push(param);
581
- }
582
- return grouped;
583
- }
584
- capitalize(str) {
585
- return str.charAt(0).toUpperCase() + str.slice(1);
586
- }
587
- };
588
- function generateTypes(parsedAPI, options) {
589
- const generator = new TypeScriptGenerator(options);
590
- return generator.generate(parsedAPI);
591
- }
592
-
593
- // src/codegen/openapi/client-generator.js
594
- var APIClientGenerator = class {
595
- options;
596
- constructor(options = {}) {
597
- this.options = {
598
- clientType: options.clientType || "axios",
599
- baseUrl: options.baseUrl || "",
600
- includeAuth: options.includeAuth !== false,
601
- authType: options.authType || "bearer",
602
- timeout: options.timeout || 1e4,
603
- retries: options.retries || 3,
604
- includeInterceptors: options.includeInterceptors !== false
605
- };
606
- }
607
- generate(parsedAPI) {
608
- return {
609
- client: this.generateClientSetup(),
610
- methods: this.generateApiMethods(parsedAPI.endpoints),
611
- types: this.generateClientTypes(),
612
- config: this.generateConfiguration(),
613
- index: this.generateIndexFile()
614
- };
615
- }
616
- generateClientSetup() {
617
- if (this.options.clientType === "axios") {
618
- return this.generateAxiosClient();
619
- } else {
620
- return this.generateFetchClient();
621
- }
622
- }
623
- generateAxiosClient() {
624
- return `/**
625
- * Axios API Client
626
- *
627
- * Auto-generated API client with interceptors and error handling
628
- */
629
-
630
- import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
631
- import { APIClientConfig, RequestOptions, APIError } from './types'
632
-
633
- export class APIClient {
634
- private client: AxiosInstance
635
- private config: APIClientConfig
636
-
637
- constructor(config: APIClientConfig) {
638
- this.config = config
639
- this.client = this.createAxiosInstance()
640
- this.setupInterceptors()
641
- }
642
-
643
- private createAxiosInstance(): AxiosInstance {
644
- return axios.create({
645
- baseURL: this.config.baseUrl,
646
- timeout: this.config.timeout || ${this.options.timeout},
647
- headers: {
648
- 'Content-Type': 'application/json',
649
- ...this.config.defaultHeaders
650
- }
651
- })
652
- }
653
-
654
- ${this.options.includeInterceptors ? this.generateAxiosInterceptors() : ""}
655
-
656
- private async makeRequest<T>(
657
- method: string,
658
- url: string,
659
- options: RequestOptions = {}
660
- ): Promise<T> {
661
- try {
662
- const config: AxiosRequestConfig = {
663
- method: method as any,
664
- url,
665
- ...options.config
666
- }
667
-
668
- if (options.params) {
669
- config.params = options.params
670
- }
671
-
672
- if (options.data) {
673
- config.data = options.data
674
- }
675
-
676
- if (options.headers) {
677
- config.headers = { ...config.headers, ...options.headers }
678
- }
679
-
680
- ${this.options.includeAuth ? this.generateAuthInjection() : ""}
681
-
682
- const response: AxiosResponse<T> = await this.client.request(config)
683
- return response.data
684
- } catch (error) {
685
- throw this.handleError(error as AxiosError)
686
- }
687
- }
688
-
689
- private handleError(error: AxiosError): APIError {
690
- const apiError: APIError = {
691
- message: error.message,
692
- status: error.response?.status,
693
- statusText: error.response?.statusText,
694
- data: error.response?.data,
695
- config: {
696
- url: error.config?.url,
697
- method: error.config?.method?.toUpperCase(),
698
- headers: error.config?.headers
699
- }
700
- }
701
-
702
- if (this.config.onError) {
703
- this.config.onError(apiError)
704
- }
705
-
706
- return apiError
707
- }
708
-
709
- public get<T>(url: string, options?: RequestOptions): Promise<T> {
710
- return this.makeRequest<T>('GET', url, options)
711
- }
712
-
713
- public post<T>(url: string, data?: any, options?: RequestOptions): Promise<T> {
714
- return this.makeRequest<T>('POST', url, { ...options, data })
715
- }
716
-
717
- public put<T>(url: string, data?: any, options?: RequestOptions): Promise<T> {
718
- return this.makeRequest<T>('PUT', url, { ...options, data })
719
- }
720
-
721
- public patch<T>(url: string, data?: any, options?: RequestOptions): Promise<T> {
722
- return this.makeRequest<T>('PATCH', url, { ...options, data })
723
- }
724
-
725
- public delete<T>(url: string, options?: RequestOptions): Promise<T> {
726
- return this.makeRequest<T>('DELETE', url, options)
727
- }
728
- }`;
729
- }
730
- generateFetchClient() {
731
- return `/**
732
- * Fetch API Client
733
- *
734
- * Auto-generated API client using native fetch with error handling
735
- */
736
-
737
- import { APIClientConfig, RequestOptions, APIError } from './types'
738
-
739
- export class APIClient {
740
- private config: APIClientConfig
741
-
742
- constructor(config: APIClientConfig) {
743
- this.config = config
744
- }
745
-
746
- private async makeRequest<T>(
747
- method: string,
748
- url: string,
749
- options: RequestOptions = {}
750
- ): Promise<T> {
751
- try {
752
- const fullUrl = this.buildUrl(url, options.params)
753
-
754
- const fetchOptions: RequestInit = {
755
- method,
756
- headers: {
757
- 'Content-Type': 'application/json',
758
- ...this.config.defaultHeaders,
759
- ...options.headers
760
- },
761
- signal: options.signal
762
- }
763
-
764
- if (options.data && method !== 'GET') {
765
- fetchOptions.body = JSON.stringify(options.data)
766
- }
767
-
768
- ${this.options.includeAuth ? this.generateFetchAuthInjection() : ""}
769
-
770
- const response = await fetch(fullUrl, fetchOptions)
771
-
772
- if (!response.ok) {
773
- throw await this.createErrorFromResponse(response)
774
- }
775
-
776
- const contentType = response.headers.get('content-type')
777
- if (contentType && contentType.includes('application/json')) {
778
- return await response.json()
779
- }
780
-
781
- return await response.text() as any
782
- } catch (error) {
783
- if (error instanceof APIError) {
784
- throw error
785
- }
786
- throw this.createGenericError(error as Error)
787
- }
788
- }
789
-
790
- private buildUrl(path: string, params?: Record<string, any>): string {
791
- const url = new URL(path, this.config.baseUrl)
792
-
793
- if (params) {
794
- Object.entries(params).forEach(([key, value]) => {
795
- if (value !== undefined && value !== null) {
796
- url.searchParams.append(key, String(value))
797
- }
798
- })
799
- }
800
-
801
- return url.toString()
802
- }
803
-
804
- private async createErrorFromResponse(response: Response): Promise<APIError> {
805
- let data: any
806
- try {
807
- data = await response.json()
808
- } catch {
809
- data = await response.text()
810
- }
811
-
812
- const error: APIError = {
813
- message: data?.message || response.statusText || 'Request failed',
814
- status: response.status,
815
- statusText: response.statusText,
816
- data,
817
- config: {
818
- url: response.url,
819
- method: 'Unknown'
820
- }
821
- }
822
-
823
- if (this.config.onError) {
824
- this.config.onError(error)
825
- }
826
-
827
- return error
828
- }
829
-
830
- private createGenericError(error: Error): APIError {
831
- const apiError: APIError = {
832
- message: error.message,
833
- config: {}
834
- }
835
-
836
- if (this.config.onError) {
837
- this.config.onError(apiError)
838
- }
839
-
840
- return apiError
841
- }
842
-
843
- public get<T>(url: string, options?: RequestOptions): Promise<T> {
844
- return this.makeRequest<T>('GET', url, options)
845
- }
846
-
847
- public post<T>(url: string, data?: any, options?: RequestOptions): Promise<T> {
848
- return this.makeRequest<T>('POST', url, { ...options, data })
849
- }
850
-
851
- public put<T>(url: string, data?: any, options?: RequestOptions): Promise<T> {
852
- return this.makeRequest<T>('PUT', url, { ...options, data })
853
- }
854
-
855
- public patch<T>(url: string, data?: any, options?: RequestOptions): Promise<T> {
856
- return this.makeRequest<T>('PATCH', url, { ...options, data })
857
- }
858
-
859
- public delete<T>(url: string, options?: RequestOptions): Promise<T> {
860
- return this.makeRequest<T>('DELETE', url, options)
861
- }
862
- }`;
863
- }
864
- generateAxiosInterceptors() {
865
- return `
866
- private setupInterceptors(): void {
867
- // Request interceptor
868
- this.client.interceptors.request.use(
869
- (config) => {
870
- if (this.config.onRequest) {
871
- return this.config.onRequest(config) || config
872
- }
873
- return config
874
- },
875
- (error) => {
876
- if (this.config.onRequestError) {
877
- this.config.onRequestError(error)
878
- }
879
- return Promise.reject(error)
880
- }
881
- )
882
-
883
- // Response interceptor
884
- this.client.interceptors.response.use(
885
- (response) => {
886
- if (this.config.onResponse) {
887
- return this.config.onResponse(response) || response
888
- }
889
- return response
890
- },
891
- async (error) => {
892
- if (this.config.onResponseError) {
893
- const result = await this.config.onResponseError(error)
894
- if (result) {
895
- return result
896
- }
897
- }
898
-
899
- // Auto-retry logic
900
- if (this.shouldRetry(error)) {
901
- return this.retryRequest(error.config)
902
- }
903
-
904
- return Promise.reject(error)
905
- }
906
- )
907
- }
908
-
909
- private shouldRetry(error: AxiosError): boolean {
910
- const retryCount = (error.config as any)?._retryCount || 0
911
- const maxRetries = this.config.retries || ${this.options.retries}
912
-
913
- return (
914
- retryCount < maxRetries &&
915
- (!error.response || error.response.status >= 500) &&
916
- error.code !== 'ECONNABORTED'
917
- )
918
- }
919
-
920
- private async retryRequest(config: any): Promise<any> {
921
- config._retryCount = (config._retryCount || 0) + 1
922
-
923
- // Exponential backoff
924
- const delay = Math.pow(2, config._retryCount) * 1000
925
- await new Promise(resolve => setTimeout(resolve, delay))
926
-
927
- return this.client.request(config)
928
- }`;
929
- }
930
- generateAuthInjection() {
931
- switch (this.options.authType) {
932
- case "bearer":
933
- return `
934
- // Inject bearer token if available
935
- if (this.config.getAuthToken) {
936
- const token = await this.config.getAuthToken()
937
- if (token) {
938
- config.headers = {
939
- ...config.headers,
940
- Authorization: \`Bearer \${token}\`
941
- }
942
- }
943
- }`;
944
- case "apiKey":
945
- return `
946
- // Inject API key if available
947
- if (this.config.getApiKey) {
948
- const apiKey = await this.config.getApiKey()
949
- if (apiKey) {
950
- if (this.config.apiKeyHeader) {
951
- config.headers = {
952
- ...config.headers,
953
- [this.config.apiKeyHeader]: apiKey
954
- }
955
- } else {
956
- config.params = { ...config.params, api_key: apiKey }
957
- }
958
- }
959
- }`;
960
- case "basic":
961
- return `
962
- // Inject basic auth if available
963
- if (this.config.getBasicAuth) {
964
- const auth = await this.config.getBasicAuth()
965
- if (auth) {
966
- const encoded = btoa(\`\${auth.username}:\${auth.password}\`)
967
- config.headers = {
968
- ...config.headers,
969
- Authorization: \`Basic \${encoded}\`
970
- }
971
- }
972
- }`;
973
- default:
974
- return "";
975
- }
976
- }
977
- generateFetchAuthInjection() {
978
- switch (this.options.authType) {
979
- case "bearer":
980
- return `
981
- // Inject bearer token if available
982
- if (this.config.getAuthToken) {
983
- const token = await this.config.getAuthToken()
984
- if (token) {
985
- fetchOptions.headers = {
986
- ...fetchOptions.headers,
987
- Authorization: \`Bearer \${token}\`
988
- }
989
- }
990
- }`;
991
- case "apiKey":
992
- return `
993
- // Inject API key if available
994
- if (this.config.getApiKey) {
995
- const apiKey = await this.config.getApiKey()
996
- if (apiKey && this.config.apiKeyHeader) {
997
- fetchOptions.headers = {
998
- ...fetchOptions.headers,
999
- [this.config.apiKeyHeader]: apiKey
1000
- }
1001
- }
1002
- }`;
1003
- default:
1004
- return "";
1005
- }
1006
- }
1007
- generateApiMethods(endpoints) {
1008
- const methods = [];
1009
- methods.push(this.generateFileHeader("API Methods"));
1010
- methods.push("");
1011
- methods.push("import { APIClient } from './client'");
1012
- methods.push("import * as Types from './types'");
1013
- methods.push("");
1014
- methods.push("export class APIService {");
1015
- methods.push(" constructor(private client: APIClient) {}");
1016
- methods.push("");
1017
- const groupedEndpoints = this.groupEndpoints(endpoints);
1018
- for (const [group, groupEndpoints] of Object.entries(groupedEndpoints)) {
1019
- methods.push(` // ${group} methods`);
1020
- for (const endpoint of groupEndpoints) {
1021
- const method = this.generateEndpointMethod(endpoint);
1022
- methods.push(method);
1023
- methods.push("");
1024
- }
1025
- }
1026
- methods.push("}");
1027
- return methods.join("\n");
1028
- }
1029
- generateEndpointMethod(endpoint) {
1030
- const methodName = this.getMethodName(endpoint);
1031
- const pathWithParams = this.generatePathWithParams(endpoint);
1032
- const httpMethod = endpoint.method.toLowerCase();
1033
- const lines = [];
1034
- lines.push(" /**");
1035
- if (endpoint.summary) {
1036
- lines.push(` * ${endpoint.summary}`);
1037
- }
1038
- if (endpoint.description) {
1039
- lines.push(` * ${endpoint.description}`);
1040
- }
1041
- lines.push(` * @param options Request options`);
1042
- lines.push(" */");
1043
- const hasPathParams = endpoint.parameters.some((p) => p.in === "path");
1044
- const hasQueryParams = endpoint.parameters.some((p) => p.in === "query");
1045
- const hasBody = endpoint.requestBody !== void 0;
1046
- let params = "options: RequestOptions = {}";
1047
- if (hasPathParams) {
1048
- const pathParams = endpoint.parameters.filter((p) => p.in === "path").map((p) => `${p.name}: ${this.getParameterType(p)}`).join(", ");
1049
- params = `${pathParams}, ${params}`;
1050
- }
1051
- const responseType = this.getResponseType(endpoint);
1052
- lines.push(` async ${methodName}(${params}): Promise<${responseType}> {`);
1053
- const urlConstruction = hasPathParams ? `const url = \`${pathWithParams}\`` : `const url = '${endpoint.path}'`;
1054
- lines.push(` ${urlConstruction}`);
1055
- if (hasQueryParams) {
1056
- lines.push(" const queryParams = {");
1057
- endpoint.parameters.filter((p) => p.in === "query").forEach((p) => {
1058
- lines.push(` ${p.name}: options.${p.name},`);
1059
- });
1060
- lines.push(" }");
1061
- lines.push(" options.params = { ...queryParams, ...options.params }");
1062
- }
1063
- if (hasBody) {
1064
- lines.push(` return this.client.${httpMethod}<${responseType}>(url, options.data, options)`);
1065
- } else {
1066
- lines.push(` return this.client.${httpMethod}<${responseType}>(url, options)`);
1067
- }
1068
- lines.push(" }");
1069
- return lines.join("\n");
1070
- }
1071
- generateClientTypes() {
1072
- const authTypes = this.generateAuthTypes();
1073
- return `/**
1074
- * API Client Types
1075
- *
1076
- * Configuration and utility types for the generated API client
1077
- */
1078
-
1079
- ${this.options.clientType === "axios" ? "import { AxiosRequestConfig, AxiosResponse } from 'axios'" : ""}
1080
-
1081
- export interface APIClientConfig {
1082
- baseUrl: string
1083
- timeout?: number
1084
- defaultHeaders?: Record<string, string>
1085
- retries?: number
1086
- ${this.options.includeAuth ? authTypes : ""}
1087
- onRequest?: (config: any) => any
1088
- onRequestError?: (error: any) => void
1089
- onResponse?: (response: any) => any
1090
- onResponseError?: (error: any) => Promise<any> | any
1091
- onError?: (error: APIError) => void
1092
- }
1093
-
1094
- export interface RequestOptions {
1095
- params?: Record<string, any>
1096
- data?: any
1097
- headers?: Record<string, string>
1098
- config?: any
1099
- signal?: AbortSignal
1100
- [key: string]: any
1101
- }
1102
-
1103
- export interface APIError {
1104
- message: string
1105
- status?: number
1106
- statusText?: string
1107
- data?: any
1108
- config: {
1109
- url?: string
1110
- method?: string
1111
- headers?: any
1112
- }
1113
- }`;
1114
- }
1115
- generateAuthTypes() {
1116
- switch (this.options.authType) {
1117
- case "bearer":
1118
- return "getAuthToken?: () => Promise<string | null> | string | null";
1119
- case "apiKey":
1120
- return `getApiKey?: () => Promise<string | null> | string | null
1121
- apiKeyHeader?: string`;
1122
- case "basic":
1123
- return "getBasicAuth?: () => Promise<{ username: string; password: string } | null> | { username: string; password: string } | null";
1124
- default:
1125
- return "";
1126
- }
1127
- }
1128
- generateConfiguration() {
1129
- return `/**
1130
- * API Client Configuration
1131
- *
1132
- * Default configuration and factory functions
1133
- */
1134
-
1135
- import { APIClient } from './client'
1136
- import { APIService } from './methods'
1137
- import { APIClientConfig } from './types'
1138
-
1139
- export function createAPIClient(config: APIClientConfig): APIService {
1140
- const client = new APIClient(config)
1141
- return new APIService(client)
1142
- }
1143
-
1144
- export const defaultConfig: Partial<APIClientConfig> = {
1145
- timeout: ${this.options.timeout},
1146
- retries: ${this.options.retries},
1147
- defaultHeaders: {
1148
- 'Content-Type': 'application/json'
1149
- }
1150
- }`;
1151
- }
1152
- generateIndexFile() {
1153
- return `/**
1154
- * Generated API Client
1155
- *
1156
- * Auto-generated from OpenAPI specification
1157
- */
1158
-
1159
- export * from './client'
1160
- export * from './methods'
1161
- export * from './types'
1162
- export * from './config'
1163
- export { createAPIClient, defaultConfig } from './config'
1164
-
1165
- // Singleton instance for convenient usage
1166
- export const apiClient = createAPIClient({
1167
- baseUrl: process.env.VITE_API_URL || '${this.options.baseUrl || "http://localhost:8080"}',
1168
- timeout: ${this.options.timeout},
1169
- defaultHeaders: {
1170
- 'Content-Type': 'application/json'
1171
- }
1172
- })`;
1173
- }
1174
- generateFileHeader(title) {
1175
- return `/**
1176
- * ${title}
1177
- *
1178
- * Auto-generated from OpenAPI specification
1179
- * Do not edit manually
1180
- */`;
1181
- }
1182
- getMethodName(endpoint) {
1183
- if (endpoint.operationId) {
1184
- return this.camelCase(endpoint.operationId);
1185
- }
1186
- const pathParts = endpoint.path.split("/").filter((part) => part && !part.startsWith("{")).map((part) => this.capitalize(part));
1187
- return this.camelCase(`${endpoint.method}_${pathParts.join("_")}`);
1188
- }
1189
- generatePathWithParams(endpoint) {
1190
- return endpoint.path.replace(/{([^}]+)}/g, "${$1}");
1191
- }
1192
- getParameterType(param) {
1193
- switch (param.schema.type) {
1194
- case "string":
1195
- return "string";
1196
- case "number":
1197
- case "integer":
1198
- return "number";
1199
- case "boolean":
1200
- return "boolean";
1201
- default:
1202
- return "any";
1203
- }
1204
- }
1205
- getResponseType(endpoint) {
1206
- const successResponse = endpoint.responses.find((r) => r.statusCode.startsWith("2") || r.statusCode === "default");
1207
- if (!successResponse?.content) {
1208
- return "void";
1209
- }
1210
- const jsonContent = successResponse.content["application/json"];
1211
- if (!jsonContent) {
1212
- return "any";
1213
- }
1214
- return "any";
1215
- }
1216
- groupEndpoints(endpoints) {
1217
- const groups = {};
1218
- for (const endpoint of endpoints) {
1219
- const group = endpoint.tags?.[0] || "default";
1220
- if (!groups[group]) {
1221
- groups[group] = [];
1222
- }
1223
- groups[group].push(endpoint);
1224
- }
1225
- return groups;
1226
- }
1227
- camelCase(str) {
1228
- return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toLowerCase());
1229
- }
1230
- capitalize(str) {
1231
- return str.charAt(0).toUpperCase() + str.slice(1);
1232
- }
1233
- };
1234
- function generateAPIClient(parsedAPI, options) {
1235
- const generator = new APIClientGenerator(options);
1236
- return generator.generate(parsedAPI);
1237
- }
1238
-
1239
- // src/codegen/openapi/hook-config.ts
1240
- var import_fs2 = require("fs");
1241
- var import_path2 = require("path");
1242
- var DEFAULT_CONFIG = {
1243
- version: "1.0.0",
1244
- nameOverrides: {},
1245
- reviewedNames: [],
1246
- patterns: {
1247
- removeDoubleWords: true,
1248
- smartCasing: true,
1249
- deduplicateSegments: true
1250
- }
1251
- };
1252
- var HookConfigManager = class {
1253
- configPath;
1254
- config = DEFAULT_CONFIG;
1255
- constructor(configPath = "./hooks.config.json") {
1256
- this.configPath = (0, import_path2.resolve)(configPath);
1257
- }
1258
- async load() {
1259
- try {
1260
- const content = await import_fs2.promises.readFile(this.configPath, "utf8");
1261
- this.config = { ...DEFAULT_CONFIG, ...JSON.parse(content) };
1262
- } catch (error) {
1263
- this.config = DEFAULT_CONFIG;
1264
- }
1265
- }
1266
- async save() {
1267
- const content = JSON.stringify(this.config, null, 2);
1268
- await import_fs2.promises.writeFile(this.configPath, content, "utf8");
1269
- }
1270
- getOverride(operationId) {
1271
- return this.config.nameOverrides[operationId];
1272
- }
1273
- addOverride(override) {
1274
- this.config.nameOverrides[override.original] = override.override;
1275
- this.config.reviewedNames.push({
1276
- ...override,
1277
- approvedAt: (/* @__PURE__ */ new Date()).toISOString()
1278
- });
1279
- }
1280
- getPatterns() {
1281
- return this.config.patterns;
1282
- }
1283
- updateStatistics(stats) {
1284
- this.config.statistics = {
1285
- ...this.config.statistics,
1286
- ...stats,
1287
- lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
1288
- };
1289
- }
1290
- getReviewedNames() {
1291
- return this.config.reviewedNames;
1292
- }
1293
- hasBeenReviewed(operationId) {
1294
- return operationId in this.config.nameOverrides;
1295
- }
1296
- };
1297
-
1298
- // src/codegen/openapi/confidence-scorer.ts
1299
- var ConfidenceScorer = class {
1300
- /**
1301
- * Score a generated hook name based on various quality indicators
1302
- */
1303
- scoreHookName(generatedName, originalOperationId, path, method) {
1304
- const issues = [];
1305
- const suggestions = [];
1306
- let score = 100;
1307
- if (!this.isProperCamelCase(generatedName)) {
1308
- score -= 20;
1309
- issues.push("Improper camelCase formatting");
1310
- }
1311
- if (this.hasConsecutiveUppercase(generatedName)) {
1312
- score -= 30;
1313
- issues.push("Consecutive uppercase letters suggest concatenation issues");
1314
- suggestions.push(this.suggestFixForConsecutiveUppercase(generatedName));
1315
- }
1316
- const nameLength = generatedName.length;
1317
- if (nameLength > 30) {
1318
- score -= 20;
1319
- issues.push(`Name is too long (${nameLength} chars)`);
1320
- }
1321
- if (this.hasRepeatedWords(generatedName)) {
1322
- score -= 25;
1323
- issues.push("Contains repeated word segments");
1324
- }
1325
- if (this.matchesCommonPattern(generatedName, method)) {
1326
- score += 10;
1327
- score = Math.min(score, 100);
1328
- }
1329
- if (this.hasWordBoundaryIssues(generatedName)) {
1330
- score -= 15;
1331
- issues.push("Potential word boundary issues");
1332
- }
1333
- let confidence;
1334
- if (score >= 80) {
1335
- confidence = "high";
1336
- } else if (score >= 60) {
1337
- confidence = "medium";
1338
- } else {
1339
- confidence = "low";
1340
- }
1341
- return {
1342
- name: generatedName,
1343
- confidence,
1344
- score,
1345
- issues,
1346
- suggestions: suggestions.filter((s) => s !== generatedName)
1347
- };
1348
- }
1349
- isProperCamelCase(name) {
1350
- if (!name.startsWith("use")) return false;
1351
- const afterUse = name.substring(3);
1352
- return /^[A-Z][a-zA-Z0-9]*$/.test(afterUse);
1353
- }
1354
- hasConsecutiveUppercase(name) {
1355
- return /[A-Z]{2,}[a-z]/.test(name) || /[a-z][A-Z]{2,}/.test(name);
1356
- }
1357
- hasRepeatedWords(name) {
1358
- const words = this.camelCaseToWords(name).map((w) => w.toLowerCase());
1359
- const uniqueWords = new Set(words);
1360
- return words.length > uniqueWords.size + 1;
1361
- }
1362
- matchesCommonPattern(name, method) {
1363
- const commonPatterns = {
1364
- get: /^use[A-Z][a-zA-Z]+$/,
1365
- post: /^useCreate[A-Z][a-zA-Z]+$/,
1366
- put: /^useUpdate[A-Z][a-zA-Z]+$/,
1367
- patch: /^useUpdate[A-Z][a-zA-Z]+$/,
1368
- delete: /^useDelete[A-Z][a-zA-Z]+$/
1369
- };
1370
- const pattern = commonPatterns[method];
1371
- return pattern ? pattern.test(name) : false;
1372
- }
1373
- hasWordBoundaryIssues(name) {
1374
- const afterUse = name.substring(3);
1375
- const knownPrefixes = ["Create", "Update", "Delete", "Get", "List", "Fetch", "Assign", "Reassign"];
1376
- for (const prefix of knownPrefixes) {
1377
- if (afterUse.startsWith(prefix)) {
1378
- const remaining = afterUse.substring(prefix.length);
1379
- if (/[a-z]{2,}[A-Z]/.test(remaining)) {
1380
- return true;
1381
- }
1382
- }
1383
- }
1384
- if (/[a-z]{3,}[A-Z]/.test(afterUse)) {
1385
- return true;
1386
- }
1387
- if (/[A-Z][a-z]+[a-z][A-Z]/.test(afterUse)) {
1388
- return true;
1389
- }
1390
- return false;
1391
- }
1392
- suggestFixForConsecutiveUppercase(name) {
1393
- let suggestion = name;
1394
- const knownFixes = {
1395
- "useAssignRolesusersUserRoles": "useAssignUserRoles",
1396
- "useReassignBudgettransactionsReassignBudget": "useReassignTransactionBudget",
1397
- "useCategorySubcategories": "useCreateSubcategory"
1398
- };
1399
- if (knownFixes[name]) {
1400
- return knownFixes[name];
1401
- }
1402
- suggestion = suggestion.replace(/([a-z]{2,})([A-Z])/g, (match, p1, p2) => {
1403
- if (p1.endsWith("roles") || p1.endsWith("users") || p1.endsWith("budget")) {
1404
- return p1 + p2;
1405
- }
1406
- return match;
1407
- });
1408
- const parts = this.camelCaseToWords(suggestion);
1409
- if (parts.length > 4) {
1410
- const action = parts[1];
1411
- const resources = parts.slice(2);
1412
- const uniqueResources = [...new Set(resources.map((r) => r.toLowerCase()))];
1413
- if (uniqueResources.length === 1) {
1414
- return `use${action}${resources[resources.length - 1]}`;
1415
- }
1416
- }
1417
- return suggestion;
1418
- }
1419
- camelCaseToWords(str) {
1420
- return str.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(" ").filter((w) => w.length > 0);
1421
- }
1422
- /**
1423
- * Generate a confidence report for review
1424
- */
1425
- generateReport(scoredNames) {
1426
- const byConfidence = {
1427
- high: scoredNames.filter((s) => s.confidence === "high"),
1428
- medium: scoredNames.filter((s) => s.confidence === "medium"),
1429
- low: scoredNames.filter((s) => s.confidence === "low")
1430
- };
1431
- let report = "# Hook Name Generation Report\n\n";
1432
- report += `Generated ${scoredNames.length} hooks
1433
-
1434
- `;
1435
- report += `- High confidence: ${byConfidence.high.length}
1436
- `;
1437
- report += `- Medium confidence: ${byConfidence.medium.length}
1438
- `;
1439
- report += `- Low confidence: ${byConfidence.low.length}
1440
-
1441
- `;
1442
- if (byConfidence.low.length > 0) {
1443
- report += "## Low Confidence Names (Review Recommended)\n\n";
1444
- for (const scored of byConfidence.low) {
1445
- report += `### ${scored.name}
1446
- `;
1447
- report += `- Score: ${scored.score}/100
1448
- `;
1449
- report += `- Issues: ${scored.issues.join(", ")}
1450
- `;
1451
- if (scored.suggestions.length > 0) {
1452
- report += `- Suggestions: ${scored.suggestions.join(", ")}
1453
- `;
1454
- }
1455
- report += "\n";
1456
- }
1457
- }
1458
- if (byConfidence.medium.length > 0) {
1459
- report += "## Medium Confidence Names (Optional Review)\n\n";
1460
- for (const scored of byConfidence.medium) {
1461
- report += `- ${scored.name} (${scored.score}/100)
1462
- `;
1463
- if (scored.issues.length > 0) {
1464
- report += ` Issues: ${scored.issues.join(", ")}
1465
- `;
1466
- }
1467
- }
1468
- report += "\n";
1469
- }
1470
- return report;
1471
- }
1472
- };
1473
-
1474
- // src/codegen/openapi/bulk-types.ts
1475
- function isBulkOperation(path, method, requestBody) {
1476
- const bulkPatterns = [
1477
- /\/bulk[-_]?delete$/i,
1478
- /\/bulk[-_]?update$/i,
1479
- /\/bulk[-_]?create$/i,
1480
- /\/batch$/i,
1481
- /\/bulk$/i,
1482
- /\/multiple$/i
1483
- ];
1484
- if (bulkPatterns.some((pattern) => pattern.test(path))) {
1485
- return true;
1486
- }
1487
- if (requestBody && typeof requestBody === "object") {
1488
- const body = requestBody;
1489
- if (body.content?.["application/json"]?.schema) {
1490
- const schema = body.content["application/json"].schema;
1491
- return schema.type === "array" && !!schema.items;
1492
- }
1493
- if ("type" in requestBody) {
1494
- const bodyType = requestBody;
1495
- return bodyType.type === "array" && !!bodyType.items;
1496
- }
1497
- }
1498
- return false;
1499
- }
1500
- function detectBulkOperationType2(path, method) {
1501
- const lowercasePath = path.toLowerCase();
1502
- const lowercaseMethod = method.toLowerCase();
1503
- if (lowercasePath.includes("delete") || lowercaseMethod === "delete") {
1504
- return "delete";
1505
- }
1506
- if (lowercasePath.includes("update") || lowercaseMethod === "put" || lowercaseMethod === "patch") {
1507
- return "update";
1508
- }
1509
- if (lowercasePath.includes("create") || lowercaseMethod === "post") {
1510
- return "create";
1511
- }
1512
- if (lowercasePath.includes("batch") || lowercasePath.includes("bulk")) {
1513
- return "mixed";
1514
- }
1515
- return null;
1516
- }
1517
- function generateBulkOperationName(resource, operationType) {
1518
- const cleanResource = resource.replace(/[^a-zA-Z0-9]/g, "");
1519
- const singular = cleanResource.endsWith("s") ? cleanResource.slice(0, -1) : cleanResource;
1520
- const capitalizedSingular = capitalize(singular);
1521
- switch (operationType) {
1522
- case "delete":
1523
- return `bulkDelete${capitalizedSingular}s`;
1524
- case "update":
1525
- return `bulkUpdate${capitalizedSingular}s`;
1526
- case "create":
1527
- return `bulkCreate${capitalizedSingular}s`;
1528
- case "mixed":
1529
- return `bulk${capitalizedSingular}Operations`;
1530
- default:
1531
- return `bulk${capitalizedSingular}s`;
1532
- }
1533
- }
1534
- function capitalize(str) {
1535
- if (!str) return "";
1536
- return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
1537
- }
1538
-
1539
- // src/codegen/openapi/bulk-hook-generator.ts
1540
- var BulkHookGenerator = class {
1541
- /**
1542
- * Generate a bulk mutation hook with progress tracking and retry logic
1543
- */
1544
- generateBulkMutationHook(endpoint, hookName, operationName) {
1545
- const bulkType = detectBulkOperationType2(endpoint.path, endpoint.method);
1546
- const lines = [];
1547
- lines.push("/**");
1548
- if (endpoint.summary) {
1549
- lines.push(` * ${endpoint.summary}`);
1550
- }
1551
- if (endpoint.description) {
1552
- lines.push(` * ${endpoint.description}`);
1553
- }
1554
- lines.push(" * @param options Mutation options with bulk operation support");
1555
- lines.push(" */");
1556
- const resource = endpoint.tags?.[0] || "default";
1557
- lines.push(`export function ${hookName}(`);
1558
- lines.push(` options?: UseMutationOptions<BulkOperationResponse, any, BulkOperationRequest> & BulkMutationOptions`);
1559
- lines.push(") {");
1560
- lines.push(" const queryClient = useQueryClient()");
1561
- lines.push(" ");
1562
- lines.push(" return useMutation({");
1563
- lines.push(" mutationFn: async (request: BulkOperationRequest) => {");
1564
- lines.push(" // Transform request if needed");
1565
- lines.push(" const transformedRequest = options?.transformRequest ");
1566
- lines.push(" ? options.transformRequest(request) ");
1567
- lines.push(" : request");
1568
- lines.push(" ");
1569
- lines.push(" // Simulate progress updates for demo");
1570
- lines.push(" if (options?.onProgress) {");
1571
- lines.push(" options.onProgress({");
1572
- lines.push(" total: request.ids.length,");
1573
- lines.push(" processed: 0,");
1574
- lines.push(" succeeded: 0,");
1575
- lines.push(" failed: 0,");
1576
- lines.push(" percentage: 0,");
1577
- lines.push(" status: 'processing'");
1578
- lines.push(" })");
1579
- lines.push(" }");
1580
- lines.push(" ");
1581
- lines.push(` const response = await apiClient.${this.camelCase(operationName)}(transformedRequest)`);
1582
- lines.push(" ");
1583
- lines.push(" // Transform response if needed");
1584
- lines.push(" const transformedResponse = options?.transformResponse");
1585
- lines.push(" ? options.transformResponse(response)");
1586
- lines.push(" : response");
1587
- lines.push(" ");
1588
- lines.push(" // Final progress update");
1589
- lines.push(" if (options?.onProgress && transformedResponse) {");
1590
- lines.push(" options.onProgress({");
1591
- lines.push(" total: transformedResponse.summary?.total || request.ids.length,");
1592
- lines.push(" processed: transformedResponse.summary?.total || request.ids.length,");
1593
- lines.push(" succeeded: transformedResponse.summary?.succeeded || 0,");
1594
- lines.push(" failed: transformedResponse.summary?.failed || 0,");
1595
- lines.push(" percentage: 100,");
1596
- lines.push(" status: 'completed'");
1597
- lines.push(" })");
1598
- lines.push(" }");
1599
- lines.push(" ");
1600
- lines.push(" return transformedResponse");
1601
- lines.push(" },");
1602
- lines.push(this.generateBulkOptimisticUpdate(resource, bulkType));
1603
- lines.push(this.generateBulkCacheInvalidation(resource));
1604
- lines.push(" onSuccess: (data, variables, context) => {");
1605
- lines.push(" // Handle partial success");
1606
- lines.push(" if (data.failed.length > 0 && options?.onPartialSuccess) {");
1607
- lines.push(" options.onPartialSuccess(data)");
1608
- lines.push(" }");
1609
- lines.push(" ");
1610
- lines.push(" // Call original onSuccess if provided");
1611
- lines.push(" options?.onSuccess?.(data, variables, context)");
1612
- lines.push(" },");
1613
- lines.push(" retry: (failureCount, error) => {");
1614
- lines.push(" // Use custom retry config if provided");
1615
- lines.push(" if (options?.retry?.maxAttempts !== undefined) {");
1616
- lines.push(" return failureCount < options.retry.maxAttempts");
1617
- lines.push(" }");
1618
- lines.push(" // Default: retry up to 3 times for bulk operations");
1619
- lines.push(" return failureCount < 3");
1620
- lines.push(" },");
1621
- lines.push(" retryDelay: (attemptIndex) => {");
1622
- lines.push(" // Use custom retry delay if provided");
1623
- lines.push(" if (options?.retry?.initialDelay) {");
1624
- lines.push(" const delay = Math.min(");
1625
- lines.push(" options.retry.initialDelay * Math.pow(options.retry.backoffMultiplier || 2, attemptIndex),");
1626
- lines.push(" options.retry.maxDelay || 30000");
1627
- lines.push(" )");
1628
- lines.push(" return delay");
1629
- lines.push(" }");
1630
- lines.push(" // Default exponential backoff: 1s, 2s, 4s...");
1631
- lines.push(" return Math.min(1000 * Math.pow(2, attemptIndex), 30000)");
1632
- lines.push(" },");
1633
- lines.push(" ...options");
1634
- lines.push(" })");
1635
- lines.push("}");
1636
- return lines.join("\n");
1637
- }
1638
- /**
1639
- * Generate optimistic updates for bulk operations
1640
- */
1641
- generateBulkOptimisticUpdate(resource, bulkType) {
1642
- switch (bulkType) {
1643
- case "delete":
1644
- return ` onMutate: async (request: BulkOperationRequest) => {
1645
- // Cancel outgoing refetches
1646
- await queryClient.cancelQueries({ queryKey: queryKeys.${resource}() })
1647
-
1648
- // Snapshot previous value
1649
- const previousData = queryClient.getQueryData(queryKeys.${resource}())
1650
-
1651
- // Optimistically remove items
1652
- queryClient.setQueryData(queryKeys.${resource}(), (old: any) => {
1653
- if (Array.isArray(old)) {
1654
- return old.filter((item: any) => !request.ids.includes(item.id))
1655
- }
1656
- return old
1657
- })
1658
-
1659
- return { previousData }
1660
- },
1661
- onError: (err: any, request: any, context: any) => {
1662
- // Rollback on error
1663
- if (context?.previousData !== undefined) {
1664
- queryClient.setQueryData(queryKeys.${resource}(), context.previousData)
1665
- }
1666
- },`;
1667
- case "update":
1668
- return ` onMutate: async (request: BulkOperationRequest) => {
1669
- await queryClient.cancelQueries({ queryKey: queryKeys.${resource}() })
1670
-
1671
- const previousData = queryClient.getQueryData(queryKeys.${resource}())
1672
-
1673
- // Optimistically update items
1674
- queryClient.setQueryData(queryKeys.${resource}(), (old: any) => {
1675
- if (Array.isArray(old)) {
1676
- return old.map((item: any) =>
1677
- request.ids.includes(item.id)
1678
- ? { ...item, ...request.data }
1679
- : item
1680
- )
1681
- }
1682
- return old
1683
- })
1684
-
1685
- return { previousData }
1686
- },
1687
- onError: (err: any, request: any, context: any) => {
1688
- if (context?.previousData !== undefined) {
1689
- queryClient.setQueryData(queryKeys.${resource}(), context.previousData)
1690
- }
1691
- },`;
1692
- case "create":
1693
- return ` onMutate: async (request: BulkOperationRequest) => {
1694
- await queryClient.cancelQueries({ queryKey: queryKeys.${resource}() })
1695
-
1696
- const previousData = queryClient.getQueryData(queryKeys.${resource}())
1697
-
1698
- // Optimistically add items (if data provided)
1699
- if (request.data && Array.isArray(request.data)) {
1700
- queryClient.setQueryData(queryKeys.${resource}(), (old: any) => {
1701
- if (Array.isArray(old)) {
1702
- return [...old, ...request.data]
1703
- }
1704
- return old
1705
- })
1706
- }
1707
-
1708
- return { previousData }
1709
- },
1710
- onError: (err: any, request: any, context: any) => {
1711
- if (context?.previousData !== undefined) {
1712
- queryClient.setQueryData(queryKeys.${resource}(), context.previousData)
1713
- }
1714
- },`;
1715
- default:
1716
- return "";
1717
- }
1718
- }
1719
- /**
1720
- * Generate cache invalidation for bulk operations
1721
- */
1722
- generateBulkCacheInvalidation(resource) {
1723
- return ` onSettled: () => {
1724
- // Invalidate related queries after bulk operation
1725
- queryClient.invalidateQueries({ queryKey: queryKeys.${resource}() })
1726
- queryClient.invalidateQueries({ queryKey: queryKeys.all })
1727
- },`;
1728
- }
1729
- /**
1730
- * Generate bulk mutation hook name
1731
- */
1732
- generateBulkMutationHookName(endpoint, resourceName) {
1733
- const requestBody = endpoint.requestBody;
1734
- if (!isBulkOperation(endpoint.path, endpoint.method, requestBody)) {
1735
- return null;
1736
- }
1737
- const bulkType = detectBulkOperationType2(endpoint.path, endpoint.method);
1738
- if (bulkType && resourceName) {
1739
- const bulkName = generateBulkOperationName(resourceName, bulkType);
1740
- return `use${this.capitalize(bulkName)}`;
1741
- }
1742
- return null;
1743
- }
1744
- /**
1745
- * Check if endpoint is a bulk operation
1746
- */
1747
- isBulkEndpoint(endpoint) {
1748
- const requestBody = endpoint.requestBody;
1749
- return isBulkOperation(endpoint.path, endpoint.method, requestBody);
1750
- }
1751
- /**
1752
- * Helper to convert to camelCase
1753
- */
1754
- camelCase(str) {
1755
- return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toLowerCase());
1756
- }
1757
- /**
1758
- * Helper to capitalize string
1759
- */
1760
- capitalize(str) {
1761
- if (str.includes("_")) {
1762
- return str.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
1763
- }
1764
- return str.charAt(0).toUpperCase() + str.slice(1);
1765
- }
1766
- };
1767
-
1768
- // src/codegen/openapi/hook-generator.js
1769
- var ReactHookGenerator = class {
1770
- options;
1771
- configManager;
1772
- confidenceScorer;
1773
- bulkHookGenerator;
1774
- scoredNames = [];
1775
- resourceConfigs = /* @__PURE__ */ new Map();
1776
- constructor(options = {}) {
1777
- this.options = {
1778
- queryKeyPrefix: options.queryKeyPrefix || "api",
1779
- includeInfiniteQueries: options.includeInfiniteQueries !== false,
1780
- includeOptimisticUpdates: options.includeOptimisticUpdates !== false,
1781
- includeMutationHelpers: options.includeMutationHelpers ?? true,
1782
- authenticationRequired: options.authenticationRequired ?? true,
1783
- errorHandling: options.errorHandling || "throw",
1784
- configPath: options.configPath || "./hooks.config.json",
1785
- enableConfidenceScoring: options.enableConfidenceScoring ?? true
1786
- };
1787
- this.configManager = new HookConfigManager(this.options.configPath);
1788
- this.confidenceScorer = new ConfidenceScorer();
1789
- this.bulkHookGenerator = new BulkHookGenerator();
1790
- }
1791
- /**
1792
- * Detect resource operations from endpoints
1793
- */
1794
- detectResourceOperations(endpoints) {
1795
- const resourceMap = /* @__PURE__ */ new Map();
1796
- endpoints.forEach((endpoint) => {
1797
- const resourceName = this.extractResourceName(endpoint.path);
1798
- if (!resourceName)
1799
- return;
1800
- const config = resourceMap.get(resourceName) || this.createDefaultConfig(resourceName);
1801
- const requestBody = endpoint.requestBody;
1802
- if (isBulkOperation(endpoint.path, endpoint.method, requestBody)) {
1803
- const bulkType = detectBulkOperationType(endpoint.path, endpoint.method);
1804
- switch (bulkType) {
1805
- case "delete":
1806
- config.operations.bulkDelete = {
1807
- path: endpoint.path,
1808
- method: endpoint.method
1809
- };
1810
- break;
1811
- case "update":
1812
- config.operations.bulkUpdate = {
1813
- path: endpoint.path,
1814
- method: endpoint.method
1815
- };
1816
- break;
1817
- case "create":
1818
- config.operations.bulkCreate = {
1819
- path: endpoint.path,
1820
- method: endpoint.method
1821
- };
1822
- break;
1823
- case "mixed":
1824
- default:
1825
- if (!config.operations.customBulk) {
1826
- config.operations.customBulk = [];
1827
- }
1828
- config.operations.customBulk.push({
1829
- name: this.getOperationName(endpoint),
1830
- path: endpoint.path,
1831
- method: endpoint.method,
1832
- operationType: bulkType || "mixed"
1833
- });
1834
- break;
1835
- }
1836
- } else {
1837
- switch (endpoint.method.toLowerCase()) {
1838
- case "get":
1839
- if (endpoint.path.includes("{")) {
1840
- } else {
1841
- config.operations.list = { path: endpoint.path, method: endpoint.method };
1842
- }
1843
- break;
1844
- case "post":
1845
- config.operations.create = { path: endpoint.path, method: endpoint.method };
1846
- break;
1847
- case "put":
1848
- case "patch":
1849
- config.operations.update = { path: endpoint.path, method: endpoint.method };
1850
- break;
1851
- case "delete":
1852
- config.operations.delete = { path: endpoint.path, method: endpoint.method };
1853
- break;
1854
- }
1855
- }
1856
- resourceMap.set(resourceName, config);
1857
- });
1858
- return resourceMap;
1859
- }
1860
- /**
1861
- * Extract resource name from path
1862
- */
1863
- extractResourceName(path) {
1864
- const cleanPath = path.replace(/^\/api\/v\d+\//, "/");
1865
- const segments = cleanPath.split("/").filter(Boolean);
1866
- for (const segment of segments) {
1867
- if (!segment.startsWith("{")) {
1868
- return segment.replace(/-/g, "_");
1869
- }
1870
- }
1871
- return null;
1872
- }
1873
- /**
1874
- * Create default API config for a resource
1875
- */
1876
- createDefaultConfig(resourceName) {
1877
- return {
1878
- baseURL: "",
1879
- resourceName,
1880
- operations: {}
1881
- };
1882
- }
1883
- async generate(parsedAPI) {
1884
- const endpoints = parsedAPI.endpoints;
1885
- await this.configManager.load();
1886
- this.resourceConfigs = this.detectResourceOperations(endpoints);
1887
- this.scoredNames = [];
1888
- const result = {
1889
- queries: this.generateQueryHooks(endpoints),
1890
- mutations: this.generateMutationHooks(endpoints),
1891
- keys: this.generateQueryKeys(endpoints),
1892
- types: this.generateHookTypes(endpoints),
1893
- index: this.generateIndexFile(),
1894
- report: void 0
1895
- };
1896
- if (this.options.enableConfidenceScoring && this.scoredNames.length > 0) {
1897
- console.log(`Generated ${this.scoredNames.length} scored hook names`);
1898
- result.report = this.confidenceScorer.generateReport(this.scoredNames);
1899
- const stats = {
1900
- totalGenerated: this.scoredNames.length,
1901
- highConfidence: this.scoredNames.filter((s) => s.confidence === "high").length,
1902
- mediumConfidence: this.scoredNames.filter((s) => s.confidence === "medium").length,
1903
- lowConfidence: this.scoredNames.filter((s) => s.confidence === "low").length,
1904
- humanReviewed: this.configManager.getReviewedNames().length
1905
- };
1906
- this.configManager.updateStatistics(stats);
1907
- await this.configManager.save();
1908
- }
1909
- return result;
1910
- }
1911
- generateQueryHooks(endpoints) {
1912
- const hooks = [];
1913
- hooks.push(this.generateFileHeader("Query Hooks"));
1914
- hooks.push("");
1915
- hooks.push("import { useQuery, useInfiniteQuery, type UseQueryOptions, type UseInfiniteQueryOptions } from '@tanstack/react-query'");
1916
- hooks.push("import { apiClient } from '../client'");
1917
- hooks.push("import { queryKeys } from './keys'");
1918
- hooks.push("import * as Types from './types'");
1919
- hooks.push("");
1920
- const queryEndpoints = endpoints.filter((endpoint) => endpoint.method === "get");
1921
- const generatedHooks = /* @__PURE__ */ new Map();
1922
- for (const endpoint of queryEndpoints) {
1923
- let hookName = this.generateQueryHookName(endpoint);
1924
- if (generatedHooks.has(hookName)) {
1925
- const existingEndpoint = generatedHooks.get(hookName);
1926
- const existingIsSimpler = existingEndpoint.path.split("/").filter((s) => !s.startsWith("{")).length < endpoint.path.split("/").filter((s) => !s.startsWith("{")).length;
1927
- if (existingIsSimpler) {
1928
- const suffix = endpoint.path.includes("/{subcategory_id}") ? "Single" : "List";
1929
- hookName = `${hookName}${suffix}`;
1930
- } else {
1931
- const existingSuffix = existingEndpoint.path.includes("/{subcategory_id}") ? "Single" : "List";
1932
- const existingHookName = hookName;
1933
- const newExistingHookName = `${existingHookName}${existingSuffix}`;
1934
- for (let i = hooks.length - 1; i >= 0; i--) {
1935
- if (hooks[i].includes(`function ${existingHookName}(`)) {
1936
- hooks[i] = hooks[i].replace(`function ${existingHookName}(`, `function ${newExistingHookName}(`);
1937
- if (i > 0 && hooks[i - 1].includes(`${existingHookName}`)) {
1938
- hooks[i - 1] = hooks[i - 1].replace(existingHookName, newExistingHookName);
1939
- }
1940
- break;
1941
- }
1942
- }
1943
- generatedHooks.delete(existingHookName);
1944
- generatedHooks.set(newExistingHookName, existingEndpoint);
1945
- }
1946
- }
1947
- generatedHooks.set(hookName, endpoint);
1948
- const hook = this.generateQueryHook(endpoint, hookName);
1949
- hooks.push(hook);
1950
- hooks.push("");
1951
- if (this.options.includeInfiniteQueries && this.isListEndpoint(endpoint)) {
1952
- const infiniteHook = this.generateInfiniteQueryHook(endpoint, hookName);
1953
- hooks.push(infiniteHook);
1954
- hooks.push("");
1955
- }
1956
- }
1957
- return hooks.join("\n");
1958
- }
1959
- generateQueryHook(endpoint, hookName) {
1960
- const operationName = this.getOperationName(endpoint);
1961
- const hasParams = this.hasRequiredParams(endpoint);
1962
- const lines = [];
1963
- lines.push("/**");
1964
- if (endpoint.summary) {
1965
- lines.push(` * ${endpoint.summary}`);
1966
- }
1967
- if (endpoint.description) {
1968
- lines.push(` * ${endpoint.description}`);
1969
- }
1970
- lines.push(` * @param ${hasParams ? "params" : "options"} ${hasParams ? "Request parameters" : "Query options"}`);
1971
- lines.push(" */");
1972
- const paramType = hasParams ? this.generateParamType(endpoint) : "";
1973
- const params = hasParams ? `params: ${paramType}, options?: UseQueryOptions<any, any, any>` : "options?: UseQueryOptions<any, any, any>";
1974
- lines.push(`export function ${hookName}(${params}) {`);
1975
- const queryKeyName = hookName.replace(/^use/, "");
1976
- const queryKeyNameCamelCase = queryKeyName.charAt(0).toLowerCase() + queryKeyName.slice(1);
1977
- const queryKeyCall = hasParams ? `queryKeys.${queryKeyNameCamelCase}(params)` : `queryKeys.${queryKeyNameCamelCase}()`;
1978
- const apiCall = hasParams ? `() => apiClient.${this.camelCase(operationName)}(params)` : `() => apiClient.${this.camelCase(operationName)}()`;
1979
- lines.push(" return useQuery({");
1980
- lines.push(` queryKey: ${queryKeyCall},`);
1981
- lines.push(` queryFn: ${apiCall},`);
1982
- lines.push(" ...options");
1983
- lines.push(" })");
1984
- lines.push("}");
1985
- return lines.join("\n");
1986
- }
1987
- generateInfiniteQueryHook(endpoint, baseHookName) {
1988
- const hookName = baseHookName.replace("use", "useInfinite");
1989
- const operationName = this.getOperationName(endpoint);
1990
- const lines = [];
1991
- lines.push("/**");
1992
- lines.push(` * Infinite query version of ${baseHookName}`);
1993
- lines.push(" */");
1994
- const paramType = this.generateParamType(endpoint);
1995
- const queryKeyName = baseHookName.replace(/^use/, "");
1996
- const queryKeyNameCamelCase = queryKeyName.charAt(0).toLowerCase() + queryKeyName.slice(1);
1997
- lines.push(`export function ${hookName}(params: ${paramType}, options?: UseInfiniteQueryOptions<any, any, any, any, any>) {`);
1998
- lines.push(" return useInfiniteQuery({");
1999
- lines.push(` queryKey: [...queryKeys.${queryKeyNameCamelCase}(), params],`);
2000
- lines.push(` queryFn: ({ pageParam = 1 }) => apiClient.${this.camelCase(operationName)}({ ...params, page: pageParam }),`);
2001
- lines.push(" getNextPageParam: (lastPage, allPages) => {");
2002
- lines.push(" // Implement pagination logic based on your API response structure");
2003
- lines.push(" return lastPage?.hasNextPage ? allPages.length + 1 : undefined");
2004
- lines.push(" },");
2005
- lines.push(" initialPageParam: 1,");
2006
- lines.push(" ...options");
2007
- lines.push(" })");
2008
- lines.push("}");
2009
- return lines.join("\n");
2010
- }
2011
- generateMutationHooks(endpoints) {
2012
- const hooks = [];
2013
- hooks.push(this.generateFileHeader("Mutation Hooks"));
2014
- hooks.push("");
2015
- hooks.push("import { useMutation, useQueryClient, type UseMutationOptions } from '@tanstack/react-query'");
2016
- hooks.push("import { apiClient } from '../client'");
2017
- hooks.push("import { queryKeys } from './keys'");
2018
- hooks.push("import * as Types from './types'");
2019
- hooks.push("import type { BulkOperationRequest, BulkOperationResponse, BulkOperationProgress, BulkMutationOptions } from '../bulk-types'");
2020
- hooks.push("");
2021
- const mutationEndpoints = endpoints.filter((endpoint) => endpoint.method !== "get");
2022
- const generatedHooks = /* @__PURE__ */ new Map();
2023
- for (const endpoint of mutationEndpoints) {
2024
- const requestBody = endpoint.requestBody;
2025
- const isBulk = isBulkOperation(endpoint.path, endpoint.method, requestBody);
2026
- let hookName = this.generateMutationHookName(endpoint);
2027
- if (generatedHooks.has(hookName)) {
2028
- const existingEndpoint = generatedHooks.get(hookName);
2029
- const methodSuffix = endpoint.method.charAt(0).toUpperCase() + endpoint.method.slice(1);
2030
- hookName = `${hookName}${methodSuffix}`;
2031
- }
2032
- generatedHooks.set(hookName, endpoint);
2033
- const hook = isBulk ? this.bulkHookGenerator.generateBulkMutationHook(endpoint, hookName, this.getOperationName(endpoint)) : this.generateMutationHook(endpoint, hookName);
2034
- hooks.push(hook);
2035
- hooks.push("");
2036
- }
2037
- return hooks.join("\n");
2038
- }
2039
- generateMutationHook(endpoint, hookName) {
2040
- const operationName = this.getOperationName(endpoint);
2041
- const lines = [];
2042
- lines.push("/**");
2043
- if (endpoint.summary) {
2044
- lines.push(` * ${endpoint.summary}`);
2045
- }
2046
- if (endpoint.description) {
2047
- lines.push(` * ${endpoint.description}`);
2048
- }
2049
- lines.push(" */");
2050
- const mutationType = this.generateMutationType(endpoint);
2051
- lines.push(`export function ${hookName}(options?: UseMutationOptions<any, any, ${mutationType}>) {`);
2052
- lines.push(" const queryClient = useQueryClient()");
2053
- lines.push("");
2054
- lines.push(" return useMutation({");
2055
- const hasParams = this.hasRequiredParams(endpoint);
2056
- if (hasParams) {
2057
- lines.push(` mutationFn: ({ pathParams, ...data }) => apiClient.${this.camelCase(operationName)}(pathParams, data),`);
2058
- } else {
2059
- lines.push(` mutationFn: (data) => apiClient.${this.camelCase(operationName)}(data),`);
2060
- }
2061
- if (this.options.includeOptimisticUpdates) {
2062
- lines.push(this.generateOptimisticUpdate(endpoint));
2063
- }
2064
- lines.push(this.generateCacheInvalidation(endpoint));
2065
- lines.push(" ...options");
2066
- lines.push(" })");
2067
- lines.push("}");
2068
- return lines.join("\n");
2069
- }
2070
- generateOptimisticUpdate(endpoint) {
2071
- const method = endpoint.method.toLowerCase();
2072
- const resource = endpoint.tags?.[0] || "default";
2073
- const hasPathParams = endpoint.parameters.some((p) => p.in === "path");
2074
- switch (method) {
2075
- case "post":
2076
- return ` onMutate: async (data: any) => {
2077
- // Cancel outgoing refetches
2078
- await queryClient.cancelQueries({ queryKey: queryKeys.${resource}() })
2079
-
2080
- // Snapshot previous value
2081
- const previousData = queryClient.getQueryData(queryKeys.${resource}())
2082
-
2083
- // Optimistically update cache
2084
- queryClient.setQueryData(queryKeys.${resource}(), (old: any) => {
2085
- if (Array.isArray(old)) {
2086
- return [...old, data]
2087
- }
2088
- return old
2089
- })
2090
-
2091
- return { previousData }
2092
- },
2093
- onError: (err: any, data: any, context: any) => {
2094
- // Rollback on error
2095
- if (context?.previousData !== undefined) {
2096
- queryClient.setQueryData(queryKeys.${resource}(), context.previousData)
2097
- }
2098
- },`;
2099
- case "put":
2100
- case "patch":
2101
- if (hasPathParams) {
2102
- return ` onMutate: async (data: any) => {
2103
- await queryClient.cancelQueries({ queryKey: queryKeys.${resource}() })
2104
-
2105
- const previousData = queryClient.getQueryData(queryKeys.${resource}())
2106
-
2107
- // Update specific item in cache
2108
- queryClient.setQueryData(queryKeys.${resource}(), (old: any) => {
2109
- if (Array.isArray(old)) {
2110
- return old.map((item: any) =>
2111
- item.id === data.pathParams?.id || item.id === data.pathParams?.${resource.slice(0, -1)}_id
2112
- ? { ...item, ...data }
2113
- : item
2114
- )
2115
- }
2116
- return old
2117
- })
2118
-
2119
- return { previousData }
2120
- },
2121
- onError: (err: any, data: any, context: any) => {
2122
- if (context?.previousData !== undefined) {
2123
- queryClient.setQueryData(queryKeys.${resource}(), context.previousData)
2124
- }
2125
- },`;
2126
- }
2127
- return ` onMutate: async (data: any) => {
2128
- await queryClient.cancelQueries({ queryKey: queryKeys.${resource}() })
2129
-
2130
- const previousData = queryClient.getQueryData(queryKeys.${resource}())
2131
-
2132
- // Update cache with new data
2133
- queryClient.setQueryData(queryKeys.${resource}(), data)
2134
-
2135
- return { previousData }
2136
- },
2137
- onError: (err: any, data: any, context: any) => {
2138
- if (context?.previousData !== undefined) {
2139
- queryClient.setQueryData(queryKeys.${resource}(), context.previousData)
2140
- }
2141
- },`;
2142
- case "delete":
2143
- return ` onMutate: async (data: any) => {
2144
- await queryClient.cancelQueries({ queryKey: queryKeys.${resource}() })
2145
-
2146
- const previousData = queryClient.getQueryData(queryKeys.${resource}())
2147
-
2148
- // Remove item from cache
2149
- queryClient.setQueryData(queryKeys.${resource}(), (old: any) => {
2150
- if (Array.isArray(old)) {
2151
- const idToDelete = data.pathParams?.id || data.pathParams?.${resource.slice(0, -1)}_id || data
2152
- return old.filter((item: any) => item.id !== idToDelete)
2153
- }
2154
- return old
2155
- })
2156
-
2157
- return { previousData }
2158
- },
2159
- onError: (err: any, data: any, context: any) => {
2160
- if (context?.previousData !== undefined) {
2161
- queryClient.setQueryData(queryKeys.${resource}(), context.previousData)
2162
- }
2163
- },`;
2164
- default:
2165
- return "";
2166
- }
2167
- }
2168
- generateCacheInvalidation(endpoint) {
2169
- const relatedTags = this.getRelatedQueryTags(endpoint);
2170
- return ` onSettled: () => {
2171
- // Invalidate related queries
2172
- ${relatedTags.map((tag) => `queryClient.invalidateQueries({ queryKey: queryKeys.${tag}() })`).join("\n ")}
2173
- },`;
2174
- }
2175
- generateQueryKeys(endpoints) {
2176
- const keys = [];
2177
- keys.push(this.generateFileHeader("Query Keys"));
2178
- keys.push("");
2179
- keys.push("/**");
2180
- keys.push(" * Centralized query key factory");
2181
- keys.push(" * Ensures consistent cache key generation across the application");
2182
- keys.push(" */");
2183
- keys.push("");
2184
- keys.push("export const queryKeys = {");
2185
- keys.push(` all: ['${this.options.queryKeyPrefix}'] as const,`);
2186
- keys.push("");
2187
- const groupedEndpoints = this.groupEndpointsByResource(endpoints);
2188
- for (const [resource, resourceEndpoints] of Object.entries(groupedEndpoints)) {
2189
- keys.push(` // ${resource} keys`);
2190
- keys.push(` ${resource}: () => [...queryKeys.all, '${resource}'] as const,`);
2191
- const generatedKeys = /* @__PURE__ */ new Map();
2192
- for (const endpoint of resourceEndpoints) {
2193
- if (endpoint.method !== "get")
2194
- continue;
2195
- const operationName = this.getOperationName(endpoint);
2196
- let keyName = this.camelCase(operationName.replace(/^get/, ""));
2197
- if (generatedKeys.has(keyName)) {
2198
- const existingEndpoint = generatedKeys.get(keyName);
2199
- const existingIsSimpler = existingEndpoint.path.split("/").filter((s) => !s.startsWith("{")).length < endpoint.path.split("/").filter((s) => !s.startsWith("{")).length;
2200
- if (existingIsSimpler) {
2201
- const suffix = endpoint.path.includes("/{subcategory_id}") ? "Single" : "List";
2202
- keyName = `${keyName}${suffix}`;
2203
- } else {
2204
- const existingSuffix = existingEndpoint.path.includes("/{subcategory_id}") ? "Single" : "List";
2205
- const existingKeyName = keyName;
2206
- const newExistingKeyName = `${existingKeyName}${existingSuffix}`;
2207
- for (let i = keys.length - 1; i >= 0; i--) {
2208
- if (keys[i].includes(`${existingKeyName}:`)) {
2209
- keys[i] = keys[i].replace(`${existingKeyName}:`, `${newExistingKeyName}:`).replace(`'${existingKeyName}'`, `'${newExistingKeyName}'`);
2210
- break;
2211
- }
2212
- }
2213
- generatedKeys.delete(existingKeyName);
2214
- generatedKeys.set(newExistingKeyName, existingEndpoint);
2215
- }
2216
- }
2217
- generatedKeys.set(keyName, endpoint);
2218
- if (this.hasRequiredParams(endpoint)) {
2219
- keys.push(` ${keyName}: (params: any) => [...queryKeys.${resource}(), '${keyName}', params] as const,`);
2220
- } else {
2221
- keys.push(` ${keyName}: () => [...queryKeys.${resource}(), '${keyName}'] as const,`);
2222
- }
2223
- }
2224
- keys.push("");
2225
- }
2226
- keys.push("}");
2227
- return keys.join("\n");
2228
- }
2229
- generateHookTypes(endpoints) {
2230
- const types = [];
2231
- types.push(this.generateFileHeader("Hook Types"));
2232
- types.push("");
2233
- types.push("// Re-export bulk operation types for convenience");
2234
- types.push("export type { BulkOperationRequest, BulkOperationResponse, BulkOperationProgress, BulkMutationOptions } from '../bulk-types'");
2235
- types.push("");
2236
- const generatedTypes = /* @__PURE__ */ new Set();
2237
- for (const endpoint of endpoints) {
2238
- const operationName = this.getOperationName(endpoint);
2239
- if (this.hasRequiredParams(endpoint)) {
2240
- const typeName = `${this.capitalize(operationName)}Params`;
2241
- if (!generatedTypes.has(typeName)) {
2242
- generatedTypes.add(typeName);
2243
- const paramType = this.generateParamType(endpoint);
2244
- types.push(`export interface ${typeName} ${paramType}`);
2245
- types.push("");
2246
- }
2247
- }
2248
- if (endpoint.method !== "get") {
2249
- const typeName = `${this.capitalize(operationName)}Data`;
2250
- if (!generatedTypes.has(typeName)) {
2251
- generatedTypes.add(typeName);
2252
- const mutationType = this.generateMutationType(endpoint);
2253
- types.push(`export interface ${typeName} ${mutationType}`);
2254
- types.push("");
2255
- }
2256
- }
2257
- }
2258
- return types.join("\n");
2259
- }
2260
- generateIndexFile() {
2261
- const exports2 = [];
2262
- exports2.push(this.generateFileHeader("Generated React Hooks"));
2263
- exports2.push("");
2264
- exports2.push("// Query hooks");
2265
- exports2.push("export * from './queries'");
2266
- exports2.push("");
2267
- exports2.push("// Mutation hooks");
2268
- exports2.push("export * from './mutations'");
2269
- exports2.push("");
2270
- exports2.push("// Query keys");
2271
- exports2.push("export { queryKeys } from './keys'");
2272
- exports2.push("");
2273
- exports2.push("// Hook types");
2274
- exports2.push("export * from './types'");
2275
- return exports2.join("\n");
2276
- }
2277
- generateFileHeader(title) {
2278
- return `/**
2279
- * ${title}
2280
- *
2281
- * Auto-generated React hooks from OpenAPI specification
2282
- * Do not edit manually - regenerate using the hook generator
2283
- */`;
2284
- }
2285
- generateQueryHookName(endpoint) {
2286
- const operationName = this.getOperationName(endpoint);
2287
- return `use${this.capitalize(operationName)}`;
2288
- }
2289
- generateMutationHookName(endpoint) {
2290
- const operationName = this.getOperationName(endpoint);
2291
- const resourceName = this.extractResourceName(endpoint.path);
2292
- if (resourceName) {
2293
- const bulkHookName = this.bulkHookGenerator.generateBulkMutationHookName(endpoint, resourceName);
2294
- if (bulkHookName) {
2295
- return bulkHookName;
2296
- }
2297
- }
2298
- return `use${this.capitalize(operationName)}`;
2299
- }
2300
- getOperationName(endpoint) {
2301
- if (endpoint.operationId) {
2302
- const override = this.configManager.getOverride(endpoint.operationId);
2303
- if (override) {
2304
- return override;
2305
- }
2306
- }
2307
- let operationName;
2308
- if (endpoint.operationId) {
2309
- operationName = this.cleanOperationId(endpoint.operationId, endpoint);
2310
- } else {
2311
- operationName = this.generateCleanName(endpoint);
2312
- }
2313
- const patterns = this.configManager.getPatterns();
2314
- if (patterns.deduplicateSegments) {
2315
- operationName = this.removeDuplicateSegments(operationName);
2316
- }
2317
- if (this.options.enableConfidenceScoring && endpoint.operationId) {
2318
- const hookName = endpoint.method === "get" ? `use${this.capitalize(operationName)}` : `use${this.capitalize(this.getMethodPrefix(endpoint.method))}${this.capitalize(operationName)}`;
2319
- const scored = this.confidenceScorer.scoreHookName(hookName, endpoint.operationId, endpoint.path, endpoint.method);
2320
- if (scored.confidence === "low") {
2321
- console.log(`Low confidence hook: ${hookName} (score: ${scored.score})`);
2322
- }
2323
- this.scoredNames.push(scored);
2324
- if (scored.confidence === "low" && scored.suggestions.length > 0) {
2325
- const suggestion = scored.suggestions[0];
2326
- const prefix = `use${this.capitalize(this.getMethodPrefix(endpoint.method))}`;
2327
- if (suggestion.startsWith(prefix)) {
2328
- operationName = this.camelCase(suggestion.substring(prefix.length));
2329
- } else if (suggestion.startsWith("use")) {
2330
- operationName = this.camelCase(suggestion.substring(3));
2331
- }
2332
- }
2333
- }
2334
- return operationName;
2335
- }
2336
- cleanOperationId(operationId, endpoint) {
2337
- const parsed = this.parseOperationId(operationId, endpoint);
2338
- return this.generateNameFromParsed(parsed, endpoint);
2339
- }
2340
- /**
2341
- * Parse operation ID into structured components
2342
- */
2343
- parseOperationId(operationId, endpoint) {
2344
- const cleaned = operationId.replace(/_api_v\d+_/g, "_").replace(/_(get|post|put|patch|delete)$/i, "");
2345
- const parts = cleaned.split("_").filter(Boolean);
2346
- const prefix = this.extractPrefix(parts, { ...endpoint, operationId });
2347
- const resources = this.extractResourcesFromPath(endpoint.path);
2348
- const segments = endpoint.path.split("/");
2349
- const lastSegment = segments[segments.length - 1];
2350
- const isCustomAction = !lastSegment.startsWith("{") && segments[segments.length - 2]?.startsWith("{");
2351
- return {
2352
- action: prefix?.action || "",
2353
- resource: resources.primary || "",
2354
- subResource: resources.sub?.[0] || "",
2355
- method: endpoint.method,
2356
- isCustomAction,
2357
- customActionName: isCustomAction ? lastSegment.replace(/-/g, "_") : void 0,
2358
- originalId: operationId,
2359
- prefix: prefix?.fullPrefix || "",
2360
- resources
2361
- };
2362
- }
2363
- /**
2364
- * Extract meaningful prefix from operation ID parts
2365
- */
2366
- extractPrefix(parts, endpoint) {
2367
- if (parts.length === 0)
2368
- return null;
2369
- const originalId = endpoint.operationId || "";
2370
- const knownActions = [
2371
- "login",
2372
- "logout",
2373
- "register",
2374
- "signup",
2375
- "signin",
2376
- "assign",
2377
- "reassign",
2378
- "create",
2379
- "update",
2380
- "delete",
2381
- "get",
2382
- "list",
2383
- "health",
2384
- "status",
2385
- "verify",
2386
- "validate"
2387
- ];
2388
- const firstPart = parts[0].toLowerCase();
2389
- if (knownActions.includes(firstPart)) {
2390
- if (firstPart === "get" && originalId.startsWith("get_")) {
2391
- const match = originalId.match(/^get_(.+?)_api_v\d+/);
2392
- if (match) {
2393
- const compoundName = match[1];
2394
- if (compoundName === "health_status" || compoundName === "current_user_info") {
2395
- return {
2396
- action: firstPart,
2397
- fullPrefix: `${firstPart}_${compoundName}`
2398
- };
2399
- }
2400
- }
2401
- }
2402
- if (parts.length > 1 && ["assign", "reassign"].includes(firstPart)) {
2403
- if (firstPart === "reassign" && parts[1] === "transaction" && parts[2] === "budget") {
2404
- return {
2405
- action: "reassign",
2406
- fullPrefix: "reassign_budget"
2407
- };
2408
- }
2409
- return {
2410
- action: firstPart,
2411
- fullPrefix: `${parts[0]}_${parts[1]}`
2412
- };
2413
- }
2414
- return {
2415
- action: firstPart,
2416
- fullPrefix: parts[0]
2417
- };
2418
- }
2419
- return null;
2420
- }
2421
- /**
2422
- * Extract resources from API path
2423
- */
2424
- extractResourcesFromPath(path) {
2425
- const cleanPath = path.replace(/^\/api\/v\d+\//, "/");
2426
- const segments = cleanPath.split("/").filter(Boolean);
2427
- const resources = [];
2428
- let lastHasParam = false;
2429
- for (let i = 0; i < segments.length; i++) {
2430
- if (!segments[i].startsWith("{")) {
2431
- resources.push(segments[i].replace(/-/g, "_"));
2432
- } else if (i === segments.length - 1) {
2433
- lastHasParam = true;
2434
- }
2435
- }
2436
- return {
2437
- primary: resources[0] || "",
2438
- sub: resources.slice(1),
2439
- lastHasParam
2440
- };
2441
- }
2442
- /**
2443
- * Generate clean hook name from parsed components
2444
- */
2445
- generateNameFromParsed(parsed, endpoint) {
2446
- if (parsed.prefix === "login")
2447
- return "login";
2448
- if (parsed.prefix === "logout")
2449
- return "logout";
2450
- if (parsed.prefix && parsed.prefix.startsWith("get_") && parsed.prefix.includes("_")) {
2451
- const withoutGet = parsed.prefix.substring(4);
2452
- if (withoutGet === "health_status" || withoutGet === "current_user_info") {
2453
- return withoutGet;
2454
- }
2455
- }
2456
- if (parsed.prefix && this.isMeaningfulPrefix(parsed.prefix, parsed.resources)) {
2457
- return this.formatWithPrefix(parsed);
2458
- }
2459
- return this.formatStandardOperation(parsed, endpoint);
2460
- }
2461
- /**
2462
- * Check if prefix adds meaningful context
2463
- */
2464
- isMeaningfulPrefix(prefix, resources) {
2465
- const action = prefix.split("_")[0];
2466
- if (prefix === resources.primary)
2467
- return false;
2468
- if (prefix === `get_${resources.primary}`)
2469
- return false;
2470
- if (prefix === `list_${resources.primary}`)
2471
- return false;
2472
- return ["assign", "reassign", "verify", "validate", "sync", "refresh"].includes(action);
2473
- }
2474
- /**
2475
- * Format name with meaningful prefix
2476
- */
2477
- formatWithPrefix(parsed) {
2478
- const { prefix, resources, originalId, isCustomAction, customActionName } = parsed;
2479
- const prefixParts = prefix.split("_");
2480
- const action = prefixParts[0];
2481
- const subject = prefixParts.slice(1).join("_");
2482
- if (isCustomAction && customActionName) {
2483
- if (action === "reassign" && subject === "budget") {
2484
- return `reassign_${this.singularize(resources.primary)}_budget`;
2485
- }
2486
- }
2487
- if (subject && resources.sub.length > 0) {
2488
- const subResource = resources.sub[0];
2489
- if (subject === subResource || subject === this.pluralize(subResource)) {
2490
- return `${action}_${this.singularize(resources.primary)}_${subResource}`;
2491
- }
2492
- }
2493
- if (resources.sub.length > 0 && !isCustomAction) {
2494
- return `${action}_${this.singularize(resources.primary)}_${resources.sub[0]}`;
2495
- }
2496
- return `${action}_${this.singularize(resources.primary)}`;
2497
- }
2498
- /**
2499
- * Format standard REST operation
2500
- */
2501
- formatStandardOperation(parsed, endpoint) {
2502
- const { resources, method } = parsed;
2503
- const hasParams = endpoint.path.includes("{");
2504
- const isListOperation = method === "get" && !hasParams;
2505
- if (resources.sub.length > 0) {
2506
- const primary = this.singularize(resources.primary);
2507
- const sub = resources.sub[0];
2508
- switch (method) {
2509
- case "get":
2510
- return isListOperation ? `${primary}_${this.pluralize(sub)}` : `${primary}_${sub}`;
2511
- case "post":
2512
- return `create_${primary}_${this.singularize(sub)}`;
2513
- case "put":
2514
- case "patch":
2515
- return `set_${primary}_${sub}`;
2516
- case "delete":
2517
- return `remove_${primary}_${sub}`;
2518
- }
2519
- }
2520
- switch (method) {
2521
- case "get":
2522
- return isListOperation ? this.pluralize(resources.primary) : this.singularize(resources.primary);
2523
- case "post":
2524
- return `create_${this.singularize(resources.primary)}`;
2525
- case "put":
2526
- case "patch":
2527
- return `update_${this.singularize(resources.primary)}`;
2528
- case "delete":
2529
- return `delete_${this.singularize(resources.primary)}`;
2530
- default:
2531
- return this.singularize(resources.primary);
2532
- }
2533
- }
2534
- generateCleanName(endpoint) {
2535
- const pathParts = endpoint.path.split("/").filter((part) => part && !part.startsWith("{"));
2536
- if (pathParts.length === 0)
2537
- return endpoint.method;
2538
- const resource = pathParts[pathParts.length - 1];
2539
- const cleanResource = resource.replace(/-/g, "_");
2540
- const segments = endpoint.path.split("/");
2541
- const lastSegment = segments[segments.length - 1];
2542
- const hasCustomAction = !lastSegment.startsWith("{") && segments[segments.length - 2]?.startsWith("{");
2543
- if (hasCustomAction) {
2544
- const mainResource = pathParts[pathParts.length - 2] || pathParts[pathParts.length - 1];
2545
- const action = lastSegment.replace(/-/g, "_");
2546
- return `${mainResource}_${action}`;
2547
- }
2548
- if (pathParts.length > 2 && segments.some((s) => s.startsWith("{"))) {
2549
- return cleanResource;
2550
- }
2551
- switch (endpoint.method) {
2552
- case "get":
2553
- const isList = !endpoint.path.includes("{");
2554
- if (isList && !cleanResource.endsWith("s") && !cleanResource.endsWith("ies")) {
2555
- return this.pluralize(cleanResource);
2556
- }
2557
- return cleanResource;
2558
- case "post":
2559
- return `create_${cleanResource}`;
2560
- case "put":
2561
- case "patch":
2562
- return `update_${cleanResource}`;
2563
- case "delete":
2564
- return `delete_${cleanResource}`;
2565
- default:
2566
- return `${endpoint.method}_${cleanResource}`;
2567
- }
2568
- }
2569
- pluralize(word) {
2570
- if (word.endsWith("s") && !word.endsWith("ss") && !word.endsWith("us") && !word.endsWith("is")) {
2571
- return word;
2572
- }
2573
- if (word.endsWith("y") && !["ay", "ey", "iy", "oy", "uy"].includes(word.slice(-2))) {
2574
- return word.slice(0, -1) + "ies";
2575
- }
2576
- if (word.endsWith("ss") || word.endsWith("x") || word.endsWith("ch") || word.endsWith("sh")) {
2577
- return word + "es";
2578
- }
2579
- if (word.endsWith("us")) {
2580
- return word.slice(0, -2) + "i";
2581
- }
2582
- if (word.endsWith("is")) {
2583
- return word.slice(0, -2) + "es";
2584
- }
2585
- return word + "s";
2586
- }
2587
- singularize(word) {
2588
- if (word.endsWith("ies")) {
2589
- return word.slice(0, -3) + "y";
2590
- }
2591
- if (word.endsWith("ses") || word.endsWith("xes") || word.endsWith("ches") || word.endsWith("shes")) {
2592
- return word.slice(0, -2);
2593
- }
2594
- if (word.endsWith("s") && !word.endsWith("ss")) {
2595
- return word.slice(0, -1);
2596
- }
2597
- return word;
2598
- }
2599
- hasRequiredParams(endpoint) {
2600
- return endpoint.parameters.some((p) => p.required) || endpoint.parameters.some((p) => p.in === "path");
2601
- }
2602
- generateParamType(endpoint) {
2603
- const pathParams = endpoint.parameters.filter((p) => p.in === "path");
2604
- const queryParams = endpoint.parameters.filter((p) => p.in === "query");
2605
- const properties = [];
2606
- pathParams.forEach((param) => {
2607
- properties.push(`${param.name}: ${this.getParameterType(param)}`);
2608
- });
2609
- queryParams.forEach((param) => {
2610
- const optional = param.required ? "" : "?";
2611
- properties.push(`${param.name}${optional}: ${this.getParameterType(param)}`);
2612
- });
2613
- return `{ ${properties.join("; ")} }`;
2614
- }
2615
- generateMutationType(endpoint) {
2616
- const hasPathParams = endpoint.parameters.some((p) => p.in === "path");
2617
- if (hasPathParams) {
2618
- const pathType = this.generateParamType(endpoint);
2619
- return `{ pathParams: ${pathType}; [key: string]: any }`;
2620
- }
2621
- return "{ [key: string]: any }";
2622
- }
2623
- getParameterType(param) {
2624
- switch (param.schema.type) {
2625
- case "string":
2626
- return "string";
2627
- case "number":
2628
- case "integer":
2629
- return "number";
2630
- case "boolean":
2631
- return "boolean";
2632
- default:
2633
- return "any";
2634
- }
2635
- }
2636
- isListEndpoint(endpoint) {
2637
- if (endpoint.method.toLowerCase() !== "get")
2638
- return false;
2639
- if (endpoint.path.includes("{"))
2640
- return false;
2641
- if (endpoint.responses?.["200"]?.schema?.type === "array")
2642
- return true;
2643
- const description = `${endpoint.summary || ""} ${endpoint.description || ""}`.toLowerCase();
2644
- return description.includes("list") || description.includes("get all") || description.includes("fetch all");
2645
- }
2646
- groupEndpointsByResource(endpoints) {
2647
- const groups = {};
2648
- for (const endpoint of endpoints) {
2649
- const resource = endpoint.tags?.[0] || "default";
2650
- if (!groups[resource]) {
2651
- groups[resource] = [];
2652
- }
2653
- groups[resource].push(endpoint);
2654
- }
2655
- return groups;
2656
- }
2657
- getRelatedQueryTags(endpoint) {
2658
- const resource = endpoint.tags?.[0] || "default";
2659
- return [resource, "all"];
2660
- }
2661
- camelCase(str) {
2662
- return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toLowerCase());
2663
- }
2664
- capitalize(str) {
2665
- return str.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
2666
- }
2667
- getMethodPrefix(method) {
2668
- const prefixes = {
2669
- post: "create",
2670
- put: "update",
2671
- patch: "update",
2672
- delete: "delete"
2673
- };
2674
- return prefixes[method.toLowerCase()] || method.toLowerCase();
2675
- }
2676
- removeDuplicateSegments(operationName) {
2677
- const parts = operationName.split("_");
2678
- const seen = /* @__PURE__ */ new Set();
2679
- const result = [];
2680
- for (const part of parts) {
2681
- const lower = part.toLowerCase();
2682
- if (!seen.has(lower)) {
2683
- seen.add(lower);
2684
- result.push(part);
2685
- }
2686
- }
2687
- return result.join("_");
2688
- }
2689
- };
2690
- async function generateHooks(parsedAPI, options) {
2691
- const generator = new ReactHookGenerator(options);
2692
- return generator.generate(parsedAPI);
2693
- }
2694
-
2695
- // cli/commands/generate-hooks.ts
2696
- async function generateHooksCommand(source, options) {
2697
- try {
2698
- console.log("\u{1F680} Pattern-Stack Hook Generator");
2699
- console.log("================================");
2700
- console.log();
2701
- console.log("\u{1F4E5} Loading OpenAPI specification...");
2702
- const spec = await loadOpenAPISpec(source);
2703
- console.log(`\u2705 Loaded: ${spec.info.title} v${spec.info.version}`);
2704
- console.log("\u{1F50D} Parsing specification...");
2705
- const parsed = await parseOpenAPI(spec);
2706
- console.log(`\u2705 Found ${parsed.endpoints.length} endpoints, ${parsed.schemas.length} schemas`);
2707
- console.log("\u{1F3D7}\uFE0F Generating TypeScript types...");
2708
- const types = generateTypes(parsed, {
2709
- prefix: options.prefix,
2710
- includeJSDoc: true,
2711
- includeExamples: true
2712
- });
2713
- console.log("\u{1F527} Generating API client...");
2714
- const client = generateAPIClient(parsed, {
2715
- clientType: options.client,
2716
- includeAuth: true,
2717
- authType: options.auth,
2718
- includeInterceptors: true
2719
- });
2720
- console.log("\u269B\uFE0F Generating React hooks...");
2721
- const hooks = await generateHooks(parsed, {
2722
- includeInfiniteQueries: true,
2723
- includeOptimisticUpdates: true,
2724
- includeMutationHelpers: true,
2725
- enableConfidenceScoring: true
2726
- });
2727
- if (options.dryRun) {
2728
- console.log("\n\u{1F4CB} Dry run - files that would be generated:");
2729
- console.log("Types:");
2730
- console.log(" - schemas.ts");
2731
- console.log(" - endpoints.ts");
2732
- console.log(" - parameters.ts");
2733
- console.log(" - responses.ts");
2734
- console.log();
2735
- console.log("API Client:");
2736
- console.log(" - client.ts");
2737
- console.log(" - methods.ts");
2738
- console.log(" - types.ts");
2739
- console.log(" - config.ts");
2740
- console.log();
2741
- console.log("React Hooks:");
2742
- console.log(" - queries.ts");
2743
- console.log(" - mutations.ts");
2744
- console.log(" - keys.ts");
2745
- console.log(" - types.ts");
2746
- console.log();
2747
- console.log("Generated code preview:");
2748
- console.log("======================");
2749
- console.log();
2750
- console.log("Types (first 20 lines):");
2751
- console.log(types.schemas.split("\n").slice(0, 20).join("\n"));
2752
- console.log("\n...");
2753
- return;
2754
- }
2755
- console.log(`\u{1F4C1} Creating output directory: ${options.output}`);
2756
- await ensureDir(options.output);
2757
- await ensureDir((0, import_path3.join)(options.output, "types"));
2758
- await ensureDir((0, import_path3.join)(options.output, "client"));
2759
- await ensureDir((0, import_path3.join)(options.output, "hooks"));
2760
- console.log("\u{1F4BE} Writing type definitions...");
2761
- await writeFile((0, import_path3.join)(options.output, "types", "schemas.ts"), types.schemas);
2762
- await writeFile((0, import_path3.join)(options.output, "types", "endpoints.ts"), types.endpoints);
2763
- await writeFile((0, import_path3.join)(options.output, "types", "parameters.ts"), types.parameters);
2764
- await writeFile((0, import_path3.join)(options.output, "types", "responses.ts"), types.responses);
2765
- await writeFile((0, import_path3.join)(options.output, "types", "index.ts"), types.index);
2766
- console.log("\u{1F4BE} Writing API client...");
2767
- await writeFile((0, import_path3.join)(options.output, "client", "client.ts"), client.client);
2768
- await writeFile((0, import_path3.join)(options.output, "client", "methods.ts"), client.methods);
2769
- await writeFile((0, import_path3.join)(options.output, "client", "types.ts"), client.types);
2770
- await writeFile((0, import_path3.join)(options.output, "client", "config.ts"), client.config);
2771
- await writeFile((0, import_path3.join)(options.output, "client", "index.ts"), client.index);
2772
- console.log("\u{1F4BE} Writing React hooks...");
2773
- await writeFile((0, import_path3.join)(options.output, "hooks", "queries.ts"), hooks.queries);
2774
- await writeFile((0, import_path3.join)(options.output, "hooks", "mutations.ts"), hooks.mutations);
2775
- await writeFile((0, import_path3.join)(options.output, "hooks", "keys.ts"), hooks.keys);
2776
- await writeFile((0, import_path3.join)(options.output, "hooks", "types.ts"), hooks.types);
2777
- await writeFile((0, import_path3.join)(options.output, "hooks", "index.ts"), hooks.index);
2778
- if (hooks.report) {
2779
- await writeFile((0, import_path3.join)(options.output, "hooks", "confidence-report.md"), hooks.report);
2780
- console.log("\u{1F4CA} Generated confidence report");
2781
- const lowConfidenceCount = (hooks.report.match(/## Low Confidence Names/g) || []).length;
2782
- if (lowConfidenceCount > 0) {
2783
- console.log("\n\u26A0\uFE0F Some hook names have low confidence and may need review.");
2784
- console.log("Run `npm run review:hooks` to interactively review and improve them.");
2785
- }
2786
- }
2787
- const mainIndex = `/**
2788
- * Generated API Integration
2789
- *
2790
- * Auto-generated from OpenAPI specification: ${spec.info.title}
2791
- * Version: ${spec.info.version}
2792
- * Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
2793
- */
2794
-
2795
- export * from './types'
2796
- export * from './client'
2797
- export * from './hooks'
2798
-
2799
- // Quick start exports
2800
- export { createAPIClient } from './client'
2801
- export { queryKeys } from './hooks'`;
2802
- await writeFile((0, import_path3.join)(options.output, "index.ts"), mainIndex);
2803
- const usageExample = generateUsageExample(spec.info.title, options);
2804
- await writeFile((0, import_path3.join)(options.output, "example.ts"), usageExample);
2805
- console.log();
2806
- console.log("\u2705 Generation complete!");
2807
- console.log(`\u{1F4E6} Generated files in: ${options.output}`);
2808
- console.log();
2809
- console.log("\u{1F680} Quick start:");
2810
- console.log(`import { createAPIClient, useGetUsers } from './${options.output}'`);
2811
- console.log();
2812
- console.log("\u{1F4A1} See example.ts for detailed usage instructions");
2813
- } catch (error) {
2814
- console.error("\u274C Generation failed:");
2815
- console.error(error instanceof Error ? error.message : error);
2816
- process.exit(1);
2817
- }
2818
- }
2819
- async function ensureDir(dir) {
2820
- try {
2821
- await import_fs3.promises.mkdir(dir, { recursive: true });
2822
- } catch (error) {
2823
- }
2824
- }
2825
- async function writeFile(path, content) {
2826
- await ensureDir((0, import_path3.dirname)(path));
2827
- await import_fs3.promises.writeFile(path, content, "utf8");
2828
- }
2829
- function generateUsageExample(apiTitle, options) {
2830
- return `/**
2831
- * ${apiTitle} - Usage Example
2832
- *
2833
- * This file demonstrates how to use the generated API integration
2834
- */
2835
-
2836
- import React from 'react'
2837
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
2838
- import { createAPIClient, useGetUsers, useCreateUser } from './'
2839
-
2840
- // 1. Set up the API client
2841
- const apiClient = createAPIClient({
2842
- baseUrl: 'https://api.example.com/v1',
2843
- ${options.auth === "bearer" ? `getAuthToken: () => localStorage.getItem('authToken'),` : ""}
2844
- ${options.auth === "apiKey" ? `getApiKey: () => process.env.REACT_APP_API_KEY,
2845
- apiKeyHeader: 'X-API-Key',` : ""}
2846
- onError: (error) => {
2847
- console.error('API Error:', error)
2848
- // Handle global errors (show toast, redirect to login, etc.)
2849
- }
2850
- })
2851
-
2852
- // 2. Set up React Query
2853
- const queryClient = new QueryClient({
2854
- defaultOptions: {
2855
- queries: {
2856
- staleTime: 5 * 60 * 1000, // 5 minutes
2857
- cacheTime: 10 * 60 * 1000, // 10 minutes
2858
- },
2859
- },
2860
- })
2861
-
2862
- // 3. Wrap your app with providers
2863
- function App() {
2864
- return (
2865
- <QueryClientProvider client={queryClient}>
2866
- <UserList />
2867
- </QueryClientProvider>
2868
- )
2869
- }
2870
-
2871
- // 4. Use generated hooks in components
2872
- function UserList() {
2873
- // Query hook with automatic loading, error, and data states
2874
- const { data: users, isLoading, error } = useGetUsers({
2875
- limit: 10
2876
- })
2877
-
2878
- // Mutation hook with optimistic updates
2879
- const createUserMutation = useCreateUser({
2880
- onSuccess: () => {
2881
- console.log('User created successfully!')
2882
- },
2883
- onError: (error) => {
2884
- console.error('Failed to create user:', error)
2885
- }
2886
- })
2887
-
2888
- const handleCreateUser = () => {
2889
- createUserMutation.mutate({
2890
- email: 'new@example.com',
2891
- name: 'New User'
2892
- })
2893
- }
2894
-
2895
- if (isLoading) return <div>Loading users...</div>
2896
- if (error) return <div>Error: {error.message}</div>
2897
-
2898
- return (
2899
- <div>
2900
- <h2>Users</h2>
2901
- <button
2902
- onClick={handleCreateUser}
2903
- disabled={createUserMutation.isLoading}
2904
- >
2905
- {createUserMutation.isLoading ? 'Creating...' : 'Create User'}
2906
- </button>
2907
-
2908
- <ul>
2909
- {users?.map(user => (
2910
- <li key={user.id}>
2911
- {user.name} ({user.email})
2912
- </li>
2913
- ))}
2914
- </ul>
2915
- </div>
2916
- )
2917
- }
2918
-
2919
- // 5. Advanced usage with infinite queries
2920
- function InfiniteUserList() {
2921
- const {
2922
- data,
2923
- fetchNextPage,
2924
- hasNextPage,
2925
- isFetchingNextPage,
2926
- } = useInfiniteGetUsers({
2927
- limit: 20
2928
- })
2929
-
2930
- return (
2931
- <div>
2932
- {data?.pages.map((page, i) => (
2933
- <React.Fragment key={i}>
2934
- {page.map(user => (
2935
- <div key={user.id}>{user.name}</div>
2936
- ))}
2937
- </React.Fragment>
2938
- ))}
2939
-
2940
- <button
2941
- onClick={() => fetchNextPage()}
2942
- disabled={!hasNextPage || isFetchingNextPage}
2943
- >
2944
- {isFetchingNextPage
2945
- ? 'Loading more...'
2946
- : hasNextPage
2947
- ? 'Load More'
2948
- : 'Nothing more to load'}
2949
- </button>
2950
- </div>
2951
- )
2952
- }
2953
-
2954
- export default App`;
2955
- }
2956
-
2957
- // cli/commands/scaffold.ts
2958
- var import_fs4 = require("fs");
2959
- var import_path4 = require("path");
2960
- async function scaffoldCommand(type, name, options) {
2961
- console.log(`\u{1F3D7}\uFE0F Scaffolding ${type}: ${name}`);
2962
- switch (type) {
2963
- case "component":
2964
- await scaffoldComponent(name, options);
2965
- break;
2966
- case "feature":
2967
- await scaffoldFeature(name, options);
2968
- break;
2969
- case "template":
2970
- await scaffoldTemplate(name, options);
2971
- break;
2972
- default:
2973
- console.error(`\u274C Unknown scaffold type: ${type}`);
2974
- console.log("Available types: component, feature, template");
2975
- process.exit(1);
2976
- }
2977
- }
2978
- async function scaffoldComponent(name, options) {
2979
- const outputDir = options.output || `./src/atoms/composed/${name}`;
2980
- const componentContent = `/**
2981
- * ${name} Component
2982
- *
2983
- * Generated by Pattern-Stack CLI
2984
- */
2985
-
2986
- import React from 'react'
2987
- import { cn } from '../../utils/utils'
2988
-
2989
- export interface ${name}Props {
2990
- className?: string
2991
- children?: React.ReactNode
2992
- }
2993
-
2994
- export function ${name}({ className, children, ...props }: ${name}Props) {
2995
- return (
2996
- <div className={cn("", className)} {...props}>
2997
- {children}
2998
- </div>
2999
- )
3000
- }
3001
-
3002
- ${name}.displayName = "${name}"`;
3003
- const indexContent = `export { ${name} } from './${name}'
3004
- export type { ${name}Props } from './${name}'`;
3005
- const testContent = `/**
3006
- * ${name} Component Tests
3007
- */
3008
-
3009
- import { render, screen } from '@testing-library/react'
3010
- import { ${name} } from './${name}'
3011
-
3012
- describe('${name}', () => {
3013
- it('renders children', () => {
3014
- render(<${name}>Test content</${name}>)
3015
- expect(screen.getByText('Test content')).toBeInTheDocument()
3016
- })
3017
-
3018
- it('applies custom className', () => {
3019
- const { container } = render(<${name} className="custom-class" />)
3020
- expect(container.firstChild).toHaveClass('custom-class')
3021
- })
3022
- })`;
3023
- await ensureDir2(outputDir);
3024
- await writeFile2((0, import_path4.join)(outputDir, `${name}.tsx`), componentContent);
3025
- await writeFile2((0, import_path4.join)(outputDir, "index.ts"), indexContent);
3026
- await writeFile2((0, import_path4.join)(outputDir, `${name}.test.tsx`), testContent);
3027
- console.log(`\u2705 Component scaffolded: ${outputDir}`);
3028
- }
3029
- async function scaffoldFeature(name, options) {
3030
- const outputDir = options.output || `./src/features/${name.toLowerCase()}`;
3031
- const hookContent = `/**
3032
- * ${name} Hooks
3033
- *
3034
- * Generated by Pattern-Stack CLI
3035
- */
3036
-
3037
- import { useState, useEffect } from 'react'
3038
-
3039
- export function use${name}() {
3040
- const [data, setData] = useState(null)
3041
- const [loading, setLoading] = useState(false)
3042
- const [error, setError] = useState<Error | null>(null)
3043
-
3044
- // Add your logic here
3045
-
3046
- return {
3047
- data,
3048
- loading,
3049
- error,
3050
- refetch: () => {
3051
- // Implement refetch logic
3052
- }
3053
- }
3054
- }`;
3055
- const componentContent = `/**
3056
- * ${name} Component
3057
- *
3058
- * Generated by Pattern-Stack CLI
3059
- */
3060
-
3061
- import React from 'react'
3062
- import { use${name} } from '../hooks/use${name}'
3063
-
3064
- export interface ${name}ComponentProps {
3065
- className?: string
3066
- }
3067
-
3068
- export function ${name}Component({ className }: ${name}ComponentProps) {
3069
- const { data, loading, error } = use${name}()
3070
-
3071
- if (loading) return <div>Loading...</div>
3072
- if (error) return <div>Error: {error.message}</div>
3073
-
3074
- return (
3075
- <div className={className}>
3076
- <h2>${name}</h2>
3077
- {/* Add your UI here */}
3078
- </div>
3079
- )
3080
- }`;
3081
- const indexContent = `export { use${name} } from './hooks/use${name}'
3082
- export { ${name}Component } from './components/${name}Component'
3083
- export type { ${name}ComponentProps } from './components/${name}Component'`;
3084
- await ensureDir2((0, import_path4.join)(outputDir, "hooks"));
3085
- await ensureDir2((0, import_path4.join)(outputDir, "components"));
3086
- await writeFile2((0, import_path4.join)(outputDir, "hooks", `use${name}.ts`), hookContent);
3087
- await writeFile2((0, import_path4.join)(outputDir, "hooks", "index.ts"), `export { use${name} } from './use${name}'`);
3088
- await writeFile2((0, import_path4.join)(outputDir, "components", `${name}Component.tsx`), componentContent);
3089
- await writeFile2((0, import_path4.join)(outputDir, "components", "index.ts"), `export { ${name}Component } from './${name}Component'`);
3090
- await writeFile2((0, import_path4.join)(outputDir, "index.ts"), indexContent);
3091
- console.log(`\u2705 Feature scaffolded: ${outputDir}`);
3092
- }
3093
- async function scaffoldTemplate(name, options) {
3094
- const outputDir = options.output || `./src/templates/${name.toLowerCase()}`;
3095
- const templateContent = `/**
3096
- * ${name} Template
3097
- *
3098
- * Generated by Pattern-Stack CLI
3099
- */
3100
-
3101
- import React from 'react'
3102
- import { PageTemplate } from '../PageTemplate'
3103
-
3104
- export interface ${name}TemplateProps {
3105
- title?: string
3106
- children?: React.ReactNode
3107
- }
3108
-
3109
- export function ${name}Template({
3110
- title = "${name}",
3111
- children
3112
- }: ${name}TemplateProps) {
3113
- return (
3114
- <PageTemplate>
3115
- <div className="space-y-6">
3116
- <header>
3117
- <h1 className="text-3xl font-bold">{title}</h1>
3118
- </header>
3119
-
3120
- <main>
3121
- {children}
3122
- </main>
3123
- </div>
3124
- </PageTemplate>
3125
- )
3126
- }`;
3127
- const indexContent = `export { ${name}Template } from './${name}Template'
3128
- export type { ${name}TemplateProps } from './${name}Template'`;
3129
- await ensureDir2(outputDir);
3130
- await writeFile2((0, import_path4.join)(outputDir, `${name}Template.tsx`), templateContent);
3131
- await writeFile2((0, import_path4.join)(outputDir, "index.ts"), indexContent);
3132
- console.log(`\u2705 Template scaffolded: ${outputDir}`);
3133
- }
3134
- async function ensureDir2(dir) {
3135
- try {
3136
- await import_fs4.promises.mkdir(dir, { recursive: true });
3137
- } catch (error) {
3138
- }
3139
- }
3140
- async function writeFile2(path, content) {
3141
- await ensureDir2((0, import_path4.dirname)(path));
3142
- await import_fs4.promises.writeFile(path, content, "utf8");
3143
- }
3144
-
3145
- // cli/commands/init.ts
3146
- async function initCommand(template = "basic", options) {
3147
- console.log(`\u{1F680} Initializing Pattern-Stack project with ${template} template`);
3148
- if (options.name) {
3149
- console.log(`\u{1F4E6} Project name: ${options.name}`);
3150
- }
3151
- if (options.dir) {
3152
- console.log(`\u{1F4C1} Target directory: ${options.dir}`);
3153
- }
3154
- console.log("\n\u26A0\uFE0F Template initialization not yet implemented");
3155
- console.log("This feature will be available in a future release.");
3156
- console.log("\nFor now, you can:");
3157
- console.log("1. Clone the Pattern-Stack repository");
3158
- console.log("2. Use the generate hooks command to create API integrations");
3159
- console.log("3. Use the scaffold command to create components");
3160
- }
3161
-
3162
- // cli/index.ts
3163
- var program = new import_commander.Command();
3164
- program.name("pattern-stack").description("Pattern-Stack CLI for code generation and scaffolding").version("1.0.0");
3165
- var generateCommand = program.command("generate").alias("g").description("Generate code from specifications");
3166
- generateCommand.command("hooks").description("Generate React hooks from OpenAPI specification").argument("<source>", "OpenAPI specification (URL or file path)").option("-o, --output <dir>", "Output directory", "./src/generated").option("--prefix <prefix>", "Type name prefix", "").option("--client <type>", "API client type", "axios").option("--auth <type>", "Authentication type", "bearer").option("--dry-run", "Show what would be generated without writing files").action(generateHooksCommand);
3167
- program.command("scaffold").alias("s").description("Scaffold components and structures").argument("<type>", "Type to scaffold (component, feature, template)").argument("<name>", "Name of the item to scaffold").option("-t, --template <template>", "Template to use").option("-o, --output <dir>", "Output directory").action(scaffoldCommand);
3168
- program.command("init").description("Initialize a new Pattern-Stack project").argument("[template]", "Template to use (financial, ecommerce, analytics)").option("-n, --name <name>", "Project name").option("-d, --dir <directory>", "Target directory").option("--git", "Initialize git repository").option("--install", "Install dependencies").action(initCommand);
3169
- program.command("config").description("Manage Pattern-Stack configuration").option("--show", "Show current configuration").option("--set <key=value>", "Set configuration value").action((options) => {
3170
- if (options.show) {
3171
- console.log("Current configuration:");
3172
- }
3173
- if (options.set) {
3174
- const [key, value] = options.set.split("=");
3175
- console.log(`Setting ${key} = ${value}`);
3176
- }
3177
- });
3178
- program.command("help").description("Display help for commands").argument("[command]", "Command to get help for").action((command) => {
3179
- if (command) {
3180
- program.help();
3181
- } else {
3182
- console.log(`
3183
- Pattern-Stack CLI
3184
-
3185
- Available commands:
3186
- generate hooks <source> Generate React hooks from OpenAPI spec
3187
- scaffold <type> <name> Scaffold components and structures
3188
- init [template] Initialize new project from template
3189
- config Manage configuration
3190
-
3191
- Examples:
3192
- pattern-stack generate hooks ./api/openapi.json
3193
- pattern-stack scaffold component UserCard
3194
- pattern-stack init financial --name my-finance-app
3195
-
3196
- For more information on a command:
3197
- pattern-stack <command> --help
3198
- `);
3199
- }
3200
- });
3201
- program.on("command:*", () => {
3202
- console.error("Invalid command: %s\nSee --help for a list of available commands.", program.args.join(" "));
3203
- process.exit(1);
3204
- });
3205
- if (process.argv.length < 3) {
3206
- program.help();
3207
- } else {
3208
- program.parse();
3209
- }
3210
- var index_default = program;