@rebasepro/studio 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/README.md +73 -140
  2. package/dist/ApiExplorer-CdIwR9Ga.js +963 -0
  3. package/dist/ApiExplorer-CdIwR9Ga.js.map +1 -0
  4. package/dist/AuthSimulationSelector-iEZ-Or_1.js +56 -0
  5. package/dist/AuthSimulationSelector-iEZ-Or_1.js.map +1 -0
  6. package/dist/BranchesView-DncIRcZt.js +461 -0
  7. package/dist/BranchesView-DncIRcZt.js.map +1 -0
  8. package/dist/CronJobsView-4gdtJvoe.js +500 -0
  9. package/dist/CronJobsView-4gdtJvoe.js.map +1 -0
  10. package/dist/JSEditor-BhAbEjCP.js +1573 -0
  11. package/dist/JSEditor-BhAbEjCP.js.map +1 -0
  12. package/dist/LogsExplorer-CqtKILj8.js +240 -0
  13. package/dist/LogsExplorer-CqtKILj8.js.map +1 -0
  14. package/dist/MonacoEditor-COZqrIJ1.js +246 -0
  15. package/dist/MonacoEditor-COZqrIJ1.js.map +1 -0
  16. package/dist/RLSEditor-CTxYbBdW.js +1362 -0
  17. package/dist/RLSEditor-CTxYbBdW.js.map +1 -0
  18. package/dist/SQLEditor-BLuq_zDM.js +1964 -0
  19. package/dist/SQLEditor-BLuq_zDM.js.map +1 -0
  20. package/dist/SchemaVisualizer-BJK2u3C0.js +1068 -0
  21. package/dist/SchemaVisualizer-BJK2u3C0.js.map +1 -0
  22. package/dist/StorageView-nDaC2foF.js +1382 -0
  23. package/dist/StorageView-nDaC2foF.js.map +1 -0
  24. package/dist/{studio/src/components → components}/ApiExplorer/ApiExplorer.d.ts +2 -1
  25. package/dist/{studio/src/components → components}/ApiExplorer/EndpointDetail.d.ts +2 -1
  26. package/dist/{studio/src/components → components}/ApiExplorer/TryItPanel.d.ts +2 -1
  27. package/dist/{studio/src/components → components}/AuthSimulationSelector.d.ts +2 -1
  28. package/dist/components/Branches/BranchesView.d.ts +2 -0
  29. package/dist/components/CronJobs/CronJobsView.d.ts +2 -0
  30. package/dist/components/JSEditor/JSEditor.d.ts +2 -0
  31. package/dist/{studio/src/components → components}/JSEditor/JSEditorSidebar.d.ts +2 -1
  32. package/dist/{studio/src/components → components}/JSEditor/JSMonacoEditor.d.ts +2 -1
  33. package/dist/components/LogsExplorer/LogsExplorer.d.ts +2 -0
  34. package/dist/{studio/src/components → components}/RLSEditor/PolicyEditor.d.ts +2 -1
  35. package/dist/{studio/src/components → components}/RLSEditor/RLSEditor.d.ts +2 -7
  36. package/dist/{studio/src/components → components}/SQLEditor/MonacoEditor.d.ts +2 -1
  37. package/dist/{studio/src/components → components}/SQLEditor/SQLEditor.d.ts +2 -1
  38. package/dist/{studio/src/components → components}/SQLEditor/SQLEditorSidebar.d.ts +2 -1
  39. package/dist/{studio/src/components → components}/SQLEditor/SchemaBrowser.d.ts +2 -1
  40. package/dist/{studio/src/components → components}/SchemaVisualizer/RelationEdge.d.ts +1 -1
  41. package/dist/components/SchemaVisualizer/SchemaVisualizer.d.ts +3 -0
  42. package/dist/{studio/src/components → components}/SchemaVisualizer/TableNode.d.ts +1 -1
  43. package/dist/{studio/src/components → components}/SchemaVisualizer/schema-visualizer.utils.d.ts +0 -8
  44. package/dist/components/StorageView/StorageView.d.ts +2 -0
  45. package/dist/{studio/src/components → components}/StudioHomePage.d.ts +1 -1
  46. package/dist/index.es.js +688 -746
  47. package/dist/index.es.js.map +1 -1
  48. package/dist/index.umd.js +10303 -9572
  49. package/dist/index.umd.js.map +1 -1
  50. package/dist/{studio/src/utils → utils}/pgColumnToProperty.d.ts +1 -1
  51. package/package.json +22 -22
  52. package/src/components/ApiExplorer/TryItPanel.tsx +15 -18
  53. package/src/components/CronJobs/CronJobsView.tsx +1 -1
  54. package/src/components/JSEditor/JSEditor.tsx +10 -15
  55. package/src/components/LogsExplorer/LogsExplorer.tsx +6 -3
  56. package/src/components/RLSEditor/PolicyEditor.tsx +0 -1
  57. package/src/components/RLSEditor/RLSEditor.tsx +1 -1
  58. package/src/components/SQLEditor/SQLEditor.tsx +40 -30
  59. package/src/components/SchemaVisualizer/schema-visualizer.utils.ts +3 -3
  60. package/src/components/SchemaVisualizer/useSchemaGraph.ts +2 -2
  61. package/src/components/StorageView/StorageView.tsx +22 -11
  62. package/src/components/StudioHomePage.tsx +51 -15
  63. package/src/utils/parseSpec.test.ts +41 -20
  64. package/src/utils/pgColumnToProperty.ts +23 -20
  65. package/src/utils/sql_utils.ts +1 -1
  66. package/dist/ApiExplorer-CGHEF1uL.js +0 -1052
  67. package/dist/ApiExplorer-CGHEF1uL.js.map +0 -1
  68. package/dist/AuthSimulationSelector-DGoXkWSg.js +0 -105
  69. package/dist/AuthSimulationSelector-DGoXkWSg.js.map +0 -1
  70. package/dist/BranchesView-BiTEwIhd.js +0 -291
  71. package/dist/BranchesView-BiTEwIhd.js.map +0 -1
  72. package/dist/CronJobsView-3PM_qR8v.js +0 -472
  73. package/dist/CronJobsView-3PM_qR8v.js.map +0 -1
  74. package/dist/JSEditor-BCSoElPg.js +0 -1297
  75. package/dist/JSEditor-BCSoElPg.js.map +0 -1
  76. package/dist/LogsExplorer-_4sZadKn.js +0 -162
  77. package/dist/LogsExplorer-_4sZadKn.js.map +0 -1
  78. package/dist/MonacoEditor-CMYEjiRf.js +0 -161
  79. package/dist/MonacoEditor-CMYEjiRf.js.map +0 -1
  80. package/dist/RLSEditor-CHEExeSB.js +0 -1871
  81. package/dist/RLSEditor-CHEExeSB.js.map +0 -1
  82. package/dist/SQLEditor-BC0IOUQu.js +0 -1797
  83. package/dist/SQLEditor-BC0IOUQu.js.map +0 -1
  84. package/dist/SchemaVisualizer-BGpmzyXT.js +0 -1069
  85. package/dist/SchemaVisualizer-BGpmzyXT.js.map +0 -1
  86. package/dist/StorageView-B7AsN2qX.js +0 -869
  87. package/dist/StorageView-B7AsN2qX.js.map +0 -1
  88. package/dist/common/src/collections/CollectionRegistry.d.ts +0 -56
  89. package/dist/common/src/collections/default-collections.d.ts +0 -9
  90. package/dist/common/src/collections/index.d.ts +0 -2
  91. package/dist/common/src/data/buildRebaseData.d.ts +0 -14
  92. package/dist/common/src/data/query_builder.d.ts +0 -55
  93. package/dist/common/src/index.d.ts +0 -4
  94. package/dist/common/src/util/builders.d.ts +0 -57
  95. package/dist/common/src/util/callbacks.d.ts +0 -6
  96. package/dist/common/src/util/collections.d.ts +0 -11
  97. package/dist/common/src/util/common.d.ts +0 -2
  98. package/dist/common/src/util/conditions.d.ts +0 -26
  99. package/dist/common/src/util/entities.d.ts +0 -58
  100. package/dist/common/src/util/enums.d.ts +0 -3
  101. package/dist/common/src/util/index.d.ts +0 -16
  102. package/dist/common/src/util/navigation_from_path.d.ts +0 -34
  103. package/dist/common/src/util/navigation_utils.d.ts +0 -20
  104. package/dist/common/src/util/parent_references_from_path.d.ts +0 -6
  105. package/dist/common/src/util/paths.d.ts +0 -14
  106. package/dist/common/src/util/permissions.d.ts +0 -6
  107. package/dist/common/src/util/references.d.ts +0 -2
  108. package/dist/common/src/util/relations.d.ts +0 -22
  109. package/dist/common/src/util/resolutions.d.ts +0 -72
  110. package/dist/common/src/util/storage.d.ts +0 -24
  111. package/dist/core/src/components/AIIcon.d.ts +0 -16
  112. package/dist/core/src/components/BootstrapAdminBanner.d.ts +0 -4
  113. package/dist/core/src/components/ConfirmationDialog.d.ts +0 -9
  114. package/dist/core/src/components/Debug/UIReferenceView.d.ts +0 -1
  115. package/dist/core/src/components/Debug/UIStyleGuide.d.ts +0 -1
  116. package/dist/core/src/components/ErrorTooltip.d.ts +0 -2
  117. package/dist/core/src/components/ErrorView.d.ts +0 -21
  118. package/dist/core/src/components/LanguageToggle.d.ts +0 -1
  119. package/dist/core/src/components/LoginView/LoginView.d.ts +0 -109
  120. package/dist/core/src/components/LoginView/index.d.ts +0 -2
  121. package/dist/core/src/components/NotFoundPage.d.ts +0 -1
  122. package/dist/core/src/components/RebaseAuth.d.ts +0 -10
  123. package/dist/core/src/components/RebaseLogo.d.ts +0 -7
  124. package/dist/core/src/components/UnsavedChangesDialog.d.ts +0 -9
  125. package/dist/core/src/components/UserDisplay.d.ts +0 -7
  126. package/dist/core/src/components/UserSelectPopover.d.ts +0 -62
  127. package/dist/core/src/components/UserSettingsView.d.ts +0 -1
  128. package/dist/core/src/components/common/index.d.ts +0 -6
  129. package/dist/core/src/components/common/table_height.d.ts +0 -5
  130. package/dist/core/src/components/common/types.d.ts +0 -66
  131. package/dist/core/src/components/common/useColumnsIds.d.ts +0 -9
  132. package/dist/core/src/components/common/useDataTableController.d.ts +0 -45
  133. package/dist/core/src/components/common/useDebouncedData.d.ts +0 -9
  134. package/dist/core/src/components/common/useScrollRestoration.d.ts +0 -14
  135. package/dist/core/src/components/index.d.ts +0 -17
  136. package/dist/core/src/contexts/AdminModeController.d.ts +0 -4
  137. package/dist/core/src/contexts/AnalyticsContext.d.ts +0 -3
  138. package/dist/core/src/contexts/AuthControllerContext.d.ts +0 -3
  139. package/dist/core/src/contexts/CustomizationControllerContext.d.ts +0 -3
  140. package/dist/core/src/contexts/DataDriverContext.d.ts +0 -3
  141. package/dist/core/src/contexts/DatabaseAdminContext.d.ts +0 -3
  142. package/dist/core/src/contexts/DialogsProvider.d.ts +0 -4
  143. package/dist/core/src/contexts/EffectiveRoleController.d.ts +0 -4
  144. package/dist/core/src/contexts/InternalUserManagementContext.d.ts +0 -3
  145. package/dist/core/src/contexts/ModeController.d.ts +0 -4
  146. package/dist/core/src/contexts/RebaseClientInstanceContext.d.ts +0 -6
  147. package/dist/core/src/contexts/RebaseDataContext.d.ts +0 -3
  148. package/dist/core/src/contexts/SnackbarProvider.d.ts +0 -2
  149. package/dist/core/src/contexts/StorageSourceContext.d.ts +0 -3
  150. package/dist/core/src/contexts/UserConfigurationPersistenceContext.d.ts +0 -3
  151. package/dist/core/src/contexts/index.d.ts +0 -13
  152. package/dist/core/src/core/PluginLifecycleManager.d.ts +0 -17
  153. package/dist/core/src/core/PluginProviderStack.d.ts +0 -21
  154. package/dist/core/src/core/Rebase.d.ts +0 -14
  155. package/dist/core/src/core/RebaseProps.d.ts +0 -147
  156. package/dist/core/src/core/RebaseRouter.d.ts +0 -4
  157. package/dist/core/src/core/RebaseRoutes.d.ts +0 -17
  158. package/dist/core/src/core/index.d.ts +0 -4
  159. package/dist/core/src/hooks/ApiConfigContext.d.ts +0 -24
  160. package/dist/core/src/hooks/data/delete.d.ts +0 -31
  161. package/dist/core/src/hooks/data/save.d.ts +0 -34
  162. package/dist/core/src/hooks/data/useCollectionFetch.d.ts +0 -62
  163. package/dist/core/src/hooks/data/useData.d.ts +0 -13
  164. package/dist/core/src/hooks/data/useDataOrder.d.ts +0 -12
  165. package/dist/core/src/hooks/data/useEntityFetch.d.ts +0 -43
  166. package/dist/core/src/hooks/data/useRelationSelector.d.ts +0 -52
  167. package/dist/core/src/hooks/data/useUserSelector.d.ts +0 -31
  168. package/dist/core/src/hooks/index.d.ts +0 -37
  169. package/dist/core/src/hooks/useAdminModeController.d.ts +0 -19
  170. package/dist/core/src/hooks/useAnalyticsController.d.ts +0 -5
  171. package/dist/core/src/hooks/useAuthController.d.ts +0 -11
  172. package/dist/core/src/hooks/useAuthSubscription.d.ts +0 -2
  173. package/dist/core/src/hooks/useBackendStorageSource.d.ts +0 -30
  174. package/dist/core/src/hooks/useBridgeRegistration.d.ts +0 -18
  175. package/dist/core/src/hooks/useBrowserTitleAndIcon.d.ts +0 -6
  176. package/dist/core/src/hooks/useBuildAdminModeController.d.ts +0 -6
  177. package/dist/core/src/hooks/useBuildEffectiveRoleController.d.ts +0 -8
  178. package/dist/core/src/hooks/useBuildLocalConfigurationPersistence.d.ts +0 -2
  179. package/dist/core/src/hooks/useBuildModeController.d.ts +0 -6
  180. package/dist/core/src/hooks/useClipboard.d.ts +0 -57
  181. package/dist/core/src/hooks/useCollapsedGroups.d.ts +0 -27
  182. package/dist/core/src/hooks/useCustomizationController.d.ts +0 -11
  183. package/dist/core/src/hooks/useDialogsController.d.ts +0 -11
  184. package/dist/core/src/hooks/useEffectiveRoleController.d.ts +0 -7
  185. package/dist/core/src/hooks/useInternalUserManagementController.d.ts +0 -12
  186. package/dist/core/src/hooks/useLargeLayout.d.ts +0 -1
  187. package/dist/core/src/hooks/useModeController.d.ts +0 -19
  188. package/dist/core/src/hooks/usePermissions.d.ts +0 -12
  189. package/dist/core/src/hooks/useRebaseClient.d.ts +0 -5
  190. package/dist/core/src/hooks/useRebaseContext.d.ts +0 -11
  191. package/dist/core/src/hooks/useRebaseRegistry.d.ts +0 -34
  192. package/dist/core/src/hooks/useResolvedComponent.d.ts +0 -47
  193. package/dist/core/src/hooks/useSlot.d.ts +0 -18
  194. package/dist/core/src/hooks/useSnackbarController.d.ts +0 -20
  195. package/dist/core/src/hooks/useStorageSource.d.ts +0 -7
  196. package/dist/core/src/hooks/useStudioBridge.d.ts +0 -91
  197. package/dist/core/src/hooks/useTranslation.d.ts +0 -17
  198. package/dist/core/src/hooks/useUnsavedChangesDialog.d.ts +0 -12
  199. package/dist/core/src/hooks/useUserConfigurationPersistence.d.ts +0 -8
  200. package/dist/core/src/i18n/RebaseI18nProvider.d.ts +0 -33
  201. package/dist/core/src/index.d.ts +0 -15
  202. package/dist/core/src/internal/common.d.ts +0 -3
  203. package/dist/core/src/internal/useRestoreScroll.d.ts +0 -6
  204. package/dist/core/src/locales/de.d.ts +0 -2
  205. package/dist/core/src/locales/en.d.ts +0 -10
  206. package/dist/core/src/locales/es.d.ts +0 -10
  207. package/dist/core/src/locales/fr.d.ts +0 -2
  208. package/dist/core/src/locales/hi.d.ts +0 -2
  209. package/dist/core/src/locales/it.d.ts +0 -2
  210. package/dist/core/src/locales/pt.d.ts +0 -7
  211. package/dist/core/src/util/constants.d.ts +0 -1
  212. package/dist/core/src/util/createFormexStub.d.ts +0 -2
  213. package/dist/core/src/util/entity_cache.d.ts +0 -22
  214. package/dist/core/src/util/enums.d.ts +0 -5
  215. package/dist/core/src/util/icon_list.d.ts +0 -5
  216. package/dist/core/src/util/icons.d.ts +0 -20
  217. package/dist/core/src/util/index.d.ts +0 -8
  218. package/dist/core/src/util/previews.d.ts +0 -4
  219. package/dist/core/src/util/useStorageUploadController.d.ts +0 -38
  220. package/dist/formex/src/Field.d.ts +0 -52
  221. package/dist/formex/src/Formex.d.ts +0 -7
  222. package/dist/formex/src/index.d.ts +0 -5
  223. package/dist/formex/src/types.d.ts +0 -40
  224. package/dist/formex/src/useCreateFormex.d.ts +0 -14
  225. package/dist/formex/src/utils.d.ts +0 -16
  226. package/dist/studio/src/components/Branches/BranchesView.d.ts +0 -1
  227. package/dist/studio/src/components/CronJobs/CronJobsView.d.ts +0 -1
  228. package/dist/studio/src/components/JSEditor/JSEditor.d.ts +0 -1
  229. package/dist/studio/src/components/LogsExplorer/LogsExplorer.d.ts +0 -1
  230. package/dist/studio/src/components/SchemaVisualizer/SchemaVisualizer.d.ts +0 -2
  231. package/dist/studio/src/components/SchemaVisualizer/index.d.ts +0 -5
  232. package/dist/studio/src/components/StorageView/StorageView.d.ts +0 -1
  233. package/dist/studio/src/utils/entities.d.ts +0 -0
  234. package/dist/types/src/controllers/analytics_controller.d.ts +0 -7
  235. package/dist/types/src/controllers/auth.d.ts +0 -104
  236. package/dist/types/src/controllers/client.d.ts +0 -168
  237. package/dist/types/src/controllers/collection_registry.d.ts +0 -46
  238. package/dist/types/src/controllers/customization_controller.d.ts +0 -60
  239. package/dist/types/src/controllers/data.d.ts +0 -207
  240. package/dist/types/src/controllers/data_driver.d.ts +0 -218
  241. package/dist/types/src/controllers/database_admin.d.ts +0 -11
  242. package/dist/types/src/controllers/dialogs_controller.d.ts +0 -36
  243. package/dist/types/src/controllers/effective_role.d.ts +0 -4
  244. package/dist/types/src/controllers/email.d.ts +0 -36
  245. package/dist/types/src/controllers/index.d.ts +0 -18
  246. package/dist/types/src/controllers/local_config_persistence.d.ts +0 -20
  247. package/dist/types/src/controllers/navigation.d.ts +0 -225
  248. package/dist/types/src/controllers/registry.d.ts +0 -63
  249. package/dist/types/src/controllers/side_dialogs_controller.d.ts +0 -67
  250. package/dist/types/src/controllers/side_entity_controller.d.ts +0 -97
  251. package/dist/types/src/controllers/snackbar.d.ts +0 -24
  252. package/dist/types/src/controllers/storage.d.ts +0 -171
  253. package/dist/types/src/index.d.ts +0 -4
  254. package/dist/types/src/rebase_context.d.ts +0 -122
  255. package/dist/types/src/types/auth_adapter.d.ts +0 -301
  256. package/dist/types/src/types/backend.d.ts +0 -536
  257. package/dist/types/src/types/backend_hooks.d.ts +0 -172
  258. package/dist/types/src/types/builders.d.ts +0 -15
  259. package/dist/types/src/types/chips.d.ts +0 -5
  260. package/dist/types/src/types/collections.d.ts +0 -941
  261. package/dist/types/src/types/component_ref.d.ts +0 -47
  262. package/dist/types/src/types/cron.d.ts +0 -102
  263. package/dist/types/src/types/data_source.d.ts +0 -64
  264. package/dist/types/src/types/database_adapter.d.ts +0 -94
  265. package/dist/types/src/types/entities.d.ts +0 -145
  266. package/dist/types/src/types/entity_actions.d.ts +0 -104
  267. package/dist/types/src/types/entity_callbacks.d.ts +0 -173
  268. package/dist/types/src/types/entity_link_builder.d.ts +0 -7
  269. package/dist/types/src/types/entity_overrides.d.ts +0 -10
  270. package/dist/types/src/types/entity_views.d.ts +0 -87
  271. package/dist/types/src/types/export_import.d.ts +0 -21
  272. package/dist/types/src/types/formex.d.ts +0 -40
  273. package/dist/types/src/types/index.d.ts +0 -28
  274. package/dist/types/src/types/locales.d.ts +0 -4
  275. package/dist/types/src/types/modify_collections.d.ts +0 -5
  276. package/dist/types/src/types/plugins.d.ts +0 -282
  277. package/dist/types/src/types/properties.d.ts +0 -1181
  278. package/dist/types/src/types/property_config.d.ts +0 -74
  279. package/dist/types/src/types/relations.d.ts +0 -336
  280. package/dist/types/src/types/slots.d.ts +0 -262
  281. package/dist/types/src/types/translations.d.ts +0 -900
  282. package/dist/types/src/types/user_management_delegate.d.ts +0 -86
  283. package/dist/types/src/types/websockets.d.ts +0 -78
  284. package/dist/types/src/users/index.d.ts +0 -1
  285. package/dist/types/src/users/user.d.ts +0 -50
  286. package/dist/ui/src/components/Alert.d.ts +0 -12
  287. package/dist/ui/src/components/Autocomplete.d.ts +0 -21
  288. package/dist/ui/src/components/Avatar.d.ts +0 -11
  289. package/dist/ui/src/components/Badge.d.ts +0 -8
  290. package/dist/ui/src/components/BooleanSwitch.d.ts +0 -14
  291. package/dist/ui/src/components/BooleanSwitchWithLabel.d.ts +0 -17
  292. package/dist/ui/src/components/Button.d.ts +0 -14
  293. package/dist/ui/src/components/Card.d.ts +0 -8
  294. package/dist/ui/src/components/CenteredView.d.ts +0 -9
  295. package/dist/ui/src/components/Checkbox.d.ts +0 -13
  296. package/dist/ui/src/components/Chip.d.ts +0 -26
  297. package/dist/ui/src/components/CircularProgress.d.ts +0 -5
  298. package/dist/ui/src/components/CircularProgressCenter.d.ts +0 -11
  299. package/dist/ui/src/components/Collapse.d.ts +0 -9
  300. package/dist/ui/src/components/ColorPicker.d.ts +0 -30
  301. package/dist/ui/src/components/Container.d.ts +0 -8
  302. package/dist/ui/src/components/DateTimeField.d.ts +0 -24
  303. package/dist/ui/src/components/DebouncedTextField.d.ts +0 -2
  304. package/dist/ui/src/components/Dialog.d.ts +0 -39
  305. package/dist/ui/src/components/DialogActions.d.ts +0 -7
  306. package/dist/ui/src/components/DialogContent.d.ts +0 -7
  307. package/dist/ui/src/components/DialogTitle.d.ts +0 -10
  308. package/dist/ui/src/components/ErrorBoundary.d.ts +0 -33
  309. package/dist/ui/src/components/ExpandablePanel.d.ts +0 -12
  310. package/dist/ui/src/components/FileUpload.d.ts +0 -23
  311. package/dist/ui/src/components/FilterChip.d.ts +0 -34
  312. package/dist/ui/src/components/IconButton.d.ts +0 -12
  313. package/dist/ui/src/components/InfoLabel.d.ts +0 -5
  314. package/dist/ui/src/components/InputLabel.d.ts +0 -11
  315. package/dist/ui/src/components/Label.d.ts +0 -7
  316. package/dist/ui/src/components/LoadingButton.d.ts +0 -7
  317. package/dist/ui/src/components/Markdown.d.ts +0 -10
  318. package/dist/ui/src/components/Menu.d.ts +0 -23
  319. package/dist/ui/src/components/Menubar.d.ts +0 -80
  320. package/dist/ui/src/components/MultiSelect.d.ts +0 -48
  321. package/dist/ui/src/components/Paper.d.ts +0 -6
  322. package/dist/ui/src/components/Popover.d.ts +0 -24
  323. package/dist/ui/src/components/RadioGroup.d.ts +0 -28
  324. package/dist/ui/src/components/ResizablePanels.d.ts +0 -18
  325. package/dist/ui/src/components/SearchBar.d.ts +0 -26
  326. package/dist/ui/src/components/Select.d.ts +0 -43
  327. package/dist/ui/src/components/Separator.d.ts +0 -5
  328. package/dist/ui/src/components/Sheet.d.ts +0 -22
  329. package/dist/ui/src/components/Skeleton.d.ts +0 -6
  330. package/dist/ui/src/components/Slider.d.ts +0 -21
  331. package/dist/ui/src/components/Table.d.ts +0 -34
  332. package/dist/ui/src/components/Tabs.d.ts +0 -19
  333. package/dist/ui/src/components/TextField.d.ts +0 -58
  334. package/dist/ui/src/components/TextareaAutosize.d.ts +0 -43
  335. package/dist/ui/src/components/ToggleButtonGroup.d.ts +0 -30
  336. package/dist/ui/src/components/Tooltip.d.ts +0 -19
  337. package/dist/ui/src/components/Typography.d.ts +0 -36
  338. package/dist/ui/src/components/VirtualTable/VirtualTable.d.ts +0 -11
  339. package/dist/ui/src/components/VirtualTable/VirtualTableCell.d.ts +0 -21
  340. package/dist/ui/src/components/VirtualTable/VirtualTableHeader.d.ts +0 -29
  341. package/dist/ui/src/components/VirtualTable/VirtualTableHeaderRow.d.ts +0 -2
  342. package/dist/ui/src/components/VirtualTable/VirtualTableProps.d.ts +0 -249
  343. package/dist/ui/src/components/VirtualTable/VirtualTableRow.d.ts +0 -3
  344. package/dist/ui/src/components/VirtualTable/index.d.ts +0 -3
  345. package/dist/ui/src/components/VirtualTable/types.d.ts +0 -38
  346. package/dist/ui/src/components/common/SelectInputLabel.d.ts +0 -5
  347. package/dist/ui/src/components/index.d.ts +0 -58
  348. package/dist/ui/src/hooks/PortalContainerContext.d.ts +0 -31
  349. package/dist/ui/src/hooks/index.d.ts +0 -6
  350. package/dist/ui/src/hooks/useDebounceCallback.d.ts +0 -1
  351. package/dist/ui/src/hooks/useDebounceValue.d.ts +0 -1
  352. package/dist/ui/src/hooks/useDebouncedCallback.d.ts +0 -1
  353. package/dist/ui/src/hooks/useInjectStyles.d.ts +0 -7
  354. package/dist/ui/src/hooks/useOutsideAlerter.d.ts +0 -5
  355. package/dist/ui/src/icons/GitHubIcon.d.ts +0 -2
  356. package/dist/ui/src/icons/HandleIcon.d.ts +0 -1
  357. package/dist/ui/src/icons/Icon.d.ts +0 -20
  358. package/dist/ui/src/icons/cool_icon_keys.d.ts +0 -1
  359. package/dist/ui/src/icons/icon_keys.d.ts +0 -1
  360. package/dist/ui/src/icons/index.d.ts +0 -8
  361. package/dist/ui/src/index.d.ts +0 -5
  362. package/dist/ui/src/styles.d.ts +0 -12
  363. package/dist/ui/src/util/chip_colors.d.ts +0 -4
  364. package/dist/ui/src/util/cls.d.ts +0 -2
  365. package/dist/ui/src/util/debounce.d.ts +0 -10
  366. package/dist/ui/src/util/hash.d.ts +0 -1
  367. package/dist/ui/src/util/index.d.ts +0 -4
  368. package/dist/ui/src/util/key_to_icon_component.d.ts +0 -1
  369. package/src/components/SchemaVisualizer/index.ts +0 -5
  370. package/src/utils/entities.ts +0 -2
  371. /package/dist/{studio/src/components → components}/ApiExplorer/parseSpec.d.ts +0 -0
  372. /package/dist/{studio/src/components → components}/ApiExplorer/types.d.ts +0 -0
  373. /package/dist/{studio/src/components → components}/RLSEditor/index.d.ts +0 -0
  374. /package/dist/{studio/src/components → components}/RebaseStudio.d.ts +0 -0
  375. /package/dist/{studio/src/components → components}/SQLEditor/ExplainVisualizer.d.ts +0 -0
  376. /package/dist/{studio/src/components → components}/SchemaVisualizer/useSchemaGraph.d.ts +0 -0
  377. /package/dist/{studio/src/index.d.ts → index.d.ts} +0 -0
  378. /package/dist/{studio/src/utils → utils}/sql_utils.d.ts +0 -0
