@rebasepro/studio 0.0.1-canary.09e5ec5

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 (361) hide show
  1. package/LICENSE +114 -0
  2. package/README.md +159 -0
  3. package/dist/ApiExplorer-gMJt5JrS.js +1053 -0
  4. package/dist/ApiExplorer-gMJt5JrS.js.map +1 -0
  5. package/dist/AuthSimulationSelector-BF4rkRGp.js +118 -0
  6. package/dist/AuthSimulationSelector-BF4rkRGp.js.map +1 -0
  7. package/dist/BranchesView-DcHZtvXo.js +292 -0
  8. package/dist/BranchesView-DcHZtvXo.js.map +1 -0
  9. package/dist/CronJobsView-CijCToeK.js +456 -0
  10. package/dist/CronJobsView-CijCToeK.js.map +1 -0
  11. package/dist/JSEditor-D8nVp3Lp.js +1308 -0
  12. package/dist/JSEditor-D8nVp3Lp.js.map +1 -0
  13. package/dist/MonacoEditor-CMYEjiRf.js +161 -0
  14. package/dist/MonacoEditor-CMYEjiRf.js.map +1 -0
  15. package/dist/RLSEditor-DBH09u9v.js +1831 -0
  16. package/dist/RLSEditor-DBH09u9v.js.map +1 -0
  17. package/dist/SQLEditor-CkVx9vgr.js +1792 -0
  18. package/dist/SQLEditor-CkVx9vgr.js.map +1 -0
  19. package/dist/SchemaVisualizer-BgD5Zb77.js +1069 -0
  20. package/dist/SchemaVisualizer-BgD5Zb77.js.map +1 -0
  21. package/dist/StorageView-CTqGFhY9.js +907 -0
  22. package/dist/StorageView-CTqGFhY9.js.map +1 -0
  23. package/dist/common/src/collections/CollectionRegistry.d.ts +56 -0
  24. package/dist/common/src/collections/index.d.ts +1 -0
  25. package/dist/common/src/data/buildRebaseData.d.ts +14 -0
  26. package/dist/common/src/index.d.ts +3 -0
  27. package/dist/common/src/util/builders.d.ts +57 -0
  28. package/dist/common/src/util/callbacks.d.ts +6 -0
  29. package/dist/common/src/util/collections.d.ts +11 -0
  30. package/dist/common/src/util/common.d.ts +2 -0
  31. package/dist/common/src/util/conditions.d.ts +26 -0
  32. package/dist/common/src/util/entities.d.ts +58 -0
  33. package/dist/common/src/util/enums.d.ts +3 -0
  34. package/dist/common/src/util/index.d.ts +16 -0
  35. package/dist/common/src/util/navigation_from_path.d.ts +34 -0
  36. package/dist/common/src/util/navigation_utils.d.ts +20 -0
  37. package/dist/common/src/util/parent_references_from_path.d.ts +6 -0
  38. package/dist/common/src/util/paths.d.ts +14 -0
  39. package/dist/common/src/util/permissions.d.ts +5 -0
  40. package/dist/common/src/util/references.d.ts +2 -0
  41. package/dist/common/src/util/relations.d.ts +22 -0
  42. package/dist/common/src/util/resolutions.d.ts +72 -0
  43. package/dist/common/src/util/storage.d.ts +24 -0
  44. package/dist/core/src/components/AIIcon.d.ts +16 -0
  45. package/dist/core/src/components/ConfirmationDialog.d.ts +9 -0
  46. package/dist/core/src/components/Debug/UIReferenceView.d.ts +1 -0
  47. package/dist/core/src/components/Debug/UIStyleGuide.d.ts +1 -0
  48. package/dist/core/src/components/ErrorTooltip.d.ts +2 -0
  49. package/dist/core/src/components/ErrorView.d.ts +21 -0
  50. package/dist/core/src/components/LanguageToggle.d.ts +1 -0
  51. package/dist/core/src/components/LoginView/LoginView.d.ts +68 -0
  52. package/dist/core/src/components/LoginView/index.d.ts +2 -0
  53. package/dist/core/src/components/NotFoundPage.d.ts +1 -0
  54. package/dist/core/src/components/RebaseAuth.d.ts +10 -0
  55. package/dist/core/src/components/RebaseLogo.d.ts +7 -0
  56. package/dist/core/src/components/UnsavedChangesDialog.d.ts +9 -0
  57. package/dist/core/src/components/UserDisplay.d.ts +7 -0
  58. package/dist/core/src/components/UserSelectPopover.d.ts +62 -0
  59. package/dist/core/src/components/UserSettingsView.d.ts +1 -0
  60. package/dist/core/src/components/common/index.d.ts +6 -0
  61. package/dist/core/src/components/common/table_height.d.ts +5 -0
  62. package/dist/core/src/components/common/types.d.ts +63 -0
  63. package/dist/core/src/components/common/useColumnsIds.d.ts +9 -0
  64. package/dist/core/src/components/common/useDataTableController.d.ts +45 -0
  65. package/dist/core/src/components/common/useDebouncedData.d.ts +9 -0
  66. package/dist/core/src/components/common/useScrollRestoration.d.ts +14 -0
  67. package/dist/core/src/components/index.d.ts +16 -0
  68. package/dist/core/src/contexts/AdminModeController.d.ts +4 -0
  69. package/dist/core/src/contexts/AnalyticsContext.d.ts +3 -0
  70. package/dist/core/src/contexts/AuthControllerContext.d.ts +3 -0
  71. package/dist/core/src/contexts/CustomizationControllerContext.d.ts +3 -0
  72. package/dist/core/src/contexts/DataDriverContext.d.ts +3 -0
  73. package/dist/core/src/contexts/DatabaseAdminContext.d.ts +3 -0
  74. package/dist/core/src/contexts/DialogsProvider.d.ts +4 -0
  75. package/dist/core/src/contexts/EffectiveRoleController.d.ts +4 -0
  76. package/dist/core/src/contexts/InternalUserManagementContext.d.ts +3 -0
  77. package/dist/core/src/contexts/ModeController.d.ts +4 -0
  78. package/dist/core/src/contexts/RebaseClientInstanceContext.d.ts +6 -0
  79. package/dist/core/src/contexts/RebaseDataContext.d.ts +3 -0
  80. package/dist/core/src/contexts/SnackbarProvider.d.ts +2 -0
  81. package/dist/core/src/contexts/StorageSourceContext.d.ts +3 -0
  82. package/dist/core/src/contexts/UserConfigurationPersistenceContext.d.ts +3 -0
  83. package/dist/core/src/contexts/index.d.ts +13 -0
  84. package/dist/core/src/core/PluginLifecycleManager.d.ts +17 -0
  85. package/dist/core/src/core/PluginProviderStack.d.ts +21 -0
  86. package/dist/core/src/core/Rebase.d.ts +14 -0
  87. package/dist/core/src/core/RebaseProps.d.ts +136 -0
  88. package/dist/core/src/core/RebaseRouter.d.ts +4 -0
  89. package/dist/core/src/core/RebaseRoutes.d.ts +17 -0
  90. package/dist/core/src/core/index.d.ts +4 -0
  91. package/dist/core/src/hooks/ApiConfigContext.d.ts +24 -0
  92. package/dist/core/src/hooks/data/delete.d.ts +31 -0
  93. package/dist/core/src/hooks/data/save.d.ts +34 -0
  94. package/dist/core/src/hooks/data/useCollectionFetch.d.ts +51 -0
  95. package/dist/core/src/hooks/data/useData.d.ts +13 -0
  96. package/dist/core/src/hooks/data/useDataOrder.d.ts +12 -0
  97. package/dist/core/src/hooks/data/useEntityFetch.d.ts +38 -0
  98. package/dist/core/src/hooks/data/useRelationSelector.d.ts +52 -0
  99. package/dist/core/src/hooks/data/useUserSelector.d.ts +31 -0
  100. package/dist/core/src/hooks/index.d.ts +37 -0
  101. package/dist/core/src/hooks/useAdminModeController.d.ts +19 -0
  102. package/dist/core/src/hooks/useAnalyticsController.d.ts +5 -0
  103. package/dist/core/src/hooks/useAuthController.d.ts +11 -0
  104. package/dist/core/src/hooks/useAuthSubscription.d.ts +2 -0
  105. package/dist/core/src/hooks/useBackendStorageSource.d.ts +30 -0
  106. package/dist/core/src/hooks/useBridgeRegistration.d.ts +18 -0
  107. package/dist/core/src/hooks/useBrowserTitleAndIcon.d.ts +6 -0
  108. package/dist/core/src/hooks/useBuildAdminModeController.d.ts +6 -0
  109. package/dist/core/src/hooks/useBuildEffectiveRoleController.d.ts +8 -0
  110. package/dist/core/src/hooks/useBuildLocalConfigurationPersistence.d.ts +2 -0
  111. package/dist/core/src/hooks/useBuildModeController.d.ts +6 -0
  112. package/dist/core/src/hooks/useClipboard.d.ts +57 -0
  113. package/dist/core/src/hooks/useCollapsedGroups.d.ts +12 -0
  114. package/dist/core/src/hooks/useCustomizationController.d.ts +11 -0
  115. package/dist/core/src/hooks/useDialogsController.d.ts +11 -0
  116. package/dist/core/src/hooks/useEffectiveRoleController.d.ts +7 -0
  117. package/dist/core/src/hooks/useInternalUserManagementController.d.ts +12 -0
  118. package/dist/core/src/hooks/useLargeLayout.d.ts +1 -0
  119. package/dist/core/src/hooks/useModeController.d.ts +19 -0
  120. package/dist/core/src/hooks/usePermissions.d.ts +12 -0
  121. package/dist/core/src/hooks/useRebaseClient.d.ts +5 -0
  122. package/dist/core/src/hooks/useRebaseContext.d.ts +11 -0
  123. package/dist/core/src/hooks/useRebaseRegistry.d.ts +34 -0
  124. package/dist/core/src/hooks/useSlot.d.ts +18 -0
  125. package/dist/core/src/hooks/useSnackbarController.d.ts +20 -0
  126. package/dist/core/src/hooks/useStorageSource.d.ts +7 -0
  127. package/dist/core/src/hooks/useStudioBridge.d.ts +91 -0
  128. package/dist/core/src/hooks/useTranslation.d.ts +17 -0
  129. package/dist/core/src/hooks/useUnsavedChangesDialog.d.ts +12 -0
  130. package/dist/core/src/hooks/useUserConfigurationPersistence.d.ts +8 -0
  131. package/dist/core/src/hooks/useValidateAuthenticator.d.ts +21 -0
  132. package/dist/core/src/i18n/RebaseI18nProvider.d.ts +33 -0
  133. package/dist/core/src/index.d.ts +15 -0
  134. package/dist/core/src/internal/common.d.ts +3 -0
  135. package/dist/core/src/internal/useRestoreScroll.d.ts +6 -0
  136. package/dist/core/src/locales/de.d.ts +2 -0
  137. package/dist/core/src/locales/en.d.ts +10 -0
  138. package/dist/core/src/locales/es.d.ts +10 -0
  139. package/dist/core/src/locales/fr.d.ts +2 -0
  140. package/dist/core/src/locales/hi.d.ts +2 -0
  141. package/dist/core/src/locales/it.d.ts +2 -0
  142. package/dist/core/src/locales/pt.d.ts +7 -0
  143. package/dist/core/src/util/constants.d.ts +1 -0
  144. package/dist/core/src/util/createFormexStub.d.ts +2 -0
  145. package/dist/core/src/util/entity_cache.d.ts +27 -0
  146. package/dist/core/src/util/enums.d.ts +5 -0
  147. package/dist/core/src/util/icon_list.d.ts +5 -0
  148. package/dist/core/src/util/icon_synonyms.d.ts +1 -0
  149. package/dist/core/src/util/icons.d.ts +20 -0
  150. package/dist/core/src/util/index.d.ts +10 -0
  151. package/dist/core/src/util/previews.d.ts +4 -0
  152. package/dist/core/src/util/useStorageUploadController.d.ts +38 -0
  153. package/dist/core/src/util/useTraceUpdate.d.ts +2 -0
  154. package/dist/formex/src/Field.d.ts +52 -0
  155. package/dist/formex/src/Formex.d.ts +7 -0
  156. package/dist/formex/src/index.d.ts +5 -0
  157. package/dist/formex/src/types.d.ts +40 -0
  158. package/dist/formex/src/useCreateFormex.d.ts +14 -0
  159. package/dist/formex/src/utils.d.ts +16 -0
  160. package/dist/index.es.js +726 -0
  161. package/dist/index.es.js.map +1 -0
  162. package/dist/index.umd.js +9647 -0
  163. package/dist/index.umd.js.map +1 -0
  164. package/dist/studio/src/components/ApiExplorer/ApiExplorer.d.ts +9 -0
  165. package/dist/studio/src/components/ApiExplorer/EndpointDetail.d.ts +9 -0
  166. package/dist/studio/src/components/ApiExplorer/TryItPanel.d.ts +15 -0
  167. package/dist/studio/src/components/ApiExplorer/parseSpec.d.ts +16 -0
  168. package/dist/studio/src/components/ApiExplorer/types.d.ts +90 -0
  169. package/dist/studio/src/components/AuthSimulationSelector.d.ts +11 -0
  170. package/dist/studio/src/components/Branches/BranchesView.d.ts +1 -0
  171. package/dist/studio/src/components/CronJobs/CronJobsView.d.ts +1 -0
  172. package/dist/studio/src/components/JSEditor/JSEditor.d.ts +1 -0
  173. package/dist/studio/src/components/JSEditor/JSEditorSidebar.d.ts +21 -0
  174. package/dist/studio/src/components/JSEditor/JSMonacoEditor.d.ts +18 -0
  175. package/dist/studio/src/components/RLSEditor/PolicyEditor.d.ts +9 -0
  176. package/dist/studio/src/components/RLSEditor/RLSEditor.d.ts +19 -0
  177. package/dist/studio/src/components/RLSEditor/index.d.ts +1 -0
  178. package/dist/studio/src/components/RebaseStudio.d.ts +2 -0
  179. package/dist/studio/src/components/SQLEditor/ExplainVisualizer.d.ts +24 -0
  180. package/dist/studio/src/components/SQLEditor/MonacoEditor.d.ts +17 -0
  181. package/dist/studio/src/components/SQLEditor/SQLEditor.d.ts +11 -0
  182. package/dist/studio/src/components/SQLEditor/SQLEditorSidebar.d.ts +21 -0
  183. package/dist/studio/src/components/SQLEditor/SchemaBrowser.d.ts +8 -0
  184. package/dist/studio/src/components/SchemaVisualizer/RelationEdge.d.ts +3 -0
  185. package/dist/studio/src/components/SchemaVisualizer/SchemaVisualizer.d.ts +2 -0
  186. package/dist/studio/src/components/SchemaVisualizer/TableNode.d.ts +3 -0
  187. package/dist/studio/src/components/SchemaVisualizer/index.d.ts +5 -0
  188. package/dist/studio/src/components/SchemaVisualizer/schema-visualizer.utils.d.ts +42 -0
  189. package/dist/studio/src/components/SchemaVisualizer/useSchemaGraph.d.ts +37 -0
  190. package/dist/studio/src/components/StorageView/StorageView.d.ts +1 -0
  191. package/dist/studio/src/components/StudioHomePage.d.ts +9 -0
  192. package/dist/studio/src/index.d.ts +4 -0
  193. package/dist/studio/src/utils/entities.d.ts +0 -0
  194. package/dist/studio/src/utils/pgColumnToProperty.d.ts +6 -0
  195. package/dist/studio/src/utils/sql_utils.d.ts +52 -0
  196. package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
  197. package/dist/types/src/controllers/auth.d.ts +119 -0
  198. package/dist/types/src/controllers/client.d.ts +170 -0
  199. package/dist/types/src/controllers/collection_registry.d.ts +45 -0
  200. package/dist/types/src/controllers/customization_controller.d.ts +60 -0
  201. package/dist/types/src/controllers/data.d.ts +168 -0
  202. package/dist/types/src/controllers/data_driver.d.ts +160 -0
  203. package/dist/types/src/controllers/database_admin.d.ts +11 -0
  204. package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
  205. package/dist/types/src/controllers/effective_role.d.ts +4 -0
  206. package/dist/types/src/controllers/email.d.ts +34 -0
  207. package/dist/types/src/controllers/index.d.ts +18 -0
  208. package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
  209. package/dist/types/src/controllers/navigation.d.ts +213 -0
  210. package/dist/types/src/controllers/registry.d.ts +54 -0
  211. package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
  212. package/dist/types/src/controllers/side_entity_controller.d.ts +90 -0
  213. package/dist/types/src/controllers/snackbar.d.ts +24 -0
  214. package/dist/types/src/controllers/storage.d.ts +171 -0
  215. package/dist/types/src/index.d.ts +4 -0
  216. package/dist/types/src/rebase_context.d.ts +105 -0
  217. package/dist/types/src/types/backend.d.ts +536 -0
  218. package/dist/types/src/types/builders.d.ts +15 -0
  219. package/dist/types/src/types/chips.d.ts +5 -0
  220. package/dist/types/src/types/collections.d.ts +856 -0
  221. package/dist/types/src/types/cron.d.ts +102 -0
  222. package/dist/types/src/types/data_source.d.ts +64 -0
  223. package/dist/types/src/types/entities.d.ts +145 -0
  224. package/dist/types/src/types/entity_actions.d.ts +98 -0
  225. package/dist/types/src/types/entity_callbacks.d.ts +173 -0
  226. package/dist/types/src/types/entity_link_builder.d.ts +7 -0
  227. package/dist/types/src/types/entity_overrides.d.ts +10 -0
  228. package/dist/types/src/types/entity_views.d.ts +61 -0
  229. package/dist/types/src/types/export_import.d.ts +21 -0
  230. package/dist/types/src/types/index.d.ts +23 -0
  231. package/dist/types/src/types/locales.d.ts +4 -0
  232. package/dist/types/src/types/modify_collections.d.ts +5 -0
  233. package/dist/types/src/types/plugins.d.ts +279 -0
  234. package/dist/types/src/types/properties.d.ts +1176 -0
  235. package/dist/types/src/types/property_config.d.ts +70 -0
  236. package/dist/types/src/types/relations.d.ts +336 -0
  237. package/dist/types/src/types/slots.d.ts +252 -0
  238. package/dist/types/src/types/translations.d.ts +870 -0
  239. package/dist/types/src/types/user_management_delegate.d.ts +121 -0
  240. package/dist/types/src/types/websockets.d.ts +78 -0
  241. package/dist/types/src/users/index.d.ts +2 -0
  242. package/dist/types/src/users/roles.d.ts +22 -0
  243. package/dist/types/src/users/user.d.ts +46 -0
  244. package/dist/ui/src/components/Alert.d.ts +12 -0
  245. package/dist/ui/src/components/Autocomplete.d.ts +21 -0
  246. package/dist/ui/src/components/Avatar.d.ts +11 -0
  247. package/dist/ui/src/components/Badge.d.ts +8 -0
  248. package/dist/ui/src/components/BooleanSwitch.d.ts +14 -0
  249. package/dist/ui/src/components/BooleanSwitchWithLabel.d.ts +17 -0
  250. package/dist/ui/src/components/Button.d.ts +14 -0
  251. package/dist/ui/src/components/Card.d.ts +9 -0
  252. package/dist/ui/src/components/CenteredView.d.ts +9 -0
  253. package/dist/ui/src/components/Checkbox.d.ts +13 -0
  254. package/dist/ui/src/components/Chip.d.ts +26 -0
  255. package/dist/ui/src/components/CircularProgress.d.ts +5 -0
  256. package/dist/ui/src/components/CircularProgressCenter.d.ts +11 -0
  257. package/dist/ui/src/components/Collapse.d.ts +9 -0
  258. package/dist/ui/src/components/ColorPicker.d.ts +30 -0
  259. package/dist/ui/src/components/Container.d.ts +8 -0
  260. package/dist/ui/src/components/DateTimeField.d.ts +24 -0
  261. package/dist/ui/src/components/DebouncedTextField.d.ts +2 -0
  262. package/dist/ui/src/components/Dialog.d.ts +39 -0
  263. package/dist/ui/src/components/DialogActions.d.ts +7 -0
  264. package/dist/ui/src/components/DialogContent.d.ts +7 -0
  265. package/dist/ui/src/components/DialogTitle.d.ts +10 -0
  266. package/dist/ui/src/components/ErrorBoundary.d.ts +11 -0
  267. package/dist/ui/src/components/ExpandablePanel.d.ts +12 -0
  268. package/dist/ui/src/components/FileUpload.d.ts +23 -0
  269. package/dist/ui/src/components/IconButton.d.ts +12 -0
  270. package/dist/ui/src/components/InfoLabel.d.ts +5 -0
  271. package/dist/ui/src/components/InputLabel.d.ts +11 -0
  272. package/dist/ui/src/components/Label.d.ts +7 -0
  273. package/dist/ui/src/components/LoadingButton.d.ts +7 -0
  274. package/dist/ui/src/components/Markdown.d.ts +10 -0
  275. package/dist/ui/src/components/Menu.d.ts +23 -0
  276. package/dist/ui/src/components/Menubar.d.ts +80 -0
  277. package/dist/ui/src/components/MultiSelect.d.ts +48 -0
  278. package/dist/ui/src/components/Paper.d.ts +6 -0
  279. package/dist/ui/src/components/Popover.d.ts +24 -0
  280. package/dist/ui/src/components/RadioGroup.d.ts +28 -0
  281. package/dist/ui/src/components/ResizablePanels.d.ts +18 -0
  282. package/dist/ui/src/components/SearchBar.d.ts +22 -0
  283. package/dist/ui/src/components/Select.d.ts +43 -0
  284. package/dist/ui/src/components/Separator.d.ts +5 -0
  285. package/dist/ui/src/components/Sheet.d.ts +22 -0
  286. package/dist/ui/src/components/Skeleton.d.ts +6 -0
  287. package/dist/ui/src/components/Slider.d.ts +21 -0
  288. package/dist/ui/src/components/Table.d.ts +34 -0
  289. package/dist/ui/src/components/Tabs.d.ts +19 -0
  290. package/dist/ui/src/components/TextField.d.ts +58 -0
  291. package/dist/ui/src/components/TextareaAutosize.d.ts +43 -0
  292. package/dist/ui/src/components/ToggleButtonGroup.d.ts +30 -0
  293. package/dist/ui/src/components/Tooltip.d.ts +19 -0
  294. package/dist/ui/src/components/Typography.d.ts +36 -0
  295. package/dist/ui/src/components/VirtualTable/VirtualTable.d.ts +11 -0
  296. package/dist/ui/src/components/VirtualTable/VirtualTableCell.d.ts +21 -0
  297. package/dist/ui/src/components/VirtualTable/VirtualTableHeader.d.ts +29 -0
  298. package/dist/ui/src/components/VirtualTable/VirtualTableHeaderRow.d.ts +2 -0
  299. package/dist/ui/src/components/VirtualTable/VirtualTableProps.d.ts +243 -0
  300. package/dist/ui/src/components/VirtualTable/VirtualTableRow.d.ts +3 -0
  301. package/dist/ui/src/components/VirtualTable/index.d.ts +3 -0
  302. package/dist/ui/src/components/VirtualTable/types.d.ts +38 -0
  303. package/dist/ui/src/components/common/SelectInputLabel.d.ts +5 -0
  304. package/dist/ui/src/components/index.d.ts +53 -0
  305. package/dist/ui/src/hooks/PortalContainerContext.d.ts +31 -0
  306. package/dist/ui/src/hooks/index.d.ts +6 -0
  307. package/dist/ui/src/hooks/useDebounceCallback.d.ts +1 -0
  308. package/dist/ui/src/hooks/useDebounceValue.d.ts +1 -0
  309. package/dist/ui/src/hooks/useDebouncedCallback.d.ts +1 -0
  310. package/dist/ui/src/hooks/useInjectStyles.d.ts +7 -0
  311. package/dist/ui/src/hooks/useOutsideAlerter.d.ts +5 -0
  312. package/dist/ui/src/icons/GitHubIcon.d.ts +2 -0
  313. package/dist/ui/src/icons/HandleIcon.d.ts +1 -0
  314. package/dist/ui/src/icons/Icon.d.ts +20 -0
  315. package/dist/ui/src/icons/cool_icon_keys.d.ts +1 -0
  316. package/dist/ui/src/icons/icon_keys.d.ts +1 -0
  317. package/dist/ui/src/icons/index.d.ts +6 -0
  318. package/dist/ui/src/index.d.ts +5 -0
  319. package/dist/ui/src/styles.d.ts +12 -0
  320. package/dist/ui/src/util/chip_colors.d.ts +4 -0
  321. package/dist/ui/src/util/cls.d.ts +2 -0
  322. package/dist/ui/src/util/debounce.d.ts +10 -0
  323. package/dist/ui/src/util/hash.d.ts +1 -0
  324. package/dist/ui/src/util/index.d.ts +4 -0
  325. package/dist/ui/src/util/key_to_icon_component.d.ts +1 -0
  326. package/package.json +84 -0
  327. package/src/components/ApiExplorer/ApiExplorer.tsx +290 -0
  328. package/src/components/ApiExplorer/EndpointDetail.tsx +271 -0
  329. package/src/components/ApiExplorer/TryItPanel.tsx +510 -0
  330. package/src/components/ApiExplorer/parseSpec.ts +104 -0
  331. package/src/components/ApiExplorer/types.ts +84 -0
  332. package/src/components/AuthSimulationSelector.tsx +77 -0
  333. package/src/components/Branches/BranchesView.tsx +370 -0
  334. package/src/components/CronJobs/CronJobsView.tsx +346 -0
  335. package/src/components/JSEditor/JSEditor.tsx +1033 -0
  336. package/src/components/JSEditor/JSEditorSidebar.tsx +340 -0
  337. package/src/components/JSEditor/JSMonacoEditor.tsx +390 -0
  338. package/src/components/RLSEditor/PolicyEditor.tsx +444 -0
  339. package/src/components/RLSEditor/RLSEditor.tsx +692 -0
  340. package/src/components/RLSEditor/index.ts +1 -0
  341. package/src/components/RebaseStudio.tsx +121 -0
  342. package/src/components/SQLEditor/ExplainVisualizer.tsx +128 -0
  343. package/src/components/SQLEditor/MonacoEditor.tsx +203 -0
  344. package/src/components/SQLEditor/SQLEditor.tsx +1419 -0
  345. package/src/components/SQLEditor/SQLEditorSidebar.tsx +174 -0
  346. package/src/components/SQLEditor/SchemaBrowser.tsx +158 -0
  347. package/src/components/SchemaVisualizer/RelationEdge.tsx +102 -0
  348. package/src/components/SchemaVisualizer/SchemaVisualizer.tsx +665 -0
  349. package/src/components/SchemaVisualizer/TableNode.tsx +257 -0
  350. package/src/components/SchemaVisualizer/index.ts +5 -0
  351. package/src/components/SchemaVisualizer/schema-visualizer.utils.ts +140 -0
  352. package/src/components/SchemaVisualizer/useSchemaGraph.ts +397 -0
  353. package/src/components/StorageView/StorageView.tsx +1035 -0
  354. package/src/components/StudioHomePage.tsx +357 -0
  355. package/src/index.ts +31 -0
  356. package/src/utils/entities.ts +2 -0
  357. package/src/utils/pgColumnToProperty.test.ts +401 -0
  358. package/src/utils/pgColumnToProperty.ts +275 -0
  359. package/src/utils/sql_utils.test.ts +265 -0
  360. package/src/utils/sql_utils.ts +291 -0
  361. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,510 @@
1
+ import React, { useState, useCallback, useMemo, useEffect } from "react";
2
+ import { Typography, Button, cls, defaultBorderMixin, iconSize } from "@rebasepro/ui";
3
+ import { LoaderIcon, SendIcon, PlusIcon, XIcon } from "lucide-react";
4
+ import { useRebaseContext, UserSelectPopover, SelectableUser } from "@rebasepro/core";
5
+ import { AuthSimulationSelector } from "../AuthSimulationSelector";
6
+ import type { ParsedEndpoint } from "./types";
7
+ import type { User } from "@rebasepro/types";
8
+
9
+ interface TryItPanelProps {
10
+ endpoint: ParsedEndpoint;
11
+ apiUrl: string;
12
+ getAuthToken: () => Promise<string | null | undefined>;
13
+ user: User | null;
14
+ basePath?: string;
15
+ }
16
+
17
+ /**
18
+ * Interactive "Try It" panel that lets the user execute API requests
19
+ * using their current JWT token directly from the Studio.
20
+ */
21
+ export function TryItPanel({ endpoint, apiUrl, getAuthToken, user, basePath = "" }: TryItPanelProps) {
22
+ const storageKey = `rebase_apiexplorer_${endpoint.method}_${endpoint.path}`;
23
+
24
+ const [pathParams, setPathParams] = useState<Record<string, string>>(() => {
25
+ try { const v = localStorage.getItem(`${storageKey}_path`); if (v) return JSON.parse(v); } catch {}
26
+ return {};
27
+ });
28
+ const [queryParams, setQueryParams] = useState<Record<string, string>>(() => {
29
+ try { const v = localStorage.getItem(`${storageKey}_query`); if (v) return JSON.parse(v); } catch {}
30
+ return {};
31
+ });
32
+ const [customHeaders, setCustomHeaders] = useState<Array<{ key: string; value: string }>>(() => {
33
+ try { const v = localStorage.getItem(`${storageKey}_headers`); if (v) return JSON.parse(v); } catch {}
34
+ return [{ key: "rebase-branch", value: "" }];
35
+ });
36
+ const [body, setBody] = useState(() => {
37
+ try { const v = localStorage.getItem(`${storageKey}_body`); if (v) return JSON.parse(v); } catch {}
38
+ return buildBodyTemplate(endpoint);
39
+ });
40
+ const [response, setResponse] = useState<{ status: number; statusText: string; body: string; time: number } | null>(
41
+ null
42
+ );
43
+ const [loading, setLoading] = useState(false);
44
+ const [authMode, setAuthMode] = useState<"jwt" | "none">("jwt");
45
+ const [validationError, setValidationError] = useState<string | null>(null);
46
+
47
+ const rebaseContext = useRebaseContext();
48
+ const userManagement = rebaseContext.userManagement;
49
+ const currentUser = rebaseContext.authController?.user;
50
+
51
+ const users = useMemo((): SelectableUser[] => {
52
+ const managed = (userManagement?.users ?? []).map(u => ({
53
+ uid: u.uid,
54
+ displayName: u.displayName,
55
+ email: u.email,
56
+ photoURL: u.photoURL,
57
+ roles: u.roles
58
+ }));
59
+ if (currentUser && !managed.some(u => u.uid === currentUser.uid)) {
60
+ managed.unshift({
61
+ uid: currentUser.uid,
62
+ displayName: currentUser.displayName,
63
+ email: currentUser.email,
64
+ photoURL: currentUser.photoURL,
65
+ roles: currentUser.roles
66
+ });
67
+ }
68
+ return managed;
69
+ }, [userManagement?.users, currentUser]);
70
+
71
+ const currentSelectableUser = useMemo((): SelectableUser | null => {
72
+ if (!currentUser) return null;
73
+ return {
74
+ uid: currentUser.uid,
75
+ displayName: currentUser.displayName,
76
+ email: currentUser.email,
77
+ photoURL: currentUser.photoURL,
78
+ roles: currentUser.roles
79
+ };
80
+ }, [currentUser]);
81
+
82
+ const [selectedUser, setSelectedUser] = useState<SelectableUser | null>(null);
83
+
84
+ useEffect(() => {
85
+ localStorage.setItem(`${storageKey}_path`, JSON.stringify(pathParams));
86
+ localStorage.setItem(`${storageKey}_query`, JSON.stringify(queryParams));
87
+ localStorage.setItem(`${storageKey}_headers`, JSON.stringify(customHeaders));
88
+ localStorage.setItem(`${storageKey}_body`, JSON.stringify(body));
89
+ }, [storageKey, pathParams, queryParams, customHeaders, body]);
90
+
91
+ // Build the final URL
92
+ const resolvedUrl = useMemo(() => {
93
+ const base = basePath.startsWith("/") ? basePath : `/${basePath}`;
94
+ const cleanBase = base === "/" ? "" : base;
95
+ let url = `${apiUrl.replace(/\/+$/, "")}${cleanBase}${endpoint.path}`;
96
+ // Replace path params
97
+ for (const [key, val] of Object.entries(pathParams)) {
98
+ url = url.replace(`{${key}}`, encodeURIComponent(val));
99
+ }
100
+ // Append query params
101
+ const qp = Object.entries(queryParams).filter(([, v]) => v.trim() !== "");
102
+ if (qp.length > 0) {
103
+ url += "?" + qp.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&");
104
+ }
105
+ return url;
106
+ }, [apiUrl, basePath, endpoint.path, pathParams, queryParams]);
107
+
108
+ const pathParamDefs = endpoint.parameters.filter((p) => p.in === "path");
109
+ const queryParamDefs = endpoint.parameters.filter((p) => p.in === "query");
110
+ const hasBody = ["post", "put", "patch"].includes(endpoint.method);
111
+
112
+ const execute = useCallback(async () => {
113
+ setValidationError(null);
114
+ if (hasBody && body.trim()) {
115
+ try {
116
+ JSON.parse(body);
117
+ } catch (err: any) {
118
+ setValidationError(`Invalid JSON: ${err.message}`);
119
+ return;
120
+ }
121
+ }
122
+
123
+ setLoading(true);
124
+ setResponse(null);
125
+ const start = performance.now();
126
+
127
+ try {
128
+ const headers: Record<string, string> = { "Content-Type": "application/json" };
129
+
130
+ for (const h of customHeaders) {
131
+ if (h.key.trim()) headers[h.key.trim()] = h.value;
132
+ }
133
+
134
+ if (authMode === "jwt") {
135
+ const token = await getAuthToken();
136
+ if (token) headers["Authorization"] = `Bearer ${token}`;
137
+ if (selectedUser && selectedUser.uid !== currentUser?.uid) {
138
+ headers["x-rebase-impersonate"] = selectedUser.uid;
139
+ }
140
+ }
141
+
142
+ const res = await fetch(resolvedUrl, {
143
+ method: endpoint.method.toUpperCase(),
144
+ headers,
145
+ body: hasBody && body.trim() ? body : undefined
146
+ });
147
+
148
+ const elapsed = Math.round(performance.now() - start);
149
+ let text: string;
150
+
151
+ const rawText = await res.text();
152
+ try {
153
+ const json = JSON.parse(rawText);
154
+ text = JSON.stringify(json, null, 2);
155
+ } catch {
156
+ text = rawText;
157
+ }
158
+
159
+ setResponse({ status: res.status,
160
+ statusText: res.statusText,
161
+ body: text,
162
+ time: elapsed });
163
+ } catch (err: any) {
164
+ setResponse({
165
+ status: 0,
166
+ statusText: "Network Error",
167
+ body: err.message ?? "Request failed",
168
+ time: Math.round(performance.now() - start)
169
+ });
170
+ } finally {
171
+ setLoading(false);
172
+ }
173
+ }, [resolvedUrl, endpoint.method, hasBody, body, authMode, getAuthToken, customHeaders, selectedUser, currentUser?.uid]);
174
+
175
+ return (
176
+ <div className="flex flex-col h-full">
177
+ <div className="p-5 space-y-5 overflow-y-auto flex-1">
178
+ {/* Auth Mode */}
179
+ <AuthSimulationSelector
180
+ authMode={authMode}
181
+ setAuthMode={setAuthMode}
182
+ selectedUser={selectedUser}
183
+ setSelectedUser={setSelectedUser}
184
+ users={users}
185
+ loading={userManagement?.loading}
186
+ currentUser={currentSelectableUser}
187
+ />
188
+
189
+ {/* Path Params */}
190
+ {pathParamDefs.length > 0 && (
191
+ <ParamSection
192
+ title="Path Parameters"
193
+ params={pathParamDefs}
194
+ values={pathParams}
195
+ onChange={(k, v) => setPathParams((prev) => ({ ...prev,
196
+ [k]: v }))}
197
+ />
198
+ )}
199
+
200
+ {/* Query Params */}
201
+ {queryParamDefs.length > 0 && (
202
+ <ParamSection
203
+ title="Query Parameters"
204
+ params={queryParamDefs}
205
+ values={queryParams}
206
+ onChange={(k, v) => setQueryParams((prev) => ({ ...prev, [k]: v }))}
207
+ />
208
+ )}
209
+
210
+ {/* Custom Headers */}
211
+ <CustomKeyValueSection
212
+ title="Custom Headers"
213
+ values={customHeaders}
214
+ onChange={(i, k, v) => {
215
+ const next = [...customHeaders];
216
+ next[i] = { key: k, value: v };
217
+ setCustomHeaders(next);
218
+ }}
219
+ onAdd={() => setCustomHeaders((prev) => [...prev, { key: "", value: "" }])}
220
+ onRemove={(i) => {
221
+ const next = [...customHeaders];
222
+ next.splice(i, 1);
223
+ setCustomHeaders(next);
224
+ }}
225
+ />
226
+
227
+ {/* Request Body */}
228
+ {hasBody && (
229
+ <div>
230
+ <Typography
231
+ variant="caption"
232
+ className="text-text-secondary dark:text-text-secondary-dark text-xs font-semibold uppercase tracking-wider mb-2 block"
233
+ >
234
+ Request Body
235
+ </Typography>
236
+ <textarea
237
+ value={body}
238
+ onChange={(e) => { setBody(e.target.value); setValidationError(null); }}
239
+ rows={10}
240
+ spellCheck={false}
241
+ className={cls(
242
+ "w-full font-mono text-xs p-3 rounded-lg resize-y",
243
+ "bg-surface-50 dark:bg-surface-900",
244
+ validationError ? "border-red-500 focus:ring-red-500/30" : cls("border focus:ring-primary/30 dark:focus:ring-primary-dark/30", defaultBorderMixin),
245
+ "text-text-primary dark:text-text-primary-dark",
246
+ "focus:outline-none focus:ring-2",
247
+ "transition-all"
248
+ )}
249
+ />
250
+ {validationError && (
251
+ <Typography variant="caption" className="text-red-500 mt-1 block text-xs">
252
+ {validationError}
253
+ </Typography>
254
+ )}
255
+ </div>
256
+ )}
257
+
258
+ {/* URL Preview */}
259
+ <div className="rounded-lg bg-surface-100 dark:bg-surface-900 p-3">
260
+ <Typography
261
+ variant="caption"
262
+ className="text-text-secondary dark:text-text-secondary-dark text-[10px] uppercase tracking-wider block mb-1"
263
+ >
264
+ Request URL
265
+ </Typography>
266
+ <code className="text-xs font-mono text-text-primary dark:text-text-primary-dark break-all">
267
+ {resolvedUrl}
268
+ </code>
269
+ </div>
270
+
271
+ {/* Execute Button */}
272
+ <Button variant="filled" onClick={execute} disabled={loading} className="w-full">
273
+ {loading ? (
274
+ <span className="flex items-center gap-2">
275
+ <LoaderIcon size={iconSize.small} className="animate-spin" />
276
+ Sending…
277
+ </span>
278
+ ) : (
279
+ <span className="flex items-center gap-2">
280
+ <SendIcon size={iconSize.small} />
281
+ Send Request
282
+ </span>
283
+ )}
284
+ </Button>
285
+
286
+ {/* Response */}
287
+ {response && (
288
+ <div className={cls("rounded-lg border overflow-hidden", defaultBorderMixin)}>
289
+ <div
290
+ className={cls(
291
+ "flex items-center justify-between px-4 py-2.5",
292
+ "bg-surface-50 dark:bg-surface-900/50"
293
+ )}
294
+ >
295
+ <div className="flex items-center gap-3">
296
+ <ResponseBadge status={response.status}/>
297
+ <Typography
298
+ variant="caption"
299
+ className="text-text-secondary dark:text-text-secondary-dark text-xs"
300
+ >
301
+ {response.statusText}
302
+ </Typography>
303
+ </div>
304
+ <Typography
305
+ variant="caption"
306
+ className="text-text-secondary dark:text-text-secondary-dark text-xs font-mono"
307
+ >
308
+ {response.time}ms
309
+ </Typography>
310
+ </div>
311
+ <pre
312
+ className={cls(
313
+ "p-4 text-xs font-mono overflow-auto max-h-96",
314
+ "bg-surface-950 text-emerald-400",
315
+ "dark:bg-surface-900 dark:text-emerald-400"
316
+ )}
317
+ >
318
+ {response.body}
319
+ </pre>
320
+ </div>
321
+ )}
322
+ </div>
323
+ </div>
324
+ );
325
+ }
326
+
327
+ /* ── Param Section ────────────────────────────────────────────────── */
328
+
329
+ function ParamSection({
330
+ title,
331
+ params,
332
+ values,
333
+ onChange
334
+ }: {
335
+ title: string;
336
+ params: ParsedEndpoint["parameters"];
337
+ values: Record<string, string>;
338
+ onChange: (_key: string, _value: string) => void;
339
+ }) {
340
+ return (
341
+ <div>
342
+ <Typography
343
+ variant="caption"
344
+ className="text-text-secondary dark:text-text-secondary-dark text-xs font-semibold uppercase tracking-wider mb-2 block"
345
+ >
346
+ {title}
347
+ </Typography>
348
+ <div className="space-y-2">
349
+ {params.map((p) => (
350
+ <div key={p.name} className="flex items-center gap-3">
351
+ <label className="w-32 shrink-0">
352
+ <code className="text-xs font-mono font-semibold">{p.name}</code>
353
+ {p.required && <span className="text-red-500 ml-0.5 text-xs">*</span>}
354
+ </label>
355
+ <input
356
+ type="text"
357
+ placeholder={p.description ?? p.name}
358
+ value={values[p.name] ?? ""}
359
+ onChange={(e) => onChange(p.name, e.target.value)}
360
+ className={cls(
361
+ "flex-1 px-3 py-1.5 text-xs rounded-lg font-mono",
362
+ "bg-surface-50 dark:bg-surface-900",
363
+ "border",
364
+ defaultBorderMixin,
365
+ "text-text-primary dark:text-text-primary-dark",
366
+ "placeholder:text-text-secondary/50",
367
+ "focus:outline-none focus:ring-2 focus:ring-primary/30",
368
+ "transition-all"
369
+ )}
370
+ />
371
+ </div>
372
+ ))}
373
+ </div>
374
+ </div>
375
+ );
376
+ }
377
+
378
+ function CustomKeyValueSection({
379
+ title,
380
+ values,
381
+ onChange,
382
+ onAdd,
383
+ onRemove
384
+ }: {
385
+ title: string;
386
+ values: Array<{ key: string; value: string }>;
387
+ onChange: (index: number, key: string, value: string) => void;
388
+ onAdd: () => void;
389
+ onRemove: (index: number) => void;
390
+ }) {
391
+ return (
392
+ <div>
393
+ <div className="flex items-center justify-between mb-2">
394
+ <Typography
395
+ variant="caption"
396
+ className="text-text-secondary dark:text-text-secondary-dark text-xs font-semibold uppercase tracking-wider block"
397
+ >
398
+ {title}
399
+ </Typography>
400
+ <button
401
+ onClick={onAdd}
402
+ className="text-xs text-primary dark:text-primary-dark hover:underline flex items-center gap-1 font-medium"
403
+ >
404
+ <PlusIcon size={iconSize.small} className="mr-1" /> Add Header
405
+ </button>
406
+ </div>
407
+ <div className="space-y-2">
408
+ {values.map((v, i) => (
409
+ <div key={i} className="flex items-center gap-2">
410
+ <input
411
+ type="text"
412
+ placeholder="Header name"
413
+ value={v.key}
414
+ onChange={(e) => onChange(i, e.target.value, v.value)}
415
+ className={cls(
416
+ "w-1/3 px-3 py-1.5 text-xs rounded-lg font-mono",
417
+ "bg-surface-50 dark:bg-surface-900",
418
+ "border",
419
+ defaultBorderMixin,
420
+ "text-text-primary dark:text-text-primary-dark",
421
+ "placeholder:text-text-secondary/50",
422
+ "focus:outline-none focus:ring-2 focus:ring-primary/30",
423
+ "transition-all"
424
+ )}
425
+ />
426
+ <input
427
+ type="text"
428
+ placeholder="Value"
429
+ value={v.value}
430
+ onChange={(e) => onChange(i, v.key, e.target.value)}
431
+ className={cls(
432
+ "flex-1 px-3 py-1.5 text-xs rounded-lg font-mono",
433
+ "bg-surface-50 dark:bg-surface-900",
434
+ "border",
435
+ defaultBorderMixin,
436
+ "text-text-primary dark:text-text-primary-dark",
437
+ "placeholder:text-text-secondary/50",
438
+ "focus:outline-none focus:ring-2 focus:ring-primary/30",
439
+ "transition-all"
440
+ )}
441
+ />
442
+ <button
443
+ onClick={() => onRemove(i)}
444
+ className="p-1.5 text-text-secondary hover:text-red-500 rounded transition-colors flex items-center justify-center shrink-0"
445
+ title="Remove"
446
+ >
447
+ <XIcon size={iconSize.small} />
448
+ </button>
449
+ </div>
450
+ ))}
451
+ {values.length === 0 && (
452
+ <Typography variant="caption" className="text-text-secondary/50 italic text-xs">
453
+ No custom headers added.
454
+ </Typography>
455
+ )}
456
+ </div>
457
+ </div>
458
+ );
459
+ }
460
+
461
+ /* ── Helpers ──────────────────────────────────────────────────────── */
462
+
463
+ function ResponseBadge({ status }: { status: number }) {
464
+ let colorClass = "text-red-500";
465
+ if (status >= 200 && status < 300) colorClass = "text-emerald-500";
466
+ else if (status >= 300 && status < 400) colorClass = "text-blue-500";
467
+ else if (status >= 400 && status < 500) colorClass = "text-amber-500";
468
+
469
+ return (
470
+ <span className={cls("text-xs font-bold font-mono", colorClass)}>
471
+ {status || "ERR"}
472
+ </span>
473
+ );
474
+ }
475
+
476
+ function buildBodyTemplate(endpoint: ParsedEndpoint): string {
477
+ if (!endpoint.requestBody?.content) return "{\n \n}";
478
+ const json = endpoint.requestBody.content["application/json"];
479
+ if (!json?.schema?.properties) return "{\n \n}";
480
+
481
+ const props = json.schema.properties;
482
+ const lines: string[] = ["{"];
483
+ const keys = Object.keys(props);
484
+ keys.forEach((key, i) => {
485
+ const prop = props[key];
486
+ if (prop.readOnly) return;
487
+ const comma = i < keys.length - 1 ? "," : "";
488
+ const val = defaultValue(prop);
489
+ lines.push(` "${key}": ${val}${comma}`);
490
+ });
491
+ lines.push("}");
492
+ return lines.join("\n");
493
+ }
494
+
495
+ function defaultValue(schema: any): string {
496
+ if (schema.enum) return JSON.stringify(schema.enum[0]);
497
+ switch (schema.type) {
498
+ case "string":
499
+ return schema.format === "date-time" ? `"${new Date().toISOString()}"` : '""';
500
+ case "number":
501
+ case "integer":
502
+ return "0";
503
+ case "boolean":
504
+ return "false";
505
+ case "array":
506
+ return "[]";
507
+ default:
508
+ return "null";
509
+ }
510
+ }
@@ -0,0 +1,104 @@
1
+ import type { OpenApiSpec, ParsedEndpoint, EndpointGroup } from "./types";
2
+
3
+ /**
4
+ * Parse an OpenAPI 3.x spec into grouped, sorted endpoints for the sidebar.
5
+ */
6
+ export function parseOpenApiSpec(spec: OpenApiSpec): {
7
+ groups: EndpointGroup[];
8
+ allEndpoints: ParsedEndpoint[];
9
+ } {
10
+ const allEndpoints: ParsedEndpoint[] = [];
11
+ const tagMap = new Map<string, ParsedEndpoint[]>();
12
+
13
+ // Build tag description lookup
14
+ const tagDescriptions = new Map<string, string>();
15
+ for (const t of spec.tags ?? []) {
16
+ tagDescriptions.set(t.name, t.description ?? "");
17
+ }
18
+
19
+ for (const [path, methods] of Object.entries(spec.paths ?? {})) {
20
+ for (const [method, op] of Object.entries(methods)) {
21
+ if (["get", "post", "put", "patch", "delete"].indexOf(method) === -1) continue;
22
+
23
+ const tags = op.tags?.length ? op.tags : ["Other"];
24
+ const shortPath = path.replace(/^\/api\/data/, "");
25
+
26
+ const endpoint: ParsedEndpoint = {
27
+ id: `${method}:${path}`,
28
+ method,
29
+ path,
30
+ shortPath: shortPath || "/",
31
+ summary: op.summary ?? "",
32
+ description: op.description ?? "",
33
+ tags,
34
+ parameters: op.parameters ?? [],
35
+ requestBody: op.requestBody,
36
+ responses: op.responses ?? {},
37
+ security: op.security,
38
+ operationId: op.operationId
39
+ };
40
+
41
+ allEndpoints.push(endpoint);
42
+ for (const tag of tags) {
43
+ if (!tagMap.has(tag)) tagMap.set(tag, []);
44
+ tagMap.get(tag)!.push(endpoint);
45
+ }
46
+ }
47
+ }
48
+
49
+ // Method sort order
50
+ const ORDER: Record<string, number> = { get: 0,
51
+ post: 1,
52
+ put: 2,
53
+ patch: 3,
54
+ delete: 4 };
55
+
56
+ const groups: EndpointGroup[] = [];
57
+ // Sort tags: use spec.tags order if available, else alphabetical
58
+ const tagOrder = (spec.tags ?? []).map((t) => t.name);
59
+ const sortedTags = [...tagMap.keys()].sort((a, b) => {
60
+ const ai = tagOrder.indexOf(a);
61
+ const bi = tagOrder.indexOf(b);
62
+ if (ai !== -1 && bi !== -1) return ai - bi;
63
+ if (ai !== -1) return -1;
64
+ if (bi !== -1) return 1;
65
+ return a.localeCompare(b);
66
+ });
67
+
68
+ for (const tag of sortedTags) {
69
+ const endpoints = tagMap.get(tag)!;
70
+ endpoints.sort((a, b) => {
71
+ const pa = a.path.localeCompare(b.path);
72
+ if (pa !== 0) return pa;
73
+ return (ORDER[a.method] ?? 99) - (ORDER[b.method] ?? 99);
74
+ });
75
+ groups.push({
76
+ tag,
77
+ description: tagDescriptions.get(tag),
78
+ endpoints
79
+ });
80
+ }
81
+
82
+ return { groups,
83
+ allEndpoints };
84
+ }
85
+
86
+ /**
87
+ * Resolve a $ref string (e.g. "#/components/schemas/Author") to a schema name.
88
+ */
89
+ export function resolveRefName(ref: string): string {
90
+ const parts = ref.split("/");
91
+ return parts[parts.length - 1];
92
+ }
93
+
94
+ /**
95
+ * Resolve a $ref to its actual schema from the spec.
96
+ */
97
+ export function resolveRef(spec: OpenApiSpec, ref: string): any {
98
+ const parts = ref.replace("#/", "").split("/");
99
+ let current: any = spec;
100
+ for (const part of parts) {
101
+ current = current?.[part];
102
+ }
103
+ return current ?? {};
104
+ }
@@ -0,0 +1,84 @@
1
+ /** Minimal OpenAPI 3.x types we care about */
2
+ export interface OpenApiSpec {
3
+ openapi: string;
4
+ info: { title: string; version: string; description?: string };
5
+ servers?: { url: string; description?: string }[];
6
+ paths: Record<string, Record<string, OpenApiOperation>>;
7
+ components?: {
8
+ schemas?: Record<string, OpenApiSchema>;
9
+ securitySchemes?: Record<string, any>;
10
+ };
11
+ tags?: { name: string; description?: string }[];
12
+ security?: Record<string, string[]>[];
13
+ }
14
+
15
+ export interface OpenApiOperation {
16
+ operationId?: string;
17
+ summary?: string;
18
+ description?: string;
19
+ tags?: string[];
20
+ parameters?: OpenApiParameter[];
21
+ requestBody?: {
22
+ required?: boolean;
23
+ content?: Record<string, { schema?: OpenApiSchema }>;
24
+ };
25
+ responses?: Record<
26
+ string,
27
+ {
28
+ description?: string;
29
+ content?: Record<string, { schema?: OpenApiSchema }>;
30
+ }
31
+ >;
32
+ security?: Record<string, string[]>[];
33
+ }
34
+
35
+ export interface OpenApiParameter {
36
+ name: string;
37
+ in: "query" | "path" | "header" | "cookie";
38
+ description?: string;
39
+ required?: boolean;
40
+ schema?: OpenApiSchema;
41
+ }
42
+
43
+ export interface OpenApiSchema {
44
+ type?: string;
45
+ format?: string;
46
+ description?: string;
47
+ properties?: Record<string, OpenApiSchema>;
48
+ required?: string[];
49
+ items?: OpenApiSchema;
50
+ enum?: (string | number)[];
51
+ oneOf?: OpenApiSchema[];
52
+ anyOf?: OpenApiSchema[];
53
+ allOf?: OpenApiSchema[];
54
+ $ref?: string;
55
+ readOnly?: boolean;
56
+ minimum?: number;
57
+ maximum?: number;
58
+ maxLength?: number;
59
+ minLength?: number;
60
+ default?: any;
61
+ example?: any;
62
+ additionalProperties?: boolean | OpenApiSchema;
63
+ }
64
+
65
+ export interface ParsedEndpoint {
66
+ id: string;
67
+ method: string;
68
+ path: string;
69
+ shortPath: string;
70
+ summary: string;
71
+ description: string;
72
+ tags: string[];
73
+ parameters: OpenApiParameter[];
74
+ requestBody?: OpenApiOperation["requestBody"];
75
+ responses: NonNullable<OpenApiOperation["responses"]>;
76
+ security?: OpenApiOperation["security"];
77
+ operationId?: string;
78
+ }
79
+
80
+ export interface EndpointGroup {
81
+ tag: string;
82
+ description?: string;
83
+ endpoints: ParsedEndpoint[];
84
+ }