@@ -0,0 +1,1362 @@
1
+ import { t as MonacoEditor } from "./MonacoEditor-COZqrIJ1.js";
2
+ import { ErrorView, useRebaseContext, useSnackbarController, useStudioCollectionRegistry, useTranslation } from "@rebasepro/core";
3
+ import { useCallback, useEffect, useMemo, useState } from "react";
4
+ import { Alert, AlertTriangleIcon, Button, Chip, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, HelpCircleIcon, IconButton, KeyIcon, MultiSelect, MultiSelectItem, Paper, RefreshCwIcon, ResizablePanels, Select, SelectItem, ShieldIcon, Tab, Tabs, TextField, Tooltip, Trash2Icon, Typography, cls, defaultBorderMixin, iconSize } from "@rebasepro/ui";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { isPostgresCollection } from "@rebasepro/types";
7
+ //#region src/components/RLSEditor/PolicyEditor.tsx
8
+ var COMMAND_OPTIONS = [
9
+ "ALL",
10
+ "SELECT",
11
+ "INSERT",
12
+ "UPDATE",
13
+ "DELETE"
14
+ ];
15
+ var ROLE_OPTIONS = [
16
+ "public",
17
+ "authenticated",
18
+ "anon",
19
+ "admin"
20
+ ];
21
+ var POLICY_PRESETS = [
22
+ {
23
+ id: "public_read",
24
+ label: "Enable read access to everyone",
25
+ description: "Anyone can read data, regardless of authentication status.",
26
+ policyname: "Enable read access for all users",
27
+ cmd: "SELECT",
28
+ permissive: "PERMISSIVE",
29
+ roles: ["public"],
30
+ qual: "true",
31
+ with_check: ""
32
+ },
33
+ {
34
+ id: "auth_read",
35
+ label: "Enable read access for authenticated users only",
36
+ description: "Only logged-in users are allowed to read data.",
37
+ policyname: "Enable read access for authenticated users",
38
+ cmd: "SELECT",
39
+ permissive: "PERMISSIVE",
40
+ roles: ["authenticated"],
41
+ qual: "true",
42
+ with_check: ""
43
+ },
44
+ {
45
+ id: "auth_insert",
46
+ label: "Enable insert for authenticated users only",
47
+ description: "Only logged-in users are allowed to insert new data.",
48
+ policyname: "Enable insert for authenticated users only",
49
+ cmd: "INSERT",
50
+ permissive: "PERMISSIVE",
51
+ roles: ["authenticated"],
52
+ qual: "",
53
+ with_check: "true"
54
+ },
55
+ {
56
+ id: "user_select_own",
57
+ label: "Users can read their own rows",
58
+ description: "Users can only read rows where the user_id matches their auth.uid()",
59
+ policyname: "Users can select their own data",
60
+ cmd: "SELECT",
61
+ permissive: "PERMISSIVE",
62
+ roles: ["authenticated"],
63
+ qual: "auth.uid() = user_id",
64
+ with_check: ""
65
+ },
66
+ {
67
+ id: "user_update_own",
68
+ label: "Users can update their own rows",
69
+ description: "Users can only update rows where the user_id matches their auth.uid()",
70
+ policyname: "Users can update their own data",
71
+ cmd: "UPDATE",
72
+ permissive: "PERMISSIVE",
73
+ roles: ["authenticated"],
74
+ qual: "auth.uid() = user_id",
75
+ with_check: "auth.uid() = user_id"
76
+ },
77
+ {
78
+ id: "user_delete_own",
79
+ label: "Users can delete their own rows",
80
+ description: "Users can only delete rows where the user_id matches their auth.uid()",
81
+ policyname: "Users can delete their own data",
82
+ cmd: "DELETE",
83
+ permissive: "PERMISSIVE",
84
+ roles: ["authenticated"],
85
+ qual: "auth.uid() = user_id",
86
+ with_check: ""
87
+ }
88
+ ];
89
+ var PolicyEditor = ({ policy, schema, table, onSave, onCancel }) => {
90
+ const { t } = useTranslation();
91
+ const [name, setName] = useState("");
92
+ const [helpOpen, setHelpOpen] = useState(false);
93
+ const [behavior, setBehavior] = useState("PERMISSIVE");
94
+ const [command, setCommand] = useState("ALL");
95
+ const [roles, setRoles] = useState(["public"]);
96
+ const [usingExpr, setUsingExpr] = useState("");
97
+ const [checkExpr, setCheckExpr] = useState("");
98
+ const [selectedPreset, setSelectedPreset] = useState("");
99
+ useEffect(() => {
100
+ if (policy) {
101
+ setName(policy.policyname || "");
102
+ setBehavior(policy.permissive || "PERMISSIVE");
103
+ setCommand(policy.cmd || "ALL");
104
+ setRoles(policy.roles ? Array.isArray(policy.roles) ? policy.roles : [policy.roles] : ["public"]);
105
+ setUsingExpr(policy.qual || "");
106
+ setCheckExpr(policy.with_check || "");
107
+ } else {
108
+ setName("");
109
+ setBehavior("PERMISSIVE");
110
+ setCommand("ALL");
111
+ setRoles(["public"]);
112
+ setUsingExpr("");
113
+ setCheckExpr("");
114
+ setSelectedPreset("");
115
+ }
116
+ }, [policy]);
117
+ const handlePresetChange = (presetId) => {
118
+ const preset = POLICY_PRESETS.find((p) => p.id === presetId);
119
+ if (!preset) return;
120
+ setSelectedPreset(presetId);
121
+ setName(preset.policyname);
122
+ setBehavior(preset.permissive);
123
+ setCommand(preset.cmd);
124
+ setRoles(preset.roles);
125
+ setUsingExpr(preset.qual);
126
+ setCheckExpr(preset.with_check);
127
+ };
128
+ const showCheck = command === "ALL" || command === "INSERT" || command === "UPDATE";
129
+ const handleSave = () => {
130
+ onSave({
131
+ policyname: name,
132
+ permissive: behavior,
133
+ cmd: command,
134
+ roles,
135
+ qual: usingExpr,
136
+ with_check: showCheck ? checkExpr : null
137
+ });
138
+ };
139
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
140
+ /* @__PURE__ */ jsxs(DialogTitle, {
141
+ className: "flex justify-between items-center w-full",
142
+ variant: "h6",
143
+ children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", { children: policy ? t("studio_policy_edit") : t("studio_policy_create") }), /* @__PURE__ */ jsxs("div", {
144
+ className: "text-sm font-normal text-text-secondary dark:text-text-secondary-dark tracking-wide mt-1",
145
+ children: [
146
+ t("studio_policy_defining_rules"),
147
+ " ",
148
+ /* @__PURE__ */ jsxs("span", {
149
+ className: "font-mono text-primary bg-primary-bg dark:bg-primary-bg-dark px-1 py-0.5 rounded",
150
+ children: [
151
+ schema,
152
+ ".",
153
+ table
154
+ ]
155
+ })
156
+ ]
157
+ })] }), /* @__PURE__ */ jsx(IconButton, {
158
+ size: "small",
159
+ onClick: () => setHelpOpen(true),
160
+ children: /* @__PURE__ */ jsx(HelpCircleIcon, { size: iconSize.smallest })
161
+ })]
162
+ }),
163
+ /* @__PURE__ */ jsx(DialogContent, {
164
+ className: "p-4 md:p-6 border-t dark:border-surface-950 bg-surface-50 dark:bg-surface-950",
165
+ includeMargin: false,
166
+ children: /* @__PURE__ */ jsxs("div", {
167
+ className: "max-w-4xl mx-auto",
168
+ children: [/* @__PURE__ */ jsxs(Paper, {
169
+ className: cls("p-4 md:p-6 flex flex-col gap-6 bg-white dark:bg-surface-900 border-none sm:border-solid rounded-none sm:rounded-xl", defaultBorderMixin),
170
+ children: [
171
+ !policy && /* @__PURE__ */ jsxs("div", {
172
+ className: "flex flex-col gap-1.5 bg-primary/5 dark:bg-primary-bg-dark/20 p-3 sm:p-4 rounded-lg border border-primary/10 dark:border-primary/20",
173
+ children: [/* @__PURE__ */ jsx(Typography, {
174
+ variant: "caption",
175
+ className: "text-primary dark:text-primary-light uppercase tracking-wider",
176
+ children: t("studio_policy_template")
177
+ }), /* @__PURE__ */ jsx(Select, {
178
+ size: "small",
179
+ value: selectedPreset,
180
+ onValueChange: handlePresetChange,
181
+ position: "item-aligned",
182
+ placeholder: t("studio_policy_select_template"),
183
+ className: "bg-white dark:bg-surface-950",
184
+ children: POLICY_PRESETS.map((preset) => /* @__PURE__ */ jsx(SelectItem, {
185
+ value: preset.id,
186
+ children: /* @__PURE__ */ jsxs("div", {
187
+ className: "flex flex-col text-left",
188
+ children: [/* @__PURE__ */ jsx("span", {
189
+ className: "text-sm",
190
+ children: preset.label
191
+ }), /* @__PURE__ */ jsx("span", {
192
+ className: "text-xs text-text-secondary dark:text-text-secondary-dark",
193
+ children: preset.description
194
+ })]
195
+ })
196
+ }, preset.id))
197
+ })]
198
+ }),
199
+ /* @__PURE__ */ jsxs("div", {
200
+ className: "grid grid-cols-1 md:grid-cols-2 gap-4 sm:gap-6",
201
+ children: [/* @__PURE__ */ jsxs("div", {
202
+ className: "flex flex-col gap-1.5",
203
+ children: [/* @__PURE__ */ jsx(Typography, {
204
+ variant: "caption",
205
+ className: "uppercase tracking-wider text-text-secondary",
206
+ children: t("studio_policy_name")
207
+ }), /* @__PURE__ */ jsx(TextField, {
208
+ value: name,
209
+ onChange: (e) => setName(e.target.value),
210
+ placeholder: t("studio_policy_name_placeholder"),
211
+ className: "w-full"
212
+ })]
213
+ }), /* @__PURE__ */ jsxs("div", {
214
+ className: "flex flex-col gap-1.5",
215
+ children: [/* @__PURE__ */ jsxs(Typography, {
216
+ variant: "caption",
217
+ className: "uppercase tracking-wider text-text-secondary",
218
+ children: [
219
+ t("studio_policy_behavior"),
220
+ " ",
221
+ /* @__PURE__ */ jsx("code", {
222
+ className: "text-[10px] bg-surface-200 dark:bg-surface-950 text-text-secondary dark:text-text-secondary-dark px-1 py-0.5 rounded ml-1",
223
+ children: "AS"
224
+ })
225
+ ]
226
+ }), /* @__PURE__ */ jsxs(Select, {
227
+ value: behavior,
228
+ onValueChange: (val) => setBehavior(val),
229
+ position: "item-aligned",
230
+ children: [/* @__PURE__ */ jsx(SelectItem, {
231
+ value: "PERMISSIVE",
232
+ children: /* @__PURE__ */ jsxs("div", {
233
+ className: "flex flex-col text-left",
234
+ children: [/* @__PURE__ */ jsx("span", {
235
+ className: "",
236
+ children: t("studio_policy_permissive")
237
+ }), /* @__PURE__ */ jsx("span", {
238
+ className: "text-xs text-text-secondary dark:text-text-secondary-dark",
239
+ children: t("studio_policy_permissive_desc")
240
+ })]
241
+ })
242
+ }), /* @__PURE__ */ jsx(SelectItem, {
243
+ value: "RESTRICTIVE",
244
+ children: /* @__PURE__ */ jsxs("div", {
245
+ className: "flex flex-col text-left",
246
+ children: [/* @__PURE__ */ jsx("span", {
247
+ className: "",
248
+ children: t("studio_policy_restrictive")
249
+ }), /* @__PURE__ */ jsx("span", {
250
+ className: "text-xs text-text-secondary dark:text-text-secondary-dark",
251
+ children: t("studio_policy_restrictive_desc")
252
+ })]
253
+ })
254
+ })]
255
+ })]
256
+ })]
257
+ }),
258
+ /* @__PURE__ */ jsxs("div", {
259
+ className: "flex flex-col gap-1.5",
260
+ children: [/* @__PURE__ */ jsxs(Typography, {
261
+ variant: "caption",
262
+ className: "uppercase tracking-wider text-text-secondary",
263
+ children: [
264
+ t("studio_policy_command"),
265
+ " ",
266
+ /* @__PURE__ */ jsx("code", {
267
+ className: "text-[10px] bg-surface-200 dark:bg-surface-950 text-text-secondary dark:text-text-secondary-dark px-1 py-0.5 rounded ml-1",
268
+ children: "FOR"
269
+ })
270
+ ]
271
+ }), /* @__PURE__ */ jsx("div", {
272
+ className: "flex flex-wrap gap-1.5",
273
+ children: COMMAND_OPTIONS.map((cmd) => /* @__PURE__ */ jsx(Button, {
274
+ size: "small",
275
+ variant: command === cmd ? "filled" : "text",
276
+ color: "neutral",
277
+ onClick: () => setCommand(cmd),
278
+ className: "min-w-[80px]",
279
+ children: cmd
280
+ }, cmd))
281
+ })]
282
+ }),
283
+ /* @__PURE__ */ jsxs("div", {
284
+ className: "flex flex-col gap-1.5",
285
+ children: [/* @__PURE__ */ jsxs(Typography, {
286
+ variant: "caption",
287
+ className: "uppercase tracking-wider text-text-secondary",
288
+ children: [
289
+ t("studio_policy_target_roles"),
290
+ " ",
291
+ /* @__PURE__ */ jsx("code", {
292
+ className: "text-[10px] bg-surface-200 dark:bg-surface-950 text-text-secondary dark:text-text-secondary-dark px-1 py-0.5 rounded ml-1",
293
+ children: "TO"
294
+ })
295
+ ]
296
+ }), /* @__PURE__ */ jsx(MultiSelect, {
297
+ size: "small",
298
+ value: roles,
299
+ onValueChange: setRoles,
300
+ placeholder: t("studio_policy_roles_placeholder"),
301
+ children: ROLE_OPTIONS.map((role) => /* @__PURE__ */ jsx(MultiSelectItem, {
302
+ value: role,
303
+ children: role
304
+ }, role))
305
+ })]
306
+ })
307
+ ]
308
+ }), /* @__PURE__ */ jsxs("div", {
309
+ className: "mt-8 flex flex-col gap-4",
310
+ children: [command !== "INSERT" && /* @__PURE__ */ jsxs("div", {
311
+ className: "flex flex-col gap-1.5",
312
+ children: [/* @__PURE__ */ jsxs("div", {
313
+ className: "flex flex-col gap-0.5",
314
+ children: [/* @__PURE__ */ jsx(Typography, {
315
+ variant: "caption",
316
+ className: "uppercase tracking-wider text-text-secondary",
317
+ children: t("studio_policy_using_expr")
318
+ }), /* @__PURE__ */ jsx(Typography, {
319
+ variant: "caption",
320
+ className: "text-text-secondary opacity-70",
321
+ children: t("studio_policy_using_expr_desc")
322
+ })]
323
+ }), /* @__PURE__ */ jsx("div", {
324
+ className: cls("h-32 border rounded-md overflow-hidden bg-white dark:bg-[#1e1e1e]", defaultBorderMixin),
325
+ children: /* @__PURE__ */ jsx(MonacoEditor, {
326
+ value: usingExpr,
327
+ onChange: (v) => setUsingExpr(v || ""),
328
+ readOnly: false,
329
+ autoFocus: true
330
+ })
331
+ })]
332
+ }), showCheck && /* @__PURE__ */ jsxs("div", {
333
+ className: "flex flex-col gap-1.5 mt-2",
334
+ children: [/* @__PURE__ */ jsxs("div", {
335
+ className: "flex flex-col gap-0.5",
336
+ children: [/* @__PURE__ */ jsx(Typography, {
337
+ variant: "caption",
338
+ className: "uppercase tracking-wider text-text-secondary",
339
+ children: t("studio_policy_check_expr")
340
+ }), /* @__PURE__ */ jsx(Typography, {
341
+ variant: "caption",
342
+ className: "text-text-secondary opacity-70",
343
+ children: t("studio_policy_check_expr_desc")
344
+ })]
345
+ }), /* @__PURE__ */ jsx("div", {
346
+ className: cls("h-32 border rounded-md overflow-hidden bg-white dark:bg-[#1e1e1e]", defaultBorderMixin),
347
+ children: /* @__PURE__ */ jsx(MonacoEditor, {
348
+ value: checkExpr,
349
+ onChange: (v) => setCheckExpr(v || ""),
350
+ readOnly: false,
351
+ autoFocus: command === "INSERT"
352
+ })
353
+ })]
354
+ })]
355
+ })]
356
+ })
357
+ }),
358
+ /* @__PURE__ */ jsxs(DialogActions, { children: [/* @__PURE__ */ jsx(Button, {
359
+ size: "small",
360
+ variant: "text",
361
+ color: "neutral",
362
+ onClick: onCancel,
363
+ children: t("studio_policy_cancel")
364
+ }), /* @__PURE__ */ jsx(Button, {
365
+ size: "small",
366
+ variant: "filled",
367
+ color: "primary",
368
+ onClick: handleSave,
369
+ disabled: !name,
370
+ children: t("studio_policy_save")
371
+ })] }),
372
+ /* @__PURE__ */ jsxs(Dialog, {
373
+ open: helpOpen,
374
+ onOpenChange: setHelpOpen,
375
+ maxWidth: "3xl",
376
+ children: [/* @__PURE__ */ jsxs(DialogContent, {
377
+ className: "p-4 sm:p-6 lg:p-8 flex flex-col gap-6",
378
+ children: [
379
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
380
+ variant: "h5",
381
+ className: "mb-2",
382
+ children: t("studio_policy_help_title")
383
+ }), /* @__PURE__ */ jsx(Typography, {
384
+ className: "text-text-secondary dark:text-text-secondary-dark",
385
+ children: t("studio_policy_help_intro")
386
+ })] }),
387
+ /* @__PURE__ */ jsxs("div", {
388
+ className: "flex flex-col gap-4",
389
+ children: [
390
+ /* @__PURE__ */ jsxs(Paper, {
391
+ className: cls("p-4 sm:p-5 flex flex-col gap-1", defaultBorderMixin),
392
+ children: [/* @__PURE__ */ jsx(Typography, {
393
+ variant: "subtitle2",
394
+ className: "text-primary dark:text-primary-light font-medium",
395
+ children: t("studio_policy_help_step1_title")
396
+ }), /* @__PURE__ */ jsx(Typography, {
397
+ variant: "body2",
398
+ className: "text-text-secondary dark:text-text-secondary-dark",
399
+ children: t("studio_policy_help_step1_desc")
400
+ })]
401
+ }),
402
+ /* @__PURE__ */ jsxs(Paper, {
403
+ className: cls("p-4 sm:p-5 flex flex-col gap-1", defaultBorderMixin),
404
+ children: [
405
+ /* @__PURE__ */ jsx(Typography, {
406
+ variant: "subtitle2",
407
+ className: "text-primary dark:text-primary-light font-medium",
408
+ children: t("studio_policy_help_step2_title")
409
+ }),
410
+ /* @__PURE__ */ jsx(Typography, {
411
+ variant: "body2",
412
+ className: "text-text-secondary dark:text-text-secondary-dark mb-1",
413
+ children: t("studio_policy_help_step2_desc")
414
+ }),
415
+ /* @__PURE__ */ jsxs("ul", {
416
+ className: "list-disc pl-5 space-y-1 text-sm text-text-secondary dark:text-text-secondary-dark",
417
+ children: [
418
+ /* @__PURE__ */ jsxs("li", { children: [
419
+ /* @__PURE__ */ jsx("strong", { children: "public" }),
420
+ ": ",
421
+ t("studio_policy_help_role_public")
422
+ ] }),
423
+ /* @__PURE__ */ jsxs("li", { children: [
424
+ /* @__PURE__ */ jsx("strong", { children: "authenticated" }),
425
+ ": ",
426
+ t("studio_policy_help_role_authenticated")
427
+ ] }),
428
+ /* @__PURE__ */ jsxs("li", { children: [
429
+ /* @__PURE__ */ jsx("strong", { children: "anon" }),
430
+ ": ",
431
+ t("studio_policy_help_role_anon")
432
+ ] })
433
+ ]
434
+ })
435
+ ]
436
+ }),
437
+ /* @__PURE__ */ jsxs(Paper, {
438
+ className: cls("p-4 sm:p-5 flex flex-col gap-1", defaultBorderMixin),
439
+ children: [
440
+ /* @__PURE__ */ jsx(Typography, {
441
+ variant: "subtitle2",
442
+ className: "text-primary dark:text-primary-light font-medium",
443
+ children: t("studio_policy_help_step3_title")
444
+ }),
445
+ /* @__PURE__ */ jsx(Typography, {
446
+ variant: "body2",
447
+ className: "text-text-secondary dark:text-text-secondary-dark mb-1",
448
+ children: t("studio_policy_help_step3_desc")
449
+ }),
450
+ /* @__PURE__ */ jsx("div", {
451
+ className: cls("bg-surface-100 dark:bg-surface-950 px-3 py-2 rounded-md font-mono text-sm my-2", defaultBorderMixin),
452
+ children: "Example: auth.uid() = user_id"
453
+ }),
454
+ /* @__PURE__ */ jsx(Typography, {
455
+ variant: "caption",
456
+ className: "text-text-secondary dark:text-text-secondary-dark",
457
+ children: t("studio_policy_help_step3_example")
458
+ })
459
+ ]
460
+ }),
461
+ /* @__PURE__ */ jsxs(Paper, {
462
+ className: cls("p-4 sm:p-5 flex flex-col gap-1", defaultBorderMixin),
463
+ children: [
464
+ /* @__PURE__ */ jsx(Typography, {
465
+ variant: "subtitle2",
466
+ className: "text-primary dark:text-primary-light font-medium",
467
+ children: t("studio_policy_help_step4_title")
468
+ }),
469
+ /* @__PURE__ */ jsx(Typography, {
470
+ variant: "body2",
471
+ className: "text-text-secondary dark:text-text-secondary-dark mb-1",
472
+ children: t("studio_policy_help_step4_desc")
473
+ }),
474
+ /* @__PURE__ */ jsx("div", {
475
+ className: cls("bg-surface-100 dark:bg-surface-950 px-3 py-2 rounded-md font-mono text-sm my-2", defaultBorderMixin),
476
+ children: "Example: auth.uid() = user_id"
477
+ }),
478
+ /* @__PURE__ */ jsx(Typography, {
479
+ variant: "caption",
480
+ className: "text-text-secondary dark:text-text-secondary-dark",
481
+ children: t("studio_policy_help_step4_example")
482
+ })
483
+ ]
484
+ }),
485
+ /* @__PURE__ */ jsxs(Paper, {
486
+ className: cls("p-4 sm:p-5 flex flex-col gap-2 bg-primary/5 dark:bg-primary-bg-dark/10", defaultBorderMixin),
487
+ children: [
488
+ /* @__PURE__ */ jsx(Typography, {
489
+ variant: "subtitle2",
490
+ className: "text-primary dark:text-primary-light font-medium",
491
+ children: t("studio_policy_help_auth_vars_title")
492
+ }),
493
+ /* @__PURE__ */ jsx(Typography, {
494
+ variant: "body2",
495
+ className: "text-text-secondary dark:text-text-secondary-dark",
496
+ children: t("studio_policy_help_auth_vars_desc")
497
+ }),
498
+ /* @__PURE__ */ jsxs("ul", {
499
+ className: "list-disc pl-5 space-y-2 text-sm text-text-secondary dark:text-text-secondary-dark font-normal",
500
+ children: [
501
+ /* @__PURE__ */ jsxs("li", { children: [/* @__PURE__ */ jsx("code", {
502
+ className: "bg-surface-100 dark:bg-surface-950 px-1.5 py-0.5 rounded mr-1 whitespace-nowrap",
503
+ children: "auth.uid()"
504
+ }), /* @__PURE__ */ jsxs("span", {
505
+ className: "block mt-0.5",
506
+ children: ["Returns the current user's ID as text. Example: ", /* @__PURE__ */ jsx("code", {
507
+ className: "bg-surface-100 dark:bg-surface-950 px-1 py-0.5 rounded text-[11px]",
508
+ children: "auth.uid() = user_id"
509
+ })]
510
+ })] }),
511
+ /* @__PURE__ */ jsxs("li", { children: [/* @__PURE__ */ jsx("code", {
512
+ className: "bg-surface-100 dark:bg-surface-950 px-1.5 py-0.5 rounded mr-1 whitespace-nowrap",
513
+ children: "auth.jwt()"
514
+ }), /* @__PURE__ */ jsxs("span", {
515
+ className: "block mt-0.5",
516
+ children: ["Returns the full JWT payload as JSONB so you can check custom claims. Example: ", /* @__PURE__ */ jsx("code", {
517
+ className: "bg-surface-100 dark:bg-surface-950 px-1 py-0.5 rounded text-[11px]",
518
+ children: "auth.jwt() ->> 'email' = 'admin@example.com'"
519
+ })]
520
+ })] }),
521
+ /* @__PURE__ */ jsxs("li", { children: [/* @__PURE__ */ jsx("code", {
522
+ className: "bg-surface-100 dark:bg-surface-950 px-1.5 py-0.5 rounded mr-1 whitespace-nowrap",
523
+ children: "auth.roles()"
524
+ }), /* @__PURE__ */ jsxs("span", {
525
+ className: "block mt-0.5",
526
+ children: ["Returns the user's role IDs as a comma-separated string. Best used with: ", /* @__PURE__ */ jsx("code", {
527
+ className: "bg-surface-100 dark:bg-surface-950 px-1 py-0.5 rounded text-[11px]",
528
+ children: "string_to_array(auth.roles(), ',') @> ARRAY['admin']"
529
+ })]
530
+ })] })
531
+ ]
532
+ })
533
+ ]
534
+ })
535
+ ]
536
+ }),
537
+ /* @__PURE__ */ jsxs("div", {
538
+ className: cls("mt-2 flex flex-col sm:flex-row justify-between items-start sm:items-center bg-primary/5 dark:bg-primary-bg-dark/10 p-4 rounded-xl border border-primary/10 dark:border-primary/20", defaultBorderMixin),
539
+ children: [/* @__PURE__ */ jsx(Typography, {
540
+ variant: "body2",
541
+ className: "text-primary dark:text-primary-light mb-4 sm:mb-0 max-w-md",
542
+ children: t("studio_policy_help_docs_cta")
543
+ }), /* @__PURE__ */ jsx(Button, {
544
+ component: "a",
545
+ href: "https://www.postgresql.org/docs/current/sql-createpolicy.html",
546
+ target: "_blank",
547
+ variant: "outlined",
548
+ color: "primary",
549
+ size: "small",
550
+ className: "whitespace-nowrap flex-shrink-0",
551
+ children: t("studio_policy_help_read_docs")
552
+ })]
553
+ })
554
+ ]
555
+ }), /* @__PURE__ */ jsx(DialogActions, {
556
+ className: "p-4 sm:px-6 sm:pb-6 pt-0 border-t-0",
557
+ children: /* @__PURE__ */ jsx(Button, {
558
+ onClick: () => setHelpOpen(false),
559
+ variant: "filled",
560
+ color: "primary",
561
+ children: t("studio_policy_help_got_it")
562
+ })
563
+ })]
564
+ })
565
+ ] });
566
+ };
567
+ //#endregion
568
+ //#region src/components/RLSEditor/RLSEditor.tsx
569
+ /**
570
+ * Validates and double-quotes a SQL identifier to prevent injection.
571
+ * Only allows safe Postgres identifiers (letters, digits, underscores).
572
+ * Throws if the identifier contains unsafe characters.
573
+ */
574
+ function sanitizeSqlIdentifier(name) {
575
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) throw new Error(`Invalid SQL identifier: "${name}". Only letters, digits, and underscores are allowed.`);
576
+ return `"${name}"`;
577
+ }
578
+ var RLSEditor = ({ apiUrl = "" }) => {
579
+ const { databaseAdmin } = useRebaseContext();
580
+ const snackbarController = useSnackbarController();
581
+ const collectionRegistry = useStudioCollectionRegistry();
582
+ const { t } = useTranslation();
583
+ const [isLoading, setIsLoading] = useState(true);
584
+ const [error, setError] = useState(null);
585
+ const [tables, setTables] = useState([]);
586
+ const [selectedTable, setSelectedTable] = useState(null);
587
+ const [activeTab, setActiveTab] = useState(0);
588
+ const [editingPolicy, setEditingPolicy] = useState(null);
589
+ const [sidebarSize, setSidebarSize] = useState(() => {
590
+ try {
591
+ const saved = localStorage.getItem("rebase_rls_editor_sidebar_size");
592
+ return saved !== null ? parseFloat(saved) : 20;
593
+ } catch (e) {
594
+ return 20;
595
+ }
596
+ });
597
+ const [expandedSchemas, setExpandedSchemas] = useState({ public: true });
598
+ const [sidebarTab, setSidebarTab] = useState("tables");
599
+ useEffect(() => {
600
+ try {
601
+ localStorage.setItem("rebase_rls_editor_sidebar_size", sidebarSize.toString());
602
+ } catch (e) {}
603
+ }, [sidebarSize]);
604
+ const fetchRLSData = useCallback(async () => {
605
+ if (!databaseAdmin?.executeSql) {
606
+ setError(t("studio_sql_sql_not_supported"));
607
+ setIsLoading(false);
608
+ return;
609
+ }
610
+ setIsLoading(true);
611
+ setError(null);
612
+ try {
613
+ const tablesResult = await databaseAdmin.executeSql(`
614
+ SELECT
615
+ schemaname,
616
+ tablename,
617
+ rowsecurity
618
+ FROM pg_tables
619
+ WHERE schemaname NOT IN ('information_schema', 'pg_catalog')
620
+ ORDER BY schemaname, tablename;
621
+ `);
622
+ const policiesResult = await databaseAdmin.executeSql(`
623
+ SELECT
624
+ schemaname,
625
+ tablename,
626
+ policyname,
627
+ permissive,
628
+ roles,
629
+ cmd,
630
+ qual,
631
+ with_check
632
+ FROM pg_policies
633
+ WHERE schemaname NOT IN ('information_schema', 'pg_catalog');
634
+ `);
635
+ const extractRows = (result) => {
636
+ if (result && typeof result === "object" && "rows" in result && Array.isArray(result.rows)) return result.rows;
637
+ if (Array.isArray(result)) return result;
638
+ return [];
639
+ };
640
+ const tRows = extractRows(tablesResult);
641
+ const pRows = extractRows(policiesResult);
642
+ const tableMap = {};
643
+ tRows.forEach((tRow) => {
644
+ const t = tRow;
645
+ const schema = t.schemaname || t.SCHEMANAME || "public";
646
+ const table = t.tablename || t.TABLENAME || "";
647
+ const rlsEnabled = t.rowsecurity || t.ROWSECURITY || false;
648
+ const key = `${schema}.${table}`;
649
+ tableMap[key] = {
650
+ schemaName: schema,
651
+ tableName: table,
652
+ rlsEnabled,
653
+ policies: []
654
+ };
655
+ });
656
+ pRows.forEach((pRow) => {
657
+ const p = pRow;
658
+ const schema = p.schemaname || p.SCHEMANAME || "public";
659
+ const table = p.tablename || p.TABLENAME || "";
660
+ const key = `${schema}.${table}`;
661
+ if (tableMap[key]) {
662
+ let parsedRoles = [];
663
+ const r = p.roles || p.ROLES;
664
+ if (Array.isArray(r)) parsedRoles = r;
665
+ else if (typeof r === "string") parsedRoles = r.replace(/^{|}$/g, "").split(",").map((s) => s.trim());
666
+ tableMap[key].policies.push({
667
+ policyname: p.policyname || p.POLICYNAME || "",
668
+ tablename: table,
669
+ permissive: p.permissive || p.PERMISSIVE || "PERMISSIVE",
670
+ roles: parsedRoles,
671
+ cmd: p.cmd || p.CMD || "ALL",
672
+ qual: p.qual || p.QUAL || null,
673
+ with_check: p.with_check || p.WITH_CHECK || null
674
+ });
675
+ }
676
+ });
677
+ const sortedTables = Object.values(tableMap).sort((a, b) => a.tableName.localeCompare(b.tableName));
678
+ setTables(sortedTables);
679
+ if (sortedTables.length > 0 && !selectedTable) setSelectedTable(`${sortedTables[0].schemaName}.${sortedTables[0].tableName}`);
680
+ } catch (e) {
681
+ console.error("RLS fetch error:", e);
682
+ setError("Failed to fetch RLS policies: " + (e instanceof Error ? e.message : String(e)));
683
+ } finally {
684
+ setIsLoading(false);
685
+ }
686
+ }, [databaseAdmin, selectedTable]);
687
+ useEffect(() => {
688
+ setEditingPolicy(null);
689
+ }, [selectedTable]);
690
+ useEffect(() => {
691
+ fetchRLSData();
692
+ }, [fetchRLSData]);
693
+ const activeTableData = useMemo(() => {
694
+ if (!selectedTable) return null;
695
+ return tables.find((t) => `${t.schemaName}.${t.tableName}` === selectedTable) || null;
696
+ }, [selectedTable, tables]);
697
+ const groupedTables = useMemo(() => {
698
+ const groups = {};
699
+ tables.forEach((table) => {
700
+ if (!groups[table.schemaName]) groups[table.schemaName] = [];
701
+ groups[table.schemaName].push(table);
702
+ });
703
+ return groups;
704
+ }, [tables]);
705
+ const activeCollection = useMemo(() => {
706
+ if (!activeTableData) return null;
707
+ return collectionRegistry.collections?.find((c) => c.id === activeTableData.tableName || c.path === activeTableData.tableName || c.table === activeTableData.tableName || c.slug === activeTableData.tableName || c.collectionId === activeTableData.tableName) || null;
708
+ }, [activeTableData, collectionRegistry.collections]);
709
+ const mergedPolicies = useMemo(() => {
710
+ if (!activeTableData) return [];
711
+ const policiesMap = {};
712
+ (activeTableData.policies || []).forEach((p) => {
713
+ policiesMap[p.policyname] = {
714
+ ...p,
715
+ status: "live"
716
+ };
717
+ });
718
+ if (activeCollection && isPostgresCollection(activeCollection) && activeCollection.securityRules) activeCollection.securityRules.forEach((rule) => {
719
+ const ruleName = rule.name;
720
+ if (!ruleName) return;
721
+ if (policiesMap[ruleName]) policiesMap[ruleName] = {
722
+ policyname: ruleName,
723
+ tablename: activeTableData.tableName,
724
+ permissive: (rule.mode || "permissive").toUpperCase(),
725
+ cmd: (rule.operation || "ALL").toUpperCase(),
726
+ roles: rule.roles || ["public"],
727
+ qual: rule.using || null,
728
+ with_check: rule.withCheck || null,
729
+ status: "both"
730
+ };
731
+ else policiesMap[ruleName] = {
732
+ policyname: ruleName,
733
+ tablename: activeTableData.tableName,
734
+ permissive: (rule.mode || "permissive").toUpperCase(),
735
+ cmd: (rule.operation || "ALL").toUpperCase(),
736
+ roles: rule.roles || ["public"],
737
+ qual: rule.using || null,
738
+ with_check: rule.withCheck || null,
739
+ status: "code_only"
740
+ };
741
+ });
742
+ return Object.values(policiesMap).sort((a, b) => a.policyname.localeCompare(b.policyname));
743
+ }, [activeTableData, activeCollection]);
744
+ const rlsStats = useMemo(() => {
745
+ return {
746
+ total: tables.length,
747
+ enabled: tables.filter((t) => t.rlsEnabled).length,
748
+ withPolicies: tables.filter((t) => t.policies.length > 0).length,
749
+ totalPolicies: tables.reduce((sum, t) => sum + t.policies.length, 0)
750
+ };
751
+ }, [tables]);
752
+ const renderPolicyTag = (label, value) => {
753
+ return /* @__PURE__ */ jsxs("div", {
754
+ className: "flex items-center gap-1.5 px-2 py-1 rounded-md bg-surface-100 dark:bg-surface-950 border border-surface-200 dark:border-surface-700/50",
755
+ children: [/* @__PURE__ */ jsxs("span", {
756
+ className: "text-[10px] uppercase text-text-secondary dark:text-text-secondary-dark font-medium tracking-wider",
757
+ children: [label, ":"]
758
+ }), /* @__PURE__ */ jsx("span", {
759
+ className: "font-mono text-xs text-text-primary dark:text-text-primary-dark break-all",
760
+ children: value
761
+ })]
762
+ });
763
+ };
764
+ return /* @__PURE__ */ jsx("div", {
765
+ className: "flex h-full w-full bg-white dark:bg-surface-950 overflow-hidden text-text-primary dark:text-text-primary-dark",
766
+ children: /* @__PURE__ */ jsx(ResizablePanels, {
767
+ orientation: "horizontal",
768
+ panelSizePercent: sidebarSize,
769
+ onPanelSizeChange: setSidebarSize,
770
+ minPanelSizePx: 220,
771
+ firstPanel: /* @__PURE__ */ jsxs("div", {
772
+ className: cls("flex flex-col h-full w-full bg-white dark:bg-surface-950 border-r", defaultBorderMixin),
773
+ children: [/* @__PURE__ */ jsxs(Tabs, {
774
+ value: sidebarTab,
775
+ onValueChange: (v) => setSidebarTab(v),
776
+ variant: "boxy",
777
+ className: "border-b border-surface-200 dark:border-surface-950",
778
+ children: [/* @__PURE__ */ jsx(Tab, {
779
+ value: "tables",
780
+ children: "Tables"
781
+ }), /* @__PURE__ */ jsx(Tab, {
782
+ value: "info",
783
+ children: "Info"
784
+ })]
785
+ }), /* @__PURE__ */ jsxs("div", {
786
+ className: "flex-grow overflow-hidden relative",
787
+ children: [sidebarTab === "tables" && /* @__PURE__ */ jsxs("div", {
788
+ className: "flex flex-col h-full",
789
+ children: [/* @__PURE__ */ jsxs("div", {
790
+ className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin),
791
+ children: [/* @__PURE__ */ jsx(Typography, {
792
+ variant: "caption",
793
+ className: "font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark",
794
+ children: t("studio_schema_tables")
795
+ }), /* @__PURE__ */ jsx(IconButton, {
796
+ size: "small",
797
+ onClick: fetchRLSData,
798
+ title: "Refresh",
799
+ children: /* @__PURE__ */ jsx(RefreshCwIcon, { size: iconSize.smallest })
800
+ })]
801
+ }), /* @__PURE__ */ jsx("div", {
802
+ className: "flex-grow overflow-y-auto no-scrollbar p-1",
803
+ children: isLoading && tables.length === 0 ? /* @__PURE__ */ jsx("div", {
804
+ className: "flex justify-center p-4",
805
+ children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" })
806
+ }) : Object.keys(groupedTables).length === 0 ? /* @__PURE__ */ jsx("div", {
807
+ className: "p-4 text-center",
808
+ children: /* @__PURE__ */ jsx(Typography, {
809
+ variant: "caption",
810
+ className: "text-text-disabled dark:text-text-disabled-dark italic",
811
+ children: t("studio_rls_no_tables")
812
+ })
813
+ }) : Object.entries(groupedTables).map(([schemaName, schemaTables]) => /* @__PURE__ */ jsxs("div", {
814
+ className: "mb-2",
815
+ children: [/* @__PURE__ */ jsxs("div", {
816
+ className: "flex items-center p-1 cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-950 rounded transition-colors",
817
+ onClick: () => setExpandedSchemas((prev) => ({
818
+ ...prev,
819
+ [schemaName]: !prev[schemaName]
820
+ })),
821
+ children: [/* @__PURE__ */ jsx("svg", {
822
+ className: cls("w-3 h-3 mr-1 transition-transform", expandedSchemas[schemaName] ? "rotate-90" : ""),
823
+ fill: "currentColor",
824
+ viewBox: "0 0 20 20",
825
+ children: /* @__PURE__ */ jsx("path", { d: "M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" })
826
+ }), /* @__PURE__ */ jsx(Typography, {
827
+ variant: "body2",
828
+ className: "text-text-primary dark:text-text-primary-dark font-medium text-xs truncate flex-grow",
829
+ children: schemaName
830
+ })]
831
+ }), expandedSchemas[schemaName] && /* @__PURE__ */ jsx("div", {
832
+ className: "ml-3 mt-1 space-y-0.5",
833
+ children: schemaTables.map((table) => {
834
+ const key = `${table.schemaName}.${table.tableName}`;
835
+ return /* @__PURE__ */ jsxs("div", {
836
+ onClick: () => setSelectedTable(key),
837
+ className: cls("flex items-center p-1 cursor-pointer rounded transition-colors group relative", selectedTable === key ? "bg-primary/10 text-primary dark:bg-primary/20 dark:text-primary-light" : "hover:bg-surface-100 dark:hover:bg-surface-950 text-text-secondary dark:text-text-secondary-dark"),
838
+ children: [
839
+ /* @__PURE__ */ jsx("svg", {
840
+ className: "w-3.5 h-3.5 mr-1 shrink-0 text-text-disabled dark:text-text-disabled-dark",
841
+ fill: "none",
842
+ stroke: "currentColor",
843
+ viewBox: "0 0 24 24",
844
+ children: /* @__PURE__ */ jsx("path", {
845
+ strokeLinecap: "round",
846
+ strokeLinejoin: "round",
847
+ strokeWidth: 2,
848
+ d: "M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
849
+ })
850
+ }),
851
+ /* @__PURE__ */ jsx(Typography, {
852
+ variant: "body2",
853
+ className: "text-xs truncate flex-1 min-w-0",
854
+ children: table.tableName
855
+ }),
856
+ /* @__PURE__ */ jsxs("div", {
857
+ className: "flex items-center gap-1.5 shrink-0 ml-2",
858
+ children: [table.rlsEnabled ? /* @__PURE__ */ jsx(Tooltip, {
859
+ title: t("studio_rls_enabled"),
860
+ children: /* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 rounded-full bg-green-500" })
861
+ }) : /* @__PURE__ */ jsx(Tooltip, {
862
+ title: t("studio_rls_disabled"),
863
+ children: /* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 rounded-full bg-orange-400 opacity-50" })
864
+ }), /* @__PURE__ */ jsx("span", {
865
+ className: "text-[10px] opacity-40 group-hover:opacity-100 min-w-[1.2rem] text-right font-medium",
866
+ children: table.policies.length
867
+ })]
868
+ })
869
+ ]
870
+ }, key);
871
+ })
872
+ })]
873
+ }, schemaName))
874
+ })]
875
+ }), sidebarTab === "info" && /* @__PURE__ */ jsxs("div", {
876
+ className: "flex flex-col h-full",
877
+ children: [/* @__PURE__ */ jsx("div", {
878
+ className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin),
879
+ children: /* @__PURE__ */ jsx(Typography, {
880
+ variant: "caption",
881
+ className: "font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark",
882
+ children: "Overview"
883
+ })
884
+ }), /* @__PURE__ */ jsxs("div", {
885
+ className: "flex-grow overflow-y-auto p-3 space-y-3 no-scrollbar",
886
+ children: [
887
+ /* @__PURE__ */ jsxs("div", {
888
+ className: cls("p-3 rounded-lg border bg-white dark:bg-surface-900", defaultBorderMixin),
889
+ children: [/* @__PURE__ */ jsxs("div", {
890
+ className: "flex items-center gap-2 mb-2",
891
+ children: [/* @__PURE__ */ jsx(ShieldIcon, {
892
+ size: iconSize.smallest,
893
+ className: "text-primary"
894
+ }), /* @__PURE__ */ jsx(Typography, {
895
+ variant: "body2",
896
+ className: "font-semibold text-[13px]",
897
+ children: "RLS Studio"
898
+ })]
899
+ }), /* @__PURE__ */ jsx(Typography, {
900
+ variant: "caption",
901
+ className: "text-text-secondary dark:text-text-secondary-dark text-[11px] leading-relaxed block",
902
+ children: "Manage Row Level Security policies for your PostgreSQL tables. Enable RLS and create fine-grained access policies."
903
+ })]
904
+ }),
905
+ /* @__PURE__ */ jsxs("div", {
906
+ className: "space-y-2",
907
+ children: [
908
+ /* @__PURE__ */ jsxs("div", {
909
+ className: cls("p-2.5 rounded border bg-white dark:bg-surface-900 flex items-center justify-between", defaultBorderMixin),
910
+ children: [/* @__PURE__ */ jsx(Typography, {
911
+ variant: "caption",
912
+ className: "text-text-secondary dark:text-text-secondary-dark text-[11px]",
913
+ children: "Total tables"
914
+ }), /* @__PURE__ */ jsx(Typography, {
915
+ variant: "body2",
916
+ className: "font-mono text-[13px] font-medium",
917
+ children: rlsStats.total
918
+ })]
919
+ }),
920
+ /* @__PURE__ */ jsxs("div", {
921
+ className: cls("p-2.5 rounded border bg-white dark:bg-surface-900 flex items-center justify-between", defaultBorderMixin),
922
+ children: [/* @__PURE__ */ jsx(Typography, {
923
+ variant: "caption",
924
+ className: "text-text-secondary dark:text-text-secondary-dark text-[11px]",
925
+ children: "RLS enabled"
926
+ }), /* @__PURE__ */ jsxs("div", {
927
+ className: "flex items-center gap-1.5",
928
+ children: [/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 rounded-full bg-green-500" }), /* @__PURE__ */ jsx(Typography, {
929
+ variant: "body2",
930
+ className: "font-mono text-[13px] font-medium",
931
+ children: rlsStats.enabled
932
+ })]
933
+ })]
934
+ }),
935
+ /* @__PURE__ */ jsxs("div", {
936
+ className: cls("p-2.5 rounded border bg-white dark:bg-surface-900 flex items-center justify-between", defaultBorderMixin),
937
+ children: [/* @__PURE__ */ jsx(Typography, {
938
+ variant: "caption",
939
+ className: "text-text-secondary dark:text-text-secondary-dark text-[11px]",
940
+ children: "Tables with policies"
941
+ }), /* @__PURE__ */ jsx(Typography, {
942
+ variant: "body2",
943
+ className: "font-mono text-[13px] font-medium",
944
+ children: rlsStats.withPolicies
945
+ })]
946
+ }),
947
+ /* @__PURE__ */ jsxs("div", {
948
+ className: cls("p-2.5 rounded border bg-white dark:bg-surface-900 flex items-center justify-between", defaultBorderMixin),
949
+ children: [/* @__PURE__ */ jsx(Typography, {
950
+ variant: "caption",
951
+ className: "text-text-secondary dark:text-text-secondary-dark text-[11px]",
952
+ children: "Total policies"
953
+ }), /* @__PURE__ */ jsx(Typography, {
954
+ variant: "body2",
955
+ className: "font-mono text-[13px] font-medium",
956
+ children: rlsStats.totalPolicies
957
+ })]
958
+ })
959
+ ]
960
+ }),
961
+ rlsStats.total - rlsStats.enabled > 0 && /* @__PURE__ */ jsxs("div", {
962
+ className: cls("p-2.5 rounded border border-yellow-200 dark:border-yellow-900/50 bg-yellow-50 dark:bg-yellow-900/20 flex items-start gap-2", defaultBorderMixin),
963
+ children: [/* @__PURE__ */ jsx(AlertTriangleIcon, {
964
+ size: 14,
965
+ className: "text-yellow-600 dark:text-yellow-500 mt-0.5 shrink-0"
966
+ }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs(Typography, {
967
+ variant: "caption",
968
+ className: "text-yellow-800 dark:text-yellow-400 text-[11px] font-semibold block",
969
+ children: [
970
+ rlsStats.total - rlsStats.enabled,
971
+ " table",
972
+ rlsStats.total - rlsStats.enabled > 1 ? "s" : "",
973
+ " without RLS"
974
+ ]
975
+ }), /* @__PURE__ */ jsx(Typography, {
976
+ variant: "caption",
977
+ className: "text-yellow-700 dark:text-yellow-600 text-[10px] block mt-0.5",
978
+ children: "These tables have no row-level access control. If auth enforcement is disabled, data may be publicly accessible."
979
+ })] })]
980
+ }),
981
+ rlsStats.enabled > 0 && rlsStats.enabled - rlsStats.withPolicies > 0 && /* @__PURE__ */ jsxs("div", {
982
+ className: cls("p-2.5 rounded border border-blue-200 dark:border-blue-900/50 bg-blue-50 dark:bg-blue-900/20 flex items-start gap-2", defaultBorderMixin),
983
+ children: [/* @__PURE__ */ jsx(ShieldIcon, {
984
+ size: 14,
985
+ className: "text-blue-600 dark:text-blue-400 mt-0.5 shrink-0"
986
+ }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs(Typography, {
987
+ variant: "caption",
988
+ className: "text-blue-800 dark:text-blue-300 text-[11px] font-semibold block",
989
+ children: [
990
+ rlsStats.enabled - rlsStats.withPolicies,
991
+ " table",
992
+ rlsStats.enabled - rlsStats.withPolicies > 1 ? "s" : "",
993
+ " with RLS but no policies"
994
+ ]
995
+ }), /* @__PURE__ */ jsx(Typography, {
996
+ variant: "caption",
997
+ className: "text-blue-700 dark:text-blue-500 text-[10px] block mt-0.5",
998
+ children: "RLS is enabled but no permissive policies exist. All access is denied by default (Postgres deny-all)."
999
+ })] })]
1000
+ })
1001
+ ]
1002
+ })]
1003
+ })]
1004
+ })]
1005
+ }),
1006
+ secondPanel: /* @__PURE__ */ jsxs("div", {
1007
+ className: "flex-grow flex flex-col min-w-0 h-full w-full bg-white dark:bg-surface-950",
1008
+ children: [/* @__PURE__ */ jsxs("div", {
1009
+ className: cls("flex items-center justify-between pr-2 border-b bg-white dark:bg-surface-950 min-h-[46px]", defaultBorderMixin),
1010
+ children: [/* @__PURE__ */ jsxs("div", {
1011
+ className: "flex items-center flex-grow overflow-hidden px-4",
1012
+ children: [/* @__PURE__ */ jsx(Typography, {
1013
+ variant: "subtitle2",
1014
+ className: "font-mono text-text-secondary dark:text-text-secondary-dark truncate",
1015
+ children: activeTableData ? `${activeTableData.schemaName}.${activeTableData.tableName}` : t("studio_rls_select_table")
1016
+ }), activeTableData && /* @__PURE__ */ jsx("div", {
1017
+ className: "ml-3",
1018
+ children: activeTableData.rlsEnabled ? /* @__PURE__ */ jsx(Chip, {
1019
+ size: "smallest",
1020
+ className: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400 border-green-200 dark:border-green-800",
1021
+ children: t("studio_rls_enabled")
1022
+ }) : /* @__PURE__ */ jsx(Chip, {
1023
+ size: "smallest",
1024
+ className: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400 border-yellow-200 dark:border-yellow-800",
1025
+ children: t("studio_rls_disabled")
1026
+ })
1027
+ })]
1028
+ }), /* @__PURE__ */ jsx("div", {
1029
+ className: "flex shrink-0 items-center justify-end gap-1.5",
1030
+ children: activeTableData && /* @__PURE__ */ jsxs(Fragment, { children: [
1031
+ /* @__PURE__ */ jsx(Button, {
1032
+ variant: "text",
1033
+ size: "small",
1034
+ onClick: async () => {
1035
+ const table = activeTableData.tableName;
1036
+ const action = activeTableData.rlsEnabled ? "DISABLE" : "ENABLE";
1037
+ if (!confirm(`Are you sure you want to ${action.toLowerCase()} Row Level Security on "${table}"?`)) return;
1038
+ try {
1039
+ await databaseAdmin.executeSql(`ALTER TABLE ${sanitizeSqlIdentifier(table)} ${action} ROW LEVEL SECURITY`);
1040
+ snackbarController.open({
1041
+ type: "success",
1042
+ message: `RLS ${action.toLowerCase()}d on ${table}`
1043
+ });
1044
+ fetchRLSData();
1045
+ } catch (e) {
1046
+ snackbarController.open({
1047
+ type: "error",
1048
+ message: e instanceof Error ? e.message : String(e)
1049
+ });
1050
+ }
1051
+ },
1052
+ children: activeTableData.rlsEnabled ? t("studio_rls_disable_rls") : t("studio_rls_enable_rls")
1053
+ }),
1054
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-surface-200 dark:bg-surface-950 mx-1" }),
1055
+ /* @__PURE__ */ jsx(Button, {
1056
+ variant: "text",
1057
+ size: "small",
1058
+ onClick: fetchRLSData,
1059
+ startIcon: /* @__PURE__ */ jsx(RefreshCwIcon, { size: iconSize.smallest }),
1060
+ children: "Refresh"
1061
+ }),
1062
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-surface-200 dark:bg-surface-950 mx-1" }),
1063
+ /* @__PURE__ */ jsx(Button, {
1064
+ size: "small",
1065
+ color: "primary",
1066
+ disabled: !activeCollection,
1067
+ onClick: () => setEditingPolicy("new"),
1068
+ children: t("studio_rls_create_policy")
1069
+ })
1070
+ ] })
1071
+ })]
1072
+ }), isLoading && !activeTableData ? /* @__PURE__ */ jsx("div", {
1073
+ className: "flex-grow flex items-center justify-center h-full",
1074
+ children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" })
1075
+ }) : error ? /* @__PURE__ */ jsx("div", {
1076
+ className: "p-6 h-full flex items-center justify-center",
1077
+ children: /* @__PURE__ */ jsx(ErrorView, {
1078
+ title: t("studio_rls_error"),
1079
+ error,
1080
+ onRetry: fetchRLSData
1081
+ })
1082
+ }) : !activeTableData ? /* @__PURE__ */ jsx("div", {
1083
+ className: "flex-grow flex items-center justify-center text-text-disabled h-full",
1084
+ children: /* @__PURE__ */ jsxs("div", {
1085
+ className: "text-center",
1086
+ children: [/* @__PURE__ */ jsx("svg", {
1087
+ className: "w-12 h-12 mx-auto mb-4 opacity-50",
1088
+ fill: "none",
1089
+ stroke: "currentColor",
1090
+ viewBox: "0 0 24 24",
1091
+ children: /* @__PURE__ */ jsx("path", {
1092
+ strokeLinecap: "round",
1093
+ strokeLinejoin: "round",
1094
+ strokeWidth: 1,
1095
+ d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
1096
+ })
1097
+ }), /* @__PURE__ */ jsx(Typography, {
1098
+ variant: "body2",
1099
+ children: t("studio_rls_select_table")
1100
+ })]
1101
+ })
1102
+ }) : editingPolicy ? /* @__PURE__ */ jsx(PolicyEditor, {
1103
+ policy: editingPolicy === "new" ? void 0 : editingPolicy,
1104
+ schema: activeTableData.schemaName,
1105
+ table: activeTableData.tableName,
1106
+ onSave: async (newPolicy) => {
1107
+ if (!activeCollection) return;
1108
+ const rule = {
1109
+ name: newPolicy.policyname,
1110
+ operation: newPolicy.cmd?.toLowerCase(),
1111
+ mode: newPolicy.permissive?.toLowerCase(),
1112
+ using: newPolicy.qual || void 0,
1113
+ withCheck: newPolicy.with_check || void 0,
1114
+ roles: newPolicy.roles
1115
+ };
1116
+ const existingRules = (isPostgresCollection(activeCollection) ? activeCollection.securityRules : void 0) || [];
1117
+ let newRules;
1118
+ if (editingPolicy === "new") newRules = [...existingRules, rule];
1119
+ else newRules = existingRules.map((r) => r.name === editingPolicy.policyname ? rule : r);
1120
+ try {
1121
+ if (!(await fetch(`${apiUrl}/api/schema-editor/collection/save`, {
1122
+ method: "POST",
1123
+ headers: { "Content-Type": "application/json" },
1124
+ body: JSON.stringify({
1125
+ collectionId: activeCollection.id || activeCollection.path || activeCollection.alias || activeTableData.tableName,
1126
+ collectionData: { securityRules: newRules }
1127
+ })
1128
+ })).ok) throw new Error("Failed to save policy");
1129
+ snackbarController.open({
1130
+ type: "success",
1131
+ message: "Policy saved successfully"
1132
+ });
1133
+ setEditingPolicy(null);
1134
+ fetchRLSData();
1135
+ } catch (e) {
1136
+ snackbarController.open({
1137
+ type: "error",
1138
+ message: e instanceof Error ? e.message : String(e)
1139
+ });
1140
+ }
1141
+ },
1142
+ onCancel: () => setEditingPolicy(null)
1143
+ }) : /* @__PURE__ */ jsx("div", {
1144
+ className: "flex-grow flex flex-col overflow-hidden",
1145
+ children: /* @__PURE__ */ jsx("div", {
1146
+ className: "p-6 pt-4 flex-grow overflow-auto bg-surface-50 dark:bg-surface-900",
1147
+ children: /* @__PURE__ */ jsxs("div", {
1148
+ className: "max-w-4xl mx-auto flex flex-col gap-6",
1149
+ children: [
1150
+ activeTableData && !activeCollection && /* @__PURE__ */ jsxs(Alert, {
1151
+ color: "warning",
1152
+ children: [/* @__PURE__ */ jsx(Typography, {
1153
+ variant: "body2",
1154
+ className: "mb-1",
1155
+ children: "Table not managed by Rebase"
1156
+ }), /* @__PURE__ */ jsx(Typography, {
1157
+ variant: "caption",
1158
+ className: "opacity-80",
1159
+ children: "This table is not mapped to a Rebase Schema via code. To edit security policies visually, you must first import this table into a Schema configuration file."
1160
+ })]
1161
+ }),
1162
+ activeTableData && !activeTableData.rlsEnabled && /* @__PURE__ */ jsxs("div", {
1163
+ className: cls("p-4 sm:p-5 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-900/50 rounded-lg flex flex-col sm:flex-row gap-4 items-start sm:items-center justify-between", defaultBorderMixin),
1164
+ children: [/* @__PURE__ */ jsxs("div", {
1165
+ className: "flex gap-3 items-start",
1166
+ children: [/* @__PURE__ */ jsx("div", {
1167
+ className: "mt-1 bg-yellow-100 dark:bg-yellow-900/50 p-1.5 rounded-md shrink-0 flex items-center justify-center",
1168
+ children: /* @__PURE__ */ jsx(AlertTriangleIcon, { size: iconSize.smallest })
1169
+ }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
1170
+ variant: "subtitle2",
1171
+ className: "text-yellow-800 dark:text-yellow-500",
1172
+ children: "Row Level Security (RLS) is disabled"
1173
+ }), /* @__PURE__ */ jsx(Typography, {
1174
+ variant: "body2",
1175
+ className: "text-yellow-700 dark:text-yellow-600/90 mt-1 max-w-2xl",
1176
+ children: "Your table is completely readable and writable by anyone with access privileges. Enable RLS to create policies that restrict access to specific rows."
1177
+ })] })]
1178
+ }), /* @__PURE__ */ jsx(Button, {
1179
+ size: "medium",
1180
+ variant: "filled",
1181
+ color: "neutral",
1182
+ onClick: () => setEditingPolicy("new"),
1183
+ className: "shrink-0 whitespace-nowrap",
1184
+ disabled: !activeCollection,
1185
+ children: t("studio_rls_create_policy")
1186
+ })]
1187
+ }),
1188
+ activeTableData && mergedPolicies && mergedPolicies.length > 0 && /* @__PURE__ */ jsxs("div", {
1189
+ className: "flex flex-col gap-3",
1190
+ children: [/* @__PURE__ */ jsx(Typography, {
1191
+ variant: "subtitle2",
1192
+ className: "text-text-secondary dark:text-text-secondary-dark uppercase tracking-wider mb-1",
1193
+ children: t("studio_rls_policies")
1194
+ }), mergedPolicies.map((policy) => /* @__PURE__ */ jsxs(Paper, {
1195
+ className: cls("p-3 sm:px-4 sm:py-3 flex flex-col sm:flex-row sm:items-center justify-between gap-4 border rounded-lg", defaultBorderMixin),
1196
+ children: [/* @__PURE__ */ jsxs("div", {
1197
+ className: "flex flex-col gap-2 min-w-0",
1198
+ children: [/* @__PURE__ */ jsxs("div", {
1199
+ className: "flex items-center gap-2",
1200
+ children: [
1201
+ /* @__PURE__ */ jsx(KeyIcon, {
1202
+ size: iconSize.smallest,
1203
+ className: "text-text-secondary dark:text-text-secondary-dark shrink-0"
1204
+ }),
1205
+ /* @__PURE__ */ jsx(Typography, {
1206
+ variant: "body2",
1207
+ className: "truncate",
1208
+ children: policy.policyname
1209
+ }),
1210
+ policy.status === "code_only" && /* @__PURE__ */ jsx(Tooltip, {
1211
+ title: "This policy is defined in your code but hasn't been applied to the database yet.",
1212
+ children: /* @__PURE__ */ jsx("div", {
1213
+ className: "px-1.5 py-0.5 rounded text-[10px] uppercase bg-primary/10 text-primary border border-primary/20 shrink-0",
1214
+ children: "Unapplied"
1215
+ })
1216
+ }),
1217
+ policy.status === "live" && /* @__PURE__ */ jsx(Tooltip, {
1218
+ title: "This policy is live in the database but missing from your codebase schema.",
1219
+ children: /* @__PURE__ */ jsx("div", {
1220
+ className: "px-1.5 py-0.5 rounded text-[10px] uppercase bg-orange-500/10 text-orange-600 border border-orange-500/20 shrink-0",
1221
+ children: "DB Only"
1222
+ })
1223
+ })
1224
+ ]
1225
+ }), /* @__PURE__ */ jsxs("div", {
1226
+ className: "flex flex-wrap gap-1.5 text-sm",
1227
+ children: [renderPolicyTag("Action", policy.cmd), renderPolicyTag("Roles", Array.isArray(policy.roles) ? policy.roles.join(", ") : policy.roles)]
1228
+ })]
1229
+ }), /* @__PURE__ */ jsxs("div", {
1230
+ className: "flex gap-2 shrink-0 items-center",
1231
+ children: [
1232
+ policy.status === "live" && activeCollection && /* @__PURE__ */ jsx(Button, {
1233
+ size: "small",
1234
+ variant: "outlined",
1235
+ color: "primary",
1236
+ onClick: async () => {
1237
+ const rule = {
1238
+ name: policy.policyname,
1239
+ operation: policy.cmd?.toLowerCase(),
1240
+ mode: policy.permissive?.toLowerCase(),
1241
+ using: policy.qual || void 0,
1242
+ withCheck: policy.with_check || void 0,
1243
+ roles: policy.roles
1244
+ };
1245
+ const newRules = [...(isPostgresCollection(activeCollection) ? activeCollection.securityRules : void 0) || [], rule];
1246
+ try {
1247
+ if (!(await fetch(`${apiUrl}/api/schema-editor/collection/save`, {
1248
+ method: "POST",
1249
+ headers: { "Content-Type": "application/json" },
1250
+ body: JSON.stringify({
1251
+ collectionId: activeCollection.id || activeCollection.path || activeCollection.alias || activeTableData.tableName,
1252
+ collectionData: { securityRules: newRules }
1253
+ })
1254
+ })).ok) throw new Error("Failed to save policy");
1255
+ snackbarController.open({
1256
+ type: "success",
1257
+ message: "Policy imported successfully"
1258
+ });
1259
+ fetchRLSData();
1260
+ } catch (e) {
1261
+ snackbarController.open({
1262
+ type: "error",
1263
+ message: e instanceof Error ? e.message : String(e)
1264
+ });
1265
+ }
1266
+ },
1267
+ children: "Import to codebase"
1268
+ }),
1269
+ /* @__PURE__ */ jsx(Button, {
1270
+ size: "small",
1271
+ variant: "text",
1272
+ color: "primary",
1273
+ onClick: () => setEditingPolicy(policy),
1274
+ disabled: !activeCollection,
1275
+ children: t("studio_rls_edit")
1276
+ }),
1277
+ policy.status !== "code_only" && /* @__PURE__ */ jsx(Tooltip, {
1278
+ title: t("studio_rls_delete"),
1279
+ asChild: true,
1280
+ children: /* @__PURE__ */ jsx(IconButton, {
1281
+ size: "small",
1282
+ onClick: async () => {
1283
+ const table = activeTableData.tableName;
1284
+ if (!confirm(`Drop policy "${policy.policyname}" from table "${table}"?`)) return;
1285
+ try {
1286
+ await databaseAdmin.executeSql(`DROP POLICY ${sanitizeSqlIdentifier(policy.policyname)} ON ${sanitizeSqlIdentifier(table)}`);
1287
+ snackbarController.open({
1288
+ type: "success",
1289
+ message: `Policy "${policy.policyname}" dropped`
1290
+ });
1291
+ fetchRLSData();
1292
+ } catch (e) {
1293
+ snackbarController.open({
1294
+ type: "error",
1295
+ message: e instanceof Error ? e.message : String(e)
1296
+ });
1297
+ }
1298
+ },
1299
+ children: /* @__PURE__ */ jsx(Trash2Icon, { size: iconSize.smallest })
1300
+ })
1301
+ })
1302
+ ]
1303
+ })]
1304
+ }, policy.policyname))]
1305
+ }),
1306
+ activeTableData && mergedPolicies.length === 0 && activeTableData.rlsEnabled && /* @__PURE__ */ jsxs("div", {
1307
+ className: "flex flex-col items-center justify-center py-12 text-center",
1308
+ children: [
1309
+ /* @__PURE__ */ jsx(ShieldIcon, {
1310
+ size: 40,
1311
+ className: "text-surface-300 dark:text-surface-600 mb-4"
1312
+ }),
1313
+ /* @__PURE__ */ jsx(Typography, {
1314
+ variant: "subtitle2",
1315
+ className: "text-text-secondary dark:text-text-secondary-dark mb-2",
1316
+ children: "No policies defined"
1317
+ }),
1318
+ /* @__PURE__ */ jsx(Typography, {
1319
+ variant: "caption",
1320
+ className: "text-text-disabled dark:text-text-disabled-dark max-w-sm mb-4",
1321
+ children: "RLS is enabled on this table but no policies exist. All access is denied by default (Postgres deny-all). Create a policy to allow specific access."
1322
+ }),
1323
+ activeCollection && /* @__PURE__ */ jsx(Button, {
1324
+ size: "small",
1325
+ variant: "filled",
1326
+ color: "primary",
1327
+ onClick: () => setEditingPolicy("new"),
1328
+ children: t("studio_rls_create_policy")
1329
+ })
1330
+ ]
1331
+ }),
1332
+ activeTableData && mergedPolicies.length === 0 && !activeTableData.rlsEnabled && activeCollection && /* @__PURE__ */ jsxs("div", {
1333
+ className: "flex flex-col items-center justify-center py-12 text-center",
1334
+ children: [
1335
+ /* @__PURE__ */ jsx(AlertTriangleIcon, {
1336
+ size: 40,
1337
+ className: "text-yellow-400 dark:text-yellow-600 mb-4"
1338
+ }),
1339
+ /* @__PURE__ */ jsx(Typography, {
1340
+ variant: "subtitle2",
1341
+ className: "text-text-secondary dark:text-text-secondary-dark mb-2",
1342
+ children: "No access control"
1343
+ }),
1344
+ /* @__PURE__ */ jsx(Typography, {
1345
+ variant: "caption",
1346
+ className: "text-text-disabled dark:text-text-disabled-dark max-w-sm",
1347
+ children: "This table has neither RLS nor policies. Enable RLS and create policies to restrict row-level access."
1348
+ })
1349
+ ]
1350
+ })
1351
+ ]
1352
+ })
1353
+ })
1354
+ })]
1355
+ })
1356
+ })
1357
+ });
1358
+ };
1359
+ //#endregion
1360
+ export { RLSEditor };
1361
+
1362
+ //# sourceMappingURL=RLSEditor-CTxYbBdW.js.map